wolfhece.mockup_spw_xlsx

Author: HECE - University of Liege, Pierre Archambeau Date: 2026

Copyright (c) 2024 University of Liege. All rights reserved.

This script and its content are protected by copyright law. Unauthorized copying or distribution of this file, via any medium, is strictly prohibited.

Module Contents

class wolfhece.mockup_spw_xlsx.LandUseType[source]
name: str[source]
runoff_coefficient: float[source]
description: str = ''[source]
class wolfhece.mockup_spw_xlsx.LandUse(*args, **kwds)[source]

Bases: enum.Enum

Inheritance diagram of wolfhece.mockup_spw_xlsx.LandUse

Create a collection of name/value pairs.

Example enumeration:

>>> class Color(Enum):
...     RED = 1
...     BLUE = 2
...     GREEN = 3

Access them by:

  • attribute access:

>>> Color.RED
<Color.RED: 1>
  • value lookup:

>>> Color(1)
<Color.RED: 1>
  • name lookup:

>>> Color['RED']
<Color.RED: 1>

Enumerations can be iterated over, and know how many members they have:

>>> len(Color)
3
>>> list(Color)
[<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]

Methods can be added to enumerations, and members can have their own attributes – see the documentation for details.

FORESTS[source]
GRASSLANDS[source]
CULTIVATED_FIELDS[source]
GREEN_ROOFS[source]
BARE_SOIL[source]
DRAINED_PAVING[source]
IMPERVIOUS_SURFACES[source]
WATER_AND_ROOFS[source]
classmethod print_summary()[source]

Print a formatted table of all land-use types with their runoff coefficients.

class wolfhece.mockup_spw_xlsx.MockupSPWXLSX[source]

Simplified stormwater retention basin sizing tool following the SPW methodology.

This class computes the required retention capacity for a given site by combining IRM rainfall data (QDF / Montana curves), land-use characteristics and infiltration parameters.

Main features

  • Management of sub-areas by land-use type (LandUse), each weighted by a runoff coefficient.

  • Chicago hyetograph computation from IRM curves for a given return period.

  • Retention capacity estimation accounting for infiltration (Darcy’s law) and the admissible outflow to the drainage network.

  • Design rainfall duration and basin emptying time, computed alongside the retention capacity and exposed as read-only properties (design_rainfall_duration, emptying_time).

  • Full import/export to JSON (to_json / from_json).

Architecture and performance

  • QDF data is cached at the class level (shared across instances); hyetographs are cached per return period at the instance level. The total_area and total_area_ponderated properties use a dirty-flag mechanism to avoid unnecessary recomputation during sensitivity analyses.

  • All physical quantities are handled via pint.Quantity, so unit conversions are automatic and verified.

Usage example

>>> from wolfhece.mockup_spw_xlsx import MockupSPWXLSX, UNITS, LandUse
>>> m = MockupSPWXLSX()
>>> m.set_locality("Liège")
>>> m.infiltration_area = 100 * UNITS.meter**2
>>> m.infiltration_darcy = 1e-5 * UNITS.meter / UNITS.second
>>> m.admissible_outflow = 5.0                          # L/s/ha by default
>>> m.add_area("parking", LandUse.IMPERVIOUS_SURFACES, 500)
>>> m.add_area("garden", LandUse.GRASSLANDS, 0.1 * UNITS.hectare)
>>> vol = m.get_retention_capacity(return_period=25)    # -> pint.Quantity in m³
>>> m.design_rainfall_duration.to('hour')               # design storm duration
>>> m.emptying_time.to('hour')                          # basin emptying time
>>> m.to_json("my_project.json")                        # save
>>> m2 = MockupSPWXLSX.from_json("my_project.json")    # reload
_localities[source]
_qdf_cache: dict[int, wolfhece.irm_qdf.Qdf_IRM][source]
_locality_nsi: int = 0[source]
_qdf_irm = None[source]
areas: dict[str, tuple[LandUse, pint.Quantity]][source]
reference_area: pint.Quantity[source]
_infiltration_area: pint.Quantity[source]
_infiltration_darcy: pint.Quantity[source]
_infiltration_security_factor: float = 2.0[source]
_admissible_outflow: pint.Quantity[source]
_climate_delta_t: float = 0.0[source]
_climate_rate: float = 0.07[source]
_areas_dirty: bool = True[source]
_cached_total_area: pint.Quantity | None = None[source]
_cached_total_area_ponderated: pint.Quantity | None = None[source]
_rainfall_cache: dict[int, tuple[numpy.ndarray, numpy.ndarray]][source]
_design_rainfall_duration: pint.Quantity | None = None[source]
_emptying_time: pint.Quantity | None = None[source]
_last_return_period: int | None = None[source]
_last_retention_capacity: pint.Quantity | None = None[source]
_last_time: numpy.ndarray | None = None[source]
_last_rainfall: numpy.ndarray | None = None[source]
_last_net_rainfall: pint.Quantity | None = None[source]
_last_total_outflow: pint.Quantity | None = None[source]
_last_stored: pint.Quantity | None = None[source]
_invalidate_area_cache()[source]

Mark area-derived caches as stale.

add_area(key: str, land_use: LandUseType | str, area: float | pint.Quantity)[source]

Add an area with its land use type and area in square meters.

Parameters:
  • key – A unique identifier for the area (e.g., “Area1”, “Area2”, etc.)

  • land_use – The land use type of the area (e.g., LandUse.FORESTS.value)

  • area – The area in square meters or a pint.Quantity representing the area.

update_area(key: str, land_use: LandUseType | str = None, area: float | pint.Quantity = None)[source]

Update an existing area with a new land use type and/or area in square meters.

Parameters:
  • key – The unique identifier for the area to update (e.g., “Area1”, “Area2”, etc.)

  • land_use – The new land use type of the area (e.g., LandUse.FORESTS.value). If None, the land use will not be updated.

  • area – The new area in square meters or a pint.Quantity representing the area. If None, the area will not be updated.

property total_area: pint.Quantity[source]

Calculate the total area by summing up all areas in the mockup. Result is cached and invalidated when areas are added or updated.

area_by_land_use(land_use: LandUseType) pint.Quantity[source]

Calculate the total area for a specific land use type.

property total_area_ponderated: pint.Quantity[source]

Calculate the total area weighted by the runoff coefficients. Result is cached and invalidated when areas are added or updated.

set_reference_area(area: float | pint.Quantity)[source]

Set the reference area for the mockup.

set_locality(nsi_or_name: int | str)[source]

Set the locality NSI for the mockup.

property locality_name: str[source]

Get the name of the locality based on the NSI.

property qdf_irm[source]

Get the QDF IRM data for the locality. Uses a class-level cache keyed by NSI to avoid reloading the same data across multiple instances.

get_rainfall(return_period: int = 25) tuple[numpy.ndarray, numpy.ndarray][source]

Get the rainfall depth for a given return period based on the QDF IRM data. Results are cached per return period for repeated calls.

Parameters:

return_period – The return period in years (e.g., 10, 25, 30, 100).

property infiltration_area: pint.Quantity[source]

Get the infiltration area in m^2.

property infiltration_darcy: pint.Quantity[source]

Get the infiltration Darcy velocity in m/s.

property climate_delta_t: float[source]

Temperature increase for climate change scenario [°C].

property climate_factor: float[source]

Multiplicative climate change factor on rainfall intensity.

Computed as 1 + climate_rate * climate_delta_t where climate_rate defaults to 0.07 (7 %/°C, Belgian convention).

property admissible_outflow: pint.Quantity[source]

Get the admissible outflow in L/s/ha.

get_retention_capacity(return_period: int = 25) pint.Quantity[source]

Calculate the retention capacity based on the infiltration area and Darcy velocity.

Also computes and stores the design rainfall duration and the emptying time, accessible via the design_rainfall_duration and emptying_time properties.

Parameters:

return_period – The return period in years (e.g., 10, 25, 30, 100).

property design_rainfall_duration: pint.Quantity[source]

Duration of the design rainfall event (filling period). Available after calling get_retention_capacity().

property emptying_time: pint.Quantity[source]

Time required to fully empty the retention basin via infiltration and network outflow. Available after calling get_retention_capacity().

generate_report() str[source]

Return a multi-line text report summarising the sizing calculation.

The report includes: - Locality information - Land-use area breakdown (table) - Infiltration / outflow parameters - Retention capacity, design rainfall duration, emptying time

Raises:

RuntimeError – if get_retention_capacity() has not been called yet.

plot_hyetograph(ax=None, show: bool = True)[source]

Plot the Chicago hyetograph used for the last sizing.

Parameters:
  • ax – Optional matplotlib Axes. Created if None.

  • show – Call plt.show() at the end (ignored when ax is provided).

Returns:

The matplotlib Axes object.

plot_volume_balance(ax=None, show: bool = True)[source]

Plot inflow, outflow and cumulative stored volume over time.

Two y-axes are used: left for flow rates [L/s], right for cumulative stored volume [m³].

Parameters:
  • ax – Optional matplotlib Axes. Created if None.

  • show – Call plt.show() at the end (ignored when ax is provided).

Returns:

The matplotlib Axes object.

plot_land_use(ax=None, show: bool = True)[source]

Pie chart of the area distribution by land-use type.

Parameters:
  • ax – Optional matplotlib Axes. Created if None.

  • show – Call plt.show() at the end (ignored when ax is provided).

Returns:

The matplotlib Axes object.

plot_summary(show: bool = True)[source]

Generate a composite figure with the three main plots.

Layout: hyetograph (top-left), volume balance (top-right), land-use pie (bottom-centre).

Parameters:

show – Call plt.show() at the end.

Returns:

The matplotlib Figure object.

_SENSITIVITY_PARAMS: dict[str, tuple[str, str, str, bool]][source]
run_sensitivity(parameter: str, values, return_period: int = 25) pandas.DataFrame[source]

Run a sensitivity analysis by sweeping parameter over values.

Supported parameters: "admissible_outflow", "infiltration_darcy", "infiltration_area", "infiltration_security_factor", "return_period".

The method restores the original value of the parameter after the sweep.

Parameters:
  • parameter – Name of the parameter to vary.

  • values – Iterable of values to test. For physical quantities, give plain floats in the parameter’s default unit (L/s/ha, m/s, m²) or pint.Quantity objects.

  • return_period – Return period used for each run (ignored when parameter is "return_period").

Returns:

A pandas.DataFrame with columns parameter, volume_m3, duration_h, emptying_h.

plot_sensitivity(parameter: str, values, return_period: int = 25, ax=None, show: bool = True)[source]

Run a sensitivity analysis and plot volume vs parameter.

See run_sensitivity() for accepted parameters and values.

Parameters:
  • ax – Optional matplotlib Axes. Created if None.

  • show – Call plt.show() at the end (ignored when ax is provided).

Returns:

Tuple (ax, DataFrame) — the Axes and the results table.

_land_use_to_name(land_use) str[source]

Convert a LandUse enum or LandUseType to its enum name.

to_dict() dict[source]

Serialize the mockup to a dictionary.

to_json(path: str | pathlib.Path) None[source]

Export the mockup to a JSON file.

Parameters:

path – Path to the output JSON file.

classmethod from_dict(data: dict) MockupSPWXLSX[source]

Create a MockupSPWXLSX instance from a dictionary.

Parameters:

data – Dictionary with the mockup data.

Returns:

A new MockupSPWXLSX instance.

classmethod make(locality: int | str, areas: dict[str, tuple[LandUse | str, float | pint.Quantity]], infiltration_area: float | pint.Quantity = 0, infiltration_darcy: float | pint.Quantity = 0, infiltration_security_factor: float = 2.0, admissible_outflow: float | pint.Quantity = 5.0, climate_delta_t: float = 0.0) MockupSPWXLSX[source]

Factory to create a fully configured instance in a single call.

Parameters:
  • locality – Commune name or NIS code.

  • areas – Dictionary {key: (land_use, area)} where land_use is a LandUse member or a string (enum name) and area is in m² (float) or a pint.Quantity.

  • infiltration_area – Infiltration surface in m² (float) or pint.Quantity.

  • infiltration_darcy – Hydraulic conductivity in m/s (float) or pint.Quantity.

  • infiltration_security_factor – Safety factor on infiltration (dimensionless, default 2).

  • admissible_outflow – Allowable outflow in L/s/ha (float) or pint.Quantity.

  • climate_delta_t – Temperature increase for climate change scenario in °C (default 0).

Returns:

A ready-to-use MockupSPWXLSX instance.

Example

>>> m = MockupSPWXLSX.make(
...     locality="Liège",
...     areas={
...         "parking":  (LandUse.IMPERVIOUS_SURFACES, 800),
...         "toitures": (LandUse.WATER_AND_ROOFS,     350),
...         "jardin":   (LandUse.GRASSLANDS,          1500),
...     },
...     infiltration_area=150,
...     infiltration_darcy=1e-5,
...     admissible_outflow=5.0,
... )
classmethod from_json(path: str | pathlib.Path) MockupSPWXLSX[source]

Import a mockup from a JSON file.

Parameters:

path – Path to the input JSON file.

Returns:

A new MockupSPWXLSX instance.