Skip to content

curve_registry

curve_registry

Single source of truth for hourly output curve names.

etengine renamed the hourly curve endpoints (merit_order -> electricity_profiles, heat_network -> district_heating_profiles, hydrogen -> hydrogen_profiles, network_gas -> network_gas_profiles) but kept the OLD names as backwards-compatible aliases. The old names therefore work on BOTH modern engines (pro) and stable engines (2025-01, which only ever had the old names), so pyetm uses them as the on-the-wire name and needs no per-engine logic.

Each logical curve maps to: - canonical: the stable, public key used inside pyetm (cache files, curve.key); the modern name. - wire: the name sent in the request URL (the universal old name where one exists). - endpoint: curves -> /scenarios/{id}/curves/{name}.csv

Classes

CurveSpec dataclass

CurveSpec(canonical, wire, endpoint, curve_type, carrier=None)

Describes one logical curve.

Functions

canonical_names

canonical_names()

Canonical key for every registered curve.

Source code in src/pyetm/config/curve_registry.py
def canonical_names() -> list[str]:
    """Canonical key for every registered curve."""
    return [s.canonical for s in _SPECS]

accept_alias

accept_alias(name)

Resolve a legacy/old curve name to its canonical key.

Emits a deprecation warning for old engine names; unknown names pass through unchanged so non-registered identifiers still reach the engine.

Source code in src/pyetm/config/curve_registry.py
def accept_alias(name: str) -> str:
    """Resolve a legacy/old curve name to its canonical key.

    Emits a deprecation warning for old engine names; unknown names pass through unchanged so
    non-registered identifiers still reach the engine.
    """
    if name in _BY_CANONICAL:
        return name
    canonical = _DEPRECATED_ALIASES.get(name)
    if canonical is None:
        return name
    logger.warning("Curve name '%s' is deprecated; use '%s' instead.", name, canonical)
    return canonical

get_spec

get_spec(name)

Spec for a curve by canonical or alias name, or None if not registered.

Source code in src/pyetm/config/curve_registry.py
def get_spec(name: str) -> Optional[CurveSpec]:
    """Spec for a curve by canonical or alias name, or None if not registered."""
    return _BY_CANONICAL.get(accept_alias(name))

curve_type_for

curve_type_for(name)

pyetm curve type tag for a curve name.

Source code in src/pyetm/config/curve_registry.py
def curve_type_for(name: str) -> str:
    """pyetm curve type tag for a curve name."""
    spec = get_spec(name)
    return spec.curve_type if spec else "output_curve"

carrier_to_canonical

carrier_to_canonical()

Carrier alias -> canonical curve name (primary curve per carrier).

Source code in src/pyetm/config/curve_registry.py
def carrier_to_canonical() -> dict[str, str]:
    """Carrier alias -> canonical curve name (primary curve per carrier)."""
    return {s.carrier: s.canonical for s in _SPECS if s.carrier}

build_path

build_path(session_id, name)

Request path for an output curve / capacity export.

curves -> /scenarios/{id}/curves/{wire_name}.csv export -> /scenarios/{id}/{name} (scenario-member, mirrors fetch_annual_exports)

Source code in src/pyetm/config/curve_registry.py
def build_path(session_id: Any, name: str) -> str:
    """Request path for an output curve / capacity export.

    ``curves``  -> /scenarios/{id}/curves/{wire_name}.csv
    ``export``  -> /scenarios/{id}/{name}   (scenario-member, mirrors fetch_annual_exports)
    """
    spec = get_spec(name)
    if spec and spec.endpoint == "export":
        return f"/scenarios/{session_id}/{spec.canonical}"
    wire = spec.wire if spec else name
    return f"/scenarios/{session_id}/curves/{wire}.csv"