Skip to main content

PyPI version Documentation Status Build Status License DOI

loadcast

A synthetic multi-carrier industrial energy demand generator

import loadcast

profiles = loadcast.generate(
    annual_mwh=10_000,
    heat_to_cold=7.4,        # this site wants 7.4x more heat than cold
    elec_share=0.20,         # a fifth of its energy is electricity
    process_class="semi_continuous",   # weekday shifts, weekend trough
    carrier_correlation=0.75,          # how tightly the carriers move together
    carrier_lag_h={"cold": 6},         # cold demand trails heat by six hours
)

Returns an 8760-row hourly or quarter-hourly frame of heat_kw, cold_kw and elec_kw.

Heat-cold cross-correlogram: the published disaggregated construction peaks at exactly 1.000; loadcast peaks at the 0.60 asked for

Left: every carrier as a fixed multiple of one shared profile, the construction behind published disaggregated data, which is correlated at 1 by algebra. Right: loadcast with carrier_correlation=0.60. More in the tutorial notebook.

Why

Designing anything with storage against an industrial site needs to know not just how much of each carrier the site wants, but whether it wants them at the same hours. A store exists to bridge the gap when it does not.

Existing sources cannot answer that question:

source approach industrial coincidence controllable?
demandlib / BDEW SLP deterministic step profiles yes no — deterministic
RAMP bottom-up from appliances no no — emerges from user schedules
LoadProfileGenerator behavioural simulation no no
EnTiSe framework, pluggable methods partly no — pipeline dependency
JERICHO-E-usage disaggregated national totals yes no — fixed at 1.000

The disaggregated datasets build every carrier as a fixed scalar times one shared profile, $P_m(t) = \kappa_m p(t)$, under which the correlation between any two carriers is identically 1 — an artefact of the construction, not a measurement. Feeding that into a storage study builds the answer into the question.

loadcast makes the relationship an input you set and sweep.

What you specify

Things you can answer from a site visit or an energy bill, not things the mathematics wants:

input meaning
annual_mwh total annual energy across all carriers
heat_to_cold ratio of annual heat to annual cold
elec_share electricity as a fraction of the total
process_class continuous, semi-continuous, campaign or batch
carrier_correlation how tightly carriers move together, at peak alignment
carrier_lag_h hours by which a carrier trails the others

The four process classes are calibrated on metered industrial sites. If none fits yours, build one from your own statistics:

from loadcast import class_from_observations, register_class

mine = class_from_observations(
    "my_plant", load_factor=0.45, cv=0.60, lag1=0.90,
    calendar_from="semi_continuous",
)
register_class(mine)
profiles = loadcast.generate(process_class="my_plant", annual_mwh=5_000)

The inversion from observables to generator parameters is closed form. See mathematics for details.

What it guarantees exactly

Not approximately, but to floating-point:

  • annual energy equals annual_mwh
  • the heat:cold ratio equals heat_to_cold
  • the electricity share equals elec_share
  • the load factor equals the process class's, via the capacity cap fixed point
  • every value is strictly positive

Diagnostics

loadcast.summary_table(profiles)                       # the four scalars
loadcast.duration_curve(profiles["heat_kw"])           # load duration curve
loadcast.cross_correlogram(profiles["heat_kw"], profiles["cold_kw"])
loadcast.integrated_drift(profiles["heat_kw"], profiles["cold_kw"], window_h=24)

Read the correlogram's peak position, not only its height. A lag and a weak coupling are indistinguishable from the contemporaneous correlation alone: as carriers are offset, the lag-0 correlation decays towards the floor the shared calendar imposes, exactly where a small correlation would also put it.

integrated_drift is the quantity a store actually responds to. A buffer does not sample a mismatch, it integrates one, so what sizes it is the area under the mismatch autocovariance over the storage window — correlation is a single point of that picture.

What it deliberately does not do

  • No temperature. It carries energy by carrier. Whether a machine can reach a given process is a separate question, answered from the machine's own limits.
  • No claim about your site. Parameters are yours to choose; defaults are indicative values with a stated provenance, not predictions. Results are meant to be reported as they hold across a swept space, not at one assumed point.
  • No cold validation. No site in the calibration archive meters refrigeration. The cold carrier's annual quantity is whatever you specify; its shape rests on the same calendar and correlation assumptions as the others, and nothing independent confirms it. Every cold result carries this.

Install

pip install loadcast

Requires Python 3.9+, numpy and pandas. Nothing else.

Documentation

A detailed documentation of the library is available at: https://loadcast.readthedocs.io/en/latest/

Refer to that documentation for usage instructions and examples and details of the method.

Calibration data

The process classes are calibrated on metered industrial sites that cannot be redistributed. What ships is the derived statistics and calendar factors — group means carrying no identifying information. The raw series are not part of this repository.

Contributing

Issues and pull requests are welcome — see CONTRIBUTING.md for scope, what a test looks like here, and support expectations. Reports that the generated profiles disagree with a real site you have measured are especially welcome: the calibration archive is small, and that is the package's main limitation.

This project follows the Contributor Covenant. Generative AI was used in building it; see AI_USAGE.md.

Citing

Use the "Cite this repository" button, or CITATION.cff. Each release is archived on Zenodo with a DOI.

Licence

MIT — see LICENSE. Changes are recorded in CHANGELOG.md.

Metadata

Release files for loadcast 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for loadcast 0.1.1
File Size Uploaded
loadcast-0.1.1.tar.gz 39.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for loadcast 0.1.1
File Interpreter ABI Platform
loadcast-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 72.7 kB

Release files / loadcast-0.1.1.tar.gz

Download URL loadcast-0.1.1.tar.gz
Size 39.8 kB
Tags Source
SHA-256 checksum
How to use checksums
88f4c833ccc2d1f1a86ef9e892e00c243273dbf796b43aa642ed1a4655e34e7a
BLAKE2b-256 checksum
How to use checksums
dcb2a4929cef76233aa0fa9c0fa1611101347ebfd14ffc93af0915ad550aa583
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.

Transparency log

Release files / loadcast-0.1.1-py3-none-any.whl

Download URL loadcast-0.1.1-py3-none-any.whl
Size 33.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e3a8e16cb64be9b410f389dcf2b217b9ae22a8bd9f99305c1c582c558d4b419c
BLAKE2b-256 checksum
How to use checksums
a44191b20a0219692ca00573d5970f9c2070c832d65c2b60108a8c84ea81f744
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

This release

0.1.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page