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.propagation.barrier_in_situ

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.

What a barrier by the road is worth, measured (ISO 10847:1997).

phonometry.environment.propagation.ground_barriers predicts what a barrier will do from its geometry. This is the measurement, and its scope paragraph is worth reading before the equations:

It does not make it possible to compare insertion loss values of an
equivalent barrier on a different site.

An insertion loss measured here belongs to that barrier, on that site, under those meteorological conditions. What it may be used for is comparing different barriers on the same site by the direct method, and what it is not for is a product specification. The intrinsic quantities, the sound reduction index and the absorption coefficient, are outside the scope altogether.

The quantity is the level at a receiver position before the barrier existed less the level after, with everything else unchanged. Nothing else is unchanged, of course, so the standard puts a second microphone at a reference position where the barrier does not reach, and normalises by what it heard:

That is the direct method, 8.2.1, and it needs a barrier that has not been built yet or can be taken down. Where it cannot, the indirect method of 8.2.2 measures the “before” pair at a substitute site judged equivalent, and adds a correction for the kind of receiver position: 0 dB in a hemi free field, 6 dB against a facade, which is the pressure doubling at a large hard surface.

The algebra of the two is the same whenever the receiver is of the same kind in both campaigns, which is what the NOTE to 8.2.2 recommends, and measured_insertion_loss_indirect reduces to measured_insertion_loss_direct exactly there.

What the standard will not let you correct

Section titled “What the standard will not let you correct”

Three times over. 6.3.2: “no attempt shall be made to adjust measured sound pressure levels based on the temperature data”. 6.3.3: the same for humidity. The remedy for both is equivalence rather than arithmetic, and the clauses say what equivalence means: the same wind class and vector components within 2 m/s, average temperatures within 10 °C, the same cloud cover class, and no measurement at all above 5 m/s of wind.

The background is the one correction it does allow, from a stepped table of two rows, and the table is not the one ISO 11820 prints and not the formula ISO 11821 prints. Three standards on the same subject, three different rules; they are three separate implementations here and share nothing.

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

barrier_background_correction_db(
level_difference_db: ArrayLike,
) -> NDArray[np.float64]

The background correction of Table 3, in decibels to add.

The table has two rows and no formula: 2 dB comes off at a margin of 4 or 5 dB, 1 dB at 6, 7, 8 or 9, and nothing at 10 or more, which is the margin 6.4 asks for in the first place. Under 4 dB “the measurement results are not valid”, and that is a refusal.

The sign is the trap. This column reads “correction to be made to the measured sound pressure level”, so its values are printed negative and are added; Table 1 of ISO 11820 reads “correction to be subtracted” and prints the same physical thing positive. The two tables also disagree numerically at a margin of 9 dB, where ISO 11820 takes off 0,5 dB and this one takes off 1. They are two tables and they stay two tables.

Parameters

NameDescription
level_difference_dbThe difference between the level measured with the source and the level without it, in decibels.

Returns: The correction to add, in decibels, which is zero or negative.

Raises

ExceptionWhen
ValueErrorFor a margin under ISO10847_MINIMUM_BACKGROUND_MARGIN_DB, which 6.4 calls invalid.

The measurement is outside a condition ISO 10847 states.

Constant (float).

CLOSE_SOURCE_DISTANCE_M = 15.0

Constant (mapping).

CLOUD_COVER_CLASSES = {1: 'heavily overcast day or night, 80 % cloud cover or more for 100 % of the measurement time', 2: 'moderately overcast day or night, 50 % to 80 % cloud cover for at least 80 % of the measurement time', 3: 'lightly overcast or sunny day or night, either continuous sun or less than 50 % cloud cover for at least 80 % of the measurement time', 4: 'clear night'}

Constant (float).

EQUIVALENT_SECTOR_DEG = 60.0

Constant (float).

EQUIVALENT_SURROUNDINGS_RADIUS_M = 30.0

Constant (float).

HEMI_FREE_FIELD_DISTANCE_FACTOR = 2.0

Constant (float).

HEMI_FREE_FIELD_DISTANCE_M = 30.0
hemi_free_field_distance_m(barrier_to_receiver_m: float) -> float

How far a receiver stands from a reflecting surface, 8.1.2 a).

with the distance from the barrier to the receiver: the clause says 30 m “or twice the barrier-receiver distance, whichever is shorter”, so a receiver close behind the barrier needs less clearance rather than more. The two rules cross at 15 m.

Parameters

NameDescription
barrier_to_receiver_m, in metres.

Returns: The least distance to any vertical reflecting surface, in metres.

Raises

ExceptionWhen
ValueErrorFor a non-positive distance.
is_short_distance(
*,
source_height_m: float,
receiver_height_m: float,
barrier_height_m: float,
source_to_barrier_m: float,
barrier_to_receiver_m: float,
) -> tuple[bool, bool]

Whether the geometry counts as a short distance, 6.3.1.

The clause prints one condition for the “before” campaign and two for the “after” one, all against the same ratio of 0,1:

The “after” pair must both hold. What hangs on the answer is Table 1: the upwind class exists only over short distances, so a long-distance measurement may be made downwind or calm and not into the wind at all.

The inequalities are strict, so a ratio of exactly 0,1 is not a short distance.

Parameters

NameDescription
source_height_m, in metres.
receiver_height_m, in metres.
barrier_height_m, in metres.
source_to_barrier_m, in metres.
barrier_to_receiver_m, in metres.

Returns: Whether the “before” and the “after” geometry each count as a short distance.

Raises

ExceptionWhen
ValueErrorFor a non-positive height or distance.

Constant (mapping).

ISO10847_BACKGROUND_CORRECTIONS_DB = {4: -2.0, 5: -2.0, 6: -1.0, 7: -1.0, 8: -1.0, 9: -1.0}

Constant (float).

ISO10847_MINIMUM_BACKGROUND_MARGIN_DB = 4.0

Constant (tuple).

ISO10847_OCTAVE_BAND_EXTENDED_RANGE_HZ = (63.0, 8000.0)

Constant (tuple).

ISO10847_OCTAVE_BAND_RANGE_HZ = (63.0, 4000.0)

Constant (float).

ISO10847_PREFERRED_BACKGROUND_MARGIN_DB = 10.0

ISO10847_THIRD_OCTAVE_BAND_EXTENDED_RANGE_HZ

Section titled “ISO10847_THIRD_OCTAVE_BAND_EXTENDED_RANGE_HZ”

Constant (tuple).

ISO10847_THIRD_OCTAVE_BAND_EXTENDED_RANGE_HZ = (50.0, 10000.0)

Constant (tuple).

ISO10847_THIRD_OCTAVE_BAND_RANGE_HZ = (50.0, 5000.0)

Constant (float).

LINE_SOURCE_DIVERGENCE_DB = 3.0

Constant (float).

LONG_DISTANCE_M = 250.0

Constant (float).

MAXIMUM_WIND_SPEED_M_S = 5.0
measured_insertion_loss_direct(
reference_before_db: ArrayLike,
reference_after_db: ArrayLike,
receiver_before_db: ArrayLike,
receiver_after_db: ArrayLike,
*,
frequencies: ArrayLike | None = None,
) -> MeasuredBarrierInsertionLoss

The insertion loss by the direct method, 8.2.1.

The reference term is the source normalisation: whatever the source did differently between the two campaigns, the reference microphone heard it too, and subtracting it leaves the barrier. A uniform change of source output therefore leaves the answer alone, which is the property the whole arrangement exists for.

The method holds only where the barrier had not been built yet or could be taken down, and 4.1 adds the condition that makes the subtraction mean anything: the same reference and receiver positions in both campaigns.

Parameters

NameDescription
reference_before_db per band, in decibels.
reference_after_db per band, in decibels.
receiver_before_db per band, in decibels.
receiver_after_db per band, in decibels.
frequenciesNominal band centres, in hertz.

Returns: The insertion loss, as a MeasuredBarrierInsertionLoss.

Raises

ExceptionWhen
ValueErrorFor levels that do not match band for band, or a band centre that is not strictly positive.
measured_insertion_loss_indirect(
reference_before_db: ArrayLike,
reference_after_db: ArrayLike,
receiver_before_db: ArrayLike,
receiver_after_db: ArrayLike,
*,
frequencies: ArrayLike | None = None,
receiver_type_before: ReceiverType = 'hemi_free_field',
receiver_type_after: ReceiverType = 'hemi_free_field',
) -> MeasuredBarrierInsertionLoss

The insertion loss by the indirect method, 8.2.2.

The “before” pair comes from a substitute site judged equivalent in terrain, ground and source, which is what makes this an estimate rather than a determination: 8.2.2 says so itself.

and correct for the kind of receiver position: 0 dB in a hemi free field, 6 dB for a microphone against a facade, where the pressure doubles. The clause attaches the unprimed symbol to the “before” equation and the primed one to the “after”, and then defines the two by receiver type rather than by campaign, which taken literally would force one type on each campaign. The NOTE settles it, by preferring receiver positions “where corrections and are essentially the same”, so the type is asked for once per campaign here (see the errata).

Where the two types agree, the correction cancels and this returns exactly what measured_insertion_loss_direct returns on the same four levels. Where they differ, the answer moves by 6 dB, which is why the NOTE exists.

Parameters

NameDescription
reference_before_db per band, at the substitute site, in decibels.
reference_after_db per band, in decibels.
receiver_before_db per band, at the substitute site, in decibels.
receiver_after_db per band, in decibels.
frequenciesNominal band centres, in hertz.
receiver_type_before"hemi_free_field" (default) or "reflecting_surface", for the substitute site.
receiver_type_afterThe same for the barrier site.

Returns: The insertion loss, as a MeasuredBarrierInsertionLoss.

Raises

ExceptionWhen
ValueErrorFor levels that do not match band for band, a band centre that is not strictly positive, or an unknown receiver type.
MeasuredBarrierInsertionLoss(
frequencies: NDArray[np.float64] | None,
reference_before_db: NDArray[np.float64],
reference_after_db: NDArray[np.float64],
receiver_before_db: NDArray[np.float64],
receiver_after_db: NDArray[np.float64],
insertion_loss_db: NDArray[np.float64],
method: str,
receiver_correction_before_db: float,
receiver_correction_after_db: float,
)

The insertion loss of a barrier as measured, ISO 10847 clause 8.2.

Attributes

NameDescription
frequenciesNominal band centres, in hertz, or None where the measurement is an A-weighted level.
reference_before_db per band.
reference_after_db per band.
receiver_before_db per band.
receiver_after_db per band.
insertion_loss_db or per band, in decibels.
method"direct" or "indirect".
receiver_correction_before_db, in decibels, zero for the direct method.
receiver_correction_after_db, in decibels, zero for the direct method.
MeasuredBarrierInsertionLoss.plot(
ax: Axes | None = None,
*,
language: str = 'en',
**kwargs: Any,
) -> Axes

Draw the four levels and the insertion loss they give.

Requires matplotlib (pip install phonometry[plot]).

Parameters

NameDescription
axExisting axes, or None to create a figure.
languageLabel language, "en" (default) or "es".
kwargsForwarded to phonometry._plot.environment.plot_barrier_in_situ.

Returns: The Axes.

MeasuredBarrierInsertionLoss.rounded() -> NDArray[np.int_]

The values as clause 10 c) reports them, to the nearest decibel.

property

The symbol clause 8.2 reports this as, "D_IL" or "D'_IL".

Constant (float).

MINIMUM_RECEIVER_HEIGHT_M = 1.2

Constant (int).

MINIMUM_REPETITIONS = 3

Constant (float).

POINT_SOURCE_DIVERGENCE_DB = 6.0

Constant (mapping).

RECEIVER_CORRECTIONS_DB = {'hemi_free_field': 0.0, 'reflecting_surface': 6.0}

Constant (float).

REFERENCE_ELEVATION_INCREMENT_DEG = 10.0

Constant (float).

REFERENCE_MICROPHONE_CLEARANCE_M = 1.5
reference_microphone_height_m(
barrier_height_m: float,
*,
source_to_barrier_m: float | None = None,
) -> float

How high the reference microphone stands, 7.2.2.

At least REFERENCE_MICROPHONE_CLEARANCE_M above the top edge of the barrier, on a vertical plane through it, so that what it hears is the source and not the barrier. For a barrier whose top is not a straight edge, a berm or a cupped profile, the clearance is measured from its highest point. The clause words the clearance with “shall” (printed folio 9, PDF page 13), and no geometry takes the microphone under it.

The NOTE adds a preference for a source that stands close. Where the near end of the source region is under CLOSE_SOURCE_DISTANCE_M from the barrier, the microphone “may be raised as high as possible” until the elevation angle from that end exceeds the angle to the barrier top by REFERENCE_ELEVATION_INCREMENT_DEG:

The NOTE only ever raises the microphone, so the height is the higher of the two. Which one governs depends on the geometry: a 4 m barrier 10 m from the source takes the angle, 6,20 m against 5,5 m, while a 3 m barrier 5 m from the source takes the clearance, because its 10 degrees are reached at 4,34 m and the clause asks for 4,5 m. The angle form is the NOTE’s own words; the height it implies is derived here rather than printed.

Once the barrier top stands 80 degrees or more above the near end of the source region, no height reaches the increment at all, and the tangent would turn negative. The microphone then keeps the clearance and a BarrierInSituWarning says that the NOTE could not be followed. That is how this module treats a NOTE, as with the one to 8.2.2: a preference it cannot meet is reported, and the clause it hangs from is enforced.

Parameters

NameDescription
barrier_height_m, the barrier height above the ground at the microphone, in metres.
source_to_barrier_m, the distance from the near end of the source region to the barrier, in metres. Omit it for the plain clearance rule.

Returns: The microphone height above the ground, in metres.

Raises

ExceptionWhen
ValueErrorFor a non-positive height or distance.

Constant (float).

SHORT_DISTANCE_RATIO = 0.1

Constant (float).

TEMPERATURE_TOLERANCE_C = 10.0
wind_class(
vector_component_m_s: float,
*,
short_distance: bool = False,
) -> str | None

The wind class of Table 1, from the vector component of the velocity.

The component is the projection of the average wind velocity on the line from the source to the receiver, in metres per second: positive downwind, negative upwind. Over all distances the table has a downwind class and a calm one; over short distances it adds an upwind class, whose interval is printed ”+ 1 to - 5” and read here as -1 to -5 (see the errata).

The calm class carries a footnote of its own over all distances: it counts “only with the case of temperature inversion”.

Above MAXIMUM_WIND_SPEED_M_S in absolute value no measurement is made at all, which is a refusal rather than a class.

Parameters

NameDescription
vector_component_m_sThe vector component, in metres per second.
short_distanceWhether the geometry is a short distance in the sense of is_short_distance.

Returns: The class name, or None where the component falls in no class the table prints, which over long distances is any upwind component.

Raises

ExceptionWhen
ValueErrorFor a component that is not finite, or past MAXIMUM_WIND_SPEED_M_S in absolute value.

Constant (mapping).

WIND_CLASSES = {'all': {'downwind': (1.0, 5.0), 'calm': (-1.0, 1.0)}, 'short': {'downwind': (1.0, 5.0), 'calm': (-1.0, 1.0), 'upwind': (-5.0, -1.0)}}

Constant (float).

WIND_VECTOR_TOLERANCE_M_S = 2.0