commands

eap

This module implements the process described in VDI 3783 Part 16 [VDI3783p16] to find a substitute anemometer position (EAP) when wind measurements provided as input to the dispersion model AUSTAL [AST31] are not taken by an anemometer inside the AUSTAL model domain (i.e., on a nearby weather station or taken from a weather model).

The position is referred to as “EAP” since in German it is called “Ersatz-Anemometer-Position” (substitute anemometer position).

The module provides three approaches for calculating reference wind profiles:

  1. General approach (calc_ref_geostrophic()): Uses geostrophic wind speeds from VDI 3783 Part 16 Table 1 prescribed at inversion height.

  2. Adapted approach (calc_ref_adapted()): Uses frequency-weighted mean wind speeds from the meteorological time series at the effective anemometer height. This matches the approach used by AUSTAL/TALdia for wind library generation.

  3. Austal approach (austal_ref()): Runs the AUSTAL model that creates a wind library for the current configuration but with terrain removed adn retrieves the reference profiles from this library

Approaches 1 & 2 use the two-layer wind profile model from VDI 3783 Part 8 [VDI3783p8] with Monin-Obukhov similarity theory in the surface layer and an Ekman spiral solution in the upper layer.

austaltools.eap.add_options(subparsers)
austaltools.eap.austal_ref(workdir, levels, dirs, tmproot=None, overwrite=False)

Generate reference wind profiles using AUSTAL/TALdia.

Creates reference profiles by running AUSTAL on flat terrain and extracting the wind profile at the model origin.

Parameters:
  • workdir (str or path-like) – Path to the working directory containing austal.txt.

  • levels (list of float) – Heights (m) to interpolate the wind profile to.

  • dirs (list of float) – Wind directions (degrees) for which to generate profiles.

  • tmproot (str or path-like or None, optional) – Directory for temporary files. Default is None.

  • overwrite (bool, optional) – Whether to overwrite existing reference file. Default is False.

Returns:

A tuple containing:

  • u_ref (numpy.ndarray) – Eastward reference wind components, shape (len(levels), N_CLASS, len(dirs)).

  • v_ref (numpy.ndarray) – Northward reference wind components, shape (len(levels), N_CLASS, len(dirs)).

Return type:

tuple(numpy.ndarray, numpy.ndarray)

austaltools.eap.calc_all_eap(g, mx_lvl=None)

Find the substitute anemometer position (EAP) for all vertical levels.

Parameters:
  • g (numpy.ndarray) – 3D array of quality measure values, shape (nx, ny, nz).

  • mx_lvl (int or None, optional) – Maximum level index to process. If None, all levels are processed. Default is None.

Returns:

A tuple containing:

  • eap_levels (list of list) – List containing, for each level, a list of EAP candidate coordinates (i, j).

  • g_upper_levels (list of list) – List containing, for each level, a list of summed quality measures G for each contiguous region.

Return type:

tuple(list, list)

Note

For levels beyond mx_lvl, empty lists are returned.

See also

find_eap()

Example:
>>> g = np.array([[[0.5, 0.8, 0.3],
...                [0.2, 0.7, 0.9],
...                [0.4, 0.6, 0.1]],
...               [[0.3, 0.6, 0.4],
...                [0.1, 0.5, 0.7],
...                [0.2, 0.8, 0.3]]])
>>> eap_levels, g_upper_levels = calc_all_eap(g, mx_lvl=1)
>>> print(eap_levels)
[[[(1, 2), (1, 1), (0, 1)], [(1, 2), (1, 1), (0, 1)]]]
>>> print(g_upper_levels)
[[2.4, 1.6, 1.3], [1.6, 1.3, 1.1]]
austaltools.eap.calc_quality_measure(u_grid, v_grid, u_ref, v_ref, nedge=3, minff=0.5, maxlev=-1)

Calculate the quality measure g according to VDI 3783 Part 16.

Compares an AUSTAL wind library to a reference profile and calculates quality criteria for wind direction (gd) and wind speed (gf), which are combined into an overall quality measure g = gd * gf.

Parameters:
  • u_grid (numpy.ndarray) – Eastward wind component from the wind library. Shape: (nx, ny, nz, nstab, ndir).

  • v_grid (numpy.ndarray) – Northward wind component from the wind library. Shape: (nx, ny, nz, nstab, ndir).

  • u_ref (numpy.ndarray) – Eastward reference wind component. Shape: (nz, nstab, ndir).

  • v_ref (numpy.ndarray) – Northward reference wind component. Shape: (nz, nstab, ndir).

  • nedge (int, optional) – Number of edge nodes to exclude along each boundary. Default is N_EGDE_NODES.

  • minff (float, optional) – Minimum wind speed threshold (m/s). Grid points with wind speed below this value are excluded. Default is MIN_FF.

  • maxlev (int, optional) – Maximum level index to evaluate. Negative values mean all levels are evaluated. Default is -1.

Returns:

A tuple containing:

  • g (numpy.ndarray) – Overall quality measure, shape (nx, ny, nz). Values in [0, 1], where 1 indicates perfect agreement.

  • gd (numpy.ndarray) – Quality measure for wind direction, shape (nx, ny, nz).

  • gf (numpy.ndarray) – Quality measure for wind speed, shape (nx, ny, nz).

Return type:

tuple(numpy.ndarray, numpy.ndarray, numpy.ndarray)

Raises:

ValueError – If grid shapes do not match or reference profile dimensions are incompatible with the wind library.

Note

The algorithm follows VDI 3783 Part 16, Section 6.1 [VDI3783p16] :

  1. Exclude edge nodes (nedge from each boundary).

  2. Reject points where wind doesn’t rotate consistently or wind speed is below minff.

  3. Calculate correlation-based direction criterion gd.

  4. Calculate speed ratio criterion gf.

  5. Combine: g = gd * gf.

See also

find_eap()

austaltools.eap.calc_ref_adapted(levels: list[float], dirs: list[float], working_dir: str | None = None, z0: float | None = None, overwrite: bool = False) tuple[ndarray, ndarray]

Calculate reference wind profiles adapted to the meteorological data.

Uses the two-layer wind profile model from VDI 3783 Part 8 with frequency-weighted mean wind speeds from the meteorological time series prescribed at the effective anemometer height for each stability class.

This approach matches what AUSTAL/TALdia uses internally when generating wind libraries from dispersion class statistics (AKS).

Parameters:
  • levels (list of float) – Heights above ground (m) for the output profile.

  • dirs (list of float) – Wind directions (degrees, meteorological convention) for which to generate profiles.

  • working_dir (str or path-like or None, optional) – Working directory containing austal.txt and the time series file. Default is current directory.

  • z0 (float or None, optional) – Roughness length (m). Default is VDI_DEFAULT_ROUGHNESS.

  • overwrite (bool, optional) – Whether to overwrite existing reference file. Default is False.

Returns:

A tuple containing:

  • u_ref (numpy.ndarray) – Eastward reference wind components, shape (len(levels), N_CLASS, len(dirs)).

  • v_ref (numpy.ndarray) – Northward reference wind components, shape (len(levels), N_CLASS, len(dirs)).

Return type:

tuple(numpy.ndarray, numpy.ndarray)

Raises:
  • FileNotFoundError – If the time series file specified in austal.txt is not found.

  • ValueError – If no time series file is defined in austal.txt or all wind data are invalid.

Note

This is the “adapted” approach that uses:

  • The effective anemometer height \(h_a\) from the time series file header (dependent on roughness length class).

  • The frequency-weighted mean wind speed for each stability class from the time series data.

For stability classes with no data, the wind speed is estimated by scaling the VDI geostrophic wind values proportionally.

austaltools.eap.calc_ref_geostrophic(levels: list[float], dirs: list[float], z0: float | None = None, overwrite: bool = False) tuple[ndarray, ndarray]

Calculate reference wind profiles using geostrophic wind values.

Uses the two-layer wind profile model from VDI 3783 Part 8 with geostrophic wind speeds from VDI 3783 Part 16 Table 1 prescribed at the inversion height for each stability class.

Parameters:
  • levels (list of float) – Heights above ground (m) for the output profile.

  • dirs (list of float) – Wind directions (degrees, meteorological convention) for which to generate profiles.

  • z0 (float or None, optional) – Roughness length (m). Default is VDI_DEFAULT_ROUGHNESS.

  • overwrite (bool, optional) – Whether to overwrite existing reference file. Default is False.

Returns:

A tuple containing:

  • u_ref (numpy.ndarray) – Eastward reference wind components, shape (len(levels), N_CLASS, len(dirs)).

  • v_ref (numpy.ndarray) – Northward reference wind components, shape (len(levels), N_CLASS, len(dirs)).

Return type:

tuple(numpy.ndarray, numpy.ndarray)

Note

This is the “general” approach that uses standardized geostrophic wind values independent of the actual meteorological data.

The friction velocity \(u_*\) is calculated iteratively to match the prescribed geostrophic wind at the top of the boundary layer.

austaltools.eap.calc_vdi3783_8(levels: list, dirs: list, z0: float = None, u_a_classes: list[float] | None = None, h_a_classes: list[float] | None = None, overwrite: bool = False)

Calculate wind profiles using the VDI 3783 Part 8 two-layer model.

Implements the two-layer boundary layer wind profile model consisting of a Monin-Obukhov surface layer with linear direction turning and an Ekman spiral solution in the upper layer.

Parameters:
  • levels (array-like) – Heights above ground (m) for the output profile, must be positive and increasing.

  • dirs (array-like) – Wind directions at reference height (degrees, meteorological convention, 0° = North, 90° = East).

  • z0 (float or None, optional) – Roughness length (m). Default is VDI_DEFAULT_ROUGHNESS.

  • u_a_classes (list of float or None, optional) – Reference wind speed (m/s) for each stability class. If None, uses VDI_GEOSTROPIC_WIND (geostrophic wind at inversion height). Default is None.

  • h_a_classes (list of float or None, optional) – Reference height (m) for each stability class where u_a_classes is prescribed. If None, uses VDI_INVERSION_HEIGHT (inversion height). Default is None.

  • overwrite (bool, optional) – Whether to overwrite existing output file. Default is False.

Returns:

A tuple containing:

  • u_ref (numpy.ndarray) – Eastward wind components, shape (len(levels), N_CLASS, len(dirs)).

  • v_ref (numpy.ndarray) – Northward wind components, shape (len(levels), N_CLASS, len(dirs)).

Return type:

tuple(numpy.ndarray, numpy.ndarray)

Note

The two-layer model from VDI 3783 Part 8 [VDI3783p8] consists of:

Lower layer (\(z \leq h_1\)):

Surface layer following Monin-Obukhov similarity with wind speed:

\[u_1(z) = \frac{u_*}{\kappa} \left[ \ln\frac{z}{z_0} - \psi_m\left(\frac{z}{L}\right) \right]\]

and linear direction turning with gradient \(a = -0.2 A\).

Upper layer (\(z > h_1\)):

Ekman spiral solution with exponentially decaying oscillations:

\[ \begin{align}\begin{aligned}\tilde{u}(z) = u_1(h_1) c_1 + \frac{1}{2A}[(1-c_z)p + s_z q]\\\tilde{v}(z) = u_1(h_1) s_1 + \frac{1}{2A}[(c_z-1)q + s_z p]\end{aligned}\end{align} \]

where \(A = \sqrt{|f_c|/(2K)}\) is the Ekman parameter.

The layer interface height \(h_1\) is calculated from Eq. (A19):

  • Stable: \(h_1 = \frac{L}{20}\left(\sqrt{1 + \frac{10 h_m}{3\alpha L}} - 1\right)\)

  • Unstable/neutral: \(h_1 = \frac{h_m}{12\alpha}\)

See also

_calc_h1(), _calc_Km(), _calc_ekman_layer(), _calc_u_star_from_vg()

austaltools.eap.contiguous_areas(array: ndarray) tuple[ndarray, int]

Identify and label contiguous areas in a 2D binary array.

Assigns a unique label to each contiguous region of adjacent True values using 4-connectivity (top, bottom, left, right neighbors).

Parameters:

array (numpy.ndarray) – A 2D boolean array where True represents cells belonging to a contiguous region and False represents background.

Returns:

A tuple containing:

  • labels (numpy.ndarray) – A 2D integer array of the same shape as array where each contiguous region is labeled with a unique non-negative integer. Background cells are labeled with -1.

  • num_areas (int) – The number of unique contiguous areas found.

Return type:

tuple(numpy.ndarray, int)

Note

The function uses the union-find algorithm with path compression for efficient region labeling in a two-pass approach.

Example:
>>> arr = np.array([[1, 0, 0], [1, 1, 0], [0, 1, 1]]).astype(bool)
>>> labels, num = contiguous_areas(arr)
>>> print(labels)
[[ 0 -1 -1]
 [ 0  0 -1]
 [-1  0  0]]
>>> print(num)
1
austaltools.eap.find_eap(g_lower: ndarray)

Find the substitute anemometer position (EAP) from quality measure.

Identifies the optimal grid point for the substitute anemometer position based on the quality measure g at a single vertical level.

Parameters:

g_lower (numpy.ndarray) – 2D array of quality measure values for each (x, y) grid point.

Returns:

A tuple containing:

  • eap (list of tuple) – List of EAP candidate coordinates (i, j) in the grid, sorted by decreasing quality (best candidate first).

  • g_upper (list of float) – List of corresponding summed quality measures G for each contiguous region, sorted in decreasing order.

Return type:

tuple(list, list)

Note

The algorithm follows VDI 3783 Part 16, Section 6.1:

  1. Within each contiguous region of valid points, sum the quality measures to get G.

  2. In the region with the largest G, find the point with the largest individual g.

  3. This point is defined as the EAP.

Example:
>>> g_lower = np.array([[0.5, 0.8, 0.3],
...                     [0.2, 0.7, 0.9],
...                     [0.4, 0.6, 0.1]]).astype(float)
>>> eap, g_upper = find_eap(g_lower)
>>> print(eap[0])  # Best EAP location
(1, 2)
austaltools.eap.interpolate_wind(u_in: list, v_in: list, z_in: list, levels: list)

Interpolate wind components to specified heights.

Uses logarithmic interpolation for wind speed and linear interpolation for wind direction.

Parameters:
  • u_in (list of float) – Eastward wind component values at input heights.

  • v_in (list of float) – Northward wind component values at input heights.

  • z_in (list of float) – Heights (m) corresponding to input wind values.

  • levels (list of float) – Target heights (m) to interpolate to.

Returns:

A tuple containing:

  • u_out (list of float) – Interpolated eastward wind components.

  • v_out (list of float) – Interpolated northward wind components.

Return type:

tuple(list, list)

Raises:

ValueError – If u_in, v_in, and z_in do not have the same length.

Example:
>>> u_in = [1.0, 2.0, 3.0]
>>> v_in = [0.5, 1.0, 1.5]
>>> z_in = [10.0, 50.0, 100.0]
>>> levels = [25.0, 75.0]
>>> u_out, v_out = interpolate_wind(u_in, v_in, z_in, levels)
austaltools.eap.main(args)

Main entry point for the EAP analysis.

Reads a wind library, calculates reference profiles, computes quality measures, finds optimal EAP locations, and optionally creates plots and updates the AUSTAL configuration.

Parameters:

args (dict) –

Command line arguments dictionary with keys:

  • working_dir: Path to working directory.

  • grid: Grid ID to evaluate.

  • reference: Reference profile method (‘general’, ‘simple’, ‘file’, or ‘austal’).

  • overwrite: Whether to overwrite existing files.

  • max_height: Maximum evaluation height.

  • edge_nodes: Number of edge nodes to exclude.

  • min_ff: Minimum wind speed threshold.

  • height: Target height for EAP selection.

  • report: Whether to print detailed report.

  • austal: Whether to update austal.txt.

  • plot: Plot output specification.

See also

add_options()

austaltools.eap.print_report(args: dict, g: ndarray, gd: ndarray, gf: ndarray, eaps: list[list[tuple]], g_upper: list[list[float]], axes: dict[str, list])

Print a detailed report of EAP analysis results.

Outputs a formatted report mimicking the style of the VDI 3783 Part 16 reference implementation (TAL-Anemo.zip).

Parameters:
  • args (dict) – Command line arguments dictionary.

  • g (numpy.ndarray) – Overall quality measure, shape (nx, ny, nz).

  • gd (numpy.ndarray) – Direction quality measure, shape (nx, ny, nz).

  • gf (numpy.ndarray) – Speed quality measure, shape (nx, ny, nz).

  • eaps (list of list of tuple) – EAP coordinates for each level, as returned by calc_all_eap().

  • g_upper (list of list of float) – Summed quality measures for each level.

  • axes (dict) – Dictionary with keys ‘x’, ‘y’, ‘z’ containing grid coordinates.

austaltools.eap.read_ref(file: str, levels: list[float], dirs: list[float], linear_interpolation: bool = False)

Read reference wind profiles from file.

Reads wind profiles in the format of Ref1d.dat from the VDI 3783 Part 16 reference implementation and interpolates to the requested heights and directions.

Parameters:
  • file (str) – Path to the reference profile file.

  • levels (list of float) – Target heights (m) to interpolate to.

  • dirs (list of float) – Target wind directions (degrees) to extract.

  • linear_interpolation (bool, optional) – If True, use linear interpolation for wind speed (for comparison with VDI reference implementation). If False, use logarithmic interpolation. Default is False.

Returns:

A tuple containing:

  • u_ref (numpy.ndarray) – Eastward reference wind components, shape (len(levels), N_CLASS, len(dirs)).

  • v_ref (numpy.ndarray) – Northward reference wind components, shape (len(levels), N_CLASS, len(dirs)).

Return type:

tuple(numpy.ndarray, numpy.ndarray)

Raises:

ValueError – If no matching profile is found for a stability class.

See also

write_ref()

austaltools.eap.run_austal(workdir, tmproot=None)

Create a reference wind library using AUSTAL/TALdia.

Invokes AUSTAL with the -l parameter to generate a wind library for flat terrain with the anemometer at the model origin.

Parameters:
  • workdir (str or path-like) – Path to the working directory containing austal.txt.

  • tmproot (str or path-like or None, optional) – Directory for temporary files. If None, uses workdir. Default is None.

Returns:

A tuple containing:

  • u_tmp (numpy.ndarray) – Eastward wind component grid.

  • v_tmp (numpy.ndarray) – Northward wind component grid.

  • ax_tmp (dict) – Dictionary containing grid axes and metadata.

Return type:

tuple(numpy.ndarray, numpy.ndarray, dict)

Raises:
  • ValueError – If austal.txt is not found or AUSTAL fails.

  • OSError – If the AUSTAL executable is not found.

Note

This function creates a temporary directory, modifies the AUSTAL configuration for flat terrain, runs AUSTAL, extracts the results, and cleans up the temporary files.

austaltools.eap.same_sense_rotation(val, ref)

Check if wind directions rotate in the same sense.

Determines whether the wind directions in val and ref both rotate in the same direction (both clockwise or both counter-clockwise) as the input wind direction varies.

Parameters:
  • val (array-like) – Tested wind directions (degrees, meteorological convention).

  • ref (array-like) – Reference wind directions (degrees, meteorological convention).

Returns:

True if both arrays rotate in the same sense, False otherwise.

Return type:

bool

Note

This function is used in the EAP algorithm to reject grid points where the wind does not rotate consistently with the reference profile as required by VDI 3783 Part 16, Section 6.1, criterion 2 [VDI3783p16] .

austaltools.eap.write_ref(file: str, out_levels: list[float] | ndarray, out_dirs: list[float] | ndarray, u_ref: ndarray, v_ref: ndarray, axes_ref: tuple[list[float] | ndarray, list[float] | ndarray, list[float] | ndarray], overwrite: bool | None = None)

Write reference wind profiles to file.

Writes wind profiles in the format of Ref1d.dat from the VDI 3783 Part 16 reference implementation (TAL-Anemo.zip).

Parameters:
  • file (str) – Output file path.

  • out_levels (array-like) – Heights (m) to include in output.

  • out_dirs (array-like) – Wind directions (degrees) to include in output.

  • u_ref (numpy.ndarray) – Eastward wind components, shape (nz, N_CLASS, ndir).

  • v_ref (numpy.ndarray) – Northward wind components, shape (nz, N_CLASS, ndir).

  • axes_ref (tuple) – Tuple of (levels, stability_classes, directions) arrays corresponding to the dimensions of u_ref and v_ref.

  • overwrite (bool or None, optional) – If True, overwrite existing file. If False, raise FileExistsError. If None, prompt user interactively. Default is None.

Raises:

FileExistsError – If file exists and overwrite is False.

See also

read_ref()

austaltools.eap.AUSTAL_ROUGHNESS = 0.01

float: Roughness length \(z_0\) (m) used for reference wind profile calculation.

Corresponds to CORINE class 231 “short grass”, according to VDI 3783 Part 8 [VDI3783p8] .

austaltools.eap.MAX_HEIGHT = 100.0

float: Maximum height (m) above ground to which wind data are included in the EAP search algorithm.

austaltools.eap.MIN_FF = 0.5

float: Minimum wind speed (m/s) for which wind data are included in the EAP search algorithm.

austaltools.eap.N_CLASS = 6

int: Number of Klug-Manier stability classes (I through V, with III split into III/1 and III/2).

austaltools.eap.N_EGDE_NODES = 3

int: Number of model nodes along each side of the model domain that should be excluded to avoid edge effects in the EAP search algorithm.

austaltools.eap.VDI_DEFAULT_ROUGHNESS = 0.1

float: Default roughness length \(z_0\) (m) for wind profile calculation.

Value of 0.1 m is used instead of the original VDI value (0.02 m for LBM-DE class 231 “Wiesen und Weiden”) since 2023, according to UBA TEXTE 144/2023 “Weiterentwicklung ausgewählter methodischer Grundlagen der Schornsteinhöhenbestimmung und der Ausbreitungsrechnung nach TA Luft”.

austaltools.eap.VDI_GEOSTROPIC_WIND = [1.6, 2.5, 7.8, 5.6, 4.2, 3.8]

list of float: Geostrophic wind speed \(v_g\) (m/s) for each stability class.

Values from VDI 3783 Part 16, Table 1.

Index 0 corresponds to Class I (very stable), Index 5 corresponds to Class V (very unstable).

austaltools.eap.VDI_INVERSION_HEIGHT = [250, 250, 800, 800, 1100, 1100]

list of int: Mixing layer / inversion height \(h_m\) (m) for each stability class.

Values from VDI 3783 Part 8 (2002), Table 4.

Index 0 corresponds to Class I (very stable), Index 5 corresponds to Class V (very unstable).

austaltools.eap.VDI_THETA_GRADIENT = [0.008, 0.0057, 0.0032, 0.0012, 0.0003, 0.0]

list of float: Potential temperature vertical gradient (K/m) for each stability class.

Values from VDI 3783 Part 16, Table 1.

Index 0 corresponds to Class I (very stable), Index 5 corresponds to Class V (very unstable).

fill_timeseries

This module allows to create time-dependent source strenght timeseries as input for simulations with the German regulatory dispersion model AUSTAL [AST31]

austaltools.fill_timeseries.add_options(subparsers)
austaltools.fill_timeseries.expand_cycles(yinfo)

Processes a dictionary of cycle information, applying templates to cycles as needed.

This function validates the provided yinfo dictionary to ensure it contains the correct data structure, extracts templates, and applies them to the cycles. If a cycle specifies a template, the template is applied, including any emission factor calculations based on specified substances.

Parameters:

yinfo (dict) – A dictionary containing cycle information. The keys represent cycle IDs and the values are dictionaries with specific cycle information, which can include ‘column’, ‘source’, ‘template’, and ‘factors’.

Raises:

ValueError

  • If yinfo is not a dictionary, or

  • if it contains invalid structure such as null at the top level,

  • missing template definitions for requested cycles,

  • missing emission factors for specified substances, or

  • if emission factors are present without a selected substance.

Returns:

A dictionary of processed cycles where each cycle has necessary attributes set such as ‘multiplier’, ‘emissionfactor’, and ‘substance’. The keys are cycle IDs and the values are dictionaries containing the expanded cycle information.

Return type:

dict

Example:

Consider a set of cycle information with one defined template and two cycles:

>>> yinfo = {
...     'template1': {'column': None, 'source': None, 'factors': {'NOX': 1.0}},
...     'cycle1': {'column': '01.nox', 'template': {'name': 'template1', 'substance': 'NOX'}},
...     'cycle2': {'column': '01.xx'},
...     'cycle3': {'column': '02.nox', 'multiplier': 2.5}
... }
>>> expand_cycles(yinfo)
{
    'cycle1': {'column': '01.nox', 'source': None, 'substance': 'NOX', 'emissionfactor': 1.0, 'multiplier': 1.0},
    'cycle2': {'column': '01.xx', 'multiplier': 1.0, 'emissionfactor': 1.0, 'substance': None},
    'cycle3': {'column': '02.nox', 'multiplier': 2.5, 'emissionfactor': 1.0, 'substance': None}}

This example demonstrates how the specified template is applied to cycle1 and cycle2 is processed without a template.

austaltools.fill_timeseries.get_timeseries(file: str, time: DatetimeIndex)

Parse yaml file containing cycle(s) information and generate an emission time series.

This funtion is essentially a wrapper that applies for parse_cycle() to a yaml file.

Parameters:
  • file (str) – filename (optionally containing a path)

  • time (pandas.Series) – Time series

Returns:

time series of emssions of all emissions descrcibed in file

Return type:

pandas.Dataframe with time as index and column-ids as colums

Example:
>>> yaml_text = '''
... meinname:
...   column: 01.so2
...   start:
...     at:
...       time: 1-11/2
...       unit: month
...     offset:
...       time: 1,3
...       unit: week
...   sequence:
...   - ramp:
...       time: 1
...       unit: day
...       value: 9.0
...   - const:
...       time: 36
...       unit: hour
...       value: 1.1
...'''
>>> with open("cycle.yaml, "w") as f:
>>>     f.write(yaml_text)
>>> time = pandas.date_range("2000-01-01 00:00",
...                          "2000-01-02 00:00", freq="1h")
>>> get_cycle(file, time)
    ('01.so2',
     2000-01-01 00:00:00    0.0
     2000-01-01 01:00:00    0.0
     2000-01-01 02:00:00    0.0
     2000-01-01 03:00:00    0.0
     2000-01-01 04:00:00    0.0
                           ...
     2000-12-24 07:00:00    1.1
     2000-12-24 08:00:00    1.1
     2000-12-24 09:00:00    1.1
     2000-12-24 10:00:00    1.1
     2000-12-24 11:00:00    1.1
     Name: foo, Length: 745, dtype: float64)
Note:

The format of the yaml file is described under variable values

austaltools.fill_timeseries.main(args)

Process the data file based on the provided arguments.

Parameters:
  • args (dict) – Dictionary containing the following keys:

  • args["action"] – (str) – The action to perform. Possible values are ‘list’, ‘week-5’, ‘week-6’, or ‘cycle’.

  • args["cycle_file"] – (str) – The name of the cycle file (required for ‘cycle’ action).

  • args["holiday_month"] – (*list, optional) – List of months (1-12) considered as holidays.

  • args["holiday_week"] – (*list, optional) – List of weeks (1-52) considered as holidays.

  • args["hour_begin"] – (int, optional) – The daily start of the working time, i.e. the first hour of each working day the source emits pollutants (evaluated for ‘week-5’ and ‘week-6’ actions). Defaults to DEFAULT__BEGIN.

  • args["hour_end"] – (int, optional) – The daily end of the working time, i.e. the last hour of each working day the source emits pollutants (evaluated for ‘week-5’ and ‘week-6’ actions). Defaults to DEFAULT_END .

  • args["column_id"] – (str) – The column ID to process (required for ‘week-5’ and ‘week-6’ actions).

  • args["output"] – (list) – The source strength (in g/s) when the source is emitting (required for ‘week-5’ and ‘week-6’ actions).

  • args["working_dir"] – (str) – The path to the directory containing the data file. The datafile is named zeitreihe.dmna or timeseries.dmna, depending on the language setting of the AUSTAL model.

Raises:
  • ValueError – If the data file is not in DMNA timeseries format.

  • ValueError – If the action is unknown.

  • ValueError – If required arguments are missing or invalid.

Note:

the datafile zeitreihe.dmna/timeseries.dmna must be created by invoking AUSTAL with paramter -z

austaltools.fill_timeseries.parse_cycle(c_id: str, c_info: dict, time: DatetimeIndex) Series

Parse cycle information and generate an emission time series.

Parameters:
  • c_id (str) – Cycle identifier

  • c_info (dict) –

    Cycle information dictionary. Must contain the keys:

    • ”column”: str, column identifier (must not be equal to c_id)

    • ”start”: dict, must contain: - “at”: str, start time information - “offset” (optional): str, offset time information

    • ”sequence” or “list”: list, sequence or list of values

    • ”unit” (optional): str, unit information in the format “<mass unit>/<time interval>”

  • time (pandas.Series) – Time series

Raises:

ValueError

If required keys are missing or invalid values are found in c_info. Possible errors include:

  • if time is an invalid type or time series does not have a unique interval

  • if c_info does not contain the referred column name

  • if the cycle name c_id is equal to the column name

  • if c_info has neithert none or both of a cycle or list entry

  • if c_info has not start entry

  • if the start entry is not a dict or does not contain an at entry

  • ’sequence’ item contains more or less than one entry or the entry cannot be parsed

  • c_info['list'] does not contain a list

  • the unit info in c_info['unit']s cannot be parsed

  • the mass unit in c_info['unit'] is not al valid weight unit

  • the time interval in c_info['unit'] is not a valid time unit

Returns:

Column identifier and generated cycle series

Return type:

tuple (str, pandas.Series)

Example:
>>> import pandas as pd
>>> c_id = "foo"
>>> c_info = {'column': '01.so2',
...   'start': {'at': {'time': '1-11/2', 'unit': 'month'},
...   'offset': {'time': '1,3', 'unit': 'week'}},
...   'sequence': [
...     {'ramp': {'time': 1, 'unit': 'day', 'value': 9.0}
...    },
...    {'const': {'time': 36, 'unit': 'hour', 'value': 1.1}}]}
>>> time = pd.date_range("2000-01-01 00:00",
...                          "2000-01-02 00:00", freq="1h")
>>> fill_timeseries.parse_cycle(c_id, c_info, time)
    ('01.so2',
     2000-01-01 00:00:00    0.0
     2000-01-01 01:00:00    0.0
     2000-01-01 02:00:00    0.0
     2000-01-01 03:00:00    0.0
     2000-01-01 04:00:00    0.0
                           ...
     2000-12-24 07:00:00    1.1
     2000-12-24 08:00:00    1.1
     2000-12-24 09:00:00    1.1
     2000-12-24 10:00:00    1.1
     2000-12-24 11:00:00    1.1
     Name: foo, Length: 745, dtype: float64)
austaltools.fill_timeseries.parse_time(info, name='', multi=True)

Parse time information from a given dictionary.

The dictionary info must contain the following keys: - ‘time’: A string representing the time information. - ‘unit’: A string representing the unit of time.

Parameters:
  • info (dict) – Dictionary containing time information.

  • name (str) – Optional name for the time info, used in error messages.

  • multi (bool) – Flag indicating whether multiple times are allowed.

Raises:
  • ValueError – If ‘time’ or ‘unit’ keys are missing in the info dictionary.

  • ValueError – If multiple times are defined when multi is False.

Returns:

A tuple containing the parsed time count and unit.

Return type:

tuple

austaltools.fill_timeseries.parse_time_unit(string)

Parse a string and determine which time unit it describes: - ‘month’, ‘months’, ‘mon’ for months - ‘day’, ‘days’, ‘d’ for days - ‘hour’, ‘hours’, ‘hr’, ‘hrs’, ‘h’ for hours

Parameters:

string (str) – the string to parse

Returns:

the parsed time unit

Return type:

str

austaltools.fill_timeseries.DEFAULT_BEGIN = 8

Default staring hour for a workday (first hour during which emsssions are created)

austaltools.fill_timeseries.DEFAULT_END = 17

Default end hour for a workday (last hour during which emsssions are created)

heating

This module contains a simple heating model that allows to simulate the room temperatures and power consumption of a building. In contrast to a full-featured building information model (BIM), it requires only little information and is intended for approximative simulations only.

class austaltools.heating.Building(name, t_out, t_soil)

A class to represent a building with rooms and walls, capable of simulating temperature and power dynamics.

Parameters:
  • name (str) – The name of the building.

  • t_out (float) – The starting temperature for the outdoor environment.

  • t_soil (float) – The starting temperature for the soil environment.

Class attributes

namestr

The name of the building.

lat: float

Latitute of the buildings postion in degrees.

lon: float

Longitude of the buildings postion in degrees.

wallsWallList

A list of walls associated with the building.

roomsRoomList

A list of rooms within the building.

hvacdict

Dictionary holding HVAC configuration details.

initbool

Initialization flag for the building; if False, triggers initial wall setup.

outputAny

Storage for output data related to building operations (can be tailored as needed).

_room_historylist

Internal storage for the historical record of room variables such as temperature and power.

_wall_historylist

Internal storage for the historical record of wall variables such as temperature and flux.

Methods

classmethod from_yaml(name, d)

Create a Building instance from YAML configuration data.

Parameters:
  • name (str) – The name of the building.

  • d (dict) – A dictionary containing building setup data, expected to include walls, rooms, and their parameters.

Returns:

A new instance of Building initialized with the configuration from the YAML data.

Return type:

Building

get_rooms()

Retrieves a list of non-special room names.

Returns:

A list containing the names of all non-special rooms in the building.

Return type:

list of str

init_walls()

Initializes wall objects by linking them with the respective rooms.

Raises:

ValueError – If the special rooms ‘soil’ and ‘outside’ are not present in the room list.

output_recording(rname=None, wname=None, sname=None, slabout=True, append=False)

Outputs the recorded room and wall data to CSV files.

Parameters:
  • rname (str, optional) – The filename for room history data, default is ‘heating_rooms_history.csv’.

  • wname (str, optional) – The filename for wall history data, default is ‘heating_walls_history.csv’.

  • sname (str, optional) – The filename for slab temperature history data, default is ‘heating_slabs_history.csv’.

  • slabout (bool, optional) – Add individual wall-slab temperatures to a separate output file. Defaults to True.

  • append (bool, optional) – Append data written to existing data files. Defaults to False.

record_variables(time, flush=False, rname=None, wname=None, sname=None, slabout=False)

Records current temperature and power variables of rooms and temperature and flux of walls to history.

set_solar(time, octa)

set or update the solar ration upon external wall surfaces

Parameters:
  • time (pd.Timestamp) – local time

  • octa (float) – cloud cover in octa (0: clear, 8: overcats)

switch_mode(mode)
tick(timedelta: float = 1)

Advances the simulation state by a given time interval, updating room and wall states.

Parameters:

timedelta (float, optional) – The duration by which the simulation is advanced. Default is TIMESTEP.

hvac = <austaltools.heating.Hvac object>
init = False
lat = None
lon = None
name = ''
output = None
rname = 'heating_rooms_history.csv'
rooms = {}
sname = 'heating_slabs_history.csv'
walls = {}
wname = 'heating_walls_history.csv'
class austaltools.heating.Hvac(rnames)

Data structure dscribing the settings and schedule for the operation of the heating, ventilation anc cooling control (HVAC)

classmethod from_yaml(d, rnames)

Create a Hvac instance from YAML configuration data.

Returns:

the cerated Hvac instance.

Return type:

Hvac

switch_mode(time: Timestamp)

Return the name of the mode in which the heating system should operate a a given time.

Parameters:

time (pd.Timestamp) – Time to evaluate the settings for

Returns:

name of the mode the heating system should be operated

Return type:

str

current = 'none'
modes = {}
rnames = []
starttable = None
switchtables = {}
timers = {}
class austaltools.heating.Room(name, width=None, length=None, height=None, maxpower=None, area=None, volume=None, t_set=None, p_set=None, t_start=None, special=None)

Represents a room within a building simulation, capable of handling temperature and power dynamics.

Parameters:
  • name (str) – The name of the room.

  • width (float, optional) – The width of the room in meters, optional.

  • length (float, optional) – The length of the room in meters, optional.

  • height (float, optional) – The height of the room in meters, optional.

  • maxpower (float) – The maximum power that can be supplied to the room in watts.

  • area (float, optional) – The area of the room in square meters, which can override width * length.

  • volume (float, optional) – The volume of the room in cubic meters, which can override area * height.

  • t_set (float, optional) – The target temperature to be maintained in the room, optional.

  • p_set (float, optional) – The target power setting for the room, optional.

  • t_start (float, optional) – The starting temperature of the room, optional.

  • special (bool, optional) – Flag to indicate if the room is of a special type, optional.

Raises:

ValueError – If required parameters for normal rooms are not provided.

Class attributes

namestr

The name of the room.

tempfloat

The current temperature of the room in degrees Celsius.

target_tempfloat

The target temperature for the room, default is NaN.

target_powerfloat

The target power setting for the room (1 represents 100% of self.power), default is NaN.

maxpowerfloat

The maximum power that can be supplied to the room in watts.

powerfloat

The current power being used by the room in watts.

widthfloat

The width of the room in meters.

lengthfloat

The length of the room in meters.

heightfloat

The height of the room in meters.

areafloat

The area of the room in square meters, which can override width * length.

volumefloat

The volume of the room in cubic meters, which can override area * height.

add_cfloat

Additional heat capacity by objects in the room, in Joules per Kelvin.

wall_signdict

Mapping of wall names to directional signs indicating their association with the room.

get_environment()

Return temperature and wind speed in the room

Returns:

temperature and wind speed

Return type:

float, float

get_fluxes(walls: WallList)

Calculate and return the fluxes for each wall associated with the room.

Parameters:

walls (WallList) – A WallList containing wall objects to calculate fluxes for.

Returns:

A dictionary mapping each wall’s name to its flux.

Return type:

dict

get_thermo()

Return thermostat setting (t_set) in the room :return: set temperature :rtype: float

get_throttle()

Return heating throttle in percent in the room. :return: set temperature :rtype: float

init_walls(walls: WallList)

Associate walls with the room based on their configurations.

Parameters:

walls (WallList) – A WallList containing wall objects to be linked with the room.

is_special()

Determine whether the room is marked as a special room.

Returns:

True if the room is special, False otherwise.

Return type:

bool

set_environment(temp=None, wind=None)

Set temperature and wind speed of the air in the room. Is only accepted for special rooms (that allow a prescribed values)

Returns:

temperature and wind speed

Return type:

float, float

set_thermo(temp)

Set the thermostat temperature (t_set) in the room :param temp: set temperature :type temp: float

set_throttle(percent)

Set the heating throttle for the room, in percent. :param percent: throttle value (0=off, 100=full power available) :type percent: float

tick(walls: WallList, timedelta: float = 1)

Update the room’s state by advancing the simulation by a given time interval, adjusting temperature based on power input and fluxes.

Parameters:
  • walls (WallList) – A WallList containing wall objects linked to this room.

  • timedelta (float, optional) – The duration by which the simulation is advanced, default is TIMESTEP.

Returns:

The updated temperature of the room.

Return type:

float

add_c = 0.0
area = 0.0
height = 0.0
length = 0.0
maxpower = 0.0
name = ''
power = 0.0
target_power = nan
target_temp = nan
temp = 0.0
volume = 0.0
wall_sign = {}
width = 0.0
wind = 0.0
class austaltools.heating.RoomList(walls)

A class to manage a list of Room objects in a building simulation, inheriting from Python’s dictionary to map names to Room instances.

Parameters:

walls (WallList) – A reference to wall structures to be associated with rooms.

append(room)

Add a Room instance to the RoomList.

Parameters:

room (Room) – The Room instance to be added to the list.

init_walls(walls)

Initialize wall connections for each Room in the RoomList.

Parameters:

walls – Reference to wall configurations used to initialize each room’s wall associations.

tick(walls, timedelta: float = 1)

Advance the simulation state by a given time interval, updating each Room’s state.

Parameters:
  • walls – Reference to wall data necessary for updating the state of each room.

  • timedelta (float, optional) – The time step duration by which to advance the simulation, default is TIMESTEP.

class austaltools.heating.Wall(name: str, room_w: str, room_c: str, d: float = None, l: float = None, h: float = None, area: float = None, facing: float = None, slant: float = None, c: float = None, k: float = None, rho: float = None, resistance=None, albedo: float = None, epsilon: float = None, partof: str = None, t_start: float = None, slabs: str | float | list = None)

Represents a wall element within a building, handling thermal dynamics between two rooms (room_w and room_c).

Parameters:
  • name (str) – The name of the wall.

  • d (float) – The thickness of the wall in meters.

  • room_w (str) – Name of the room on the warmer side of the wall.

  • room_c (str) – Name of the room on the cooler side of the wall.

  • l (float, optional) – The length of the wall in meters, optional.

  • h (float, optional) – The height of the wall in meters, optional.

  • area (float, optional) – The full area of the wall in square meters, optional.

  • c (float, optional, mutually exclusive with resistance) – The heat capacity of the wall material in J/kgK, optional.

  • k (float, optional, mutually exclusive with resistance) – The thermal conductivity of the wall material in W/mK, optional.

  • rho (float, optional, mutually exclusive with resistance) – The density of the wall material in kg/m³, optional.

  • resistance (float, optional, mutually exclusive with k, c abd rho)

  • partof (str, optional) – Indicates what part of the building the wall belongs to, optional.

  • t_start (float, optional) – Starting temperature for the wall slabs in degrees Celsius, optional.

Definition of positive flux:

room_w (warm) -> positive flux -> room_c (cold)

The wall consists of slabs and flux nodes for thermal calculations:

The grid is staggered like this:

layer0

layer1

layerN

width

slab

slab

slab

temp

X

X

X

X

width

slab + excess

slab

slab + excess

flux

X

X

X

X

X

Surface heat fluxes

generally:

\(Q_\mathrm{s} - B_\mathrm{s} - H_\mathrm{s} - E_\mathrm{s} = 0\)

indoor wall:

Shortwave radiation fluxes are approximately zero; longwave radiative transfer included in surfac-to-atmosphere heat transfer coefficient, effecitvily making \(Q_\mathrm{s} = 0\). Walls are assumed to be dry making \(E_\mathrm{s} = 0\).

Hence: \(- B_\mathrm{s} - H_\mathrm{s} = 0\)

Following DIN 6946, write \(H_\mathrm{s} = h_c (T_\mathrm{s} - T_\mathrm{air})\)

where \(T_\mathrm{s}\) is the temperature of the surface. Because this model uses thin slabs, it can be approximated by the temperature of the outemost slab.

outdoor wall:

Shortwave radiation fluxes are significant; longwave radiative transfer is again included in surface-to-atmosphere heat transfer coefficient, effecitvily making \(Q_\mathrm{s} = K_\mathrm{s}\).

Hence: \(K_\mathrm{s} - B_\mathrm{s} - H_\mathrm{s} = 0\)

Class attributes

namestr

The name of the wall.

partofstr

Indicates what part of the building the wall belongs to.

thicknessfloat

The thickness of the wall in meters (default is 0.36m).

lengthfloat

The length of the wall in meters.

heightfloat

The height of the wall in meters.

area_fullfloat

The full area of the wall without any corrections in square meters.

areafloat

The effective area of the wall, adjusted for embedded elements, in square meters.

facingfloat

The horizontal orientation of the wall in degrees clockwise from north.

slantfloat

The vertical orientation of the wall in degrees upward from horizontal.

d_slabfloat

The thickness of each slab section in the wall in meters.

n_slabint

The number of slab sections in the wall.

t_slablist

List containing the temperature of each slab section in degrees Celsius.

n_fluxint

The number of flux nodes calculated across the wall.

f_fluxlist

List containing the flux values at each node in watts per square meter.

d_fluxlist

List containing the distance between slab centers used in flux calculations in meters.

resistance: bool

If True, a thin wall is assumed of which the bulk heat resistance (1 / heat_conduct) is known.

heat_conductfloat

The thermal conductivity of the wall material in watts per meter kelvin (default is 0.58 W/mK). (1 / heat_resistance) if resistance is True.

heat_capacityfloat

The heat capacity of the wall material in joules per kilogram kelvin (default is 836 J/kgK). Irrelevant when resistance is True.

densityfloat

The density of the wall material in kilograms per cubic meter (default is 1400 kg/m³). Irrelevant when resistance is True.

albedofloat

The albedo of the cold-side wall material in 1, defaults to WALL_ALBEDO

epsilonfloat

The emissivity of the cold-side wall material in 1, defaults to WALL_EPSILON

k_in, k_out, l_in, l_out: float, float, float, float

The net radiation components on the cold-side wall surface: shortwave (solar) incoming, shortwave (solar) outgoing, longwave (infrared) incoming, longwave (infrared) outgoing,

set_solar(time, lat, lon, octa, rooms)

Set or update the radiative fluxes at the surface of the outside-facing side (if the wall has one).

Parameters:
  • time (datetime64 (timezone-aware) – Time (incl time zone)

  • lat (float) – building position latitude in degrees

  • lon (float) – building position longitude in degrees

  • octa (float) – total cloud cover of the sky in octa, i.e. 0 = clear, 8 = overcast.

  • rooms (RoomList) – list of Room objects of the building

tick(rooms, timedelta=1)

Update the wall’s state by advancing the simulation.

Parameters:
  • rooms (dict) – A dictionary of room objects linked to the wall.

  • timedelta (float, optional) – The duration by which the simulation advances, default is TIMESTEP.

TOLERANCE = 0.001

allowed difference between sum ob slab thicknesses and wall thickness

albedo = None
area = 0.0
area_full = 0.0
d_flux = []
d_slab = 0.0
density = 1400
epsilon = None
f_flux = []
facing = 0.0
heat_capacty = 836.0
heat_conduct = 0.58
height = 0.0
k_in = nan
k_out = nan
l_in = nan
l_out = nan
lenght = 0.0
n_flux = 0
n_slab = 0
name = ''
partof = ''
resistance = False
slant = 0.0
t_slab = []
thickness = 0.36
class austaltools.heating.WallList

A class to manage a list of Room objects in a building simulation context, inheriting from Python’s dictionary to map room names to Room instances.

append(wall: Wall)

Add a Wall instance to the WallList.

Parameters:

wall (Wall) – The Room instance to be added to the list.

a ValueError is raised

  • if wall declares a parent wall via its partof attribute that is not already contained in the WallList

  • if partof attribute of wall refers to itself.

  • if wall declares a parent wall via its partof attribute whos area is not larger

set_solar(time, lat, lon, octa, rooms)

set or update the solar ration upon external wall surfaces

Parameters:
  • time (pd.Timestamp) – local time

  • lat (float) – latitude in degrees

  • lon (float) – longitude in degrees

  • octa (float) – cloud cover in octa (0: clear, 8: overcats)

  • rooms (RoomList) – Room objects linked to the walls

tick(rooms, timedelta: float = 1)

Advance the simulation state by a given time interval, updating each Room’s state.

Parameters:
  • rooms – Reference to room data necessary for updating the state of each wall.

  • timedelta (float, optional) – The time step duration by which to advance the simulation, default is TIMESTEP.

austaltools.heating.add_options(subparsers)
austaltools.heating.exponential_slabs(dist)

Function to partition distance dist into the minimal set of intervals that grow approximately exponentially from the edge to the middle, are multiples of WIDTHSTEP (except the two in the center two), have a minimal width of WIDTHMIN and are symmetrical around the center of L.

Parameters:

dist (float) – distance to patition

Returns:

interval widths

Return type:

list

austaltools.heating.main(args)

main routine of the module heating, i.e. “the command”

Parameters:

args (dict) – parsed command-line arguments

austaltools.heating.run_building_model(bldg: Building, tseries: Series | str, wseries: Series | str = None, cseries: Series | str = None, df: DataFrame | None = None, rec=None, slabout=False, flush=True, radiation=True) DataFrame

Run a time dependent simulation of the building heating.

Parameters:
  • bldg (Building) – the Building instance to run the model on

  • tseries (pandas.Series | str) – Timeseries containg the air temperature, with time as index or column name if df is given and has temperature in column ts

  • wseries (pandas.Series | str) – (optional) Timeseries containg the wind speed, with time as index or column name if df is given and has temperature in column ts

  • cseries (pandas.Series | str) – (optional) Timeseries containg the cloud cover in octa, with time as index or column name if df is given and has temperature in column ts

  • df (pandas.DataFrame | None) – (optional) Data frame containing timeseries of input data in the columns with the names given. df must not be given or None if tseries is a pandas.Series.

  • rec (str or None) – (optional) a pandas interval string describing the time interval at which the model variables shall be recorded when running the model. For exampe “1min” for every minute. Defaults to for no recording

  • slabout (bool) – (optional) add additional file to the output that contains the individual wall-slab temperatures. This parameter is only relevant when rec is not False. Defaults to False

  • flush (bool) – (optional) whether to flush the simulation recording each (modeled) hour. Default is True.

  • radiation (bool) – Enable heat gain by net radiation on outside walls. Defaults to True.

Returns:

the modeled temperatures and heating powers. The index is the time, columns are seconds (passed since last time), power (total heating power of all rooms), tmp_NAME and pwr_NAME for every room where NAME is the name the respective room

Return type:

pandas.DataFrame

austaltools.heating.speradsheet_import(dictionary, building, filename)

Import building data from a spreadsheet file into a dictionary.

Parameters:
  • dictionary (dict) – A dictionary containing building data to be updated.

  • building (str) – The name of the building to import data for.

  • filename (str) – The name of the spreadsheet file to import data from.

Returns:

The updated dictionary with imported building data.

Return type:

dict

This function imports the ‘walls’ and ‘rooms’ data for a specified building from a given spreadsheet file into an existing dictionary structure. It performs the following steps:

The spreadsheet file must contain the required sheets ‘walls’ and ‘rooms’.

Raises:

ValueError – If the specified building is not found in the dictionary or if required sheets are missing in the file.

austaltools.heating.spreadsheed_engine(filename)

Determine the spreadsheet engine based on the file extension and ensure the filename is complete.

Parameters:

filename (str) – The name of the spreadsheet file, which may or may not include an extension.

Raises:

ValueError – If the file extension is unsupported.

Returns:

A tuple containing the filename (with extension) and the spreadsheet engine.

Return type:

tuple

The function checks the file extension of the provided filename to determine the appropriate spreadsheet engine to use. Supported extensions are .ods, .xlsx, and .xls. If no extension is provided, .ods is assumed by default. It returns the possibly modified filename and the corresponding engine.

Raises:

ValueError – for unsupported extensions, such as .csv.

austaltools.heating.spredsheet_export(dictionary, building, basename)

Export specific building data from a Building object to a spreadsheet file.

Parameters:
  • dictionary (dict) – A dictionary containing building data, including structures like walls and rooms.

  • building (str) – The name of the building to export data for.

  • basename (str) – The base name of the output spreadsheet file (may or may not include extension).

Returns:

None

This function exports the walls and rooms data of a specified building from a given dictionary (e.g. read from a heating.yaml) into a spreadsheet file. The file is named based on the provided basename and uses an appropriate engine determined by the spreadsheed_engine function. The spreadsheet will contain sheets for ‘walls’ and ‘rooms’, if available.

Raises:

ValueError – If the specified building is not found in the dictionary.

austaltools.heating.surface_heat_transfer_resistance(indoor: bool, angle: float = 0, t_wall: float = None, wind: float = None)

Calculate heat transfer resistance between wall and air.

Parameters:
  • indoor (bool) – Surface is indoor (True) or outdoor (False)

  • angle (float) – Elevation angle of the wall normal direction. 0 means the wall is vertical. +90 means the wall is a floor. -90 a ceiling.

  • t_wall (float) – wall surface temperature in °C

  • wind (float) – wind speed

Returns:

heat transfer resistance in \(m^2 K / W\)

Return type:

float

Commonly H is parameterized as: \(H = C_\mathrm{H} \left( T_\mathrm{sfc} - \mathrm{air}\right)\) or in resistance notation: \(R_\mathrm{H} = \frac{ T_\mathrm{sfc} - \mathrm{air}}{H}\) where \(C_\mathrm{H} = \frac{1}{R_\mathrm{H}}\)

DIN 6946:2008 appendix A.1 “even surface” states \(R_\mathrm{S} = \frac{1}{h_\mathrm{c} + h_\mathrm{r}}\)

with:
  • \(h_\mathrm{c}\): heat transfer coefficient due to convection

  • \(h_\mathrm{r}\): heat transfer coefficient due to radiation

values in case of a “well ventilated” indoor surfaces: \(h_\mathrm{c} ~=~ h_\mathrm{ci}\) with

  • \(h_\mathrm{ci} ~=~ 5.0 \mathrm{W}/(\mathrm{m}^2 \mathrm{K})\) for heat flow upwards (i.e. from the floor);

  • \(h_\mathrm{ci} ~=~ 2.5 \mathrm{W}/(\mathrm{m}^2 \mathrm{K})\) for heat flow horizontal (i.e. from a wall);

  • \(h_\mathrm{ci} ~=~ 0.7 \mathrm{W}/(\mathrm{m}^2 \mathrm{K})\) for heat flow downwards (i.e. from the ceiling)

values in case of outdoor surfaces: \(h_\mathrm{c} ~=~ h_\mathrm{ce}\)

with \(h_\mathrm{ce} ~=~ 4. + 4. v \mathrm{W}/(\mathrm{m}^2 \mathrm{K})\)

where \(v\) is the wind speed ‘’above he surface’’ in m/s

austaltools.heating.surface_net_radiation(time: Timestamp, lat: float, lon: float, t_wall: float, t_air: float, heading: float, slant: float, octa: float, albedo: float = None, epsilon: float = None, components: bool = False) float | tuple[float, float, float, float]

Calculate the surface radiation budget for a specified wall.

This function computes the net radiation budget of a vertical or slanted surface at a particular location and time, considering both shortwave and longwave radiation components.

Parameters:
  • time (pd.Timestamp) – Time for which the calculation is made.

  • lat (float) – Latitude of the location in degrees.

  • lon (float) – Longitude of the location in degrees.

  • t_wall (float) – Temperature of the wall surface in degrees Celsius.

  • t_air (float) – Air temperature in degrees Celsius.

  • heading (float) – Orientation angle of the wall normal with respect to north in degrees.

  • slant (float) – Slant angle of the wall from horizontal in degrees upward.

  • octa (float) – Cloud cover in oktas, an integer from 0 (clear sky) to 8 (completely overcast).

  • albedo (float, optional) – Surface albedo of the wall, default is set to WALL_ALBEDO if None.

  • epsilon (float, optional) – Emissivity of the wall surface, default is set to WALL_EPSILON if None.

  • components (bool, optional) – If True, returns the individual radiation components, otherwise returns the net radiation.

Returns:

Net radiation (or individual components if requested), consisting of shortwave and longwave calculation terms.

Return type:

float or tuple[float]

Raises:

ValueError – If the input values are out of expected ranges.

Note

This function uses the simplified Kasten and Czeplak [Kas1980] model for clear-sky conditions with adjustments for cloud cover.

austaltools.heating.DEFAULT_COVER = 4.8

default cloud cover in octa mean value the 1991–2020 reference period (https://climate.copernicus.eu/esotc/2022/clouds-and-sunshine-duration)

austaltools.heating.DEFAULT_SLAB = 0.04

wall slab default thickness in m

austaltools.heating.DEFAULT_SLABS_OPT = 'even'

default scheme how walls are partitioned into slabs

austaltools.heating.DEFAULT_WIND = 3.0

default wind speed in m/s mean 10-m wind speed for Europe (https://www.eea.europa.eu/publications/ europes-changing-climate-hazards-1/wind/wind-mean-wind-speed)

austaltools.heating.PRESSURE = 101325

ambient air pressure in Pa

austaltools.heating.SOIL_ALBEDO = 0.15

soil surface default albedo in 1, typical values form Central Europe mixed vegetation after [SSS2016]

austaltools.heating.SOIL_EPSILON = 0.8

soil surface default spectral emissivity in 1, for dry soil, also for a mixture of forest and fields, see [Tah1992]

austaltools.heating.TIMESTEP = 1

model timestep in s

austaltools.heating.WALL_ALBEDO = 0.45

soil surface default albedo in 1, median value for typical European building materials after [Tah1992]

austaltools.heating.WALL_EPSILON = 0.95

wall default spectral emissivity in 1, for brick as well as grey to white paint from [Tah1992]

austaltools.heating.WIDTHEXP = 2.0

all slab thickness max exponent (>1)

austaltools.heating.WIDTHMIN = 0.01

wall slab minimal thickness for exponentially growing slabs in m

austaltools.heating.WIDTHSTEP = 0.005

wall slab thickness steps for exponentially growing slabs in m

import_buildings

This module provides funtions to processes a GeoJSON file containing building data, extracts the corner points, fit rectangles to corner points, plot the buildings and to write building inforamtion the ‘austal.txt’ configuration file.

austaltools.import_buildings.add_options(subparsers)
austaltools.import_buildings.building_corners(build: Building) list[tuple[float, float]]

Return the four corner positions of a rectangle with the properties:

Parameters:

build – Building object defining lower-left corner, rectangle extensions and rotation in degrees counterclockwise from the x-axis.

Returns:

list of corner positions

Return type:

list[tuple[float, float]]

austaltools.import_buildings.building_new()

return a new Building object :return: empty building object :rtype: _tools.Building()

austaltools.import_buildings.check_tolerances(tolerance: float, build: Building, points: list[tuple[float, float]]) bool

Check if the given points are within the specified tolerance from the building corners.

This function calculates the minimum distance from each point to the building corners and checks if all distances are within the specified tolerance. It also ensures that all four corners of the building are represented by the closest points.

Parameters:
  • tolerance (float) – The maximum allowable distance from the points to the building corners.

  • build (_tools.Building) – The building object containing the corner coordinates.

  • points (list[tuple[float, float]]) – A list of tuples representing the coordinates of the points to be checked.

Returns:

True if all points are within the tolerance and all corners are represented, False otherwise.

Return type:

bool

Example:
>>> building = _tools.Building(corners=[(0, 0), (0, 10), (10, 0), (10, 10)])
>>> points = [(1, 1), (1, 9), (9, 1), (9, 9)]
>>> check_tolerances(2.0, building, points)
True
austaltools.import_buildings.deduplicate(points, tolerance=None)

Removes duplicate points from a list of points.

Parameters:

points (list[tuple[float, float]]:) – A list of (x, y) coordinate tuples. tolerance (float, optional): Maximum distance for considering points as duplicates. If provided, points within this distance are considered duplicates.

Returns:

A list of unique points after removing duplicates.

Return type:

list[tuple[float, float]]:

Note:
  • If tolerance is specified, points within the tolerance distance are considered duplicates.

  • The dist_points function (not defined here) calculates the distance between two points.

Example:
>>> points = [(1.0, 2.0), (3.0, 4.0), (1.0, 2.0), (5.0, 6.0)]
>>> deduplicate(points)
[(1.0, 2.0), (3.0, 4.0), (5.0, 6.0)]
austaltools.import_buildings.dist_points(p1: tuple[float, float], p2: tuple[float, float]) float

Calulate distance between two points in a 2D a cartesian coordinate system

Parameters:
  • p1 (tuple[float, float]) – point 1

  • p2 (tuple[float, float]) – point 2

Returns:

distance

Return type:

float

austaltools.import_buildings.dist_to_line(a: float, b: float, s: float, p: tuple[float, float]) float

returns distance of point p to line with slope b ant offset a

Parameters:
  • a (float) – offset

  • b (float) – slope

  • s – (rotation) sense (see austaltools.austal_buildings_geojson.line_through())

  • p (tuple[float, float]) – point

Returns:

distance

Return type:

float

austaltools.import_buildings.extract_polygons(features, origin)

Extracts polygons from a list of features.

This function processes a list of features and extracts polygons from them. It checks the type of each feature, validates the geometry, and converts coordinates to a model coordinate system based on the specified origin.

Parameters:
  • features (list[dict]) – A list of feature dictionaries.

  • origin (tuple[float, float]) – The origin point for coordinate conversion.

Returns:

A list of polygons, where each polygon is represented by a tuple containing: - Feature index - Polygon index within the feature - List of points (x, y) in the model coordinate system

Return type:

list[tuple[int, int, list[tuple[float, float]]]]

Note:
  • If a feature has unsupported geometry type, it will be skipped.

  • For MultiPolygon features, only the exterior ring (first set of coordinates) is considered.

  • Holes in polygons are ignored.

  • The logger is used to report errors and warnings.

Example:
>>> features = [
...     {'type': 'Feature', 'geometry': {
...         'type': 'Polygon',
...         'coordinates': [[(0, 0), (1, 0), (1, 1), (0, 1)]]}
...     },
...     {'type': 'Feature', 'geometry': {
...         'type': 'MultiPolygon',
...         'coordinates': [[[(2, 2), (3, 2), (3, 3), (2, 3)]]]}
...     },
... ]
>>> origin = (0, 0)
>>> extract_polygons(features, origin)
[(0, 0, [(0.0, 0.0), (1.0, 0.0), (1.0, 1.0), (0.0, 1.0)]),
 (1, 0, [(2.0, 2.0), (3.0, 2.0), (3.0, 3.0), (2.0, 3.0)])]
austaltools.import_buildings.find_building_around(points: list[tuple[float, float]], tolerance: float) Building | None

Find the minimal rectagle encircling the points. Returns lower left corner as x and y coordinate, the exetensions of the rectangle, width in x-direction and depth in y-direction and its rotation angle in degrees counterclockwise from the x-axis.

Parameters:
  • points (list[tuple[float, float]]) – list of the points positions

  • tolerance (float) – minimum distance between points to consider them as different positions

Returns:

Building object defining x, y, width, depth and angle or none if finding fails

Return type:

_tools.Building or None

austaltools.import_buildings.is_rectangle(points, tolerance=0.1)

Check if the given points form a rectangle within the specified tolerance.

This function calculates the diagonals of the quadrilateral formed by the points and checks if the difference between the diagonals is within the specified tolerance value.

Parameters:
  • points (list[tuple[float, float]]) – A list of tuples representing the points.

  • tolerance (float, optional) – The maximum allowed difference between the diagonals.

Returns:

True if the points form a rectangle within the tolerance, False otherwise.

Return type:

bool

Example:

>>> points = [(0, 0), (0, 2), (2, 0), (2, 2)]
>>> is_rectangle(points)
True
austaltools.import_buildings.line_through(p1: tuple[float, float], p2: tuple[float, float]) -> (<class 'float'>, <class 'float'>)

Returns parameters of the line through two points: slope and offset of the linear equation and (rotation) sense: - +1 if p2 is to the right (positive x axis) of p1 - -1 if p2 is to the left (negative x axis) of p1

Parameters:
  • p1 (tuple[float, float]) – first point

  • p2 (tuple[float, float]) – second point

Returns:

intercept and slope of the line

Return type:

float, float

Example:
>>> p1 = (1, 2)
>>> p2 = (3, 4)
>>> line_through(p1, p2)
(1.0, 1.0, 1)
austaltools.import_buildings.main(args)

Main entry point: extract buildings from a GeoJSON file and write them to the config file ‘austal.txt’.

This function processes a GeoJSON file containing building data, extracts the relevant information, and writes it to a configuration file for further use. The function also supports optional plotting of building shapes.

Parameters:

args (dict) – A dictionary containing the following keys: - ‘zvalue’: (optional) The name of the JSON variable denoting building height. - ‘height’: (optional) A fixed height value for all buildings. - ‘tolerance’: The tolerance value for checking if the points form a rectangle. - ‘wdir’: The working directory where the ‘austal.txt’ file is located. - ‘file’: The name of the GeoJSON file containing building data. - ‘dry_run’: A boolean flag indicating whether to perform a dry run (no file output). - ‘plot’: A boolean flag indicating whether to plot the building shapes.

Raises:
  • ValueError – If the GeoJSON file is not of type ‘FeatureCollection’ or if the CRS is not ‘EPSG:31463’.

  • ValueError – If neither GaussKrueger nor UTM coordinates are found in the configuration.

  • ValueError – If no height information is available for a building.

Example:
>>> args = {
>>>     'zvalue': 'height',
>>>     'height': None,
>>>     'tolerance': 0.1,
>>>     'wdir': '/path/to/working/directory',
>>>     'file': 'buildings.geojson',
>>>     'dry_run': True,
>>>     'plot': False
>>> }
>>> main(args)
austaltools.import_buildings.nearest_point_on_line(a: float, b: float, p: tuple[float, float]) tuple[float, float]

Returns position of the point on the line of slope b ant offset a that is closest to point p.

Parameters:
  • a (float) – offset

  • b (float) – slope

  • p (tuple[float, float]) – point

Returns:

distance

Return type:

tuple[float, float]

austaltools.import_buildings.plot_building_shapes(args: dict, polygons: list[tuple], buildings: list[Building], topo: str = None)

Plot buildings and polygon shapes from geojson file

Parameters:
  • args (dict) – command line arguments

  • polygons (list[tuple]) – list of tuple (#feature, # polygon, list of points)

  • buildings (list[_tools.Building]) – Building objects

  • topo (str (optional)) – Name of topography file (*.grid)

austaltools.import_buildings.rotating_caliper(points: list[tuple[float, float]]) -> (<class 'float'>, <class 'float'>, <class 'float'>, tuple[float, float])

Return the equation of the one of all lines through two adjacent points, for which all other points are closest to the line, as well as dististance to and postion of the most distant point

Parameters:

points (tuple[float, float]) – point positions

Returns:

offset and slope of the line, most distant point distance and position of the first base point

Return type:

float, float, float, tuple[float, float]

austaltools.import_buildings.sort_anticlock(points: list[tuple[float, float]]) list[tuple[float, float]]

Sort points anticlockwise around the center point

Parameters:

points (list[tuple[float,float]]) – point positions to sort

Returns:

sorted point positions

Return type:

list[tuple[float,float]]

austaltools.import_buildings.DEFAULT_FILE = 'haeuser.geojson'

default name of the geojson value that indicates building height

austaltools.import_buildings.DEFAULT_ZVALUE = 'height'

allowed difference between geojson polygon corners and the rectangle fitted to them in m

austaltools.import_buildings.logger = <RootLogger root (WARNING)>

default name of the geojson file that contains building data

input_terrain

This module provides funtionailty to generate terrain input files for simulations with the German regulatory dispersion model AUSTAL [AST31]

austaltools.input_terrain.add_options(subparsers)
austaltools.input_terrain.main(args: dict)

This is the main working function.

Parameters:
  • args (dict) – The command line arguments as a dictionary.

  • args["gk"] (list[float, float]) – Gauß-Krüger coordinates as a list of two floats [rechts, hoch].

  • args["ut"] (list[float, float]) – UTM coordinates as a list of three floats [rechts, hoch, zone].

  • args["ll"] (list[float, float]) – Latitude and longitude as a list of two floats [lat, lon].

  • args["source"] (str) – The source of the terrain data, must be one of the available source IDs.

  • args["extent"] (float) – The extent of the area to be extracted in kilometers.

  • args["output"] (str) – The output file name without extension.

Note:

  • args["gk"], args["ut"], and args["ll"] are mutally exclusive.

Raises:

ValueError – If the source is not one of the available sources.

austaltools.input_terrain.show_notice(storage_path, source)

Shows a notice to the user when a dataset is accessed, if this is required by the original supplier of the dataset.

Parameters:
  • storage_path (str) – path to the dataset files

  • source (str) – dataset ID

austaltools.input_terrain.DEM_FMT = '%s.elevation.nc'

string format that forms the data file name from the ID of a dataset

austaltools.input_terrain.STORAGE_AUX_FILES = PosixPath('/builds/druee/austaltools/austaltools/data')

location where auxiliary files (e.g. license texts and dataset definitions) that are part of the module are stored

austaltools.input_terrain.STORAGE_DIR = 'terrain'

keyword that marks terrain datasets and is the name of the subdirectory of each storage locaton, where terrain data are stored

austaltools.input_terrain.SUBCOMMAND = 'terrain'

the keyword under which the subcommand provided by this module appears

input_weather

Created on Fri Dec 17 13:36:08 2021

@author: clemens

austaltools.input_weather.add_options(subparsers)
austaltools.input_weather.area_of_triangle(abc: list[tuple[float, float]]) float

calculate area of the triangle spanned by the corners abc

Parameters:

abc (list[tuple[float, float]]) – corner positions of the triangle

Returns:

area of the triangle. Positive if triangle node numbering is counter-clockwise, negative if clockwise

Return type:

float

austaltools.input_weather.austal_weather(args)

This is the main function implementing the command ‘weather’.

The function processes weather data based on the provided arguments and retrieves weather observations from various sources.

Parameters:

args (dict) –

A dictionary containing the following keys:

  • dwd (str or None): DWD station ID, used to retrieve station information.

  • wmo (str or None): WMO station ID, used to retrieve station information.

  • gk (list of float or None): Gauss-Krüger coordinates [rechts, hoch].

  • ut (list of float or None): UTM coordinates.

  • ll (list of float or None): Latitude and longitude coordinates.

  • ele (float or None): Elevation information.

  • year (int): Year for which the weather data is required.

  • output (str): Output name for the results.

  • source (str): Source of the weather data (e.g., “ERA5”, “CERRA”, “DWD”).

  • prec (bool): Flag indicating whether precipitation data should be included.

Raises:

ValueError – If an unknown source is provided.

austaltools.input_weather.cloud_type_from_cover(tcc: Series, lmcc: Series) Series

Estimate dominant cloud type from total and low/middle cloud cover

Parameters:
  • tcc (pd.Series[float]) – total cloud cover in 1

  • lmcc (pd.Series[float]) – low/middle cloud cover in 1

Returns:

cloud type

Return type:

pd.Series[str]

austaltools.input_weather.decode_nc_time(nc: Dataset, timevar: str = 'time') Series

Decode a time variable from a NetCDF dataset into a pandas Series of datetime objects.

This function reads a time variable from a NetCDF4 dataset, extracts its time units and calendar, and decodes the raw time values into Timestamps using netCDF4.num2date().

Parameters:
  • nc (netCDF4.Dataset) – The NetCDF dataset containing the time variable.

  • timevar (str, optional) – Name of the time variable to decode. Defaults to ‘time’.

Returns:

A pandas Series of decoded time values as pandas.Timestamp.

Return type:

pandas.Series

Raises:
  • KeyError – If the specified time variable does not exist.

  • AttributeError – If the time variable lacks ‘units’ or ‘calendar’.

  • ValueError – If the units or calendar are invalid for decoding.

Notes:
  • Uses netCDF4.num2date for decoding.

  • Ensures native Python datetime objects with: only_use_cftime_datetimes=False and only_use_python_datetimes=True.

  • Expects the time variable to follow CF conventions.

Example:
>>> import netCDF4
>>> import pandas as pd
>>> ds = netCDF4.Dataset('example.nc')
>>> times = decode_nc_time(ds)
>>> print(times.head())
austaltools.input_weather.get_cerra_weather(lat, lon, year, datafile=None) -> (<class 'pandas.DataFrame'>, <class 'float'>)

Get weather timeseries for the provided position from source CERRA for the year provided and calulate cloud cover of non-high clouds (lmcc) and roughness length z0 from “forecast surface roughness”

Parameters:
  • lat (float) – position latitude in degrees

  • lon (float) – position laongitude in degrees

  • year (int) – get data from this calendar year

  • datafile (str | None) – (optional) read from this CERRA data file

Returns:

weather timeseries as dataframe and surface roughness in m. The index of the dataframe is the measurement time as datetime64, the columns are:

column

unit

comment

’time’

UTC

’ff’

m/s

wind speed at 10m height

’dd’

degrees

wind direction

’sp’

Pa

surface air pressure (QFE)

’t2m’

K

air temperature at 2 m height

’lmcc’

1

low and medium cloud cover

’tcc’

1

total cloud cover

’sshf’

W/m²

surface sensible heat flux

’slhf’

W/m²

surface latent heat flux

’fsr’

m

forecast surface roughness

’tp’

mm

total precipitation per hour

Return type:

(pd.DataFrame, float)

austaltools.input_weather.get_dwd_weather(lat: float, lon: float, year: int, station: int = None, datafile: str = None) -> (<class 'pandas.DataFrame'>, <class 'float'>)

Get weather timeseries for the provided position from source DWD for the year provided. Units are converted and calulate cloud cover of non-high clouds (lmcc) and roughness length z0 from “forecast surface roughness”

Parameters:
  • lat (float) – position latitude in degrees

  • lon (float) – position laongitude in degrees

  • year (int) – get data from this calendar year

  • station (int) – (optional) DWD station number

  • datafile (str | None) – (optional) read from this data file

Returns:

weather timeseries as dataframe and surface roughness in m. The index of the dataframe is the measurement time as datetime64, the columns are:

column

unit

comment

’time’

UTC

’ff’

m/s

wind speed at 10m height

’dd’

degrees

wind direction

’sp’

Pa

surface air pressure (QFE)

’t2m’

K

air temperature at 2 m height

’r2m’

1

relative humidity at 2 m height

’tcc’

1

total cloud cover

’cbh’

m

cloud base height above ground

’cty’

cloud type (2-letter code)

’fsr’

m

forecast surface roughness

’tp’

mm

total precipitation per hour

Return type:

(pd.DataFrame, float)

austaltools.input_weather.get_era5_weather(lat, lon, year, wind_variant=None, datafile=None) -> (<class 'pandas.DataFrame'>, <class 'float'>)

Get weather timeseries for the provided position from source ERA5 for the year provided and calulate cloud cover of non-high clouds (lmcc) and roughness length z0 from “forecast surface roughness”

Parameters:
  • lat (float) – position latitude in degrees

  • lon (float) – position laongitude in degrees

  • year (int) – get data from this calendar year

  • wind_variant (str | None) – (optional) select the variant how the wind at 10 m height is caclulated from the ERA5 data

  • datafile (str | None) – (optional) read from this ERA5 data file

Returns:

weather timeseries as dataframe and surface roughness in m. The index of the dataframe is the measurement time as datetime64, the columns are:

column

unit

comment

’time’

UTC

’ff’

m/s

wind speed at 10m height

’dd’

degrees

wind direction

’sp’

Pa

surface air pressure (QFE)

’t2m’

K

air temperature at 2 m height

’lmcc’

1

low and medium cloud cover

’tcc’

1

total cloud cover

’sshf’

W/m²

surface sensible heat flux

’slhf’

W/m²

surface latent heat flux

’fsr’

m

forecast surface roughness

’tp’

mm

total precipitation per hour

Return type:

(pd.DataFrame, float)

austaltools.input_weather.get_hostrada_weather(lat, lon, year, datafile=None) -> (<class 'pandas.DataFrame'>, <class 'float'>)

Get weather timeseries for the provided position from source HOSTRADA by DWD for the year provided and calulate cloud cover of non-high clouds (lmcc) and roughness length z0 from “forecast surface roughness”

Parameters:
  • lat (float) – position latitude in degrees

  • lon (float) – position laongitude in degrees

  • year (int) – get data from this calendar year

  • datafile (str | None) – (optional) read from this HOSTRADA data file

Returns:

weather timeseries as dataframe and surface roughness in m. The index of the dataframe is the measurement time as datetime64, the columns are:

column

unit

comment

’time’

UTC

’ff’

m/s

wind speed at 10m height

’dd’

degrees

wind direction

’sp’

Pa

surface air pressure (QFE)

’t2m’

K

air temperature at 2 m height

’r2m’

%

relative humidity at 2 m height

’tcc’

1

total cloud cover

Return type:

(pd.DataFrame, float)

austaltools.input_weather.grid_calulate_weights(pos: list, inter_variant=None) list[float]

calculate the weights for barycentrict averaging of the sourrounding values

Parameters:
  • pos (list[tuple[float, float, float]]) – the three grid node positions and distances as tuple (x,y,d)

  • inter_variant (str) – method user for interpolation

Returns:

weights

Return type:

list[float]

austaltools.input_weather.grid_surrounding_nodes(lat: float, lon: float, dims: dict) list[tuple[float, float, float]]

get the three nodes from dims that surround position lat / lon

Parameters:
  • lat (float) – point position latitude

  • lon (float) – point position longitude

  • dims (dict[np.array]) – 2-D array of lat and lon grid positions

Returns:

Three corner positions and the distance to each of them as tuple (grid-index x, grid-index y, distance)

Return type:

list[tuple[float, float, float]]

austaltools.input_weather.h_eff(has: float, z0s: float) list

Calculate the effective anemometer heights of an anemometer mounted at height has at a postion with roughness length z0s (in m), for each of the 9 AUSTAL roughness-lenght classes (0.01m, 0.02m, 0.05m, 0.1m, 0.2m, 0.5m, 1m, 1.5m, 2m). :param has: actual aneometer height above ground in m :param z0s: roughness length at the anemoeter position in m :return: nine effective anemometer heights corresponding to the nine roughness classes. :rtype: list of float

austaltools.input_weather.main(args)

This is the main routine that processes the input arguments and calls the main working function austal_weather.

Parameters:

args (dict) – A dictionary containing the following keys: - dwd (str or None): DWD option, mutually exclusive with ‘wmo’ and required with ‘ele’. - wmo (str or None): WMO option, mutually exclusive with ‘dwd’ and required with ‘ele’. - ele (str or None): Element option, required with either ‘dwd’ or ‘wmo’. - year (int or None): Year option, required with ‘-L’, ‘-G’, ‘-U’, ‘-D’, or ‘-W’. - output (str or None): Output name, required with ‘-L’, ‘-G’, ‘-U’, ‘-D’, or ‘-W’. - station (str or None): Station option, only valid with ‘dwd’ or ‘wmo’.

Raises:

SystemExit – If mutually exclusive options are provided or required options are missing.

austaltools.input_weather.point_in_triangle(p: tuple[float, float], abc: list[tuple[float, float]]) bool

check if point p is inside the triangle spanned by the corners abc

Parameters:
  • p (tuple[float, float]) – position of point p

  • abc (list[tuple[float, float]]) – corner positions of the triangle

Returns:

returns True if point is inside triangle, returns False otherwise OR when the triangle is trivial (has zero area)

Return type:

bool

austaltools.input_weather.read_cerra_nc(ncfile, lat, lon)

Read a CERRA NetCDF file and interpolate variables to a given position (lat, lon), converting units where necessary and recalculating wind speed and direction using surface roughness.

The function interpolates variables to the provided coordinates, converts units for physical consistency, decomposes and recomputes 10-meter wind speed and direction, decomposes accumulated variables and normalizes them and returns the processed data as a pandas DataFrame

Parameters:
  • ncfile (str) – Path to the NetCDF file.

  • lat (float) – Latitude (decimal degrees) for interpolation.

  • lon (float) – Longitude (decimal degrees) for interpolation.

Returns:

DataFrame containing time series of interpolated and derived variables at the specified location. Returned columns include:

Required:
  • ’time’ : Timestamp (UTC)

  • ’t2m’ : 2-metre temperature [K]

  • ’sp’ : Surface pressure [Pa]

  • ’sshf’ : Sensible heat flux [W m**-2]

  • ’slhf’ : Latent heat flux [W m**-2]

  • ’sr’ → ‘fsr’ : Surface roughness [m]

  • ’r2’ → ‘r2m’ : Relative humidity [1]

  • ’lcc’ : Low-level cloud cover [1]

  • ’mcc’ : Medium-level cloud cover [1]

  • ’tcc’ : Total cloud cover [1]

Optional (if available):
  • ’tp’ : Total precipitation [mm]

Computed variables:
  • ’zust’ : Friction velocity [m s**-1]

  • ’ff’ : 10-metre wind speed [m s**-1]

  • ’dd’ : 10-metre wind direction [deg]

Return type:

pandas.DataFrame

Raises:

ValueError – If any required variable is missing in the NetCDF file.

Notes:

The ERA5 variables expected in the input file are:

name

unit

description

‘time’

‘wdir10’

deg

10-metre wind direction true

‘si10’

m s**-1

10-metre wind speed

‘r2’

%

2-metre relative humidity

‘t2m’

K

2-metre temperature

‘lcc’

%

low-level cloud cover

‘mcc’

%

medium-level cloud cover

‘tisemf’

N m**-2 s

time integral of surface eastward momentum flux

‘tisnmf’

N m**-2 s

time integral of surface northward momentum flux

‘slhf’

J m**-2

surface latent heat flux

‘sp’

Pa

surface pressure

‘sr’

m

surface roughness

‘sshf’

J m**-2

surface sensible heat flux

‘tcc’

%

total cloud cover

optional:

‘tp’

kg m**=2

total precipitation

Warning:

Missing optional variables are skipped with a warning.

austaltools.input_weather.read_era5_nc(ncfile, lat, lon, wind_variant=None)

Read an ERA5 NetCDF file, interpolate meteorological variables to a specific geographic position (latitude, longitude), and calculate wind speed and direction adjusted for surface roughness.

This function extracts required and optional ERA5 meteorological variables from the input NetCDF file, interpolates them to the given point location, applies surface flux and roughness adjustments, and optionally computes wind speed based on selected surface roughness models.

Parameters:
  • ncfile (str) – Path to the ERA5 NetCDF file.

  • lat (float) – Latitude (in degrees) of the point at which to interpolate values.

  • lon (float) – Longitude (in degrees) of the point at which to interpolate values.

  • wind_variant (str) –

    Method used to compute 10 m wind speed (ff). Default is DEFAULT_WIND_VARIANT. Supported options:

    • ’fixed_057’ : Assumes fixed surface roughness z₀ = 0.57 m.

    • ’fixed_010’ : Assumes fixed surface roughness z₀ = 0.10 m.

    • ’model_mean’ : Uses mean surface roughness from model data.

    • ’model_uv10’ : Uses u10 and v10 without adjustment.

    • ’model_fsr’ : Uses model-provided roughness field (fsr).

Returns:

DataFrame containing interpolated meteorological variables and computed wind metrics. Includes the following variables (if present in the input data):

Required:
  • time : datetime64[ns], timestamps

  • u10 : float, 10 m u-component of wind [m/s]

  • v10 : float, 10 m v-component of wind [m/s]

  • sp : float, surface pressure [Pa]

  • zust : float, friction velocity [m/s]

  • fsr : float, forecast surface roughness [m]

  • t2m : float, 2 m temperature [K]

  • d2m : float, 2 m dewpoint temperature [K]

  • cbh : float, cloud base height [m]

  • sshf : float, surface sensible heat flux [W/m²]

  • slhf : float, surface latent heat flux [W/m²]

  • lcc : float, low cloud cover [fraction]

  • tcc : float, total cloud cover [fraction]

Optional (included if available):
  • mcc : float, medium cloud cover [fraction]

  • tp : float, total precipitation [mm]

Computed:
  • ff : float, 10 m wind speed [m/s]

  • dd : float, wind direction in degrees from North [°]

Return type:

pandas.DataFrame

Raises:

ValueError – If a required variable is missing from the NetCDF file or if the wind_variant is unknown or unsupported.

Notes:

The ERA5 variables expected in the input file are:

name

unit

description

code

‘time’

‘u10’

m s**-1

10m_u-component_of_wind

10u

‘v10’

m s**-1

10m_v-component_of_wind

10v

‘sp’

Pa

surface_pressure

sp

‘zust’

m s**-1

friction_velocity

zust

‘fsr’

m

forecast_surface_roughness

fsr

‘t2m’

K

2m_temperature

2t

‘d2m’

K

2m_dewpoint_temperature

2d

‘cbh’

m

cloud_base_height

cbh

‘sshf’

J m**-2

surface_sensible_heat_flux

sshf

‘slhf’

J m**-2

surface_latent_heat_flux

slhf

‘lcc’

1

low_cloud_cover

lcc

‘tcc’

1

total_cloud_cover

tcc

optional:

‘mcc’

1

medium_cloud_cover

mcc

‘tp’

m

total_precipitation

tp

  • The function uses logarithmic wind profile theory to estimate wind speeds when wind_variant involves surface roughness.

  • Heat fluxes (sshf, slhf) are converted from J/m² per hour to W/m² (SI units).

  • Total precipitation (tp) is converted from meters to millimeters.

  • Wind direction (dd) is computed as meteorological direction (from which the wind blows).

  • Wind components (u10, v10) in ERA5 are based on a fixed roughness length for short grass (z₀=0.03m), so wind speed (ff) is recalculated accordingly.

Example:
>>> df = read_era5_nc("era5_data.nc", lat=52.52, lon=13.405)
>>> print(df[['time', 'ff', 'dd']].head())
austaltools.input_weather.read_hostrada_nc(ncfile, lat, lon, wind_variant=None)

Read a HOSTRADA NetCDF file and interpolate variables to a given position (lat, lon), converting units where needed.

This function reads the NetCDF file, interpolates variables to the specified location, converts units to standardized formats, returning the interpolated values renamed to the unified naming convention

Parameters:
  • ncfile (str) – Path to the HOSTRADA NetCDF file.

  • lat (float) – Latitude (decimal degrees) at which to interpolate data.

  • lon (float) – Longitude (decimal degrees) at which to interpolate data.

  • wind_variant (str | None) – Placeholder for future use (e.g., handling different wind input schemes). Currently unused.

Returns:

A DataFrame containing interpolated and converted variables at the given point. The following variables are included:

Required:
  • ’time’ : Timestamp (UTC)

  • ’sp’ : Surface pressure [Pa]

  • ’ff’ : Wind speed at 10 m [m s**-1]

  • ’dd’ : Wind direction at 10 m [deg]

Computed:
  • ’t2m’ : 2-metre temperature [K] (converted from °C)

  • ’tcc’ : Total cloud cover [1] (from 0–8 octas)

  • ’r2m’ : Relative humidity [1] (from %)

Return type:

pandas.DataFrame

Raises:

ValueError – If any required variable is missing in the NetCDF file.

Notes:

Variables expected in the input file are:

name

unit

long name

‘time’

‘tas’

°C

Near-Surface Air Temperature

‘clt’

octa

Total Cloud Fraction

‘hurs’

%

Near-Surface Relative Humidity

‘ps’

Pa

Surface Air Pressure

‘sfcWind_direction’

deg

Near-Surface Wind Direction

‘sfcWind’

m s**-1

Near-Surface Wind Speed

  • The function assumes the NetCDF contains 2D longitude/latitude fields.

  • Missing or malformed wind data will result in interpolation errors or incorrect wind values.

austaltools.input_weather.DEFAULT_CLASS_SCHEME = 'all'

Default method to calculate stability class

Overridden by environment variable “CLASS_SCHEME”

Possible values: ‘all’ or a space-delimited list containing one ore multiple of: ‘kms’, ‘k2s’, ‘kmc’, ‘pts, ‘pgc’

austaltools.input_weather.DEFAULT_INTER_VARIANT = 'weighted'

Default method to interpolate to a given position

Overridden by environment variable “INTER_VARIANT”

Possible values are: ‘weighted’, ‘nearest’, ‘mean’

austaltools.input_weather.DEFAULT_WIND_VARIANT = 'model_uv10'

Default method to calculate the 10-m wind

Overridden by environment variable “WIND_VARIANT”

Possible values are: ‘fixed_057’ ‘fixed_010’ ‘model_mean’ ‘model_uv10’ ‘model_fsr’

plot

Module containing functions to create a basic plot from austal result data

Plots can be shon interactively if the user operates on a terminal that has an X-server running. For example Linux with a running desktop environment, an Anaconda environment or a ssh connection with active X-forwarding and a local X-server running.

austaltools.plot.add_options(subparsers)
austaltools.plot.main(args)

This is the main working function

Parameters:
  • args (dict) – The command line arguments as a dictionary.

  • args['working_dir'] (str) – The working directory where files are located (i.e. where austal.txt is stored).

  • args['file'] (str) – The input file name. If it doesn’t have a ‘.dmna’ extension, it will be added.

  • args['buildings'] (bool) – A flag indicating whether to plot buildings from the configuration.

  • args['stdvs'] (float) – The standard deviation value to mark (additional) concentrations as significant by overlaying dots..

  • args['plot'] (str or None) – The plot file name. If None or ‘-’, the plot will be shown interactively. If ‘__default__’, the name of the displayed data file with extension .png will beused.

Raises:
  • OSError – If the configuration file cannot be found or read.

  • ValueError – If the data shape is not understood or if the standard deviation shape does not match the data shape.

austaltools.plot.parse_austal_outputname(filename: str)

analyze name of austal output file

Parameters:

filename – str

Returns:

information about file contents:

  • substance: name of pollutant (xx for unknown/not specified)

  • averaging: duration of averaging interval (accumulation, year, day or hour)

  • rank: rank of output value in list of all averages of the same length

  • kind: type of output (load, stdev or index)

  • grid: number of grid. 0 if not given / no staggered grids.

Return type:

dict

steepness

create basic plot for austal result files

austaltools.steepness.add_options(subparsers)
austaltools.steepness.main(args)

transform

This module provides convenience funtions to translate between ccordinate systems. If the ‘austal.txt’ configuration file is in the working directory, conversion from model coordinates to real world coordinates is also possible

austaltools.transform.add_options(subparsers)
austaltools.transform.crs_bounds(crs)

return corners of area of use of a coordinate refernce system

Parameters:

crs (osgeo.osr.SpatialReference) – coordinate refernce system object

Returns:

area of use (lower left, upper right (LLUR) in lattitude / logitude)

Return type:

list[float]

austaltools.transform.in_bounds(lat, lon, crs)

check if a position is insidethe area of use of a coordinate refernce system

Parameters:
  • lat (float) – position latitude

  • lon (float) – position longitude

  • crs (osgeo.osr.SpatialReference) – coordinate refernce system object

Returns:

True if in area of use

Return type:

bool

austaltools.transform.main(args)
austaltools.transform.model_origin(path=None)

volout

This module …

austaltools.volout.add_options(subparsers)
austaltools.volout.contrasting_shade(color, factor=0.4)

Return a darker or lighter shade of the same hue that contrasts with the input.

If the color is light (luminance > 0.5), returns a darker shade. If the color is dark, returns a lighter shade.

Parameters:
  • color – any matplotlib color specification

  • factor – how far to shift the lightness (0..1)

Returns:

RGBA tuple

austaltools.volout.is_valid_color(c)
austaltools.volout.main(args)

This is the main working function

Parameters:

args (dict) – the command line arguments as dictionary

austaltools.volout.plot_voxels(grid: ndarray, xmin: float, ymin: float, delt: float, hh: ndarray | list, color: tuple[str] | None = None, camera: tuple[float] | None = None, zoom: float | None = None, clip: str | None = None)

Plot isometric view of a 3D binary grid.

Parameters:
  • grid (np.ndarray) – 3D ndarray of 0s and 1s, shape (ni, nj, nk)

  • xmin (float) – x origin

  • ymin (float) – y origin

  • delt (float) – grid spacing in x and y

  • hh (np.ndarray | list) – 1D array of z-levels, length nk

  • camera (tuple[float]) – plot view from azimuth (geodetic, clockwise from north) and elevation (upward) angle

  • zoom (float | None) – zoom focal length (1 = 90° viewing angle) or None for isometric plot

  • clip (str | None) – zoom to - out: show full grid - ‘center’: keep center position, clip axes (symetrically) to max building extent - in: show only space filled with buildings

windfield

This module …

austaltools.windfield.add_options(subparsers)
austaltools.windfield.load_topo(path: str, variable: str = '') Tuple[list, list, ndarray]

Get the AUSTAL model topography from the file topo_path

Parameters:
  • path (str) – file name of the topography file

  • variable (str) – variable name, defaults to empty string

Returns:

axes coordinates and topography grid

Return type:

(list, list, np.ndarray)

austaltools.windfield.main(args)

This is the main working function

Parameters:

args (dict) – the command line arguments as dictionary

austaltools.windfield.superpose(u_grid: ndarray, v_grid: ndarray, axes: dict, dirs: list, ua: float, va: float, xa: float, ya: float, ha: float, ak: int)

Calculate the wind field by superposition of u_grid and v_grid

Parameters:
  • u_grid (np.ndarray) – wind field for eastward flow, eastward (u) and northward (v) components

  • v_grid (np.ndarray) – wind field for northward flow

  • axes (dict[str, list[float]]) – x and y axes

  • dirs (list) – list of wind directions in lib

  • ua (float) – anemometer eastward wind component

  • va (float) – anemometer northward wind component

  • xa (float) – anemometer position

  • ya (float) – anemometer position

  • ha (float) – anemometer height

  • ak (int) – Klug/Manier stability class

Returns:

superposed wind field eastward (u) and northward (v) components

Return type:

(np.ndarray[float], np.ndarray[float])

windrose

This module …

austaltools.windrose.add_options(subparsers)
austaltools.windrose.main(args)

This is the main working function

Parameters:

args (dict) – the command line arguments as dictionary