Building_eload
Version: 0.9.0
District-level building energy simulation at hourly resolution.
This model was first presented in the research article : https://doi.org/10.1016/j.enbuild.2026.117409
building_eload is developed as a library, released on PyPI. The Snakemake
workflow reproducing the paper's results lives in a separate repository
(building_eload_paper), pinned to the published 0.4.x releases of this
package.
Overview
The model is a two-stage pipeline, split across two packages since 0.9.0:
- Static simulation — annual building-level energy estimates and district
calibration. This stage now lives in the separate
buildingcalibrationpackage (buildingcalibration.calibration), together with the validation (.validation), the representative-district clustering (.clustering) and their figures (.plots). - Dynamic simulation — hourly electricity load profiles from those static outputs. This package.
building_eload is therefore a pure dynamic-simulation library: the hourly
end-use models (models/), the simulation orchestrator
(core/dynamic_simulation) and the load-curve plots. It does not import
buildingcalibration, and buildingcalibration does not import it — the
handover is either a set of parquet files on disk or an in-memory object
matching core.dynamic_simulation.StaticResultsLike (see
DynamicSimulation.from_static_results below).
Main dependencies:
buildingdata(reference datasets: ELMAS non-residential load curves, occupant activity diaries, ERA5-derived climate)heatpumpmodel(the opt-in heat-pump performance core)
Installation
git clone https://git.persee.minesparis.psl.eu/planeterr/building_eload.git
cd building_eload
pip install -e .
The static-calibration half of the pipeline is a separate install:
pip install buildingcalibration
Data Paths Exposed by the Package
Defined in building_eload/__init__.py (a registry task G8 retires; the keys
the dynamic stage actually reads are marked):
data_path["data"]data_path["simulation"]— read (static-stage inputs, dynamic outputs)data_path["activity_calendar"]— read (occupant diaries)data_path["climate"]data_path["elmas"]data_path["bdtopo"],data_path["validation"],data_path["representative_districts"]— kept for compatibility only; their readers moved tobuildingcalibrationin 0.9.0plot_path
Data Layout
The data/ directory is not tracked in git (multi-GB). All paths in
data_path resolve relative to the repository root:
data/
├── activity_calendar/ # occupant activity calendars (10-min time step)
├── climate/ # ERA5-derived weather files (EPW)
├── elmas/ # ELMAS dataset
└── simulation/ # static-stage inputs + dynamic simulation results
The keys of the historical tree that only the static/validation/clustering
stages read (bdtopo/, validation/, representative_districts/) belong to
buildingcalibration since 0.9.0; they remain in data_path (a dict) until
task G8 retires the registry, but nothing in this package reads them.
Reference data (occupant diaries, ELMAS, ERA5 climate) is fetched through the
buildingdata package. The unit test suite runs without data/; the
integration tests (DynamicSimulation.from_files, the generated-EPW checks)
require it.
Since 0.9.0 every module that read
data_pathother thancore.dynamic_simulationhas left the package (improvement plan, tasks G3/G5), and the two rules that made that possible now apply tobuildingcalibration:
- External open data is never a path — it comes from a
buildingdatagetter, so nodata/tree is needed out of the box.- Pipeline intermediates are frames first, explicit paths second, and have no default — a missing one raises a
ValueErrornaming the parameter.
data_pathitself still exists forcore.dynamic_simulation(DynamicParametersresolves its IO and activity-calendar roots from it at import time) and is removed by task G8, which applies the same two rules here.
Current Core API
Dynamic simulation (building_eload.core.dynamic_simulation)
Main classes:
DynamicParametersDynamicSimulation
Primary methods used by users:
DynamicSimulation.from_files(district_id, parameters)DynamicSimulation.from_static_results(static_results, parameters)DynamicSimulation.run()DynamicSimulation.save_results()DynamicSimulation.plot_results(...)
The static-stage seam (StaticResultsLike)
from_static_results accepts any object carrying the seven attributes the
dynamic stage reads — district_id, climate_year, climate_path,
climate_file, residential_buildings, dwellings,
non_residential_buildings. That contract is published as a
typing.Protocol:
from buildingcalibration.calibration import StaticSimulation, StaticParameters
from building_eload.core.dynamic_simulation import (
DynamicParameters, DynamicSimulation, StaticResultsLike,
)
static_results = StaticSimulation("262320000", StaticParameters(...)).run()
assert isinstance(static_results, StaticResultsLike) # runtime-checkable
sim = DynamicSimulation.from_static_results(static_results, DynamicParameters(year=2023))
Neither package imports the other; the isinstance check is the whole
coupling. Passing files instead (from_files) needs no adapter at all.
Static calibration, validation, clustering
Moved to buildingcalibration in 0.9.0 — same public names, new import paths:
buildingcalibration.calibration (StaticParameters, StaticSimulation,
StaticResults, BuildingModelResults, StaticProcessor, BuildingLoader,
the representative-district selectors), buildingcalibration.validation
(Validation), buildingcalibration.clustering (cluster_districts,
screen_unreliable_iris*) and buildingcalibration.plots.
Minimal Usage
Tutorials for the dynamic simulation are available in /doc/tutorials; the
static/validation ones moved with their domain (see
doc/tutorials/moved_to_buildingcalibration.md).
1) Dynamic simulation
from building_eload.core.dynamic_simulation import DynamicParameters, DynamicSimulation
district_id = "262320000"
params = DynamicParameters(
year=2023,
run_non_residential=True,
run_again=True,
)
sim = DynamicSimulation.from_files(district_id=district_id, parameters=params)
sim.run()
sim.save_results()
2) Dynamic simulation with the heat-pump model (opt-in)
The conversion of hourly heating demand into heating electricity happens in
a single place, building_eload.models.heating_system. Leaving
DynamicSimulation.heating_system at None keeps the published
constant-efficiency (static-COP) behaviour; assigning a converter swaps the
model without touching anything else:
from building_eload.models import heat_pump as hp
from building_eload.models.heat_pump_system import HeatPumpHeatingSystem
# Defaults: air-to-water, medium-temperature radiators with weather
# compensation, inverter, monovalent with an electric-resistance backup --
# the reference configuration of Rogeau et al. (2024). Applied to the
# buildings whose `heating_system` is "electric heat pump"; every other
# building keeps the published conversion.
sim.heating_system = HeatPumpHeatingSystem(
hp.HeatPumpConfig(
system=hp.System.A_W,
mode=hp.Mode.M,
emitter=hp.Emitter.FH, # floor heating; the biggest SCOP lever
technology=hp.Technology.INVERTER,
)
)
sim.run()
The hourly results then carry heat_pump_electricity_need and
heating_backup_electricity_need alongside the usual
heating_electricity_need (their sum), plus heat_pump_heat_delivered.
Air-source configurations require the weather frame's humidity column and
fail loudly without it, rather than silently disabling the defrost derate.
Running Simulations
The former building_eload.scripts entry points were removed in 0.8.0; use
the public API instead (the tutorials in doc/tutorials/ walk through each
step):
building_eload.core.dynamic_simulation.DynamicSimulation— dynamic hourly simulation (this package)buildingcalibration.calibration.StaticSimulation— static annual calibration (moved out in 0.9.0)buildingcalibration.validation.Validation— validation against measured consumption (moved out in 0.9.0)buildingcalibration.clustering.cluster_districts— representative-district selection (moved out in 0.9.0)- EPW climate generation lives in the
buildingdatapackage (buildingdata.prefetch_era5for the bulk ERA5 download,buildingdata.get_era5_climatefor per-point EPW files)
For an end-to-end orchestrated pipeline, see the Snakemake workflow in the
building_eload_paper repository.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file building_eload-0.9.0-py3-none-any.whl.
File metadata
- Download URL: building_eload-0.9.0-py3-none-any.whl
- Upload date:
- Size: 100.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
07d246d24d07b54403d8be54c4ac393cdae5bd4aeb47d947dd470909b52ae8ef
|
|
| MD5 |
7c6d87a9611f0894ad3e1669349b41d7
|
|
| BLAKE2b-256 |
7843d07acbba74eb41fa202d61dd313471ccf06dfc450e56f46e752708e51a63
|