Skip to content

Short term scenarios

This submodule contains the definition of the scenarios as prescribed by the ENSI G14 directive.

Optional Photon Comparison

Using PKI

Pass pki_nuclides to compare the photon point-kernel result with the existing ENSI-G14 direct and residence hotspots. The min_radius_direct and min_radius_residence arguments belong to the G-14 hotspot selector, not to PKI: they define the spatial exclusions used while selecting those ENSI-G14 points. PKI runs only after that selection and does not choose or change the hotspots. To evaluate arbitrary coordinates without hotspot selection, see the arbitrary-coordinate example.

The short-term PKI path is an advanced, photon-only, non-regulatory comparison. It is disabled by default, and ENSI-G14 remains the reference model. Enable it only after choosing the nuclides and the existing ENSI hotspot constraints:

from ensi_g14_calculator.dose import PointKernelConfig

results = evaluator.evaluate_short_term_dose(
    nuclides_bq=nuclides,
    x=x,
    y=y,
    pki_nuclides=["Cs-137"],
    pki_config=PointKernelConfig(
        radial_order=12,
        polar_order=12,
        azimuthal_order=16,
    ),
    pki_hotspot_age_group="adult",
    min_radius_direct=200 * m,
    min_radius_residence=500 * m,
)

pki_nuclides may currently contain only nuclides with packaged photon spectra. The Cs-137 line is 0.6617 MeV with yield 0.8510. The PKI comparison is evaluated at the ENSI-selected direct and residence points and does not add a PKI grid or change ENSI hotspot selection. Point comparisons are available from results.get_point_doses() and the weather reports are in results.hotspot_report; default dose totals exclude the nonreference PKI records.

For a PKI result at arbitrary coordinates, without running the G-14 grid or hotspot selector, call ScenarioEvaluator.evaluate_short_term_pki(...). Pass scalar or broadcastable x, y, and optional z coordinates, one weather category, and the wind direction. It returns a DoseCollection containing pki_photon point records for both 0-8h and 8-24h; use get_point_doses() to filter by coordinate index, nuclide, interval, and age group. If z is omitted, the observer is placed at local terrain height. See the arbitrary-coordinate example for a complete call.

The PKI dose uses integrated released activity Q and returns integrated Sv. Parent transport decay and shielding are applied, but daughter ingrowth and kSPE are omitted. The underlying ISO fluence-to-effective-dose conversion is used. See the dose API page for geometry, terrain, truncation, and spectrum extension policies.

ensi_g14_calculator.short_term_scenarios

Modules

release_by_time_interval

Classes
ReleaseInterval dataclass

Represents a specific release window with its released activity and calculated deposition factors.

Scenario

Bases: ABC

Scenario class, mainly implements the computation of the \(\overline{\xi \, Q}\) term given activity releases in successive time intervals.

Tor future users: do not use this abstract class, use its children. (ShortTermScenario, PotentialExposureScenario)

ShortTermScenario

Bases: Scenario

Short term scenario implementation, from Chapter 4: Kurzzeitabgaben (SE1 and SE2). Uses a weighted average of two dispersion factors, with an activity Q released homogeneously over 24h.

Potential deviation

for such scenarios, the G14 does not allow \(Q\) do be released entirely in the first interval. in Mars 2026, test scenarios were given to us by PSI and included a release in the first hour only. If agreed upon with ENSI, we can a modified ShortTermScenario where this is possible. (Q entirely dispersed in first 8h)

Resolution

In the subsequent version of the tests (Avril 2026), \(Q\) is spread over 24h as prescribed.

Usage example:

intervals = [
    ReleaseInterval(Q=1e10 * Bq, xi=1e-5 / m**2, xi_p=2e-5 / m**2, label='0-8h', shielding_factor=1),
    ReleaseInterval(Q=1e10 * Bq, xi=5e-6 / m**2, xi_p=1e-5 / m**2, label='8-24h')  # Q has to be identical to first
]
scenario = ShortTermScenario(intervals)
# then, use "scenario" as an argument in the short term dose calculator methods.

PotentialExposureScenario

Bases: Scenario

Potential exposure scenario implementation, from Chapter 6: Potenzielle Expositionen (SE3 and SE4). Sums releases over 4 distinct time intervals. Similar to ShortTermScenario but with more freedom. (\(Q\) can vary, defined in each time interval separately. However, the dispersion has to scale in each interval according to paragraph 6.1.1.1.b.3. I cannot enforce this check here, as we only know about deposition here and not deposition). The time intervals are 0-8h, 8-24h, 24-72h, 72h-168h.

Usage example:

intervals = [
    ReleaseInterval(Q=3e10 * Bq, xi=1e-5 / m**2, xi_p=2e-5 / m**2, label='0-8h', shielding_factor=1),
    ReleaseInterval(Q=2e10 * Bq, xi=5e-6 / m**2, xi_p=1e-5 / m**2, label='8-24h'),
    ReleaseInterval(Q=1e10 * Bq, xi=3e-6 / m**2, xi_p=1e-5 / m**2, label='8-24h'),
    ReleaseInterval(Q=1e10 * Bq, xi=9e-6 / m**2, xi_p=1e-5 / m**2, label='8-24h'),
]
scenario = PotentialExposureScenario(intervals)
# then, use "scenario" as an argument in the short term dose calculator methods.
# the shielding factor is set to 1 to denote no shielding during the first 8h, per Richtlinie.

runner

This file implements a high level class for running short term scenarios. You can find examples in the main documentation.

Classes
DoseCollection
Functions
add_dose(weather, nuclide, interval, pathway, dose_age_groups_dict, model='ensi_g14', is_reference=True)

unpacks the age_group dictionary returned by your dose calculators into flat keys

add_point_dose(weather, nuclide, interval, pathway, age_group, observer_role=None, grid_index=None, x=None, y=None, z=None, dose=None, model='pki_photon', is_reference=False, role=None)

Store a scalar dose at an observer without creating a full grid.

get_point_doses(weather=None, nuclide=None, interval=None, pathway=None, age_group=None, role=None, model=None, reference_only=False, observer_role=None)

Return PKI point doses matching the supplied filters.

sum_doses(weather=None, nuclide=None, interval=None, pathway=None, age_group=None, model=None, reference_only=True)

Sums dose arrays matching the conditions.

Parameters:

Name Type Description Default
weather

string, default None --> matches weather. If not given, sums across weather categories (not wanted)

None
nuclide

string, default None --> matches nuclide. If not given, sums across nuclides.

None
interval

string, default 'medium_term' --> matches interval. If None given, sums across release intervals (not wanted).

None
pathway

string, default None --> matches pathway. If not given, sums across pathways.

None
age_group

string, default None --> matches age group. If None given, sums across age groups (not wanted).

None
model

string, default None --> matches a dose model. If not given, sums all models subject to reference_only.

None
reference_only

bool, default True --> excludes comparison records unless explicitly disabled.

True

Returns:

Type Description

grid of dose with units.

ScenarioEvaluator

This is the class you should be using to compute a short term scenario, you can look at the examples in the documentation.

usage pattern:

evaluator = ScenarioEvaluator()
result = evaluator.evaluate_short_term_dose(
      nuclides_bq={'nuclide1': 1*Bq, 'nuclide2': 10*Bq, ...},
      x=x,
      y=y,  # x and y array or float of positions relative to the release where you want to conduct dose evaluations
      wind_direction=-90, # default wind from west, you can change it
)

class members: (override after initialisation for deviations from the G-14) - wind_speed, default 1.0 (m / s). - calculate_time_of_flight, default False. If True, calculates time of flight as distance to chimney over wind speed. Only used when decay_in_plume is False. - decay_in_plume, default True. Radioactive decay during transport is applied inside the plume, at the travel time x / U of every point (dispersion/plume_decay.py), instead of over the G-14 flight time T_fz in the dose formulae. Deposition is decayed as well for nuclides without daughters (for decay chains it stays undecayed, as in G-14, so that the daughters grown in the air are deposited). False: G-14 T_fz.

Functions
__init__(source_params, orography, recorder=NULL_RECORDER, near_field=None)

Parameters:

Name Type Description Default
source_params SourceParams

SourceParams object

required
orography Orography

Orography object

required
recorder IntermediateRecorder

IntermediateRecorder instance, default NULL_RECORDER

NULL_RECORDER
near_field Optional[NearFieldConfig]

optional near_field.NearFieldConfig: building-wake dispersion for a short stack (outside G-14, see prototyping/near_field_dispersion.tex). None: plain G-14.

None
evaluate_short_term_pki(nuclides_bq, x, y, z=None, weather_category='A', wind_direction=-90, wind_speed=None, pki_nuclides=None, pki_config=None, T_fz=None, k_s_0_8h=1.0, k_s_8_24h=None)

Evaluate short-term photon PKI doses at arbitrary coordinates.

This method deliberately does not run the ENSI-G14 grid calculation or select regulatory hotspots. It reuses this evaluator's source, orography, short-term wind convention, and physical plume model to evaluate the requested points directly.

The standard short-term release is split into Q / 3 for 0-8h and 2 * Q / 3 for 8-24h. The latter interval also applies the G-14 factor of one half to the physical plume dispersion. The returned :class:DoseCollection contains only non-reference pki_photon point records and can be queried with get_point_doses.

Parameters:

Name Type Description Default
nuclides_bq

mapping of nuclide names to total released activity over 24 hours, in Bq.

required
x

scalar or array of east coordinates relative to the chimney, with length units.

required
y

scalar or array of north coordinates relative to the chimney, with length units. It must broadcast with x.

required
z

optional scalar or array of global vertical coordinates relative to the chimney base, with length units. If omitted, the observer is placed at local terrain height.

None
weather_category

one ENSI-G14 category (A-F or 1-6).

'A'
wind_direction

meteorological wind-from direction in degrees.

-90
wind_speed

wind speed in m/s, as a quantity or plain number. If omitted, self.wind_speed is used.

None
pki_nuclides

optional subset of nuclides_bq. If omitted, every supplied nuclide must have a packaged photon spectrum.

None
pki_config

optional PointKernelConfig or mapping of its settings.

None
T_fz

optional scalar or array flight time with time units. If omitted, the standard short-term flight-time policy is used; when calculate_time_of_flight is enabled, horizontal distance is divided by the supplied wind speed.

None
k_s_0_8h

shielding factor for the first interval.

1.0
k_s_8_24h

shielding factor for the second interval. If omitted, the short-term G-14 value is used.

None

Returns:

Type Description

DoseCollection containing one point record per coordinate, nuclide, interval, and age group.

evaluate_short_term_dose(nuclides_bq, x, y, wind_direction=-90, T_exp=1.0 * year, release_date='08-01', pki_nuclides=None, pki_config=None, pki_hotspot_age_group='adult', min_radius_direct=None, min_radius_residence=None, height=None)

Method for evaluating a standard G14 24h release. Returns a DoseCollection: query dose grids with DoseCollection.sum_doses(weather=, interval=, age_group=, [nuclide=, pathway=]), the weather categories being 'A' to 'F', the intervals '0-8h', '8-24h' and 'medium_term'. Each grid has the same shape as the x and y arguments. Dispersion and deposition grids are in DoseCollection.dispersion and DoseCollection.deposition. The result can be plotted with the ensi_g14_calculator.misc.plots.plot_dose_summary function.

Parameters:

Name Type Description Default
nuclides_bq

dict like {'H-3_HTO': 1e10 * Bq}

required
x

scalar or array, with astropy unit (length) -- locations at which to evaluate the dose.

required
y

scalar or array, with astropy unit (length)

required
wind_direction

int, wind direction (default -90, wind coming from west)

-90
T_exp

scalar, astropy units (time), default 1 year. Exposure time after release, value according to directive (1 year for short term scenarios).

1.0 * year
release_date

string, default '08-01'. Release date with format 'mm-dd'. Conservatively assumed to happen two months before the end of harvest season according to directive, hence default '08-01'.

'08-01'
pki_nuclides

optional iterable of nuclides for point-kernel comparisons.

None
pki_config

optional PointKernelConfig or mapping of its settings.

None
pki_hotspot_age_group

age group used for ENSI hotspot selection, default 'adult'.

'adult'
min_radius_direct

required radius when PKI is requested for direct hotspot selection.

None
min_radius_residence

required radius when PKI is requested for residence selection.

None
height

optional observer height above local ground (scalar or array like x), with units (length). Outside G-14. Inhalation, submersion (and the PKI observers) are evaluated at that height, and DoseCollection.dispersion holds chi at that height; deposition and ingestion use the ground-level dispersion. Not supported with the PKI surrogate.

None

Returns:

Type Description

DoseCollection. When PKI is requested, hotspot_report contains the weather reports with point comparisons and worst_weather contains the ENSI-selected worst weather category.

Functions
get_max_report(results, age_group, x, y, min_radius_direct, min_radius_residence)

Evaluates the scenario over all weather categories and finds the locations of the maximum doses while respecting the spatial exclusions (min_radius_direct and min_radius_residence).

get_short_term_weather(weather_category, wind_direction=-90.0, wind_speed=1.0)

Returns the standard 0-8h (2mm/h) and 8-24h (1mm/h) weather objects, according to ENSI-G14 2025 section 4.1.1.2.b.1. As a user, you should not have to care about this method and go straight to the ScenarioEvaluator class.

Parameters:

Name Type Description Default
weather_category

string, from 'A' to 'F'

required
wind_direction

direction of the wind, default -90 (wind coming from west)

-90.0
wind_speed

speed of the wind, in m/s, default=1.0 (as prescribed by G-14 for short-term scenarios.)

1.0

Returns:

Type Description

tuple of WeatherStats objects with correct weathers, ready to be used with the averager.