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.wind_turbine_modulation

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.

Amplitude modulation of wind turbine sound at a receptor (IEC TS 61400-11-2:2024, clause 13).

A turbine’s level rises and falls once per blade passage, the “swish” or “thump” a neighbour describes. Clause 13 of IEC TS 61400-11-2:2024 rates it with the reference method of the UK Institute of Acoustics Amplitude Modulation Working Group (the AMWG Final Report, 2016), which the TS implements (13.2) with more specific outputs and the worst case band in each bin. The input is a series of A-weighted 100 ms Leq values summed over seven one-third-octave bands (13.6.2.1.1): amplitude_modulation_band_levels forms it from logged band levels.

The 10 s block (13.6.2.3), amplitude_modulation_block. The 100 values are de-trended with a cubic least-squares fit, transformed with a rectangular-window DFT of 0.1 Hz resolution and turned into the power spectrum

The highest local maximum inside the user’s range of fundamental modulation frequencies is the fundamental. Its prominence is the line itself over the linear mean of the two lines beyond each adjacent line,

and a block with no local maximum in the range, or with , is “prominence-failed”. The second and third harmonics join if a local maximum sits at (or within one or two lines of) twice and three times the fundamental and both the fundamental alone and the harmonic alone swing more than 1.5 dB peak to peak. Three lines about each kept component, with their negative-frequency mirrors, are transformed back, and the modulation depth is the 95th percentile of the reconstructed series minus its 5th percentile (L5 - L95).

The 10 min period (13.6.3), amplitude_modulation_period: the AM rating is the 90th percentile of the valid 10 s depths when at least 30 of the 60 blocks are valid, and 0 dB otherwise, with the mean and the mode of the valid fundamental frequencies.

The bins (13.6.4), bin_amplitude_modulation: the 10 min ratings of each band are averaged per 1 m/s wind speed bin and 30 degree sector, the zeros included, and each bin reports the band with the highest mean.

Where the TS and the AMWG Final Report part ways, the TS is implemented: a period with fewer than 30 valid blocks is kept at 0 dB and counted in its bin (TS 13.6.3, 13.6.4), where the AMWG discards it (Figure 4.2.2); and the band is chosen per bin (TS 13.6.4), where the AMWG chooses one band for the whole survey by regressing the three bands’ ratings against each other (Figure 4.2.1, 4.3.2). 13.6.4 also leaves out of the bin mean “any excluded periods due to pf or other exclusions”; read literally, that would drop the very periods 13.6.3 rates 0 dB (their blocks failed the prominence test), and the “including 0 values” of the same sentence, with the count of non-zero values 13.6.4 asks for, would mean nothing. It is read as the periods the practitioner excludes, the excluded flags of bin_amplitude_modulation. The TS says both “at least 50 %” (13.6.2.2) and “greater than 50 % (30 valid 10 s blocks)” (13.6.3) of a period’s blocks; a period of exactly 30 valid blocks is rated, as 13.6.2.2 and the AMWG (4.4.4, “at least 50 % (i.e. 30)”) both say.

Two steps the TS leaves open are read as the IOA’s published reference code reads them: the percentiles interpolate linearly between the order statistics, and the spectrum runs from 0.1 Hz to 4.9 Hz, without the zero frequency the de-trending has emptied and without the Nyquist line, whose three-line window would have no mirror of its own.

A spectral line within rounding of zero is read as zero: a line no larger than the square of of the block’s largest absolute level. Once de-trended, a steady block, or one that follows a cubic, holds nothing else, so it has no local maximum and is prominence-failed, the block of 13.6.2.3 d) in which “there is no significant AM” (the AMWG Final Report, 4.5.2 step 4: “either no AM, or the block is corrupted”). Read as they come out of the fit, its rounding lines would decide its status by their last bits.

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

Constant (int).

AM_BLOCK_SAMPLES = 100

Constant (tuple).

AM_EXCEEDANCE_THRESHOLDS_DB = (3.0, 6.0, 9.0)

Constant (mapping).

AM_FREQUENCY_BANDS_HZ = {1: (50.0, 63.0, 80.0, 100.0, 125.0, 160.0, 200.0), 2: (100.0, 125.0, 160.0, 200.0, 250.0, 315.0, 400.0), 3: (200.0, 250.0, 315.0, 400.0, 500.0, 630.0, 800.0), 4: (400.0, 500.0, 630.0, 800.0, 1000.0, 1250.0, 1600.0), 5: (800.0, 1000.0, 1250.0, 1600.0, 2000.0, 2500.0, 3150.0), 6: (1600.0, 2000.0, 2500.0, 3150.0, 4000.0, 5000.0, 6300.0)}

Constant (int).

AM_MINIMUM_VALID_BLOCKS = 30

Constant (tuple).

AM_MODULATION_FREQUENCY_LIMITS_HZ = (0.3, 1.6)

Constant (int).

AM_PERIOD_BLOCKS = 60

Constant (float).

AM_PROMINENCE_THRESHOLD = 4.0

Constant (float).

AM_SAMPLE_INTERVAL_S = 0.1
amplitude_modulation_band_levels(
band_levels_db: ArrayLike,
frequencies_hz: ArrayLike,
*,
band: int,
weighting: Literal['A', 'Z'],
) -> NDArray[np.float64]

Band-limited A-weighted 100 ms levels of one AM band (13.6.2.1.1).

The 100 ms one-third-octave band Leq values of the seven bands of band are A-weighted, if they were logged unweighted, and summed logarithmically sample by sample into the LAeq,100ms (BP) series the 10 s analysis takes. The A-weighting is the IEC 61672-1:2013 Table 3 value at each nominal centre frequency.

Parameters

NameDescription
band_levels_dbThe logged band levels, in dB: one row per 100 ms sample and one column per one-third-octave band (a single sample may be given as one row).
frequencies_hzNominal centre frequency of each column, in Hz; it must include the seven centres of band.
bandThe AM band number, 1 to 3 (13.6.2.1.1) or 4 to 6 (Annex G.3), as an integer; see AM_FREQUENCY_BANDS_HZ.
weighting"A" when the band levels are already A-weighted, "Z" when the A-weighting is still to be applied. Required: a wrong guess is a 20 dB to 30 dB error at the lowest bands.

Returns: The band-limited LAeq,100ms series, in dB, one value per sample.

Raises

ExceptionWhen
ValueErrorIf the band is not one of the band numbers (1.5 and True are not), a band centre is missing or duplicated, the weighting is neither "A" nor "Z", or the levels are not finite.
amplitude_modulation_block(
levels_db: ArrayLike,
*,
modulation_frequency_range_hz: Sequence[float],
) -> ModulationBlock

Analyse one 10 s block of 100 ms levels (IEC TS 61400-11-2, 13.6.2.3).

Steps a) to f) of 13.6.2.3 and the reconstruction after them: cubic de-trending, a rectangular-window DFT of 0.1 Hz resolution, the power spectrum of Equation (12), the fundamental as the highest local maximum within modulation_frequency_range_hz, its prominence (Equation (13)) against the threshold of 4, the second and third harmonics under the two 1.5 dB conditions, and the modulation depth L5 - L95 of the series transformed back from three lines about each kept component.

The local maxima, the fundamental, the harmonics and the prominence are read with the lines at rounding set to zero: a line no larger than , the largest absolute level of the block. A steady block, or one that follows a cubic, then has no local maximum and is NO_PEAK rather than a verdict drawn from the last bits of its levels, and a peak whose masking lines hold only rounding has an infinite prominence. ModulationBlock.power_spectrum keeps every line as Equation (12) gives it.

Parameters

NameDescription
levels_dbThe 100 band-limited A-weighted Leq,100ms values of the block, in dB (see amplitude_modulation_band_levels).
modulation_frequency_range_hz(low, high) range, in Hz, where the fundamental modulation frequency is expected: the blade passage frequencies of the turbines with some tolerance (13.6.2.1.2), within 0.3 Hz to 1.6 Hz (13.2).

Returns: A ModulationBlock.

Raises

ExceptionWhen
ValueErrorIf the block does not hold 100 finite values or the range is outside 0.3 Hz to 1.6 Hz or holds no spectrum line.
amplitude_modulation_period(
levels_db: ArrayLike,
*,
modulation_frequency_range_hz: Sequence[float],
excluded_blocks: ArrayLike | None = None,
) -> ModulationPeriod

Rate one 10 min period of 100 ms levels (IEC TS 61400-11-2, 13.6.3).

The 6 000 values are cut into sixty consecutive 10 s blocks, each analysed by amplitude_modulation_block. With at least 30 valid blocks the rating is the 90th percentile of their depths and the mean and mode of their fundamentals are reported; otherwise the rating is 0 dB and no modulation frequency is given. That 0 dB period is kept, and counted in its bin by bin_amplitude_modulation, as the TS says (13.6.3, 13.6.4); the AMWG Final Report discards it instead.

Parameters

NameDescription
levels_dbThe 6 000 band-limited LAeq,100ms values of the period, in dB, synchronised to the hour (13.6.3).
modulation_frequency_range_hz(low, high) range of the fundamental, in Hz, as for amplitude_modulation_block.
excluded_blocksOptional sixty flags, True for a block the practitioner excludes by hand (13.6.2.2); those blocks are not analysed and do not count as valid. The TS notes that standard practice excludes whole 10 min periods, so excluding single blocks is an adaptation to be justified.

Returns: A ModulationPeriod.

Raises

ExceptionWhen
ValueErrorIf the period does not hold 6 000 finite values or the exclusion flags are not sixty booleans (or 0 and 1).
bin_amplitude_modulation(
ratings_db: ArrayLike,
wind_speeds_m_s: ArrayLike,
wind_directions_deg: ArrayLike | None = None,
*,
bands: Iterable[int] = (1, 2, 3),
excluded: ArrayLike | None = None,
sector_width_deg: float = 30.0,
) -> BinnedModulation

Bin 10 min AM ratings and pick the worst band per bin (13.6.4).

Each 10 min period is a data point of its rating in each band, aligned with the period’s wind speed and direction. Wind speed bins are 1 m/s wide and centred on the integers (0.5 m/s to 1.5 m/s is bin 1); direction sectors are sector_width_deg wide and the first is centred on north (345 degrees to 15 degrees for 30 degree sectors). The mean rating of each bin includes the 0 dB of unrated periods; excluded periods are left out altogether. Each bin reports the band with the highest mean.

Parameters

NameDescription
ratings_dbThe 10 min ratings, in dB, one row per period and one column per band of bands (see ModulationPeriod.rating_db).
wind_speeds_m_sThe reference wind speed of each period, in m/s.
wind_directions_degThe wind direction of each period, in degrees from north, or None to bin by wind speed alone.
bandsThe AM band numbers of the columns, as integers.
excludedOptional flags, True for a period the practitioner excluded; 13.6.4 leaves excluded periods out of the bin mean, whatever the reason. A period rated 0 dB for having fewer than 30 valid blocks is not excluded: it counts, at 0 dB, since 13.6.4 averages “including 0 values” and 13.6.3 assigns that 0 to such a period (the “excluded periods due to pf” of 13.6.4 are read as periods excluded by hand).
sector_width_degWidth of the direction sectors, in degrees; it must divide 360. Wider sectors (downwind, crosswind) are reached by rotating the directions so that the sector of interest is centred on zero.

Returns: A BinnedModulation.

Raises

ExceptionWhen
ValueErrorIf the shapes disagree, a value is not finite, a wind speed is negative, a band is not a band number or is repeated, the exclusion flags are not booleans (or 0 and 1), or the sector width does not divide 360 degrees.
BinnedModulation(
bands: tuple[int, ...],
wind_speeds_m_s: NDArray[np.float64],
wind_directions_deg: NDArray[np.float64] | None,
counts: NDArray[np.int64],
nonzero_counts: NDArray[np.int64],
mean_ratings_db: NDArray[np.float64],
type_a_uncertainty_db: NDArray[np.float64],
exceedance_percent: NDArray[np.float64],
*,
selected_bands: NDArray[np.int64],
selected_ratings_db: NDArray[np.float64],
)

AM ratings binned by wind speed and direction (IEC TS 61400-11-2, 13.6.4).

One row per occupied bin, sorted by wind direction sector then wind speed; one column per band in bands.

Attributes

NameDescription
bandsThe AM bands analysed, in the column order of the arrays.
wind_speeds_m_sCentre of each bin’s 1 m/s wind speed class.
wind_directions_degCentre of each bin’s direction sector, or None when the ratings were binned by wind speed alone.
countsNumber of 10 min data points in each bin.
nonzero_countsNumber of those with a non-zero rating, per band.
mean_ratings_dbMean 10 min rating per bin and band, the zeros of unrated periods included (13.6.4), in dB.
type_a_uncertainty_dbStandard deviation of that mean, Equation (9) of 10.3.3 (13.6.5); NaN for a bin of one data point.
exceedance_percentPercentage of the bin’s data points rated above 3 dB, 6 dB and 9 dB (AM_EXCEEDANCE_THRESHOLDS_DB), shape (bins, bands, 3).
selected_bandsThe band with the highest mean rating in each bin, the lowest-numbered of equally high ones.
selected_ratings_dbThe mean rating of that band, in dB.
BinnedModulation.plot(
ax: Axes | None = None,
*,
language: str = 'en',
**kwargs: Any,
) -> Axes

Plot the worst-band mean rating of each bin against wind speed.

One line per direction sector, in its own colour (or one line when binned by wind speed alone), each point labelled with the band that bin selected. The twelve 30° sectors of 13.7 take twelve colours; narrower sectors past the twelfth take them again, in the same order.

Parameters

NameDescription
axExisting axes, or None to create a figure.
language"en" (default) or "es".
kwargsForwarded to the lines.

Returns: The axes.

ModulationBlock(
levels_db: NDArray[np.float64],
detrended_db: NDArray[np.float64],
frequencies_hz: NDArray[np.float64],
power_spectrum: NDArray[np.float64],
modulation_frequency_range_hz: tuple[float, float],
*,
fundamental_frequency_hz: float | None,
prominence: float | None,
harmonic_frequencies_hz: tuple[float, ...],
reconstructed_db: NDArray[np.float64],
modulation_depth_db: float | None,
excluded: bool = False,
)

The analysis of one 10 s block (IEC TS 61400-11-2:2024, 13.6.2.3).

Attributes

NameDescription
levels_dbThe 100 band-limited LAeq,100ms values analysed, in dB.
detrended_dblevels_db minus its cubic least-squares fit, in dB.
frequencies_hzThe spectrum lines, 0.1 Hz to 4.9 Hz.
power_spectrum of Equation (12) at those lines, from the positive frequencies (the half magnitude the TS allows).
modulation_frequency_range_hzThe user’s range of fundamental modulation frequencies, in Hz.
fundamental_frequency_hzThe fundamental modulation frequency, the highest local maximum in the range, in Hz; None for NO_PEAK.
prominenceThe prominence ratio of Equation (13); None for NO_PEAK, infinite for a peak whose masking lines hold nothing above rounding.
harmonic_frequencies_hzThe frequencies of the harmonics kept in the reconstruction, second before third; empty when none is.
reconstructed_dbThe reconstructed series, in dB about zero; empty for a prominence-failed block.
modulation_depth_dbL5 - L95 of the reconstructed series, in dB; None unless the block is valid.
excludedWhether the practitioner excluded the block by hand (13.6.2.2, third bullet).

status is read from the prominence, the threshold of 4 of 13.6.2.3 e) and the exclusion, so it is not a field.

property

The spectrum lines transformed back, three about each component.

ModulationBlock.plot(
ax: Axes | None = None,
*,
kind: Literal['spectrum', 'series'] = 'spectrum',
language: str = 'en',
**kwargs: Any,
) -> Axes

Plot the block’s power spectrum (Figure 1) or its two time series.

kind="spectrum" draws with the range of fundamental frequencies, the lines kept in the reconstruction and the prominence, as Figure 1 of the TS does. kind="series" draws the de-trended series with the reconstructed one over it and the L5 and L95 of the reconstruction.

Parameters

NameDescription
axExisting axes, or None to create a figure.
kind"spectrum" (default) or "series".
language"en" (default) or "es".
kwargsForwarded to the primary artist.

Returns: The axes.

property

ModulationBlockStatus of the block (13.6.2.2 and 13.6.2.3).

EXCLUDED when the practitioner excluded it, NO_PEAK without a local maximum in the range, LOW_PROMINENCE for a prominence under AM_PROMINENCE_THRESHOLD, VALID otherwise.

property

Whether the block carries a modulation depth (13.6.2.2).

ModulationBlockStatus(*values)

Why a 10 s block counts or does not (13.6.2.2 and 13.6.2.3).

VALID blocks carry a modulation depth. NO_PEAK and LOW_PROMINENCE are the two prominence-failed (pf) outcomes of 13.6.2.3 d) and e): no local maximum inside the range of fundamental frequencies, or a prominence ratio under 4. A steady block, or one that follows a cubic, is NO_PEAK: once de-trended it holds nothing but rounding, the case in which d) considers “that there is no significant AM”. EXCLUDED is a block the practitioner excluded by hand (13.6.2.2, third bullet).

ModulationPeriod(blocks: tuple[ModulationBlock, ...])

The AM rating of one 10 min period (IEC TS 61400-11-2:2024, 13.6.3).

Everything but the blocks is read from them, against the 30 valid blocks of 13.6.2.2 and the 90th percentile of 13.6.3, so a period cannot be built to rate blocks the TS does not count.

Attributes

NameDescription
blocksThe sixty ModulationBlock analyses, in time order.

ModulationPeriod.fundamental_frequencies_hz

Section titled “ModulationPeriod.fundamental_frequencies_hz”

property

The fundamental of each valid block, in Hz; NaN elsewhere.

ModulationPeriod.mean_modulation_frequency_hz

Section titled “ModulationPeriod.mean_modulation_frequency_hz”

property

Mean fundamental of the valid blocks, in Hz; None when not rated.

ModulationPeriod.mode_modulation_frequency_hz

Section titled “ModulationPeriod.mode_modulation_frequency_hz”

property

Most frequent fundamental of the valid blocks, in Hz.

The lowest of equally frequent ones; None when not rated.

property

The depth of each block, in dB; NaN where the block is not valid.

ModulationPeriod.plot(
ax: Axes | None = None,
*,
language: str = 'en',
**kwargs: Any,
) -> Axes

Plot the 10 s depths through the period and the 10 min rating.

Parameters

NameDescription
axExisting axes, or None to create a figure.
language"en" (default) or "es".
kwargsForwarded to the 10 s depths.

Returns: The axes.

property

Whether at least 30 blocks are valid (13.6.2.2).

property

The AM rating of the period, in dB.

The 90th percentile of the valid depths when rated, else 0 dB (13.6.3).

property

Number of valid blocks, the n number of 13.6.2.2.