Skip to content

feat: EN/ES language option for the psychoacoustics/hearing/vibration plots#253

Merged
jmrplens merged 1 commit into
mainfrom
feat/i18n-plots-psycho
Jul 20, 2026
Merged

feat: EN/ES language option for the psychoacoustics/hearing/vibration plots#253
jmrplens merged 1 commit into
mainfrom
feat/i18n-plots-psycho

Conversation

@jmrplens

@jmrplens jmrplens commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Summary

The .plot() methods of the psychoacoustics, hearing and vibration results now accept a language keyword. "en" is the default and its output is unchanged; "es" renders the axis labels, titles and legends in Spanish and switches the decimal separator to a comma.

What changed

  • New phonometry._i18n module with the shared locale helpers: language validation, locale-aware number formatting, and linear-axis tick localisation.
  • The three _plot renderers (psychoacoustics.py, hearing.py, vibration.py, 24 plot functions in total) gain a module-level string table and localise every fixed label, title and legend. Unit symbols are kept; Spanish terminology follows the convention already used in the site (sonios, fonios, and so on).
  • The language keyword is threaded through the delegating .plot() methods, which validate it before forwarding.
  • The _i18n helpers are imported lazily inside the render functions, so the _plot leaves keep no module-level domain imports (the package-architecture test stays green).
  • Per-domain tests: a Spanish label is produced and an unknown language raises ValueError.
  • Regenerated API reference pages for the new .plot() signatures.

Verification

  • English output is byte-for-byte identical: every one of the 24 plots was rendered in English and compared against the previous implementation, with zero differences in labels, titles and legends.
  • The committed documentation figures regenerate with zero diff.
  • ruff check ., mypy src scripts, and pytest tests/psychoacoustics tests/hearing tests/vibration tests/test_package_architecture.py all pass (767 passed, 50 skipped).

Review in cubic

Summary by CodeRabbit

  • New Features

    • Plotting results across hearing, psychoacoustics, and vibration now supports English and Spanish labels, titles, legends, and localized decimal formatting.
    • Added a keyword-only language option to plotting methods, defaulting to English.
    • Unsupported language codes now produce a clear validation error.
  • Documentation

    • Updated API references and changelog to describe language selection and Spanish formatting.
  • Tests

    • Added coverage for localized labels, titles, decimal separators, and invalid language handling.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @jmrplens, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Plot methods for hearing, psychoacoustics, and vibration results now accept a keyword-only language parameter. English and Spanish labels, titles, legends, numeric formatting, and axis localization are implemented, with validation and focused tests for Spanish output and unsupported languages.

Changes

Plot internationalization

Layer / File(s) Summary
Public plotting API documentation
CHANGELOG.md, site/src/content/docs/reference/api/{hearing,psychoacoustics,speech,vibration}/...
Reference signatures and changelog entries document the new keyword-only language: str = 'en' parameter.
Hearing plot localization
src/phonometry/_plot/hearing.py, src/phonometry/hearing/..., tests/hearing/*
Hearing plot entry points validate language and render localized labels, titles, legends, numeric formatting, and axes.
Psychoacoustics plot localization
src/phonometry/_plot/psychoacoustics.py, src/phonometry/psychoacoustics/..., tests/psychoacoustics/*
Psychoacoustics plotters localize text, annotations, multi-panel axes, and decimal formatting.
Vibration plot localization
src/phonometry/_plot/vibration.py, src/phonometry/vibration/..., tests/vibration/*
Vibration plotters localize labels, titles, legends, annotations, numeric values, and axes.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Poem

A rabbit hopped through plots so bright,
Adding Spanish hues beside the white.
Commas danced where decimals lay,
Labels changed from night to day.
“Language!” I twitch, “what a delight!”

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding EN/ES language support to psychoacoustics, hearing, and vibration plots.
Docstring Coverage ✅ Passed Docstring coverage is 90.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/i18n-plots-psycho

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces internationalization support for plotting methods across the library, allowing users to specify a language ('en' or 'es') for axis labels, titles, and legends. The implementation includes a new locale helper module and updates to various plotting functions to handle locale-aware number formatting and decimal separators. The review feedback highlights that the current approach of clearing and restoring categorical labels in localize_axes is fragile and redundant. The reviewer suggests improving localize_axes to automatically skip axes using FixedFormatter, which would eliminate the need for manual restoration logic in multiple plotting functions.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/phonometry/_i18n.py Outdated
Comment on lines +39 to +53
def localize_axes(ax: Any, language: str = "en") -> None:
"""Localise linear-axis tick decimals to a comma for Spanish; no-op for English."""
if language != "es":
return
from matplotlib.ticker import FuncFormatter, NullFormatter

def _comma(x: float, _pos: int) -> str:
return f"{x:g}".replace(".", ",")

for axis in (ax.xaxis, ax.yaxis):
if axis.get_scale() != "linear":
continue
if isinstance(axis.get_major_formatter(), NullFormatter):
continue
axis.set_major_formatter(FuncFormatter(_comma))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Instead of blindly applying FuncFormatter to both axes and then having to manually "restore" categorical/fixed labels in almost every plotting function, we can make localize_axes smarter by skipping axes that use a FixedFormatter (which is what categorical/fixed labels use under the hood). This eliminates the fragile and redundant "destroy and restore" pattern across the codebase.

Suggested change
def localize_axes(ax: Any, language: str = "en") -> None:
"""Localise linear-axis tick decimals to a comma for Spanish; no-op for English."""
if language != "es":
return
from matplotlib.ticker import FuncFormatter, NullFormatter
def _comma(x: float, _pos: int) -> str:
return f"{x:g}".replace(".", ",")
for axis in (ax.xaxis, ax.yaxis):
if axis.get_scale() != "linear":
continue
if isinstance(axis.get_major_formatter(), NullFormatter):
continue
axis.set_major_formatter(FuncFormatter(_comma))
def localize_axes(ax: Any, language: str = "en") -> None:
"""Localise linear-axis tick decimals to a comma for Spanish; no-op for English."""
if language != "es":
return
from matplotlib.ticker import FixedFormatter, FuncFormatter, NullFormatter
def _comma(x: float, _pos: int) -> str:
return f"{x:g}".replace(".", ",")
for axis in (ax.xaxis, ax.yaxis):
if axis.get_scale() != "linear":
continue
if isinstance(axis.get_major_formatter(), (NullFormatter, FixedFormatter)):
continue
axis.set_major_formatter(FuncFormatter(_comma))

Comment on lines +154 to 157
localize_axes(ax, language)
if language == "es" and banded: # restore categorical band labels
_band_axis(ax, np.asarray(_STI_BAND_CENTERS), xlabel=_t("freq_hz", language))
return ax

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

With the proposed improvement to localize_axes to skip FixedFormatter axes, we no longer need to manually restore the categorical band labels here.

    localize_axes(ax, language)
    return ax

Comment on lines 188 to +191
ax.set_xticks(positions)
ax.set_xticklabels([f"{f:g}" for f in freqs], rotation=45, ha="right")
ax.set_xlabel("One-third-octave band [Hz]")
ax.set_ylabel("Mean intermediate correlation")
ax.set_xlabel(_t("third_octave_band", language))
ax.set_ylabel(_t("mean_corr", language))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

We can localize the categorical band labels at creation time using decimal_comma instead of doing it in a separate restore block at the end of the function.

Suggested change
ax.set_xticks(positions)
ax.set_xticklabels([f"{f:g}" for f in freqs], rotation=45, ha="right")
ax.set_xlabel("One-third-octave band [Hz]")
ax.set_ylabel("Mean intermediate correlation")
ax.set_xlabel(_t("third_octave_band", language))
ax.set_ylabel(_t("mean_corr", language))
ax.set_xticks(positions)
ax.set_xticklabels([decimal_comma(f"{f:g}", language) for f in freqs], rotation=45, ha="right")
ax.set_xlabel(_t("third_octave_band", language))
ax.set_ylabel(_t("mean_corr", language))

Comment on lines +206 to 210
localize_axes(ax, language)
if language == "es" and banded: # restore categorical band labels
ax.set_xticklabels([decimal_comma(f"{f:g}", language) for f in freqs],
rotation=45, ha="right")
return ax

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since the categorical labels are now localized at creation time and localize_axes skips FixedFormatter axes, we can remove this redundant restore block.

    localize_axes(ax, language)
    return ax

Comment on lines +249 to 252
localize_axes(ax, language)
if language == "es": # restore categorical band labels
_band_axis(ax, freqs, xlabel=_t("freq_hz", language))
return ax

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

With the proposed improvement to localize_axes to skip FixedFormatter axes, we no longer need to manually restore the categorical band labels here.

    localize_axes(ax, language)
    return ax

Comment on lines +634 to 637
localize_axes(ax, language)
if language == "es": # restore the categorical x labels localize_axes cleared
ax.set_xticklabels(labels)
return ax

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

With the proposed improvement to localize_axes to skip FixedFormatter axes, we no longer need to manually restore the categorical labels here.

    localize_axes(ax, language)
    return ax

Comment on lines 673 to +677
ax.set_xticks(positions)
ax.set_xticklabels([f"{f:g}" for f in freqs], rotation=45, ha="right")
ax.set_xlabel("Tone frequency [Hz]")
ax.set_ylabel(r"Audibility $\Delta L$ [dB]")
ax.set_title("ISO/PAS 20065 tonal audibility")
ax.set_xlabel(_t("tone_frequency", language))
ax.set_ylabel(_t("audibility_dl", language))
ax.set_title(_t("tone_audibility_title", language))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

We can localize the categorical tone frequency labels at creation time using decimal_comma instead of doing it in a separate restore block at the end of the function.

Suggested change
ax.set_xticks(positions)
ax.set_xticklabels([f"{f:g}" for f in freqs], rotation=45, ha="right")
ax.set_xlabel("Tone frequency [Hz]")
ax.set_ylabel(r"Audibility $\Delta L$ [dB]")
ax.set_title("ISO/PAS 20065 tonal audibility")
ax.set_xlabel(_t("tone_frequency", language))
ax.set_ylabel(_t("audibility_dl", language))
ax.set_title(_t("tone_audibility_title", language))
ax.set_xticks(positions)
ax.set_xticklabels([decimal_comma(f"{f:g}", language) for f in freqs], rotation=45, ha="right")
ax.set_xlabel(_t("tone_frequency", language))
ax.set_ylabel(_t("audibility_dl", language))
ax.set_title(_t("tone_audibility_title", language))

Comment on lines +681 to 685
localize_axes(ax, language)
if language == "es": # restore the categorical x labels localize_axes cleared
ax.set_xticklabels([decimal_comma(f"{f:g}", language) for f in freqs],
rotation=45, ha="right")
return ax

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since the categorical labels are now localized at creation time and localize_axes skips FixedFormatter axes, we can remove this redundant restore block.

    localize_axes(ax, language)
    return ax

Comment on lines +207 to 210
localize_axes(ax, language)
if language == "es": # restore categorical band labels
_band_axis(ax, freqs, xlabel=_t("freq_hz", language))
return ax

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

With the proposed improvement to localize_axes to skip FixedFormatter axes, we no longer need to manually restore the categorical band labels here.

    localize_axes(ax, language)
    return ax

Comment on lines +260 to 263
localize_axes(ax, language)
if language == "es": # restore categorical operation labels
ax.set_xticklabels(labels, rotation=45, ha="right")
return ax

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

With the proposed improvement to localize_axes to skip FixedFormatter axes, we no longer need to manually restore the categorical operation labels here.

    localize_axes(ax, language)
    return ax

@codecov

codecov Bot commented Jul 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.42060% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.12%. Comparing base (50a195e) to head (02b8f4e).

Files with missing lines Patch % Lines
src/phonometry/_plot/vibration.py 87.80% 5 Missing ⚠️
src/phonometry/_plot/psychoacoustics.py 95.65% 3 Missing ⚠️
src/phonometry/psychoacoustics/roughness_ecma.py 33.33% 2 Missing ⚠️
...c/phonometry/vibration/multiple_shock_vibration.py 33.33% 2 Missing ⚠️
src/phonometry/_plot/hearing.py 98.03% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #253      +/-   ##
==========================================
- Coverage   96.13%   96.12%   -0.02%     
==========================================
  Files         157      157              
  Lines       20448    20548     +100     
==========================================
+ Hits        19658    19751      +93     
- Misses        790      797       +7     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Numerical conformance report

354/354 conformance checks pass across 44 domains and 225 standards - filters class 1 - weightings within IEC 61672-1 class 1.

Each row pins a standard clause to its expected normative value and the value the library computes. Every section below is collapsible and stays collapsed while all of its rows pass; a section with any failing row opens automatically.

Numerical validation - filters & weightings: class showcase (IEC 61260-1 · IEC 61672-1 · ISO 7196)

IEC 61260-1:2014 class per filter architecture (order 6, one-third-octave, 100 Hz-10 kHz, fs = 48 kHz). For each architecture the table shows, at its binding band, the measured relative attenuation and the class-1 limit it must clear, so the number and the range it must sit in are both visible. A positive margin means the acceptance limits are met with that much room.

Architecture Class verdict Binding band Measured rel. atten. Class-1 limit Margin cl.1 Margin cl.2
butter Class 1 (default) 100 Hz +0.00 dB ≥ -0.40 dB +0.400 dB +0.600 dB
cheby1 By design (passband ripple) 6310 Hz +0.19 dB ≥ +1.44 dB -1.246 dB -0.837 dB
cheby2 Class 1 100 Hz +0.00 dB ≥ -0.40 dB +0.400 dB +0.600 dB
ellip By design (passband ripple) 10000 Hz +0.10 dB ≥ +1.32 dB -1.218 dB -0.813 dB
bessel By design (soft rolloff) 100 Hz +12.46 dB ≥ +16.60 dB -4.133 dB -3.133 dB

Only Butterworth (the library default) and Chebyshev-II are class-compliant architectures. Chebyshev-I and elliptic trade the mask for passband ripple, and Bessel for a maximally-flat group delay (soft rolloff); they cannot satisfy the IEC 61260-1 Class 1/2 attenuation mask by construction, so they are labelled By design - this is expected, not a failure or regression.

Frequency-weighting conformance (A/C: IEC 61672-1 Table 3; G: ISO 7196 A.3). The max deviation from nominal is informational (it falls at a frequency extreme where the tolerance is widest and asymmetric); compliance is judged at the binding frequency - the one with the least headroom - where the deviation, the applicable tolerance band and the headroom are shown together.

Curve fs Max dev. from nominal (info) Binding freq Deviation there Tolerance band Headroom
A 48 kHz -0.867 dB @ 19953 Hz 1000 Hz +0.000 dB [-0.70, +0.70] dB +0.700 dB
A 96 kHz -0.482 dB @ 19953 Hz 1000 Hz +0.000 dB [-0.70, +0.70] dB +0.700 dB
C 48 kHz -0.900 dB @ 19953 Hz 1000 Hz +0.000 dB [-0.70, +0.70] dB +0.700 dB
G 48 kHz +0.047 dB @ 1 Hz 1 Hz +0.047 dB [-1.00, +1.00] dB +0.953 dB
Filters & weightings: 100% (7/7)
Standard Quantity Expected (norm) Computed Δ Status
IEC 61260-1:2014 Table 1 Octave-band filter class (butterworth, fs=48 kHz) class 1 class 1 (margin +0.400 dB) +0.400 dB
IEC 61260-1:2014 Table 1 One-third-octave filter class (butterworth, fs=48 kHz) class 1 class 1 (margin +0.400 dB) +0.400 dB
IEC 61260:1995 / ANSI S1.11-2004 Table 1 Class 0 (strictest) octave-band filter (butterworth, fs=48 kHz) class 0 class 0 (margin +0.150 dB) +0.150 dB
IEC 61260-1:2014 Table F.1 Formula (9) breakpoint mapping, b=3, Omega at G**(1/2) 1.12202 (+/-0.00001) 1.12202 0
IEC 61672-1:2013 Table 3 A-weighting deviation vs class-1 limits (fs=48 kHz) deviation within limits @ 1000 Hz +0.000 dB in [-0.70, +0.70] dB headroom +0.700 dB
IEC 61672-1:2013 Table 3 C-weighting deviation vs class-1 limits (fs=48 kHz) deviation within limits @ 1000 Hz +0.000 dB in [-0.70, +0.70] dB headroom +0.700 dB
ISO 7196:1995 Table 2 / A.3 G-weighting deviation vs +/-1 dB tolerance (fs=48 kHz) deviation within limits @ 1 Hz +0.047 dB in [-1.00, +1.00] dB headroom +0.953 dB
Levels & dosimetry: 100% (6/6)
Standard Quantity Expected (norm) Computed Δ Status
IEC 61672-1:2013 (Leq) Leq of a 1 Pa 1 kHz sine 90.97 dB (+/-0.05 dB) 90.969 dB -0.001 dB
IEC 61252:1995 (LEX,8h) 8 h exposure to 90 dB(A) noise 90 dB (+/-0.05 dB) 90.008 dB 0.008 dB
ISO 1996-1:2016 3.6.4 Lden, constant 60 dB in day/evening/night 66.3952 dB (+/-0 dB) 66.3952 dB 0 dB
ISO 1996-2:2007 Annex C.5 Example 1 Tonal audibility ΔLta (Formula C.3), 4 kHz tone 13.7 dB (+/-0.05 dB) 13.66 dB -0.044 dB
ISO 1996-2:2007 Annex C.5 Example 1 Tonal adjustment Kt (Formulae C.4-C.6) 6 dB (+/-0 dB) 6 dB 0 dB
ISO 1996-2:2017 Annex G.2 Combined measurement uncertainty u = √(Σ(cj·uj)²) 2.18 dB (+/-0.01 dB) 2.18 dB -0.002 dB
Room acoustics: 100% (12/12)
Standard Quantity Expected (norm) Computed Δ Status
Sabine (W. C. Sabine, 1922) Reverberation time T = k·V/A (V=120 m³, S=158 m², α=0.2) 0.611825 s (+/-0.000001 s) 0.611825 s 0 s
Everest, Master Handbook of Acoustics 4th ed, Fig. 7-22 Sabine RT, worked Example 1 @ 1 kHz (untreated 23.3×16×10 ft room, SI) 3.39 s (+/-0.02 s) 3.402 s 0.012 s
Eyring (Norris-Eyring, 1930) Reverberation time T = k·V/(-S·ln(1-ᾱ)) (α=0.2) 0.548369 s (+/-0.000001 s) 0.548369 s 0 s
Arau-Puchades (Acustica 65, 1988, Formula 18) T (α=0.5/0.1/0.1 per wall pair, dims 8×5×3 m) 0.812147 s (+/-0.000001 s) 0.812147 s 0 s
Model identity (uniform absorption) Arau-Puchades ≡ Eyring when ᾱ is uniform 0.548369 s (= Eyring) 0.548369 s 0 s
Vorlander Auralization 2e, Eq. (11.38)-(11.39) Image-source direct-sound amplitude 1/(4πr) and delay r/c (r = 4 m) 0.0198944 (+/-0) 0.0198944 0
Kuttruff Room Acoustics 6e, Eq. (9.23) Audible shoebox image count up to order 10 (= 1560) 156 (+/-0) 156 0
Kuttruff Room Acoustics 6e, Eq. (4.6) Temporal reflection density dN/dt = 4πc³t²/V (t = 0.1 s, V = 120 m³) 42258.2 1/s (+/-0 1/s) 42258.2 1/s 0 1/s
Bies Engineering Noise Control 5e, Eq. (6.44) Room constant R = Sᾱ/(1-ᾱ) (S = 100 m², ᾱ = 0.2 → 25 m²) 25 m² (+/-0 m²) 25 m² 0 m²
Bies Engineering Noise Control 5e, Eq. (6.43) Critical distance rc: direct field = reverberant field (R = 25, Q = 1) 0.160000 (= reverberant term) 0.16 0
Kuttruff Room Acoustics 6e, Eq. (3.44) Schroeder frequency f_s = 2000√(T/V) (V = 200 m³, T = 1 s) 141.421 Hz (+/-0 Hz) 141.421 Hz 0 Hz
Bies Engineering Noise Control 5e, Eq. (6.43) Steady-state SPL Lp = Lw + 10lg(Q/4πr² + 4/R) (Lw=90, r=1, R=25, Q=1) 83.7945 dB (+/-0 dB) 83.7945 dB 0 dB
Psychoacoustics: 100% (12/12)
Standard Quantity Expected (norm) Computed Δ Status
ISO 532-1:2017 Annex B.2 Zwicker loudness N, stationary test signal 1 83.2957 sone (+/-0.1%) 83.2957 sone 0 sone
ISO 532-1:2017 Annex B.5 Time-varying loudness Nmax, technical signal 14 (aircraft, free field) 22.6399 sone (+/-0.1%) 22.6399 sone 0 sone
ISO 532-1:2017 Annex B.5 Time-varying loudness Nmax, technical signal 15 (vehicle interior, diffuse field) 9.6059 sone (+/-0.1%) 9.6059 sone 0 sone
DIN 45692:2009 Clause 6 Sharpness of the standard 1 kHz reference signal 1 acum (+/-0 acum) 1 acum 0 acum
DIN 45692:2009 Table A.2 Sharpness of critical-band noise at 2.5 kHz (2320-2700 Hz, 4 sone) 1.78 acum (+/-0.089 acum) 1.747 acum -0.033 acum
ISO 226:2023 Table B.1 Equal-loudness contour, 60 phon @ 100 Hz 78.5 dB SPL (+/-0.05 dB SPL) 78.504 dB SPL 0.004 dB SPL
ECMA-418-2:2025 Clause 5.1.8 HMS loudness of a 1 kHz / 40 dB tone (c_N=0.0211964) 1 sone_HMS (+/-0.03 sone_HMS) 0.9843 sone_HMS -0.016 sone_HMS
ECMA-418-2:2025 Clause 6.2.8 HMS tonality of a 1 kHz / 40 dB tone (c_T=2.8758615) 1 tu_HMS (+/-0.03 tu_HMS) 0.9998 tu_HMS 0 tu_HMS
ECMA-418-2:2025 Clause 7 HMS roughness of a 1 kHz / 70 Hz / m=1 / overall 60 dB tone (c_R=0.0180685) 1 asper (+/-0.01 asper) 0.9999 asper 0 asper
ISO 532-2:2017 Clause 3.17 / Annex B.1 Moore-Glasberg loudness of a 1 kHz / 40 dB tone (C=0.0617) 1 sone (+/-0.01 sone) 1.0001 sone 0 sone
ISO 532-3:2023 Annex C.1 Moore-Glasberg-Schlittenlacher peak LTL, steady 1 kHz / 40 dB 1 sone (+/-0.02 sone) 0.9996 sone 0 sone
ECMA-418-2:2025 Clause 9 HMS fluctuation strength of a 1 kHz / 4 Hz / m=1 / overall 60 dB tone (c_F=0.003840572) 1 vacil_HMS (+/-0.01 vacil_HMS) 0.9931 vacil_HMS -0.007 vacil_HMS
Speech transmission (IEC 60268-16): 100% (9/9)
Standard Quantity Expected (norm) Computed Δ Status
IEC 60268-16:2020 A.2.2 STI weighting-factor pair (500 Hz + 1 kHz bands) 0.398 (+/-0.001) 0.398 0
IEC 60268-16:2020 A.3.1.2 Uniform MTF m=0.5 maps to STI=0.5 0.5 (+/-0.01) 0.5 0
IEC 60268-16:2020 C.3.2 STIPA direct method, Formula (C.1) signal at m=0.2 0.3 (+/-0.01) 0.2992 -0.001
IEC 60268-16:2020 C.3.2 STIPA direct method, Formula (C.1) signal at m=0.5 0.5 (+/-0.01) 0.4998 0
IEC 60268-16:2020 C.3.2 STIPA direct method, Formula (C.1) signal at m=0.8 0.7 (+/-0.01) 0.7002 0
IEC 60268-16:2020 C.3.3 Indirect method: exponential decay RT60=1 s vs Schroeder MTF 0.5885 (+/-0.005) 0.5885 0
IEC 60268-16:2020 C.4.2 Filter-bank slope: +41 dB unmodulated tone one octave below 125 Hz m >= 0.5 (C.4.2 pass criterion) 0.9812 0.481
IEC 60268-16:2020 A.2.2 (audio path) Weighting factors: modulated 500 Hz + 1 kHz pair through stipa() 0.398 (+/-0.005) 0.398 0
IEC 60268-16:2020 A.3.1.2 (audio path) Filter-bank phase: half-octave edge carriers at TI=0.9 0.9 (+/-0.01) 0.8975 -0.003
Intensity & sound power: 100% (4/4)
Standard Quantity Expected (norm) Computed Δ Status
IEC 61043:1994 Clause 5 Plane-wave intensity I = p^2 / (rho c) 0.00238 W/m^2 (+/-1.5%) 0.00239 W/m^2 0 W/m^2
ISO 3744:2010 Eq. 18 Monopole hemisphere recovers LW (r=4 m) 95 dB (+/-0 dB) 95 dB 0 dB
ISO 9614-2:1996 Eq. 12 Intensity scan recovers LW of an enclosed source 90 dB (+/-0.000001 dB) 90 dB 0 dB
ISO 3741:2010 Eq. 20 Reverberation-room method inverts to a known LW 0 dB error 0 dB 0 dB
Room & building acoustics: 100% (51/51)
Standard Quantity Expected (norm) Computed Δ Status
ISO 3382-2:2008 5.3.3 T30 from a synthetic exponential decay (T=1.0 s) 1 s (+/-1%) 1 s 0 s
ISO 18233:2006 (swept-sine method) Sweep deconvolution recovers a known IIR response 0 dB in-band error (+/-0.1 dB) 0.0006 dB 0.001 dB
ISO 717-1 Annex C, Table C.1 Weighted sound reduction index Rw (C;Ctr) Rw 30 (C -2; Ctr -3) Rw 30 (C -2; Ctr -3) sum 31.8 dB
ISO 717-1:2020 Annex C, Table C.2 Enlarged range 50-5000 Hz: Rw (C; Ctr; C50-5000; Ctr,50-5000) Rw 30 (C -2; Ctr -3; C50-5000 -2; Ctr,50-5000 -4) Rw 30 (C -2; Ctr -3; C50-5000 -2; Ctr,50-5000 -4) exact
ISO 717-2 Annex C, Table C.1 Weighted impact sound pressure level Ln,w (CI) Ln,w 79 (CI -11; sum 28.0 dB) Ln,w 79 (CI -11; sum 28.0 dB) +0 dB
ISO 717-2 Annex C, Table C.1 (covered) Weighted impact level of the floor WITH covering Ln,w (CI) Ln,w 64 (CI -3; sum 30.0 dB) Ln,w 64 (CI -3; sum 30.0 dB) +0 dB
ISO 717-2 Annex C, Table C.2 Floor-covering improvement ΔLw and CI,Δ (Formulae (2)/(A.4); CI,Δ from the normative Table 4 floor, not the 2020 print's misprinted C.2 chain) ΔLw 15 dB; CI,Δ -9 dB (Table 4 reference floor) ΔLw 15 dB; CI,Δ -9 dB +0 dB
ISO 354:2003 Eq. 5/8 Sabine inversion recovers absorption area 9.212828 m^2 (+/-0 m^2) 9.212828 m^2 0 m^2
ISO 3382-3:2012 Clause 6.2 Open-plan spatial decay rate D2,S (-6 dB/doubling) 6 dB (+/-0 dB) 6 dB 0 dB
ISO 16283-3:2016 Clause 3.12 Facade R'45 isolates the -1.5 dB incidence correction (S=A) 38.5 dB (+/-0 dB) 38.5 dB 0 dB
ISO 10140-2:2010 Formula (2) Lab airborne R on the ISO 717-1 reference shape -> Rw = 54 Rw 54 dB Rw 54 dB +0 dB
ISO 10140-5:2010+A1 Annex B, Table B.1 Reference elements end-to-end: printed Rw (C; Ctr) of all three Rw(C;Ctr) = 53(-1;-5) / 52(-1;-5) / 33(-1;-2) 53(-1;-5) / 52(-1;-5) / 33(-1;-2) exact
ISO 10140-5:2010+A1 Annex C, Table C.1 Reference floors end-to-end: printed Ln,t,r,0,w (CI) of both Ln,t,r,0,w(CI) = 72(0) / 75(-3) 72(0) / 75(-3) exact
ISO 15186-1:2000 Formula (7) Intensity RI on the ISO 717-1 reference shape -> RI,w = 30 RI,w 30 dB (scalar anchor RI = 34 dB) RI,w 30 dB (RI = 34 dB) +0 dB
ISO 15186-1:2000 Annex B, Table B.1 Adaptation term Kc: all 18 printed rows; (B.1) reduces to (B.2) max abs(Kc - Table B.1) <= 0,05 dB (1 dp print) 0.046 dB (B.1 vs B.2: 4.33e-04 dB) 0.046 dB
ISO 10052:2021 Clause 3.6 Survey R' applies the V/7,5 minimum-area rule 26.197888 dB (+/-0 dB) 26.197888 dB 0 dB
ISO 10052:2021 Clause 3.16 Service-equipment LXY is the 3-position energy average 32.823329 dB (+/-0 dB) 32.823329 dB 0 dB
ISO 10052:2021 Table 4 Reverberation-index estimate (35 <= V < 60, type g) k = [4.5, 5.0, 5.5, 5.5, 5.5] dB k = [4.5, 5.0, 5.5, 5.5, 5.5] dB exact
ISO 717-2:2020 Table 4 / Clause 5.2 Reference-floor weighted level Ln,r,0,w and CI (ISO 16251-1 ΔLw anchor) Ln,r,0,w = 78 dB, CI = -11 dB Ln,r,0,w = 78 dB, CI = -11 dB exact
ISO 16251-1:2014 / ISO 717-2 Formula (2) Floor-covering ΔLw: zero improvement gives ΔLw = 0 ΔLw = 0 dB (ΔL = 0 -> Ln,r = Ln,r,0) ΔLw = 0 dB exact
ISO 10848-1:2006 Formula (14) Flanking Kij (simplified) matches closed form Kij = 1.9897 dB Kij = 1.9897 dB exact
ISO 10848-1:2006 Formula (12) Flanking equivalent absorption length aj at f_ref aj = 1.2661 m aj = 1.2661 m exact
ISO 10848-1:2006 Clause 7.3.1 Flanking total loss factor η = 2,2/(f·Ts) η = 0.0044 η = 0.0044 exact
ISO 12354-1:2017 Formula (20) vs Hopkins Eq. 2.201 (6 mm glass) Flanking critical frequency (c0²/1,8·cL·h) vs plate coincidence (c0²/2π · sqrt(m''/B')) 2107.4 Hz (+/-1%) 2123.5 Hz 16.156 Hz
EN 29052-1:1992 Formula 4 Apparent dynamic stiffness s't = 4π²·m't·fr² (m't=200 kg/m², fr=25 Hz) 4.934802 MN/m³ (+/-0.000001 MN/m³) 4.934802 MN/m³ 0 MN/m³
EN 29052-1:1992 clause 8.2 NOTE Enclosed-gas stiffness s'a·d = 111 MN·mm/m³ (p₀=0,1 MPa, ε=0,9) 5.55556 MN/m³ (+/-0.0001 MN/m³) 5.55556 MN/m³ 0 MN/m³
EN 29052-1:1992 Formula 2 Floating-floor natural frequency f0 = (1/2π)√(s'/m') (s'=10 MN/m³, m'=100 kg/m²) 50.32921 Hz (+/-0 Hz) 50.32921 Hz 0 Hz
ISO 7626-1:2011 Table 1 / 3.1.2 Closed-form SDOF driving-point mobility peak mag(Y(f0)) = 1/c (c=5 N·s/m) 0.2 m/(N·s) (+/-0.000001 m/(N·s)) 0.2 m/(N·s) 0 m/(N·s)
ISO 7626-1:2011 Table 1 / 3.1.2 Closed-form SDOF static receptance H(0) = 1/k (k=8000 N/m) 0.000125 m/N (+/-0.0001%) 0.000125 m/N 0 m/N
ISO 7626-1:2011 Table 1 FRF reciprocity: impedance × mobility = 1 (at 37 Hz) 1 (= Z·Y) 1 0
ISO 10846-2:2008 3.17 Transfer-stiffness level Lk = 20 lg( k /k0), k0 = 1 N/m ( k = 1 MN/m)
ISO 10846-3:2002 Formula (1) Indirect method k2,1 = -(2πf)²·m2·T (f=500 Hz, m2=10 kg, T=0,01) -986960.4 N/m (+/-0.1%) -986960.4 N/m 0 N/m
ISO 10846-1:2008 Table A.2 FRF relation k = jω·Z at 250 Hz ( k recovered from impedance) 1001249.2 N/m (+/-0.0001%) 1001249.2 N/m
ISO 7626-2:2015 7.5.2 Rigid-mass calibration: accelerance mag(A) = 1/m (m=10 kg) 0.1 1/kg (+/-0 1/kg) 0.1 1/kg 0 1/kg
ISO 7626-2:2015 7.5.2 Rigid-mass calibration: mobility mag(Y) = 1/(2πf·m) at 100 Hz (m=10 kg) 0.0001592 m/(N·s) (+/-0.001%) 0.0001592 m/(N·s) 0 m/(N·s)
ISO 7626-2:2015 Annex A Normalized random error ε = √((1−γ²)/(2nγ²)): γ²=0,8, n=75 → 4,08 % (< 5 %) 4.08 % (+/-0.01 %) 4.08 % 0.002 %
ISO 7626-1:2011 Table 1 Rigid 1 kg mass at ω = 1000 rad/s: mobility 1e-3, compliance 1e-6 (decades) 0.001 m/(N·s) (+/-1e-07%) 0.001 m/(N·s) 0 m/(N·s)
ISO 10846-3:2002 6.1 Inequality (2) Indirect-method validity limit mag(T) = 0,1 ↔ ΔL1,2 = 20 dB 20 dB (+/-0 dB) 20 dB 0 dB
ISO 10846-3:2002 6.1 Model bias at the validity limit: k_ind/k = 1,1 (0,83 dB ≤ 1 dB, 10 % ≤ 12 %) 1.1 (+/-1e-07%) 1.1 0
ISO 10846-1:2008 Equation (6) Delivered/blocking force F2/F2,b = 1/1,1 at mag(k2,2/kt) = 0,1 (within 10 %) 0.9091 (+/-0) 0.9091 0
ISO 10846-2:2008 / -3:2002 7.6 Linearity: ΔLk ≤ 1,5 dB for input spectra 10 dB apart (linear element: 0) ΔLk ≤ 1,5 dB (7.6 c) 0 dB 0 dB
ISO/TS 7849-1:2009 Formula (8) Calibration L_v from â = 9,81 m/s² at 100 Hz (standard's EXAMPLE) 106.9 dB (+/-0.1 dB) 106.9 dB -0.02 dB
ISO/TS 7849-2:2009 Formula (15) L_W from L_v via measured radiation factor = 10 lg(P/P0) (round-trip) 84.771 dB (+/-0 dB) 84.771 dB 0 dB
ISO/TS 7849-1:2009 Formula (12) Impedance term: L_W − L_v = 10 lg(411/400) at ε = 1, S = S0 0.1178 dB (+/-0 dB) 0.1178 dB 0 dB
EN 15657:2018 Formula (14) Reception-plate L_Ws = resonant-plate power P = ωη(mS)⟨v²⟩ (round-trip) 55.545 dB (+/-0 dB) 55.545 dB 0 dB
EN 15657:2018 Formula (13) Plate loss factor η = 2,2/(f·Ts) at 1 kHz, Ts = 0,3 s 0.0073 (+/-0) 0.0073 0
EN 15657:2018 Formulae (15)/(17) + EN 12354-5 Annex I.3 Source conversion chain reproduces Table I.8 (wall, installed) max abs(L_Ws,inst - Table I.8) <= 0,15 dB 0.055 dB 0.055 dB
ISO 9611:1996 eq. (9) Mean free velocity level (energy mean, v0 = 5e-8 m/s) 72.3017 dB (+/-0 dB) 72.3017 dB 0 dB
EN 12354-5:2009 Formula (19b/19c) Coupling term → force-source limit 10 lg(mag(Ys)/Re{Yi}) as mag(Ys) ≫ mag(Yi) 40 dB (+/-0.01 dB) 40.001 dB 0.001 dB
EN 12354-5:2009 Annex I.3, Table I.9 Flushing cistern: four paths + Formula (17) total -> 29 dB(A) max path/total dev <= 0.15 dB; total 29 dB(A) 0.055 dB; 29.3 dB(A) 0.055 dB
EN 12354-5:2009 Annex I.2, Table I.6a Whirlpool floor component: mobility correction + path 11 max abs(dev vs Table I.6a) <= 0,15 dB 0.1 dB 0.1 dB
Building prediction & uncertainty: 100% (15/15)
Standard Quantity Expected (norm) Computed Δ Status
EN 12354-1:2000 Annex H.3 Airborne prediction R'w (direct + 12 flanking paths) R'w 52 dB (13 paths) R'w 52 dB (13 paths, 52.17) +0.17 dB
EN 12354-1:2000 Annex H.3 (paths) All 12 printed flanking-path values Rij,w max abs(Rij,w - printed) <= 0,05 dB 0.042 dB 0.042 dB
EN 12354-1:2000 Formula (5b) / Annex H.3 DnT,w closure from R'w (both H.3 examples -> 54 dB) DnT,w 54 dB (printed 53,8/54,3) DnT,w 53.63 / 54.13 dB -0.17 dB vs printed
EN 12354-2:2000 Annex E.3 Impact prediction L'n,w = Ln,w,eq - dLw + K 45 dB (+/-0 dB) 45 dB 0 dB
EN 12354-2:2000 Formula (3) / Annex E.3 Standardized impact level L'nT,w (exact 0,032 V form -> 43 dB) L'nT,w 43 dB (exact 42,96; E.3 prints 42,8) L'nT,w 42.96 dB -0.001 dB
EN 12354-3:2000 Annex F Facade airborne prediction (R'tr,s,w / D2m,nT,w single numbers) R'tr,s,w 31 (Ctr -3); D2m,nT,w 33 dB R'tr,s,w 31 (Ctr -3); D2m,nT,w 33 dB 0
EN 12354-4:2000 Annex G / Formula (2) Radiated LW of a wall+door segment (side 1, low bands) LW 63/125 Hz [59.8, 61.2] dB (+/-0.1) LW [59.8, 61.2] dB 0.038 dB
EN 12354-4:2000 Annex E / Table G.9 Exterior level of all four Table G.9 reception cells Lp 36,6 / 28,5 / 44,6 / 37,3 dB (+/-0,05) Lp 36.6 / 28.5 / 44.6 / 37.3 dB 0.046 dB
ISO 12999-1:2020 Table 2 Airborne band uncertainty, situation A @ 1 kHz 1.8 dB (+/-0 dB) 1.8 dB 0 dB
ISO 12999-1:2020 Annex B, Table B.2 One-decimal single numbers Rw / Rw+C50-5000 / Rw+Ctr,50-5000 57.4 / 56.4 / 51.1 dB 57.4 / 56.4 / 51.1 dB +0.00 dB
ISO 12999-1:2020 Annex B, Formulae (B.2)/(B.6) Single-number uncertainties (uncorrelated 0,6/0,8; correlated u(Rw) 1,9) u_uncorr 0.6 / 0.8 dB; u_corr(Rw) 1.9 dB 0.60 / 0.79 dB; 1.90 dB -0.00 dB
ISO 12999-1:2020 Clause 8 / Table 8 Expanded uncertainty U = 1.96 u (95 % two-sided, Rw sit. A) 2.352 dB (+/-0 dB) 2.352 dB 0 dB
ISO 12999-2:2020 Table 4 / Formula (1) Absorption coefficient +/-U (k=2), reproducibility, 20 x 1/3-oct bands U(k=2) = [0.33, 0.26, 0.22, 0.17, 0.13, 0.11, 0.09, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.09, 0.09, 0.09, 0.1, 0.11, 0.13, 0.16] U(k=2) = [0.33, 0.26, 0.22, 0.17, 0.13, 0.11, 0.09, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.09, 0.09, 0.09, 0.1, 0.11, 0.13, 0.16] exact
ISO 12999-2:2020 Table 5 / Formula (4) Practical coefficient +/-U (k=2), reproducibility, 5 octave bands U(k=2) = [0.09, 0.08, 0.08, 0.08, 0.1] U(k=2) = [0.09, 0.08, 0.08, 0.08, 0.1] exact
ISO 12999-2:2020 Clause 7, Examples 1/2 Single-number U (k=2): alpha_w and DLalpha,NRD alpha_w +/-0.07, DLalpha +/-1.6 dB alpha_w +/-0.07, DLalpha +/-1.6 dB exact
Outdoor propagation & occupational exposure: 100% (10/10)
Standard Quantity Expected (norm) Computed Δ Status
ISO 9613-1:1993 Table 1 Air attenuation @ 10 degC, 70 %, 1 kHz 3.66 dB/km (+/-0.01 dB/km) 3.658 dB/km -0.002 dB/km
ISO 9613-1:1993 Table 1 Air attenuation @ 0 degC, 20 %, 2 kHz 34.6 dB/km (+/-0.1 dB/km) 34.64 dB/km 0.04 dB/km
ISO 9613-2:1996 Table 2 Atmospheric attenuation grid, 6 conditions x 8 octave bands, dB/km all 48 cells within half a printed digit worst residual 0.939 x tolerance 0.939 x
ISO 9613-2:1996 Eq. (7) Geometrical divergence Adiv = 20 lg(d/d0) + 11 at 100 m 51 dB (+/-0 dB) 51 dB 0 dB
ISO 9613-2:1996 Table 3 Ground b'(0) porous limit -> Agr(250 Hz) = 2(-1.5 + 10.1) 17.2 dB (+/-0 dB) 17.2 dB 0 dB
ISO 9613-2:1996 clause 7.4 Single-edge diffraction saturates at the 20 dB cap 20 dB (+/-0 dB) 20 dB 0 dB
ISO 9613-2:1996 clause 7.4 Double-edge diffraction saturates at the 25 dB cap 25 dB (+/-0 dB) 25 dB 0 dB
ISO 9612:2009 Annex D Task-based LEX,8h + U (welder day, case a) LEX,8h 84.3; U 2.7 dB LEX,8h 84.3; U 2.7 dB -0.01; +0.02 dB
ISO 9612:2009 Annex E Job-based LEX,8h + U (production line, 18 workers) LEX,8h 88.1; U 3.8 dB LEX,8h 88.2; U 3.8 dB +0.06; -0.03 dB
ISO 9612:2009 Annex F Full-day LEX,8h + U (forklift drivers) LEX,8h 90.1; U 3.4 dB LEX,8h 90.1; U 3.4 dB +0.02; +0.03 dB
Materials: absorption, airflow & impedance: 100% (6/6)
Standard Quantity Expected (norm) Computed Δ Status
ISO 11654:1997 Annex A.1 Weighted absorption alpha_w (no indicator) 0.60 (class C, no indic.) 0.60 (class C, '') 0
ISO 11654:1997 Annex A.2 Weighted absorption alpha_w with M indicator 0.60(M) 0.60(M) 0
ISO 9053-2:2020 Annex A.3 Thermal boundary-layer thickness b 0.00183 m (+/-0.00001 m) 0.00183 m 0 m
ISO 9053-2:2020 Annex A.3 Effective ratio of specific heats kappa' 1.37 (+/-0.001) 1.37 0
ISO 10534-1:1996 Eqs (9)/(13)/(14) Absorption from standing-wave ratio s=3 alpha 0.75 (+/-0), |r| 0.5 alpha 0.75, |r| 0.5000 0
ISO 10534-2 Eq. (17) / Annex D Two-microphone round trip recovers a known reflection factor abs(r - (0.3-0.4j)) = 0 (identity, +/-1e-9) 0 0
Scattering & diffusion (ISO 17497): 100% (5/5)
Standard Quantity Expected (norm) Computed Δ Status
ISO 17497-1:2004 Eq (2) Reference speed of sound at 20 C 343.2 m/s (+/-0 m/s) 343.2 m/s 0 m/s
ISO 17497-1:2004 Eqs (1)/(4)/(5) Scattering coefficient (synthetic chain) 0.0931 (+/-0) 0.0931 0
ISO 17497-1:2004 Annex A.5 Expanded uncertainty of scattering coefficient 0.02971 (+/-0) 0.02971 0
ISO 17497-2:2012 Formula (5) Diffusion coefficient (autocorrelation) 0.7367 (+/-0) 0.7367 0
ISO 17497-2:2012 Formula (8) Zenith area factor (radians convention) 1.57105 (+/-0) 1.57105 0
In-situ road absorption (ISO 13472): 100% (3/3)
Standard Quantity Expected (norm) Computed Δ Status
ISO 13472-1:2002 Clause 4.2 Geometrical-spreading factor Kr 0.6667 (+/-0) 0.6667 0
ISO 13472-1:2002 Annex A Maximum-sampled-area radius 1.3425 m (+/-0 m) 1.3425 m 0 m
ISO 13472-2:2010 Clause 5.4.1 Spot-tube upper usable frequency f_u 1989.4 Hz (+/-0.1 Hz) 1989.4 Hz 0 Hz
Precision sound power (ISO 3745 / 9614-3): 100% (4/4)
Standard Quantity Expected (norm) Computed Δ Status
ISO 3745:2012 Clause 10.5 EXAMPLE Expanded uncertainty U (k=2) 4.123 dB (+/-0.001 dB) 4.123 dB 0 dB
ISO 3745:2012 Eq (11) K1 background floor (6 dB edge band) 1.2563 dB (+/-0.0001 dB) 1.2563 dB 0 dB
ISO 3745:2012 Eq (16) Meteorological C1 at 23 C reference -0.1282 dB (+/-0.0001 dB) -0.1282 dB 0 dB
ISO 9614-3:2002 Eqs (5)/(8)/(9) Uniform-intensity LW recovery 80 dB (+/-0 dB) 80 dB 0 dB
Human vibration (ISO 8041 / 2631 / 5349): 100% (15/15)
Standard Quantity Expected (norm) Computed Δ Status
ISO 8041-1:2017 Table B.8 Wk design-goal factor at 6,31 Hz 1.054 (+/-0.1%) 1.0544 0
ISO 8041-1:2017 Table B.9 Wm design-goal factor at 1,585 Hz 0.9342 (+/-0.1%) 0.9342 0
ISO 8041-1:2017 Table 1 Wh factor at the 500 rad/s reference 0.202 (+/-0.15%) 0.202 0
ISO 8041-1:2017 Table B.1 Wb design-goal factor at 6,31 Hz 1.054 (+/-0.1%) 1.0545 0
ISO 8041-1:2017 Table B.1 Wb design-goal factors at 1 / 100 Hz max rel dev ≤ 0,1 % 0.000267 0
ISO 8041-1:2017 Table 1 Wc factor at the 100 rad/s reference 0.5145 (+/-0.1%) 0.5145 0
ISO 8041-1:2017 Table 1 + Table B.3 Wd factors at the 100 rad/s reference and 1 Hz max rel dev ≤ 0,1 % 0.000162 0
ISO 8041-1:2017 Table B.4 We design-goal factor at 8 Hz 0.1263 (+/-0.1%) 0.1263 0
ISO 8041-1:2017 Table B.5 Wf design-goal factors at 0,1585 / 0,1 Hz max rel dev ≤ 0,1 % 0.000098 0
ISO 8041-1:2017 Table B.7 Wj design-goal factors at 6,31 / 8 Hz max rel dev ≤ 0,1 % 0.00001 0
ISO 8041-1:2017 Table 5 + Annex B All nine weightings inside the tolerance envelope (318 printed bands) 0 bands outside the Table 5 tolerances 0 0
ISO 5349-2:2001 Example E.2.1 Single-tool daily exposure A(8) 4.1 m/s^2 (+/-0.05 m/s^2) 4.14 m/s^2 0.037 m/s^2
ISO 5349-2:2001 Example E.3 Forestry three-task A(8) 3.6 m/s^2 (+/-0.05 m/s^2) 3.61 m/s^2 0.01 m/s^2
ISO 5349-1:2001 Eq. (C.1) VWF 10 % lifetime Dy at A(8)=7 4 yr (+/-0.1 yr) 4.04 yr 0.042 yr
Directive 2002/44/EC Art. 3 HAV/WBV action & limit values HAV 2.5/5.0, WBV 0.5/1.15 m/s^2 HAV 2.5/5.0, WBV 0.5/1.15 m/s^2 0
Speech intelligibility (ANSI S3.5-1997): 100% (7/7)
Standard Quantity Expected (norm) Computed Δ Status
ANSI S3.5-1997 Table 3 Band-importance function normalisation 1 (+/-0) 1 0
ANSI S3.5-1997 clause 5.4 Equivalent masking spectrum level at 200 Hz -1.665 (+/-0.001) -1.665 0
ANSI S3.5-1997 clause 5.6 Equivalent disturbance in quiet at 5000 Hz -23.6 dB (+/-0.01 dB) -23.6 dB 0 dB
ANSI S3.5-1997 clause 6 SII, noise 30 dB plus hearing loss 40 dB 0.2185 (+/-0.0001) 0.2185 0
R CRAN 'SII' Example C.2 One-third-octave method, independent oracle 0.851375 (+/-0.0001) 0.851375 0
ANSI S3.5-1997 clause 6 SII, standard speech in quiet, normal hearing 0.99582517 (+/-0.000001) 0.99582517 0
ANSI S3.5-1997 Table 3 Loud-effort speech spectrum level at 1 kHz 42.16 dB (+/-0 dB) 42.16 dB 0 dB
Objective intelligibility (STOI / ESTOI): 100% (3/3)
Standard Quantity Expected (norm) Computed Δ Status
Taal et al. 2011 (Eq. 6, degenerate) STOI of a signal against itself = 1 (perfect correlation) 1 (+/-0.000001) 1 0
Jensen & Taal 2016 (Eq. 8, degenerate) ESTOI of a signal against itself = 1 (perfect spectral correlation) 1 (+/-0.000001) 1 0
Taal et al. 2011 (monotonicity with SNR) STOI rises from -15 dB to +25 dB SNR speech-shaped noise STOI(+25 dB) - STOI(-15 dB) > 0.2 0.462 (0.389 -> 0.851) 0
Impulsive-sound prominence (NT ACOU 112): 100% (2/2)
Standard Quantity Expected (norm) Computed Δ Status
NT ACOU 112:2002 Formula 1 Predicted prominence, OR=1000 dB/s, LD=30 dB 11.9542 (+/-0.0001) 11.9542 0
NT ACOU 112:2002 Formula 2 Adjustment KI to LAeq at prominence P=10 9 dB (+/-0 dB) 9 dB 0 dB
Room noise (ANSI S12.2-2019): 100% (3/3)
Standard Quantity Expected (norm) Computed Δ Status
ANSI S12.2-2019 Table 1 NC-40 curve, tangency self-consistency 40 (+/-0) 40 0
ANSI S12.2-2019 Table D.1 RC-31 Mark II curve, 63 Hz level 51 (+/-0) 51 0
ANSI S12.2-2019 clause D.4 RC-35 curve, mid-frequency average LMF 35 (+/-0) 35 0
Hearing threshold (ISO 7029 / ISO 389-7): 100% (3/3)
Standard Quantity Expected (norm) Computed Δ Status
ISO 7029:2017 Table 1 Median threshold, male age 60 at 4 kHz 20.209 dB (+/-0.001 dB) 20.208 dB 0 dB
ISO 7029:2017 Table 2 Upper spread su, male age 60 at 1 kHz 10.153 dB (+/-0.001 dB) 10.153 dB 0 dB
ISO 389-7:2005 Table 1 Free-field reference threshold at 1 kHz 2.4 dB (+/-0 dB) 2.4 dB 0 dB
Measurement uncertainty (GUM / Supplement 1): 100% (7/7)
Standard Quantity Expected (norm) Computed Δ Status
ISO/IEC Guide 98-3-1 clause 9.2 Combined uncertainty, additive model 2 (+/-0) 2 0
ISO/IEC Guide 98-3 Table G.2 Coverage factor, p=0.99, v=16 2.92 (+/-0.005) 2.921 0.001
ISO/IEC Guide 98-3 Annex G.4 Welch-Satterthwaite effective dof 40 (+/-0) 40 0
ISO/IEC Guide 98-3 Annex H.1 End-gauge combined uncertainty uc, nm 31.71 nm (+/-0.01 nm) 31.71 nm 0.001 nm
ISO/IEC Guide 98-3 Annex H.1 End-gauge expanded uncertainty U99, nm 92.1 nm (+/-0.1 nm) 92.1 nm 0.04 nm
ISO/IEC Guide 98-3 Annex H.2 (Table H.3) Correlated V/I/phi budget: uc(R), ohm 0.071 ohm (+/-0.001 ohm) 0.071 ohm 0 ohm
ISO/IEC Guide 98-3-1 Table 3 (clause 9.2.3) Seeded Monte Carlo, rectangular sum: 95 % interval endpoint +/-3.88 (u = 2.0) +/-3.886 (u = 2.002) 0.006
Noise-induced hearing loss (ISO 1999): 100% (3/3)
Standard Quantity Expected (norm) Computed Δ Status
ISO 1999:2013 Table D.2 Median NIPTS, 4 kHz, 90 dB, 20 yr 13 dB (+/-0.5 dB) 12.9 dB -0.057 dB
ISO 1999:2013 Table D.2 Worst-10 % NIPTS, 4 kHz, 90 dB, 20 yr 18 dB (+/-0.5 dB) 17.8 dB -0.239 dB
ISO 1999:2013 Table D.4 Worst-10 % NIPTS, 3 kHz, 100 dB, 40 yr 60 dB (+/-0.5 dB) 59.8 dB -0.172 dB
Multiple-shock whole-body vibration (ISO 2631-5): 100% (6/6)
Standard Quantity Expected (norm) Computed Δ Status
ISO 2631-5:2018 Formula 3 Daily acceleration dose, 5 x 40 m/s2 peaks 55.97 m/s2 (+/-0.01 m/s2) 55.97 m/s2 -0.002 m/s2
ISO 2631-5:2018 Formula C.3 Stress variable R, Annex C male example 1.22 (+/-0.01) 1.22 0
ISO 2631-5:2018 Formula C.5 Injury probability, Annex C male example 0.37 (+/-0.01) 0.37 -0.003
ISO 2631-5:2018 Annex C NOTE 5 Compressive stress Sd, female example 1.4 MPa (+/-0.01 MPa) 1.4 MPa -0.001 MPa
ISO 2631-5:2018 Annex C NOTE 5 Stress variable R, female example 0.97 (+/-0.01) 0.96 -0.008
ISO 2631-5:2018 Formula 1 vs Annex D Table D.1 Seat-to-spine transfer vs the 256 Hz digital filter (0,5-80 Hz) max abs(Formula 1 - filter) ≤ 0,04 0.001 0.001
Sound absorption in enclosed spaces (EN 12354-6): 100% (2/2)
Standard Quantity Expected (norm) Computed Δ Status
EN 12354-6:2003 Formula 1 Equivalent absorption area, Annex E bare room 2.26 m2 (+/-0.01 m2) 2.26 m2 0.003 m2
EN 12354-6:2003 Formula 5 Reverberation time, Annex E bare room 2.1 s (+/-0.1 s) 2.1 s 0.003 s
Prominent discrete tones (ECMA-418-1): 100% (2/2)
Standard Quantity Expected (norm) Computed Δ Status
ECMA-418-1:2024 Clause 10 Formula (2) Critical band at 1 kHz (f1,c / f2,c / dfc) dfc 162.2 Hz (+/-0.05 Hz); edges 922.2-1084.4 Hz dfc 162.22 Hz; edges 922.2-1084.4 Hz 0.017 Hz
ECMA-418-1:2024 Clause 11.6 Formula (14) Proximity spacing dfprox at 150 / 850 Hz 23 Hz @ 150 Hz; 63.8 Hz @ 850 Hz (+/-0.5 Hz) 23.0 Hz; 63.8 Hz +0.004; +0.044 Hz
Tonal audibility (ISO/PAS 20065): 100% (11/11)
Standard Quantity Expected (norm) Computed Δ Status
ISO/PAS 20065:2016 Formulae (12)-(14) Audibility at 137.3 Hz, Annex E spectrum 1 4.99 dB (+/-0.05 dB) 5.01 dB 0.022 dB
ISO/PAS 20065:2016 Formula (13) Masking index av at 137.3 / 592.2 Hz -2.02 dB @ 137.3 Hz; -2.4 dB @ 592.2 Hz (+/-0.005 dB) -2.017 dB; -2.400 dB +0.003; +0.000 dB
ISO/PAS 20065:2016 Formula (20) Mean audibility of the five spectra, Annex E 6.96 dB (+/-0.05 dB) 6.98 dB 0.018 dB
ISO/PAS 20065:2016 Formula (6) Mean narrow-band level LS from spectrum, Table E.1 49.22 dB (+/-0.02 dB) 49.22 dB -0.001 dB
ISO/PAS 20065:2016 Clause 6 Extended uncertainty U of the 137.3 Hz tone, Table E.2 2.79 dB (+/-0.02 dB) 2.8 dB 0.006 dB
ISO/PAS 20065:2016 Formulae (28)-(29) Extended uncertainty of the mean audibility, Annex E Step 4 1.38 dB (+/-0.01 dB) 1.38 dB -0.003 dB
ISO/PAS 20065:2016 Formula (8) Tone level LT from spectrum, Table E.1 67.96 dB (+/-0.02 dB) 67.96 dB -0.005 dB
ISO/PAS 20065:2016 Clause 5.3.8 Tone detection over the spectrum, Table E.1 tones at [118.4, 137.3, 158.8] Hz tones at [118.4, 137.3, 158.8] Hz exact
ISO/PAS 20065:2016 Clause 5.3.8 Step 3 Same-band FG combination inside analyze_spectrum, Table E.2 row 2 FG 72.15 dB (+/-0.02 dB) 72.15 dB -0.002 dB
ISO/PAS 20065:2016 Formula (17) Multi-tone FG combination, Table E.1 72.15 dB (+/-0.02 dB) 72.15 dB -0.002 dB
ISO/PAS 20065:2016 Formulae (18)/(19) Two-tone separation fD (DIN 45681 Annex J), 137.3 / 212 Hz fD(137.3)=24.09, fD(212)=21.0 Hz; Annex E pair combined fD(137.3)=24.09, fD(212)=21.00 Hz; Annex E pair combined exact
Psychoacoustic annoyance & fluctuation strength (Fastl & Zwicker): 100% (3/3)
Standard Quantity Expected (norm) Computed Δ Status
Fastl & Zwicker Eqs (16.2)-(16.4) Psychoacoustic annoyance, worked (N5,S,F,R) tuple 37.0478 (+/-0.001) 37.0477 0
Fastl & Zwicker Eq (10.2) Fluctuation strength of AM broadband noise (60 dB, m=1, 4 Hz) 3.6943 vacil (+/-0.001 vacil) 3.6943 vacil 0 vacil
Fastl & Zwicker Ch. 10 / Osses et al. 2016 Fluctuation-strength calibration: 1 kHz / 60 dB / m=1 / 4 Hz AM tone 1 vacil (+/-0.05 vacil) 1 vacil 0 vacil
Electroacoustics: distortion & frequency response: 100% (14/14)
Standard Quantity Expected (norm) Computed Δ Status
IEC 60268-3:2013 (14.12.3.2) THD (rel. total RMS, the R convention the clause defines) 0.112853 (+/-0.0001) 0.112853 0
Closed-form harmonic synthesis (THD_F convention) THD (rel. fundamental, the widespread datasheet convention) 0.113578 (+/-0.0001) 0.113578 0
IEC 60268-3:2013 (14.12.5) 2nd-order harmonic distortion d2 (rel. total) 0.099361 (+/-0.0001) 0.099361 0
IEC 60268-3:2013 (14.12.7.2 g) Modulation distortion d_m,2 (arithmetic sideband sum over U_2,f2) 0.16 (+/-0.0001) 0.16 0
IEC 60268-3:2013 (14.12.7.2 h) Modulation distortion d_m,3 (arithmetic sideband sum over U_2,f2) 0.08 (+/-0.0001) 0.08 0
IEC 60268-3:2013 (14.12.8.1 a) Difference-frequency distortion d_d,2 (over U_2,ref = 2 U_2,f2) 0.03 (+/-0.0001) 0.03 0
IEC 60268-3:2013 (14.12.8.1 b) Difference-frequency distortion d_d,3 (arithmetic product sum) 0.04 (+/-0.0001) 0.04 0
IEC 60268-3:2013 (14.12.10) Total difference-frequency distortion (8 kHz / 11.95 kHz tones) 0.03605551 (+/-0.0001) 0.03605551 0
ITU-R BS.468-4 Table 1 Weighting network response at the 6.3 kHz peak (14.12.11 network) 12.2 dB (+/-0 dB) 12.2 dB 0 dB
IEC 60268-3:2013 (14.12.9) DIM of the 15 kHz / 3.15 kHz signal (Table 2, 9 products) 0.168819 (+/-0.0001) 0.168819 0
Bendat & Piersol, Random Data 4e H1 recovers a known first-order IIR gain at 1 kHz 0.8954 (+/-2%) 0.8954 0
Bendat & Piersol, Random Data 4e Ordinary coherence = 1 for a noiseless LTI path 1 (+/-0.001) 1 0
AES17-2015 (6.4.2 / 5.2.7) Idle channel noise, 1 kHz -20 dBFS tone (CCIR-RMS -5.63 dB offset) -25.63 dB (+/-0.01 dB) -25.63 dB 0 dB
AES17-2015 (6.4.1) Dynamic range, full-scale reference over a -40 dBFS residual at 2 kHz 40 dB (+/-0.6 dB) 40.41 dB 0.414 dB
Calibrated spectral analysis (Bendat & Piersol): 100% (6/6)
Standard Quantity Expected (norm) Computed Δ Status
Bendat & Piersol, Random Data 4e Eq. (5.67) White-noise autospectral density = sigma^2/(fs/2) 0.000977 (+/-3%) 0.000982 0
Bendat & Piersol, Random Data 4e Eq. (8.158) PSD random error = 1/sqrt(nd) (Monte Carlo, 100 seeded records) 0.1768 (+/-6%) 0.1764 0
Bendat & Piersol, Random Data 4e Eq. (8.163) 95% chi-square confidence interval coverage (Monte Carlo) 0.95 (+/-0.025) 0.94 -0.01
Bendat & Piersol, Random Data 4e Eqs. (9.55)/(6.39) Coherent output spectrum of a known-SNR path: gamma^2 = SNR/(1+SNR) 0.7191 (+/-0.03) 0.7255 0.006
Closed-form power-law slope (10*lg(2) dB/octave per unit exponent) Pink-noise PSD slope over 20 Hz - 20 kHz, dB/octave -3.0103 dB/oct (+/-0.05 dB/oct) -3.0116 dB/oct -0.001 dB/oct
Constant-power 1/n-octave kernel (closed form) 1/3-octave smoothed line level = Pdf/(f0(2^(1/6)-2^(-1/6))) 0.021592 (+/-1e-07%) 0.021592 0
Correlation, time delay and envelope (B&P / Knapp & Carter): 100% (7/7)
Standard Quantity Expected (norm) Computed Δ Status
Bendat & Piersol, Random Data 4e Eq. (5.21) Cross-correlation peak of a 16-sample pure delay, samples 16 (+/-0.001) 16 0
Knapp & Carter 1976, Table I (PHAT) + sub-sample interpolation GCC-PHAT estimate of an exact 12.25-sample fractional delay, samples 12.25 (+/-0.005) 12.2483 -0.002
Bendat & Piersol, Random Data 4e Eq. (5.101) Cross-spectrum phase-slope estimate of the same fractional delay 12.25 (+/-0.001) 12.2498 0
Bendat & Piersol, Random Data 4e Eq. (8.120) BLWN autocorrelation coefficient at 3 samples vs sin(2piBt)/(2piBt) -0.1559 (+/-0.02) -0.1666 -0.011
Bendat & Piersol, Random Data 4e Example 8.5 Random error of the correlation peak: B=100 Hz, T=5 s, M/S=N/S=10 0.35 (+/-0.001) 0.3493 -0.001
Bendat & Piersol, Random Data 4e Table 13.1 Hilbert transform of cos recovers sin: max interior error 0 (+/-0) 0 0
Bendat & Piersol, Random Data 4e Eq. (13.27) Envelope of an AM waveform recovers 1 + mcos(2pifm*t) exactly 0 (+/-0) 0 0
Underwater acoustics (ISO 18405/17208/18406): 100% (6/6)
Standard Quantity Expected (norm) Computed Δ Status
ISO 18405:2017 / ISO 18406 Formula 7 Sound pressure level of a synthetic tone, dB re 1 µPa 123.0103 (+/-0.0001) 123.0103 0
ISO 18405:2017 / ISO 18406 Formulae 3-4 Sound exposure level of a 2 s tone, dB re 1 µPa²·s 120 (+/-0.001) 120 0
ISO 18406:2017 (6.4.2.1.3) Peak sound pressure level of a known waveform, dB re 1 µPa 129.5424 (+/-0.0001) 129.5424 0
ISO 17208-1:2016 Radiated noise level from RMS pressure and distance, dB re 1 µPa·m 46.0206 (+/-0.0001) 46.0206 0
ISO 17208-2:2019 (Formula 3) Lloyd's-mirror surface correction ΔL at a known k·d_s -3.5211 (+/-0.0001) -3.5211 0
ISO 18406:2017 (Formulae 8-9) Cumulative SEL of N identical strikes = SEL_ss + 10·lg(N) 196.9897 (+/-0) 196.9897 0
Underwater sound propagation (transmission loss): 100% (15/15)
Standard Quantity Expected (norm) Computed Δ Status
Mackenzie (1981) nine-term equation Speed of sound at 25 °C, 35 ‰, 1000 m (canonical check value), m/s 1550.744 m/s (+/-0.01 m/s) 1550.744 m/s 0 m/s
UNESCO/Chen-Millero vs Mackenzie Sound-speed agreement at 10 °C, 35 ‰, 1000 m (cross-model), m/s 1506.264 m/s (+/-1 m/s) 1506.524 m/s 0.261 m/s
Del Grosso (1974) vs Mackenzie Sound-speed agreement at 10 °C, 35 ‰, 1000 m (cross-model), m/s 1506.264 m/s (+/-1 m/s) 1506.313 m/s 0.049 m/s
Spherical spreading 20·lg(R) Geometrical spreading loss at R = 1000 m, dB 60 dB (+/-0 dB) 60 dB 0 dB
Thorp (1967) absorption Volume absorption α at 10 kHz (cold deep water), dB/km 1.1498 dB/km (+/-0 dB/km) 1.1498 dB/km 0 dB/km
Ainslie-McColm (1998) vs Francois-Garrison (1982) Absorption agreement at 10 kHz, 10 °C, 35 ‰, 0 m, pH 8, dB/km 0.9626 dB/km (+/-0.0963 dB/km) 0.9866 dB/km 0.024 dB/km
Francois-Garrison (1982) Part II Table IV Absorption α at 100 kHz, 10 °C, 35 ‰, 0 m, pH 8 (printed value), dB/km 33.6 dB/km (+/-0.05 dB/km) 33.63 dB/km 0.03 dB/km
Del Grosso refit (Wong-Zhu 1995 Table IV) c(t90 = 20 °C, S = 35, P = 500 bar) vs the printed check table, m/s 1603.679 m/s (+/-0.001 m/s) 1603.679 m/s 0 m/s
Wales-Heitmeyer (2002) ensemble spectrum Merchant-ship source PSD at 100 Hz (printed equation), dB re 1 µPa²/Hz 158.45 dB (+/-0.001 dB) 158.45 dB 0 dB
Passive sonar equation (Urick/Etter) Figure of merit SL − (NL − DI) − DT, dB 85 dB (+/-0 dB) 85 dB 0 dB
Seabed reflection (Rayleigh, normal incidence) Bottom loss at 90° grazing, sand ρ=1900 c=1650 over water, dB 9.0506 dB (+/-0 dB) 9.0506 dB 0 dB
Wenz wind noise (rule of fives) Wind spectrum level at 1 kHz, 5 kn (canonical anchor), dB re 1 µPa²/Hz 51.0206 dB (+/-0.0001 dB) 51.0206 dB 0 dB
Mellen thermal noise Thermal spectrum level at 50 kHz, 16.85 °C (physical), dB re 1 µPa²/Hz 19.3426 dB (+/-0 dB) 19.3426 dB 0 dB
JOMOPANS-ECHO ship source level Bulker V=13.5 kn L=211 m band level at 1 kHz (File S1 oracle), dB re 1 µPa m 161.394 dB (+/-0.01 dB) 161.394 dB 0 dB
UNESCO sound speed (EOS-80 canonical value) SVEL(S = 40, T68 = 40 °C, P = 1000 bar) vs Fofonoff & Millard 1983, m/s 1731.995 m/s (+/-0.02 m/s) 1732.004 m/s 0.009 m/s
Underwater numerical propagation (modes / rays / PE): 100% (4/4)
Standard Quantity Expected (norm) Computed Δ Status
Normal modes vs ideal waveguide Fundamental horizontal wavenumber kr1 at 20 Hz, 100 m (analytic), rad/m 0.077662 rad/m (+/-0.0001 rad/m) 0.077662 rad/m 0 rad/m
Normal modes vs image-source oracle Absolute TL at 1 km in the ideal waveguide (converged image sum), dB 48.238 dB (+/-0.02 dB) 48.239 dB 0.001 dB
Ray tracing vs linear gradient Turning depth of a 10° ray, c = 1500 + 0.05z (circular arc), m 462.8 m (+/-1 m) 462.8 m 0 m
Parabolic equation vs free field PE transmission loss at 2 km, homogeneous medium (spherical spreading), dB 66.021 dB (+/-0.1 dB) 66.021 dB 0 dB
Aircraft noise (ICAO Annex 16 / IEC 61265): 100% (14/14)
Standard Quantity Expected (norm) Computed Δ Status
ECAC Doc 29 noise fraction (half path) Finite-segment correction ΔF for a perpendicular foot at the segment start, dB -3.0103 dB (+/-0.001 dB) -3.0103 dB 0 dB
ECAC Doc 29 single-event chain SEL of a long level flyover vs the infinite-path limit LE∞ + ΔI − Λ, dB 83.444 dB (+/-0.01 dB) 83.444 dB 0 dB
ECAC Doc 29 impedance adjustment (standard atmosphere) Acoustic-impedance adjustment of NPD data at 15 °C / 101.325 kPa (Eq. 4-6/4-7), dB 0.074 dB (+/-0.0005 dB) 0.0741 dB 0 dB
ECAC Doc 29 reference workbook (segment Λ) Lateral attenuation of a climbing segment vs the ECAC Vol 3 Part 1 workbook, dB 6.3769 dB (+/-0.01 dB) 6.3769 dB 0 dB
ECAC Doc 29 start-of-roll directivity (jet) ΔSOR behind a takeoff ground-roll segment vs the Vol 3 Part 1 workbook, dB 0.3196 dB (+/-0.01 dB) 0.3196 dB 0 dB
ECAC Doc 29 start-of-roll directivity (turboprop) ΔSOR behind a takeoff ground-roll segment (turboprop, Eq. 4-24b), dB 1.0943 dB (+/-0.01 dB) 1.0944 dB 0 dB
ECAC Doc 29 workbook event assembly (JETFDS/R03, behind SOR) Energy sum of the reference per-segment SELs vs the B-1 event total, dB 74.73 dB (+/-0.01 dB) 74.733 dB 0.003 dB
SAE ARP 5534 band-attenuation continuity SAE-Method δ_B at the 150 dB branch split (Eq. 7 vs Eq. 8), dB 123.95 dB (+/-0.01 dB) 123.953 dB 0.003 dB
ECAC Doc 29 NPD interpolation Log-linear NPD level at the log-midpoint distance (Eq. 4-4), dB 97 dB (+/-0 dB) 97 dB 0 dB
SAE ARP 5534 pure-tone coefficient (ISO 9613-1) Mid-band α at 1 kHz, 25 °C, 70 % RH, 101.325 kPa, dB/m 0.006186 dB/m (+/-0 dB/m) 0.006186 dB/m 0 dB/m
ICAO Annex 16 Vol. I App. 2 Table A2-3 Perceived noisiness at SPL(b), 1 kHz band, in noys 1 (+/-0) 1 0
ICAO Doc 9501 ETM Vol. I Table 3-7 Tone correction of the turbofan example, dB 2 (+/-0) 2 0
ICAO Doc 9501 ETM Vol. I Table 4-4 Integrated-method reference EPNL, EPNdB 92.619 EPNdB (+/-0.01 EPNdB) 92.619 EPNdB 0 EPNdB
IEC 61265:1995 Table 1 Directional-response tolerance at 4 kHz / 90°, dB 2 dB (+/-0 dB) 2 dB 0 dB
Rotorcraft noise (ECAC Doc 32 / NORAH2): 100% (12/12)
Standard Quantity Expected (norm) Computed Δ Status
ECAC Doc 32 atmospheric attenuation (Table 4) ΔLa over a 1 km excess path at 1 kHz vs the NORAH2 guidance Table 4, dB 6.3 dB (+/-0.2 dB) 6.186 dB -0.114 dB
ECAC Doc 32 spherical spreading ΔLs at ten times the 60 m hemisphere reference distance (Eq. 24), dB -20 dB (+/-0 dB) -20 dB 0 dB
ECAC Doc 32 ground effect (rigid limit) ΔLg over a rigid surface at grazing incidence tends to +6 dB (Eq. 29), dB 6 dB (+/-1 dB) 6 dB 0.002 dB
ECAC Doc 32 propagation chain (NORAH2 prototype) LA of a single-hemisphere emission vs the NORAH2 prototype single-event history (R22 approach, 223.66 m slant), dB(A) 55.87 dB(A) (+/-0.1 dB(A)) 55.886 dB(A) 0.016 dB(A)
ECAC Doc 32 flight-condition interpolation (NORAH2 Eq. 8) Distance-scaled triangle blend of three uniform hemispheres, hand-checked, dB 97.0367 dB (+/-0.001 dB) 97.0364 dB 0 dB
ECAC Doc 32 flight-path kinematics (Eq. 17) Airspeed of a straight climbing track, 40 m/s ground speed at a 5° path angle, m/s 40.15279 m/s (+/-0.0001 m/s) 40.15279 m/s 0 m/s
ECAC Doc 32 retarded time (Eq. 22) Recorded-time delay at 100 m slant distance, r/c with c = 346.1 m/s, s 0.288934 s (+/-0.00001 s) 0.288934 s 0 s
ECAC Doc 32 single event (Eq. 27) SEL − LASmax of a constant-speed level flyover, 10·lg(π·d/V) closed form, dB 7.982 dB (+/-0.1 dB) 7.942 dB -0.04 dB
NORAH2 guidance mean ground plane (Eq. 36-40) Intercept of the plane fitted to a symmetric 20 m roofline, hand-checked, m 10 m (+/-0 m) 10 m 0 m
NORAH2 guidance mean flow resistivity (Eq. 41) Log-average of equal 1e4 and 1e6 Pa·s/m2 halves, hand-checked, Pa·s/m2 100000 Pa·s/m² (+/-0 Pa·s/m²) 100000 Pa·s/m² 0 Pa·s/m²
NORAH2 guidance diffraction at grazing (Eq. 42) Pure diffraction with the edge on the line of sight, 10·lg 3, dB 4.7712 dB (+/-0.0001 dB) 4.7712 dB 0 dB
NORAH2 guidance screening path difference (§A.4.5) Rubber-band delta over a 40 m hill, hand-checked geometry, m 4.2848 m (+/-0 m) 4.2848 m 0 m
Wind-turbine noise (IEC 61400-11): 100% (3/3)
Standard Quantity Expected (norm) Computed Δ Status
IEC 61400-11:2012 Formula 30 Critical bandwidth about a 500 Hz tone, Hz 117.255 Hz (+/-0 Hz) 117.255 Hz 0 Hz
IEC 61400-11:2012 Formula 26 Apparent sound power level of a single band, dB re 1 pW 148.5139 dB (+/-0.0001 dB) 148.5139 dB 0 dB
IEC 61400-11:2012 Formulae 31-34 Tonal audibility of a synthetic clean tone, dB 16.38 dB (+/-0.06 dB) 16.38 dB -0.001 dB
Porous & multilayer absorbers (Mechel / Bies / Cox & D'Antonio): 100% (10/10)
Standard Quantity Expected (norm) Computed Δ Status
Bies 5e App. D Table D.1 / Mechel 2e G.11 (2) Delany-Bazley normalised Zc at X = 0.1, real part 1.3241 (+/-0) 1.3241 0
Bies 5e App. D Table D.1 / Mechel 2e G.11 (2) Delany-Bazley normalised Zc at X = 0.1, imaginary part -0.4694 (+/-0) -0.4694 0
Miki 1990 Eqs. (30)-(34) Miki normalised wavenumber at f/sigma = 0.1, real part 1.4523 (+/-0) 1.4523 0
Johnson et al. 1987 / Cox & D'Antonio 3e Eq. (6.19) JCA static viscous limit j w rho_e -> sigma, Pa s/m2 20000 Pa s/m2 (+/-0.01%) 20000 Pa s/m2 0 Pa s/m2
Mechel 2e Sect. D.3 Eq. (1) Hard-backed layer: TMM vs -j Zc cot(kd), max rel deviation 0 (+/-0) 0 0
Lossless-layer limit (Mechel 2e Sect. D.3-D.4) Air cavity over a rigid wall at lambda/4: alpha 0 (+/-0) 0 0
Mechel 2e Sect. D.5 Maximum statistical absorption of a locally reacting plane 0.951 (+/-0.001) 0.951 0
Cox & D'Antonio 3e Eq. (7.9) Membrane resonance 60/sqrt(m d), m = 5 kg/m2, d = 5 cm, Hz 120 Hz (+/-2%) 119.85 Hz -0.15 Hz
Maa 1998 Fig. 5 / Cox & D'Antonio 3e Fig. 7.28 Microperforated panel (d=t=0.2 mm, b=2.5 mm, D=6 cm): peak alpha 0.95 (+/-0.05) 0.956 0.006
Maa 1998 Eqs. (5a)/(10) MPP peak absorption vs 4r/(1+r)^2 with Maa's printed resistance 4r/(1+r)^2 = 0.949 0.956 0.007
Program loudness (ITU-R BS.1770 / EBU R 128): 100% (8/8)
Standard Quantity Expected (norm) Computed Δ Status
ITU-R BS.1770-5 Annex 1 997 Hz sine at 0 dB FS on the left channel, LKFS -3.01 LKFS (+/-0.01 LKFS) -3.01 LKFS 0 LKFS
EBU Tech 3341:2023 Table 1 case 1 Integrated loudness of the -23 dBFS stereo sine, LUFS -23 LUFS (+/-0.1 LUFS) -22.99 LUFS 0.007 LUFS
EBU Tech 3341:2023 Table 1 case 5 Gated integrated loudness of the -26/-20/-26 dBFS steps, LUFS -23 LUFS (+/-0.1 LUFS) -22.98 LUFS 0.021 LUFS
EBU Tech 3341:2023 Table 1 case 6 Integrated loudness of the 5.0-channel sine (Table 3 weights), LUFS -23 LUFS (+/-0.1 LUFS) -23.02 LUFS -0.016 LUFS
EBU Tech 3341:2023 Table 1 case 15 True-peak level of the fs/4 sine at 0.5 FFS, dBTP -6 dBTP (+0.2/-0.4 dB) -6.02 dBTP -0.015 dBTP
EBU Tech 3341:2023 Table 1 case 19 True-peak level of the fs/4 sine at 1.41 FFS, dBTP 3 dBTP (+0.2/-0.4 dB) 3 dBTP 0.001 dBTP
EBU Tech 3342:2023 Table 1 case 1 Loudness range of the -20/-30 dBFS tone steps, LU 10 LU (+/-1 LU) 10 LU 0 LU
EBU Tech 3342:2023 Table 1 case 3 Loudness range of the -40/-20 dBFS tone steps, LU 20 LU (+/-1 LU) 20 LU 0 LU
2D FDTD wave simulation (Attenborough & Van Renterghem 2021, Ch. 4): 100% (2/2)
Standard Quantity Expected (norm) Computed Δ Status
Rigid rectangular box eigenfrequency Mode (1,1) of a 1.0 x 0.7 m rigid box, f = (c/2)*sqrt(1/lx^2 + 1/ly^2), Hz 299.06 Hz (+/-1.5 Hz) 298.91 Hz -0.153 Hz
Free-field pulse arrival delay Probe-to-probe delay of a pulse over 0.6 m of air, (r2 - r1)/c, ms 1.749 ms (+/-0.05 ms) 1.756 ms 0.007 ms
Swept-sine distortion & phase utilities (Farina / Novak): 100% (7/7)
Standard Quantity Expected (norm) Computed Δ Status
Farina 2000 / Novak et al. 2015 (Chebyshev identity) 3rd-harmonic response H3 magnitude of a cubic polynomial, re a3/4 0.05 (+/-0.0005) 0.05001 0
Novak et al. 2015, JAES 63(10), Eqs. 18/49 Synchronized-sweep phase of H3 (Chebyshev: -sin(3wt)), rad 3.1416 rad (+/-0.005 rad) 3.1411 rad 0 rad
Farina 2000, AES 108th Conv. (THD from one sweep) THD(1 kHz) of the polynomial vs sqrt((a2/2)^2+(a3/4)^2)/(1+3a3/4) 0.06149 (+/-0.001) 0.06159 0
Farina 2000 (distortion rejected from the linear IR) THD floor of a purely linear path (gain 0.5), max over 100-2000 Hz 0 (+/-0.001) 0.00033 0
Bendat & Piersol, Random Data 4e Sec. 13.1.4 (Hilbert relation) Min-phase reconstruction of a strictly min-phase biquad, max err, rad 0 rad (+/-0 rad) 0 rad 0 rad
First-order allpass closed form (1-a^2)/(1+2a cos w+a^2) Group delay of the a = 0.5 allpass at w = pi/2, samples 0.6 (+/-0.00001) 0.6 0
All-pass decomposition of a pure latency (B&P Sec. 13.1.4) Excess group delay of a biquad delayed 7.25 samples, samples 7.25 (+/-0) 7.25 0
Spherical ground & barriers (Attenborough / Salomons / Bies): 100% (6/6)
Standard Quantity Expected (norm) Computed Δ Status
Attenborough 2e Eq. (2.40c) (spherical Q, hard-ground limit) abs(Q) as Z grows large (Rp -> 1 so (1 - Rp) -> 0 and Q -> 1) 1 (+/-0.000001) 1 0
Salomons 2001 Sec. 3.4 (two-ray field over a rigid ground) dL enhancement at small path difference (constructive, +6 dB) 6.0206 dB (+/-0.1 dB) 6.0205 dB 0 dB
Salomons 2001 Eq. (D.59) (plane-wave Rp, grazing incidence) Re(Rp) at grazing (hs, hr -> 0, cos(theta) -> 0 so Rp -> -1) -1 (+/-0.001) -1 0
Bies 5e Eq. (5.138) (Kurze-Anderson, N -> 0) Barrier attenuation at the shadow boundary N = 0 5 dB (+/-0 dB) 5 dB 0 dB
Bies 5e Eq. (5.138) (Kurze-Anderson, large-N slope) Delta(N=10) - Delta(N=1) vs the 10 lg(10) = 10 dB decade growth 10 dB (+/-0.5 dB) 9.8845 dB -0.116 dB
Attenborough 2e Eqs. (9.19)-(9.20) (rigid half-plane, shadow boundary) Exact thin-screen insertion loss at grazing (field halved, 6 dB) 6.0206 dB (+/-0.6 dB) 5.7932 dB -0.227 dB
Panel & aperture sound insulation (Bies / Hopkins / Cremer): 100% (11/11)
Standard Quantity Expected (norm) Computed Δ Status
Bies 5e Eq. 7.40 (mass law) 6 dB per octave (500 -> 1000 Hz) 6.0206 dB (+/-0.01 dB) 6.02 dB -0.001 dB
Bies 5e Eq. 7.40 (mass law) 6 dB per doubling of mass 6.0206 dB (+/-0.01 dB) 6.02 dB -0.001 dB
Bies 5e Eq. 7.42 (field incidence) One-third-octave correction 5.5 dB 5.5 dB (+/-0.001 dB) 5.5 dB 0 dB
Hopkins Eq. 2.201 / Bies Eq. 7.3 Coincidence frequency, 6 mm glass 2079 Hz (+/-3%) 2107.3639 Hz 28.364 Hz
Cremer Table 5.1 Thin-plate point impedance Z = 8 sqrt(B' m'') 2529.8221 N.s/m (+/-0 N.s/m) 2529.8221 N.s/m 0 N.s/m
Cremer Table 5.1 Infinite-beam mobility phase -45 deg -45 deg (+/-0 deg) -45 deg 0 deg
Hopkins Eq. 2.229 (Leppington/Maidanik) Radiation efficiency at f = 2 fc 1.4142 (+/-0) 1.4142 0
Bies Eq. 7.62 / Hopkins Eq. 4.73 Mass-air-mass resonance f0, empty cavity 76.9484 Hz (+/-0.5%) 76.8521 Hz -0.096 Hz
Bies Eq. 7.64 (double wall) Below f0 = mass law of the combined mass 11.6144 dB (+/-0 dB) 11.6144 dB 0 dB
Hopkins Eq. 4.92 (composite) 1 % open area caps R at 10 lg(S/Sa) 20 dB (+/-0.05 dB) 19.9996 dB 0 dB
Hopkins Eq. 4.99/4.101 (Gomperts slit) Transmission maximum at first resonance 1544.9615 Hz (+/-15 Hz) 1542.9615 Hz -2 Hz
Atmospheric refraction (Salomons rays / GFPE): 100% (3/3)
Standard Quantity Expected (norm) Computed Δ Status
Salomons Sec. 4.4 (ray turning height, linear profile) Turning height of a 10 deg ray vs Rc(1 - cos theta0) (circular arc), m 26.457 m (+/-0.1 m) 26.457 m 0 m
Salomons Eq. (3.4) (GFPE vs spherical-wave ground effect, homogeneous) PE relative level at 500 m over grassland vs Weyl-Van der Pol, dB -13.919 dB (+/-0.5 dB) -13.842 dB 0.077 dB
Salomons Eq. (3.4) (GFPE hard ground vs two-ray, homogeneous) PE relative level at 500 m over a rigid ground vs the coherent two-ray, dB 5.997 dB (+/-0.6 dB) 5.593 dB -0.405 dB
Electroacoustics: 100% (6/6)
Standard Quantity Expected (norm) Computed Δ Status
Beranek & Mellow 2e Eq. (13.117) Piston resistance R1(x) = 1 - 2 J1(x)/x at x = 2ka = 2 0.423275 (+/-0.00001) 0.423275 0
Beranek & Mellow 2e Eq. (13.118) Piston reactance X1(x) = 2 H1(x)/x at x = 2ka = 2 0.646764 (+/-0.00001) 0.646764 0
Beranek & Mellow 2e Eq. (13.117) (low-frequency limit) R1 -> (ka)^2/2 as ka -> 0 (x = 0.02, ka = 0.01) 0.00005 (+/-0.01%) 0.00005 0
Beranek & Mellow 2e Eq. (4.151) Radiation mass M = 8 rho a^3 / 3 (a = 0.1 m, rho = 1.206) 0.003216 kg (+/-0 kg) 0.003216 kg 0 kg
Beranek & Mellow 2e Eq. (13.102), Table 14.1 First directivity null at ka sin(theta) = 3.8317 (first zero of J1) 0 (+/-0.000001) 0 0
Beranek & Mellow 2e §4.19 (half-space baffle) Directivity index DI -> 10 lg 2 = 3.01 dB as ka -> 0 3.0103 dB (+/-0.001 dB) 3.0103 dB 0 dB
Industrial noise control: 100% (9/9)
Standard Quantity Expected (norm) Computed Δ Status
Bies 5e Eq. (8.111) Expansion-chamber peak TL = 10 lg[1 + (1/4)(m - 1/m)^2], m = 4 at kL = pi/2 6.5472 dB (+/-0 dB) 6.5472 dB 0 dB
Bies 5e Eq. (8.111) Expansion-chamber trough TL = 0 at kL = pi (chamber transparent) 0 dB (+/-0 dB) 0 dB 0 dB
Bies 5e Eq. (8.44) / Example 8.1 Quarter-wave tube tuning f = c/(4 l_e), l_e = 1.516 m -> 56.6 Hz 56.6 Hz (+/-0.1 Hz) 56.6 Hz 0.003 Hz
Bies 5e Eq. (8.46) Helmholtz resonance f0 = (c/2pi) sqrt(S/(l_e V)) (S=1e-4, l_e=0.02, V=1e-3) 122.067 Hz (+/-0 Hz) 122.067 Hz 0 Hz
Bies 5e Eq. (8.73) Side-branch TL = 20 lg abs(1 + rho c/(2 Sd Zb)) (QWT branch, closed form) 0.1638 dB (+/-0 dB) 0.1638 dB 0 dB
Bies 5e Eqs. (8.141)/(8.148) (four-pole insertion loss) Insertion loss = transmission loss for the anechoic reference Zs=Zr=rho c/S 6.2498 dB (= TL) 6.2498 dB 0 dB
Bies 5e Eq. (8.275) (Wells' plenum method) Plenum TL = -10 lg[S_out(cos0/pi r^2 + (1-a)/(Sw a))] (S_out=.1,r=1,Sw=20,a=.2) 12.8541 dB (+/-0 dB) 12.8541 dB 0 dB
Bies 5e Table 8.14 (ASHRAE end reflection, flush) Duct end reflection D = 200 mm at 125 Hz = 10 dB (table node) 10 dB (+/-0 dB) 10 dB 0 dB
Bies 5e Eqs. (7.103), (7.111) (enclosure, fully absorbing limit) Enclosure correction C -> 10 lg 0.3 = -5.23 dB as alpha_i -> 1 -5.2288 dB (+/-0.001 dB) -5.2288 dB 0 dB

Tests & coverage — 24912 tests, 0 failures (✅ all green)
Python Version Tests Failures Coverage Status
macos-latest-3.13 4152 0 96.1% ✅ Passed
macos-latest-3.14 4152 0 96.1% ✅ Passed
ubuntu-latest-3.13 4152 0 96.1% ✅ Passed
ubuntu-latest-3.14 4152 0 96.1% ✅ Passed
windows-latest-3.13 4152 0 96.1% ✅ Passed
windows-latest-3.14 4152 0 96.1% ✅ Passed

Conformance harness: scripts/conformance_report.py · full CI artifacts

… plots

Add a `language` keyword ("en" default, "es") to the `.plot()` methods of
every psychoacoustics, hearing and vibration result. Spanish renders the axis
labels, titles and legends in Spanish and switches the decimal separator to a
comma; the English output is unchanged.

- New `phonometry._i18n` module with the shared locale helpers (language
  validation, locale-aware number formatting and linear-axis tick localisation).
- Each `_plot` renderer gains a module-level string table and localises its
  fixed text; the `_i18n` helpers are imported lazily inside the functions so
  the render leaves keep no module-level domain imports.
- Per-domain tests covering a Spanish label and the unknown-language error.
- Regenerated the API reference for the new `.plot()` signatures.
@jmrplens
jmrplens force-pushed the feat/i18n-plots-psycho branch from 8814f70 to 02b8f4e Compare July 20, 2026 11:06
@jmrplens

Copy link
Copy Markdown
Owner Author

Thanks for the review. Applied in the latest push (after rebasing onto main, which now carries the improved localize_axes):

  • Redundant categorical-label "restore" blocks (gemini). Removed across hearing.py (STI, STOI, SII, occupational-exposure), psychoacoustics.py (annoyance, tone audibility) and vibration.py (weighted spectrum, daily exposure). localize_axes now installs a ScalarFormatter subclass only on axes still using the automatic formatter, so categorical band/task axes (a FuncFormatter from set_xticklabels) are left untouched and no longer need restoring.
  • Localize at creation, not after (gemini). Where the restore block also did the comma localization (plot_stoi, plot_tone_audibility), the tick labels are now built with decimal_comma at set_xticklabels time, so the comma-localized labels are set once and survive localize_axes.
  • S5778 (Sonar). Hoisted the result construction out of the pytest.raises block in the three new test_*_plot_i18n.py files so only the .plot() call can raise.

Verified: 814 domain tests pass, committed English figures are byte-identical, ruff and the package-architecture test are clean.

@sonarqubecloud

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/phonometry/_plot/hearing.py`:
- Around line 34-119: Move the shared localization lookup/fallback logic from
hearing.py’s _t helper into the existing _i18n.py module as a generic translate
helper accepting a strings table, key, and language. Update hearing.py’s _t and
the corresponding helper in psychoacoustics.py to delegate to translate while
preserving domain-specific _STRINGS tables and English fallback behavior.
- Around line 284-285: Translate the raw sex value before formatting both
localized plot titles: add or reuse a helper such as _sex and pass its result to
iso7029_title at src/phonometry/_plot/hearing.py lines 284-285 and htlan_title
at lines 359-362. Support the existing "male" and "female" values for English
and Spanish, preserving the raw domain values elsewhere.

In `@src/phonometry/_plot/vibration.py`:
- Around line 246-249: Update the EAV and ELV legend labels in the vibration
plotting code to use localized acronym strings from _STRINGS, mapping them to
the Spanish VLA and VLE translations while preserving the existing numeric
formatting and legend structure.
- Around line 252-256: Localize interpolated properties before rendering titles:
in the daily exposure title construction around kind and zone, pass
assessment.kind and assessment.zone through _t() using their corresponding
_STRINGS keys; likewise, in the injury_title construction, localize result.sex
through _t() before interpolation. Apply these changes at
src/phonometry/_plot/vibration.py lines 252-256 and 405 respectively.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 89db9545-4128-46f4-a990-fe6a5ec32c5d

📥 Commits

Reviewing files that changed from the base of the PR and between 50a195e and 02b8f4e.

📒 Files selected for processing (49)
  • CHANGELOG.md
  • site/src/content/docs/reference/api/hearing/noise-induced-hearing-loss.md
  • site/src/content/docs/reference/api/hearing/occupational-exposure.md
  • site/src/content/docs/reference/api/hearing/threshold.md
  • site/src/content/docs/reference/api/psychoacoustics/fluctuation-strength-ecma.md
  • site/src/content/docs/reference/api/psychoacoustics/fluctuation-strength.md
  • site/src/content/docs/reference/api/psychoacoustics/loudness-ecma.md
  • site/src/content/docs/reference/api/psychoacoustics/loudness-moore-glasberg-time.md
  • site/src/content/docs/reference/api/psychoacoustics/loudness-moore-glasberg.md
  • site/src/content/docs/reference/api/psychoacoustics/loudness-zwicker.md
  • site/src/content/docs/reference/api/psychoacoustics/psychoacoustic-annoyance.md
  • site/src/content/docs/reference/api/psychoacoustics/roughness-ecma.md
  • site/src/content/docs/reference/api/psychoacoustics/tonality-ecma.md
  • site/src/content/docs/reference/api/psychoacoustics/tone-audibility.md
  • site/src/content/docs/reference/api/speech/objective-intelligibility.md
  • site/src/content/docs/reference/api/speech/sii.md
  • site/src/content/docs/reference/api/speech/sti.md
  • site/src/content/docs/reference/api/vibration/human-vibration.md
  • site/src/content/docs/reference/api/vibration/mechanical-mobility.md
  • site/src/content/docs/reference/api/vibration/multiple-shock-vibration.md
  • site/src/content/docs/reference/api/vibration/radiation-efficiency.md
  • site/src/content/docs/reference/api/vibration/transfer-stiffness.md
  • src/phonometry/_plot/hearing.py
  • src/phonometry/_plot/psychoacoustics.py
  • src/phonometry/_plot/vibration.py
  • src/phonometry/hearing/noise_induced_hearing_loss.py
  • src/phonometry/hearing/objective_intelligibility.py
  • src/phonometry/hearing/occupational_exposure.py
  • src/phonometry/hearing/sii.py
  • src/phonometry/hearing/sti.py
  • src/phonometry/hearing/threshold.py
  • src/phonometry/psychoacoustics/fluctuation_strength.py
  • src/phonometry/psychoacoustics/fluctuation_strength_ecma.py
  • src/phonometry/psychoacoustics/loudness_ecma.py
  • src/phonometry/psychoacoustics/loudness_moore_glasberg.py
  • src/phonometry/psychoacoustics/loudness_moore_glasberg_time.py
  • src/phonometry/psychoacoustics/loudness_zwicker.py
  • src/phonometry/psychoacoustics/psychoacoustic_annoyance.py
  • src/phonometry/psychoacoustics/roughness_ecma.py
  • src/phonometry/psychoacoustics/tonality_ecma.py
  • src/phonometry/psychoacoustics/tone_audibility.py
  • src/phonometry/vibration/human_vibration.py
  • src/phonometry/vibration/mechanical_mobility.py
  • src/phonometry/vibration/multiple_shock_vibration.py
  • src/phonometry/vibration/radiation_efficiency.py
  • src/phonometry/vibration/transfer_stiffness.py
  • tests/hearing/test_hearing_plot_i18n.py
  • tests/psychoacoustics/test_psychoacoustics_plot_i18n.py
  • tests/vibration/test_vibration_plot_i18n.py

Comment on lines +34 to +119
#: EN/ES text for every fixed label, title and legend of this module. The
#: English entries are byte-for-byte the historical strings; ``_t`` returns
#: them unchanged for ``language="en"``.
_STRINGS: dict[str, dict[str, str]] = {
"freq_hz": {"en": "Frequency [Hz]", "es": "Frecuencia [Hz]"},
"band": {"en": "Band", "es": "Banda"},
"mti": {
"en": "Modulation transfer index MTI",
"es": "Índice de transferencia de modulación MTI",
},
"third_octave_band": {
"en": "One-third-octave band [Hz]",
"es": "Banda de tercio de octava [Hz]",
},
"mean_corr": {
"en": "Mean intermediate correlation",
"es": "Correlación intermedia media",
},
"spectral_corr": {
"en": r"Spectral correlation $d_m$",
"es": r"Correlación espectral $d_m$",
},
"analysis_segment": {"en": "Analysis segment", "es": "Segmento de análisis"},
"band_audibility": {"en": "Band audibility", "es": "Audibilidad de banda"},
"band_audibility_ai": {
"en": r"Band audibility $A_i$",
"es": r"Audibilidad de banda $A_i$",
},
"importance_weighted": {
"en": r"Importance-weighted $I_i A_i$ (scaled)",
"es": r"$I_i A_i$ ponderada por importancia (escalada)",
},
"median": {"en": "Median", "es": "Mediana"},
"median_n50": {"en": r"Median $N_{50}$", "es": r"Mediana $N_{50}$"},
"threshold_dev_18": {
"en": "Threshold deviation from age 18 [dB]",
"es": "Desviación del umbral respecto a 18 años [dB]",
},
"nipts_db": {"en": "NIPTS [dB]", "es": "NIPTS [dB]"},
"htla_age": {"en": "Age (HTLA, ISO 7029)", "es": "Edad (HTLA, ISO 7029)"},
"noise_nipts": {"en": "Noise (NIPTS)", "es": "Ruido (NIPTS)"},
"age_noise_htlan": {
"en": "Age + noise (HTLAN)",
"es": "Edad + ruido (HTLAN)",
},
"htl_level": {
"en": "Hearing threshold level [dB]",
"es": "Nivel del umbral de audición [dB]",
},
"a_weighted_level": {
"en": "A-weighted level [dB]",
"es": "Nivel ponderado A [dB]",
},
# Templates (``.format`` fields hold already-localised numbers).
"sti_title": {
"en": "IEC 60268-16 STI = {sti} (rating {rating})",
"es": "IEC 60268-16 STI = {sti} (calificación {rating})",
},
"stoi_title": {"en": "{name} = {v}", "es": "{name} = {v}"},
"sii_title": {"en": "ANSI S3.5 SII = {sii}", "es": "ANSI S3.5 SII = {sii}"},
"fractile": {"en": "Fractile {v}", "es": "Fractil {v}"},
"iso7029_title": {
"en": "ISO 7029 hearing threshold — {sex}, age {age}",
"es": "ISO 7029 umbral de audición — {sex}, edad {age}",
},
"nipts_title": {
"en": "ISO 1999 NIPTS — $L_{{EX,8h}}$ = {lex} dB, {years} yr",
"es": "ISO 1999 NIPTS — $L_{{EX,8h}}$ = {lex} dB, {years} años",
},
"htlan_title": {
"en": "ISO 1999 HTLAN — {sex}, age {age}, {lex} dB / {years} yr",
"es": "ISO 1999 HTLAN — {sex}, edad {age}, {lex} dB / {years} años",
},
"occupational_title": {
"en": ("ISO 9612 daily noise exposure — $L_{{EX,8h}}$ = "
"{lex} dB (U = {u} dB)"),
"es": ("ISO 9612 exposición diaria al ruido — $L_{{EX,8h}}$ = "
"{lex} dB (U = {u} dB)"),
},
}


def _t(key: str, language: str) -> str:
"""Look up the localised text for ``key`` (falls back to English)."""
entry = _STRINGS[key]
return entry.get(language, entry["en"])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial

Consider sharing the _t lookup helper via _i18n.py.

The entry.get(language, entry["en"]) pattern in _t (Line 116-119) is duplicated verbatim across plot modules (e.g. _plot/psychoacoustics.py also defines its own _t). Each module's _STRINGS table is naturally domain-specific, but the lookup/fallback logic itself could be a single generic helper in _i18n.py (e.g. translate(strings, key, language)) that every plot module reuses with its own dict.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/phonometry/_plot/hearing.py` around lines 34 - 119, Move the shared
localization lookup/fallback logic from hearing.py’s _t helper into the existing
_i18n.py module as a generic translate helper accepting a strings table, key,
and language. Update hearing.py’s _t and the corresponding helper in
psychoacoustics.py to delegate to translate while preserving domain-specific
_STRINGS tables and English fallback behavior.

Comment on lines +284 to +285
ax.set_title(_t("iso7029_title", language).format(
sex=result.sex, age=decimal_comma(f"{result.age:g}", language)))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Spanish titles leave sex untranslated ("male"/"female" literals in Spanish text).

Both plot_age_threshold's iso7029_title and plot_htlan's htlan_title format sex=result.sex directly into the title, but AgeThresholdResult.sex/HtlanResult.sex only ever hold the raw domain string "male"/"female" — never localized. For language="es" this renders e.g. "ISO 7029 umbral de audición — male, edad 60", mixing English into an otherwise Spanish title, contrary to the PR's goal of fully localized titles. The existing test (tests/hearing/test_hearing_plot_i18n.py) only checks a substring of the title, so it doesn't catch this.

  • src/phonometry/_plot/hearing.py#L284-L285: translate result.sex (e.g. via a small {"male": {"en": "male", "es": "hombre"}, "female": {...}} lookup similar to _t) before formatting iso7029_title.
  • src/phonometry/_plot/hearing.py#L359-L362: apply the same sex translation before formatting htlan_title.
🌐 Proposed fix sketch
+_SEX_LABELS: dict[str, dict[str, str]] = {
+    "male": {"en": "male", "es": "hombre"},
+    "female": {"en": "female", "es": "mujer"},
+}
+
+
+def _sex(value: str, language: str) -> str:
+    return _SEX_LABELS.get(value, {}).get(language, value)

Then use sex=_sex(result.sex, language) in both iso7029_title and htlan_title .format() calls.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ax.set_title(_t("iso7029_title", language).format(
sex=result.sex, age=decimal_comma(f"{result.age:g}", language)))
_SEX_LABELS: dict[str, dict[str, str]] = {
"male": {"en": "male", "es": "hombre"},
"female": {"en": "female", "es": "mujer"},
}
def _sex(value: str, language: str) -> str:
return _SEX_LABELS.get(value, {}).get(language, value)
📍 Affects 1 file
  • src/phonometry/_plot/hearing.py#L284-L285 (this comment)
  • src/phonometry/_plot/hearing.py#L359-L362
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/phonometry/_plot/hearing.py` around lines 284 - 285, Translate the raw
sex value before formatting both localized plot titles: add or reuse a helper
such as _sex and pass its result to iso7029_title at
src/phonometry/_plot/hearing.py lines 284-285 and htlan_title at lines 359-362.
Support the existing "male" and "female" values for English and Spanish,
preserving the raw domain values elsewhere.

Comment on lines +246 to +249
ax.axhline(eav, color=_C_SECONDARY, ls="--",
label="EAV = " + decimal_comma(f"{eav:g}", language))
ax.axhline(elv, color=_C_REFERENCE, ls="--",
label="ELV = " + decimal_comma(f"{elv:g}", language))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider localizing the EAV and ELV acronyms.

EAV (Exposure Action Value) and ELV (Exposure Limit Value) are English acronyms. In the official Spanish translation of Directive 2002/44/EC, these are typically referred to as VLA (Valor que da lugar a una acción) and VLE (Valor límite de exposición). You may want to fetch these from _STRINGS so the legend is fully localized.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/phonometry/_plot/vibration.py` around lines 246 - 249, Update the EAV and
ELV legend labels in the vibration plotting code to use localized acronym
strings from _STRINGS, mapping them to the Spanish VLA and VLE translations
while preserving the existing numeric formatting and legend structure.

Comment on lines 252 to +256
kind = str(assessment.kind).upper()
ax.set_title(
f"Directive 2002/44/EC daily {kind} exposure "
f"(A(8) = {float(result.a8):.2f} " rf"m/s$^2$, {assessment.zone})"
)
ax.set_title(_t("daily_exposure_title", language).format(
kind=kind, a8=format_number(float(result.a8), language, decimals=2),
zone=assessment.zone,
))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Localize interpolated string properties to prevent mixed-language output.

When localized string templates are populated with unlocalized properties, the resulting Spanish text contains untranslated English words. The affected properties should be mapped through _STRINGS using _t() before interpolation.

  • src/phonometry/_plot/vibration.py#L252-L256: localize assessment.kind (e.g., "hand-arm") and assessment.zone (e.g., "below action value") before passing them to the daily_exposure_title template.
  • src/phonometry/_plot/vibration.py#L405-L405: localize result.sex ("male" or "female") before passing it to the injury_title template.
📍 Affects 1 file
  • src/phonometry/_plot/vibration.py#L252-L256 (this comment)
  • src/phonometry/_plot/vibration.py#L405-L405
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/phonometry/_plot/vibration.py` around lines 252 - 256, Localize
interpolated properties before rendering titles: in the daily exposure title
construction around kind and zone, pass assessment.kind and assessment.zone
through _t() using their corresponding _STRINGS keys; likewise, in the
injury_title construction, localize result.sex through _t() before
interpolation. Apply these changes at src/phonometry/_plot/vibration.py lines
252-256 and 405 respectively.

@jmrplens
jmrplens merged commit 36dc226 into main Jul 20, 2026
25 checks passed
@jmrplens
jmrplens deleted the feat/i18n-plots-psycho branch July 20, 2026 11:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant