Skip to content
This documentation describes version 4.0.0, which is not released yet. The current version on PyPI is 3.3.0 and does not carry everything described here.

environment.sources.acoustic_roughness

The acoustic roughness of a rail, measured directly on it (EN 15610:2009).

Rolling noise is excited by the unevenness of the wheel and rail running surfaces, and the rail’s share of it, its acoustic roughness , is the height of the running surface along the rail (3.1). EN 15610 measures it with a probe that follows a line on the rail head and turns the record into a one-third octave band spectrum of wavelength, which is how a test track is shown to be smooth enough for a vehicle type test (ISO 3095, 6.2.5, whose limit lives in REFERENCE_TRACK_ROUGHNESS_LIMIT_DB).

Clause 7, the processing. A record goes through three stages before its spectrum is taken (7.1): the data of joints, welds and rail defects are edited out by the operator (Annex A shows what is and is not a defect); narrow upward spikes from particles on the rail are removed (7.2, remove_roughness_spikes); and every point is raised to where a wheel of 0,375 m radius would stand on it, because the probe tip is far smaller than a wheel and reaches into pits a wheel rolls over (7.3, curvature_processed_roughness).

The spectrum. Method A of 7.4.2 (acoustic_roughness_spectrum) cuts the record into segments at least 1 m long overlapping by half, removes the mean and the linear trend of each, applies a Hanning window and averages the squared magnitudes of their discrete Fourier transforms into a narrow band spectrum. The one-third octave band value is the energy sum of the narrow band lines, the two lines that straddle a band edge counted only for the portion of their width inside the band (Annex C, redistributed_band_energies). The level is

(3.3, Formula 1). A record of a given length only resolves wavelengths up to a quarter of it (7.5), so a 1 m segment reports down to the 0,25 m band.

Method B of 7.4.3 (filtered_roughness_spectrum) runs digital one-third octave filters along the record itself and takes the mean square of each band’s output, once 2 m at either end have been discarded for the filter transients; a record therefore needs at least 5 m (NOTE 1), and the records of a line at least 15 m once those ends are gone. The filters “shall comply with EN 61260”, the 1995 edition the normative references date. The bank is the library’s own (roughness_filter_bank, an OctaveFilterBank running at so many samples per metre): base-ten bands, the same ones Method A reports, of order 4 Butterworth sections, every band run at the record’s own sampling rate, class 0 of EN 61260:1995 on its Table 1 (verify_filter_class with edition="1995", up to the Nyquist wavenumber of the record), on the filter integrated response of 4.5.3 and on the summation of outputs of 4.9.

7.6, the average. The spectra of the records of one line are averaged on their mean squares, without weighting by where along the test section they were taken (average_roughness_spectra), and 6.4.3 sets how many lines a rail needs by the width of its reference surface (roughness_measurement_lines). Clause 8 compares every average with the limit and allows no band above it; that verdict, with the flexibility of ISO 3095 Annex C, is check_reference_track.

Readings of the library. The spike height of 7.2 is not defined by the clause; it is read here, as the Annex B listing computes it, as the height of the peak above the straight line the spike is replaced by. The filters of Method B ring for a distance that grows with the wavelength of their band, and 7.4.3 allows them 2 m to settle whatever the band: a band is reported only when, over the length analysed, its filter has built up to within 0,15 dB of its steady output, the class 0 tolerance of EN 61260:1995 4.5.3 on the integrated response. That is the reason for order 4, the lowest whose bank is class 0: it settles soonest. The bank is not decimated band by band, as the library’s banks are by default: run at the record’s own rate, a band has no alias at all for 4.8 to bound, and what its response is graded on up to the Nyquist wavenumber is exactly what a record goes through. The filters of the Annex B listing do not comply with EN 61260 (see the errata register).

Read from BS EN 15610:2009, which is identical to EN 15610:2009 (its national foreword).

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

acoustic_roughness_spectrum(
roughness_um: ArrayLike,
*,
sample_spacing_m: float,
spike_removal: bool = True,
curvature_processing: bool = True,
segment_length_m: float = 1.0,
) -> AcousticRoughnessSpectrum

The one-third octave band acoustic roughness of a record (7.2 to 7.4, Method A).

The record is processed as 7.1 asks, spikes first (remove_roughness_spikes) and curvature next (curvature_processed_roughness), then cut into segments of segment_length_m overlapping by half. Each has its mean and linear trend removed and a Hanning window applied; the squared magnitudes of their discrete Fourier transforms are averaged into a one-sided spectral density normalised by the window’s energy, so that its sum over the lines is the mean square of the roughness. Each one-third octave band of wavenumber then collects the lines within it and the portions of the two straddling its edges (Annex C, redistributed_band_energies), and the level is with (Formula 1).

The bands reported are those whose nominal wavelength is at most a quarter of the segment length (7.5) and whose upper edge lies below the Nyquist wavenumber of the sampling.

Parameters

NameDescription
roughness_umThe roughness record, in micrometres, at equal intervals, with joints, welds and defects already edited out.
sample_spacing_mThe sampling interval, in metres; 5.5 asks for 1 mm or less.
spike_removalWhether to apply 7.2 first.
curvature_processingWhether to apply 7.3 next.
segment_length_mThe length of each Fourier segment, in metres; at least 1 m (7.4.2).

Returns: The spectrum, longest wavelength first, with the record length and the number of segments averaged.

Raises

ExceptionWhen
ValueErrorFor a sampling interval above 1 mm, a segment shorter than 1 m, or a record shorter than one segment.
AcousticRoughnessSpectrum(
wavelengths_m: NDArray[np.float64],
levels_db: NDArray[np.float64],
record_length_m: float | None = None,
segment_count: int | None = None,
method: str | None = None,
)

A one-third octave band spectrum of acoustic rail roughness (EN 15610).

Built by acoustic_roughness_spectrum (Method A) or filtered_roughness_spectrum (Method B) from a record, by average_roughness_spectra from several, or directly from the band levels of a report, which is all the ISO 3095 checks need.

Parameters

NameDescription
wavelengths_mThe nominal band wavelengths, in metres, from the longest to the shortest as clause 9 draws them; each names the base-ten one-third octave band of wavenumber it is nominal for.
levels_dbThe acoustic roughness level of each band, dB re 1 µm.
record_length_mThe length of roughness the spectrum was taken from, in metres: for Method B, what is left once the 2 m at either end of each record have been discarded (7.4.3); None when not known.
segment_countHow many Fourier segments were averaged into it; None when not known, and for Method B, which has none.
method"A" for the Fourier analysis of 7.4.2, "B" for the digital filters of 7.4.3; None when not known or when an average mixes the two.

property

The band index of each wavelength, centred on per metre.

AcousticRoughnessSpectrum.level_at(wavelength_m: float) -> float

The level of the band a nominal wavelength names, dB re 1 µm.

Parameters

NameDescription
wavelength_mA nominal band wavelength, in metres.

Returns: The level of that band.

Raises

ExceptionWhen
KeyErrorIf the spectrum has no such band.
AcousticRoughnessSpectrum.plot(
ax: Axes | None = None,
*,
limit_db: Mapping[float, float] | None = None,
language: str = 'en',
**kwargs: Any,
) -> Axes

Draw the spectrum as EN 15610 clause 9 presents it.

Level against wavelength in decreasing order, one octave to 10 dB, with a limit curve when one is given.

Parameters

NameDescription
axAxes to draw on; a new figure is made when omitted.
limit_dbA limit spectrum to draw with it, nominal wavelength in metres to level, such as REFERENCE_TRACK_ROUGHNESS_LIMIT_DB.
language"en" or "es".
kwargsPassed to the spectrum line.

Returns: The axes drawn on.

average_roughness_spectra(
spectra: Sequence[AcousticRoughnessSpectrum],
) -> AcousticRoughnessSpectrum

The mean square average of roughness spectra of one line (7.6).

band by band, with no weighting for where along the test section each record was taken. ISO 3095 C.2.1 averages the spectra of a test section the same way (“quadratically averaged”) before comparing them with the limit. Only the bands every spectrum has are averaged.

Parameters

NameDescription
spectraThe spectra to average.

Returns: The average, with the record lengths and segment counts summed when every spectrum carries them, and the method of the spectra when they all share one.

Raises

ExceptionWhen
ValueErrorFor no spectrum, or spectra with no band in common.
curvature_processed_roughness(
roughness_um: ArrayLike,
*,
sample_spacing_m: float,
curve_radius_m: float = 0.375,
) -> NDArray[np.float64]

The record as a wheel of radius 0,375 m would ride it (7.3).

At every sample a circle of radius passes through with its centre above the record, and the point is raised by the largest amount the record stands above that circle:

A pit narrower than the circle is bridged at the height where the circle rests on its rims; a crest is unchanged, since the circle through it lies above its flanks. Only the samples whose circle height is within the range of the record can win the maximum, so the search is limited to them.

Parameters

NameDescription
roughness_umThe roughness record, in micrometres, usually after remove_roughness_spikes.
sample_spacing_mThe sampling interval, in metres.
curve_radius_mThe radius of the circle, in metres; the 0,375 m of 7.3 by default.

Returns: A new array , in micrometres.

Raises

ExceptionWhen
ValueErrorFor an invalid record, spacing or radius.
filtered_roughness_spectrum(
roughness_um: ArrayLike,
*,
sample_spacing_m: float,
spike_removal: bool = True,
curvature_processing: bool = True,
) -> AcousticRoughnessSpectrum

The one-third octave band acoustic roughness of a record by digital filters (7.4.3, Method B).

The record is processed as 7.1 asks, spikes first (remove_roughness_spikes) and curvature next (curvature_processed_roughness), and its mean and linear trend are removed, as the Annex B listing does before either analysis. It then runs through the one-third octave filters of roughness_filter_bank, and 2 m of every band’s output are discarded at either end “to remove the effects of filter transients” (7.4.3). The band level is the mean square of what is left, with (Formula 1).

The bands reported are those whose nominal wavelength is at most a quarter of the length analysed (7.5) and whose filter, over that length, has built up to within 0,15 dB of its steady output, the class 0 tolerance of EN 61260:1995 4.5.3; the longest bands ring on past the 2 m allowed and are left out until the record is long enough to dilute what is left of their transient. A 5 m record reports from the 0,25 m band down, a 19 m one from the 0,5 m band, and the shortest band is the one whose upper edge lies below the Nyquist wavenumber.

Parameters

NameDescription
roughness_umThe roughness record, in micrometres, at equal intervals, with joints, welds and defects already edited out.
sample_spacing_mThe sampling interval, in metres; 5.5 asks for 1 mm or less, and the filter bank needs a whole number of samples per metre.
spike_removalWhether to apply 7.2 first.
curvature_processingWhether to apply 7.3 next.

Returns: The spectrum, longest wavelength first, with the length analysed (the record less 2 m at either end) as its record length and "B" as its method. The records of one line need at least 15 m analysed in total (7.4.3), which check_reference_track judges on their average.

Raises

ExceptionWhen
ValueErrorFor a sampling interval above 1 mm or that is not a whole number of samples per metre, or a record shorter than 5 m (7.4.3 NOTE 1: 1 m left once 2 m are discarded at either end).
redistributed_band_energies(
source_lower: ArrayLike,
source_upper: ArrayLike,
energies: ArrayLike,
target_lower: ArrayLike,
target_upper: ArrayLike,
) -> NDArray[np.float64]

Band energies moved onto other bands in proportion to their overlap (Annex C).

EN 15610 Annex C builds a one-third octave band from narrow band lines of width : every line wholly inside the band counts in full and the two lines that straddle its edges count for the portions and of their width that lie inside it,

(Formula C.1). Written for source bands of any width, that is the energy of each source band shared among the target bands in proportion to how much of its width, on the linear axis, each target band covers, which is the form ISO 3095 Annex C asks for when the bands being shared are one-third octaves of wavelength carried onto frequency (“adapted to non-constant frequency bandwidths”). The energy of a source band outside every target band is dropped.

Parameters

NameDescription
source_lowerLower edges of the source bands, on any linear axis (hertz, cycles per metre).
source_upperTheir upper edges, on the same axis.
energiesThe energy of each source band: a mean square, not a level.
target_lowerLower edges of the target bands, on the same axis.
target_upperTheir upper edges.

Returns: The energy of each target band.

Raises

ExceptionWhen
ValueErrorFor edges that are not finite, not increasing within a band or not one per band, or a negative energy.
remove_roughness_spikes(
roughness_um: ArrayLike,
*,
sample_spacing_m: float,
) -> NDArray[np.float64]

The record with its narrow upward spikes replaced by straight lines (7.2).

A spike is a sample where the second derivative of the roughness falls below and the first derivative changes sign; its edges are the samples either side of it where the magnitude of the first derivative falls below , and its width is the distance between them. It is removed, by linear interpolation between its edges, when its height above that line satisfies

with and in metres, and the procedure is repeated until a sweep removes nothing. A narrow peak is taken for a particle of dirt; a broad one is roughness a wheel does feel, and stays.

The derivatives are central differences, as in the Annex B listing. That listing repeats its sweep while any second derivative is below the threshold, change of sign or not, which never ends on a sharp bend with no extremum nor on a sharp peak the height test keeps; the sweep here stops when a pass removes no spike, which is what “until no further spike is detected” can mean for a peak that is detected and kept.

Parameters

NameDescription
roughness_umThe roughness record , in micrometres, sampled at equal intervals, with joints, welds and defects already edited out (7.1 a) 1)).
sample_spacing_mThe sampling interval, in metres.

Returns: A new array, the record with the spikes removed, in micrometres.

Raises

ExceptionWhen
ValueErrorFor a record that is not a finite one-dimensional array of at least three samples, or a spacing that is not positive.
roughness_filter_bank(
*,
sample_spacing_m: float,
longest_wavelength_m: float = 0.5,
) -> OctaveFilterBank

The one-third octave filters Method B runs along a record (7.4.3).

7.4.3 asks for digital one-third octave band filters that “shall comply with EN 61260”, the 1995 edition (IEC 61260:1995) the normative references of EN 15610:2009 date. This is the library’s own bank, OctaveFilterBank, run with the record’s samples per metre for a sample rate, so that its frequencies are wavenumbers in cycles per metre: base-ten bands centred on per metre, the bands Method A reports, of order 4 Butterworth sections, every band run at the record’s own rate. Passed to verify_filter_class with edition="1995" it grades class 0 on Table 1 of EN 61260:1995 in every band, from the lowest wavenumbers up to the Nyquist wavenumber of the record, and its filter integrated response (4.5.3) and summation of outputs (4.9) are within the class 0 limits too. Order 4 is the lowest that is class 0, and the lowest settles soonest inside the 2 m 7.4.3 discards for the filter transients.

The bank is designed without the band-by-band decimation the library’s banks use by default (FilterDesign(resample=False)). At the record’s own rate a band has no alias at all for 4.8 to bound, and what the grade reads is exactly what a record goes through.

Parameters

NameDescription
sample_spacing_mThe sampling interval of the records, in metres; 5.5 asks for 1 mm or less, and the bank needs a whole number of samples per metre.
longest_wavelength_mThe longest band the bank holds, by its nominal wavelength, in metres; 0,5 m by default, where the Annex B listing stops (wl_max). The bank runs from that band to the shortest whose upper edge lies below the Nyquist wavenumber.

Returns: The filter bank.

Raises

ExceptionWhen
ValueErrorFor a sampling interval above 1 mm or that is not a whole number of samples per metre, or a longest wavelength that leaves no band above the Nyquist band.
roughness_measurement_lines(reference_width_mm: float) -> tuple[int, float]

How many parallel lines a rail’s reference surface is measured on (6.4.3).

Up to 20 mm wide, one line on the centre line of the reference surface; above 20 mm and up to 30 mm, three lines 5 mm apart; above 30 mm, three lines 10 mm apart. More lines may be measured, but those compared with the acceptance criteria follow this rule (6.4.3 NOTE).

Parameters

NameDescription
reference_width_mmThe width of the reference surface, in millimetres.

Returns: The number of lines and the distance between neighbouring lines, in millimetres (0 for a single line).

Raises

ExceptionWhen
ValueErrorFor a width that is not positive.