Ir al contenido
Esta documentación describe la versión 4.0.0, todavía sin publicar. La versión actual en PyPI es la 3.3.0 y no incluye todo lo que se describe aquí.

environment.assessment.exposure_distribution

La referencia de la API se publica en inglés en los dos idiomas: se genera a partir de los docstrings del código, que son su texto original.

How often a blast is how loud: the distribution of its sound exposure level (ISO 13474:2009, clauses 4 and 5).

A blast, a shot or a detonation a few kilometres away is heard at a level that changes from one event to the next by ten decibels and more, because the weather between source and receiver changes. ISO 13474 does not predict one level; it describes the weather as a set of replica atmospheres, each one a combination of an atmospheric-absorption class k and an excess-attenuation class l with its probability of occurrence, computes the frequency-weighted single-event sound exposure level L_E,w,k,l for each, and turns that list into a statistical distribution. This module is that statistical core. The propagation that produces each L_E,w,k,l (clause 6), the classification of the weather (clause 7) and the probability of each class from meteorological data (clause 8) are the caller’s input.

The chain, in the order the standard writes it:

  • the frequency-weighted level of each replica from its band levels, Equation (5), frequency_weighted_sel;

  • the joint probability of the two classes, Equation (14), replica_probabilities;

  • the long-term average of the single-event level, Equation (7), and the rating level that adds the adjustment K for highly impulsive sound, Equation (8), long_term_sel;

  • the levels placed in increasing order as M classes with contiguous boundaries half-way between consecutive levels and the density of each class, Equations (10) to (16);

  • each class split into N_sub subclasses, Equations (17) to (20), and each subclass replaced by a normal distribution of standard deviation (5 dB is the value the standard says is typically used) whose mean is shifted down by

    so that the energetic mean of the subclass stays where it was, Equations (21) to (23), turbulence_level_shift;

  • from the continuous density , the probability that the level exceeds x, Equation (24), and the n-percent exceedance level, Equation (25), and the long-term level computed a second time from the distribution, Equation (A.4) of Annex A.

sel_distribution does the last three steps and returns a SelDistribution, whose .plot() draws the class density, the continuous density or the exceedance curve.

Two readings the text leaves to the implementer

Section titled “Two readings the text leaves to the implementer”

Equal levels. Equation (11) puts a boundary half-way between consecutive levels, so two equal levels share a boundary at that level and each keeps a class of non-zero width on its own side; Annex A does exactly that with its two classes at 30,8 dB and its two at 31,8 dB, and so does this module. The standard names one case, three consecutive equal levels, whose middle class then has no width and no defined density, and for it says “classes with the same level shall be combined”. A run of two equal levels at either end of the list leaves a class of no width in the same way, through Equation (12) or (13); the standard does not mention it, and this module reads it as the same case. Every run of equal levels that would leave a class of no width is therefore combined into one class carrying the sum of their probabilities; every other run is left as the standard writes it.

The integrals. Equations (22), (24) and (A.4) are integrals of Gaussian functions and are evaluated here in closed form, not by quadrature: the shift is , the exceedance is a sum of Gaussian tail probabilities, and is a sum of lognormal means. There is no integration range to choose and no truncation to account for.

Auto-generated from the source docstrings by scripts/generate_api_docs.py (make api-docs). Do not edit by hand.

frequency_weighted_sel(
band_levels_db: ArrayLike,
weighting_db: ArrayLike,
) -> float | NDArray[np.float64]

Frequency-weighted sound exposure level from band levels (Equation (5)).

The standard prefers one-third-octave bands and requires every band from 1 Hz (index 0) to 10 kHz (index 40) whose weighted level is within 20 dB of the largest weighted band level. Which bands those are depends on the spectrum, so the function sums every band it is given: passing the whole range from 1 Hz to 10 kHz always meets the requirement.

Parameters

NameDescription
band_levels_dbBand sound exposure levels , in dB, along the last axis. Leading axes are kept, so an array of shape (N_atm, N_exc, n_bands) of the replica atmospheres returns their (N_atm, N_exc) weighted levels at once.
weighting_dbThe frequency weighting of each band, in dB (A-weighting, C-weighting or any other), broadcast against band_levels_db.

Returns: in dB, a float for a single spectrum.

Raises

ExceptionWhen
ValueErrorfor an empty or non-finite input, or shapes that do not broadcast.
long_term_sel(
levels_db: ArrayLike,
probabilities: ArrayLike,
*,
rating_adjustment_db: float = 0.0,
) -> float

Long-term average single-event sound exposure level (Equations (7), (8)).

With the rating level adjustment K for highly impulsive sound of ISO 1996-1 inside the sum, the same expression is the long-term average single-event sound exposure rating level of Equation (8), the quantity the standard offers to ISO 1996-1 as the frequency-weighted and adjusted single-event level. K is one constant for the source, so Equation (8) is Equation (7) plus K.

Annex A calls this value LT1 and computes it with a single atmospheric-absorption class of probability 1.

Parameters

NameDescription
levels_db of each replica atmosphere, in dB, any shape ((N_atm, N_exc) or already flattened).
probabilitiesThe probability of each replica, the same shape as levels_db (see replica_probabilities).
rating_adjustment_dbK, in dB; 0 dB (the default) gives Equation (7).

Returns: The long-term average level, in dB.

Raises

ExceptionWhen
ValueErrorif the shapes differ, a probability is negative, the probabilities do not sum to one, every probability is zero, or a value is not finite.
replica_probabilities(
absorption_probabilities: ArrayLike,
excess_attenuation_probabilities: ArrayLike,
) -> NDArray[np.float64]

Probability of occurrence of each replica atmosphere (Equation (14)).

The two classifications are taken as independent (clause 4.5, NOTE 1 to Equation (6)), so the probability of the replica (k, l) is the product of the probability of its atmospheric-absorption class and that of its excess-attenuation class.

Parameters

NameDescription
absorption_probabilities, one per atmospheric-absorption class. Annex A uses a single class of probability 1.
excess_attenuation_probabilities, one per excess-attenuation class.

Returns: An array of shape (N_atm, N_exc), row k and column l, the shape sel_distribution and long_term_sel read levels_db in.

Raises

ExceptionWhen
ValueErrorfor an empty, multi-dimensional, non-finite or negative input.
sel_distribution(
levels_db: ArrayLike,
probabilities: ArrayLike,
*,
sigma_db: float = 5.0,
subclasses: int = 10,
) -> SelDistribution

Statistical distribution of the single-event sound exposure level (ISO 13474:2009, clause 5).

The levels of the replica atmospheres are placed in increasing order (Equation (10)); boundaries between consecutive classes lie half-way between their levels (Equation (11)) and the two outer boundaries mirror the nearest inner one about the end level (Equations (12), (13)); each class has the constant density (Equation (15)). Each class is then divided into subclasses equal subclasses of width centred at (Equations (17), (18)), and each subclass is replaced by a normal distribution of standard deviation sigma_db and weight , centred at (Equations (21) to (23)).

Equal levels keep their own classes unless that leaves a class of no width, in which case the run is combined (see the module documentation).

Parameters

NameDescription
levels_db of each replica atmosphere, in dB, any shape; a (N_atm, N_exc) array is read row by row.
probabilitiesThe probability of occurrence of each replica, the same shape as levels_db, summing to one (see replica_probabilities).
sigma_dbStandard deviation of the spread due to turbulence, in dB; 5 dB by default, the value clause 5 says is typically used.
subclasses, the subclasses per class; 10 by default, the number Annex A uses. The standard fixes none.

Returns: The distribution.

Raises

ExceptionWhen
ValueErrorif the shapes differ, a value is not finite, a probability is negative, the probabilities do not sum to one, every probability is zero, fewer than two distinct levels remain once equal levels are combined, sigma_db is not positive, or subclasses is not a whole number of at least one.
SelDistribution(
levels_db: NDArray[np.float64],
probabilities: NDArray[np.float64],
lower_bounds_db: NDArray[np.float64],
upper_bounds_db: NDArray[np.float64],
class_densities_per_db: NDArray[np.float64],
subclass_centres_db: NDArray[np.float64],
sigma_db: float,
level_shift_db: float,
subclasses: int,
long_term_level_db: float,
distribution_long_term_level_db: float,
replicas: tuple[tuple[int, ...], ...],
)

The statistical distribution of a single-event sound exposure level (ISO 13474:2009, clause 5).

The replica atmospheres, sorted by level, are the M classes of Equations (10) to (16); each class is split into subclasses equal subclasses (Equations (17) to (20)) and each subclass is replaced by a normal distribution of standard deviation sigma_db centred level_shift_db below the subclass centre (Equations (21) to (23)).

Attributes

NameDescription
levels_db of the M classes, in increasing order, in dB.
probabilities of each class (Equation (14)).
lower_bounds_db, in dB (Equations (11), (12)).
upper_bounds_db, in dB (Equations (11), (13)).
class_densities_per_db, the constant density of each class, in 1/dB (Equation (15)).
subclass_centres_db, shape (M, subclasses), in dB (Equation (18)).
sigma_db of the turbulent spread, in dB.
level_shift_db, in dB (Equation (22)).
subclasses, the subclasses per class.
long_term_level_db from the classes, Equation (7); Annex A’s LT1.
distribution_long_term_level_dbthe same average taken over the continuous distribution, Equation (A.4); Annex A’s LT2. It differs from long_term_level_db only by the spreading of each class over its width, since preserves the energy of each subclass.
replicasFor each class, the flat indices of the replica atmospheres it holds, in the row-major order the input was given in; a class holds more than one only where equal levels were combined.
SelDistribution.class_density(
x_db: ArrayLike,
) -> float | NDArray[np.float64]

The class density before the turbulent spread (Equations (15), (16)), in 1/dB.

A step function, constant inside each class and zero outside the classes; at a boundary itself, where Equation (15) defines neither neighbour, it is zero.

Parameters

NameDescription
x_dbLevel or levels x, in dB.

Returns: , a float for a scalar x.

SelDistribution.density(x_db: ArrayLike) -> float | NDArray[np.float64]

The continuous density (Equations (21), (23)), in 1/dB.

Parameters

NameDescription
x_dbLevel or levels x, in dB.

Returns: , a float for a scalar x.

SelDistribution.exceedance(x_db: ArrayLike) -> float | NDArray[np.float64]

Probability that the level exceeds x (Equation (24)).

evaluated exactly as a sum of Gaussian upper-tail probabilities. It tends to the sum of the probabilities of the classes, one, as x falls.

Parameters

NameDescription
x_dbLevel or levels x, in dB.

Returns: The probability, a float for a scalar x.

SelDistribution.exceedance_level(
percent: ArrayLike,
) -> float | NDArray[np.float64]

The n-percent exceedance level (Equation (25)).

The level exceeded with probability n / 100: the root of , found to 10⁻¹⁰ dB. exceedance_level(95) is the level exceeded by 95 % of the events, the lowest of the usual set; exceedance_level(1) the highest.

Parameters

NameDescription
percentn, in per cent, strictly between 0 and 100 times the total probability of the classes.

Returns: The level, in dB, a float for a scalar percent.

Raises

ExceptionWhen
ValueErrorfor a percentage outside that range.
SelDistribution.plot(
ax: Axes | None = None,
*,
view: str = 'density',
language: str = 'en',
**kwargs: Any,
) -> Axes

Plot the distribution, as its class density, density or exceedance.

Parameters

NameDescription
axExisting axes to draw on, or None to create a figure.
view"density" (default) draws the continuous density with the long-term level of Equation (A.4) marked, the curve of Annex A Figure A.2; "classes" draws the step density of the classes before the turbulent spread, Figure A.1; "exceedance" draws with the 95, 50, 10, 5 and 1 per cent exceedance levels marked, Figure A.3.
languageLabel language, "en" (default) or "es".
kwargsForwarded to the primary artist.

Returns: The axes. Requires matplotlib (pip install phonometry[plot]).

Raises

ExceptionWhen
ValueErrorIf view is not one of the three names above.
turbulence_level_shift(sigma_db: float) -> float

Shift of the mean of each Gaussian subclass, (Equation (22)).

The shift that keeps the energetically averaged level of a subclass at its centre once the subclass is spread by a normal distribution of standard deviation . The integral of Equation (22) is the mean of a lognormal variable and has the closed form

2,878 dB for the 5 dB the standard says is typically used.

Parameters

NameDescription
sigma_dbThe standard deviation of the turbulent spread, in dB.

Returns: , in dB.

Raises

ExceptionWhen
ValueErrorfor a non-positive or non-finite sigma_db.