From 63218c52b378f1d546d235e48e6646e199db72b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20M=2E=20Requena=20Plens?= Date: Wed, 22 Jul 2026 23:51:34 +0200 Subject: [PATCH 1/3] Add noise-control performance reports via .report() Add a one-page PDF .report() fiche to the three noise_control result types, each laid out with a per-band table beside the result's own plot, a boxed single-number performance figure and an optional PASS/FAIL verdict: - EnclosureResult: machine-enclosure insertion loss (Bies, Hansen & Howard, section 7.4.2). The table lists the supplied panel transmission loss R, the interior build-up correction C and the net insertion loss IL = R - C; the boxed figure is the mean insertion loss with the external and internal surface areas. verbose=True adds the interior room constant column. A declared minimum passes when the mean meets it. - ReactiveSilencerResult: reactive-silencer transmission loss (Munjal Eq. (3.27); Bies sections 8.8-8.9). The table lists the transmission loss TL and, when end impedances were given, the insertion loss IL; the boxed figure is the mean transmission loss with the peak and the device kind. A declared minimum passes when the mean meets it. - HvacSpectrumResult: HVAC duct-noise spectrum (Bies Chapter 8; VDI 2081-1). A regenerated-noise spectrum boxes the A-weighted sound power level with the overall total (lower is better); an attenuation spectrum boxes the mean attenuation (more is better). verbose=True adds the A-weighting correction and A-weighted band-level columns. The three renderers share a two-panel skeleton in _report/_noise_control_fiche.py and reuse the sound-power table builder, band labels and header grid. Each accepts an optional metadata header, states its method basis and renders in English or Spanish. Register one committed example per fiche under .github/reports/, add structural and clean-room number-presence tests (EN and ES), and update the CHANGELOG and the regenerated API reference. --- .../enclosure_insertion_loss_example.pdf | Bin 0 -> 15116 bytes .../enclosure_insertion_loss_example.webp | Bin 0 -> 64912 bytes .github/reports/hvac_duct_noise_example.pdf | Bin 0 -> 16974 bytes .github/reports/hvac_duct_noise_example.webp | Bin 0 -> 63644 bytes .github/reports/reactive_silencer_example.pdf | Bin 0 -> 13606 bytes .../reports/reactive_silencer_example.webp | Bin 0 -> 61382 bytes CHANGELOG.md | 31 ++ scripts/generate_reports.py | 107 ++++++ .../reference/api/noise_control/enclosures.md | 46 +++ .../docs/reference/api/noise_control/hvac.md | 46 +++ .../reference/api/noise_control/silencers.md | 47 +++ src/phonometry/_report/_i18n.py | 41 +++ .../_report/_noise_control_fiche.py | 198 +++++++++++ src/phonometry/_report/enclosure.py | 206 +++++++++++ src/phonometry/_report/hvac.py | 323 ++++++++++++++++++ src/phonometry/_report/silencer.py | 204 +++++++++++ src/phonometry/noise_control/enclosures.py | 57 ++++ src/phonometry/noise_control/hvac.py | 58 ++++ src/phonometry/noise_control/silencers.py | 58 ++++ tests/noise_control/test_enclosure_report.py | 215 ++++++++++++ tests/noise_control/test_hvac_report.py | 193 +++++++++++ tests/noise_control/test_silencer_report.py | 177 ++++++++++ 22 files changed, 2007 insertions(+) create mode 100644 .github/reports/enclosure_insertion_loss_example.pdf create mode 100644 .github/reports/enclosure_insertion_loss_example.webp create mode 100644 .github/reports/hvac_duct_noise_example.pdf create mode 100644 .github/reports/hvac_duct_noise_example.webp create mode 100644 .github/reports/reactive_silencer_example.pdf create mode 100644 .github/reports/reactive_silencer_example.webp create mode 100644 src/phonometry/_report/_noise_control_fiche.py create mode 100644 src/phonometry/_report/enclosure.py create mode 100644 src/phonometry/_report/hvac.py create mode 100644 src/phonometry/_report/silencer.py create mode 100644 tests/noise_control/test_enclosure_report.py create mode 100644 tests/noise_control/test_hvac_report.py create mode 100644 tests/noise_control/test_silencer_report.py diff --git a/.github/reports/enclosure_insertion_loss_example.pdf b/.github/reports/enclosure_insertion_loss_example.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fbeae7759a191e484fee54233c10be3c0ad38770 GIT binary patch literal 15116 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 NTKI1OFp;Le{U6DeM{xiE literal 0 HcmV?d00001 diff --git a/.github/reports/enclosure_insertion_loss_example.webp b/.github/reports/enclosure_insertion_loss_example.webp new file mode 100644 index 0000000000000000000000000000000000000000..4873b79a734dbcc692fa7c22479c7231e4b9440d GIT binary patch literal 64912 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 E11}P#m;e9( literal 0 HcmV?d00001 diff --git a/.github/reports/hvac_duct_noise_example.pdf b/.github/reports/hvac_duct_noise_example.pdf new file mode 100644 index 0000000000000000000000000000000000000000..43640c70e3db785fb29a5e6684b34c84983b8116 GIT binary patch literal 16974 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

BoeqMLiD$*vIU{^*_c=4 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 p4`dm~pP%16_WXF|{qN52Bl{AZpSd|1ZtgRFD7w literal 0 HcmV?d00001 diff --git a/.github/reports/hvac_duct_noise_example.webp b/.github/reports/hvac_duct_noise_example.webp new file mode 100644 index 0000000000000000000000000000000000000000..86bc7ffe30a31aacc4d5b265eb7758f0bb181df2 GIT binary patch literal 63644 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

IutUqEPVZzY6fS42I4 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

$<|7fCTi;1z|u&#uDf|m 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

@zR?SP06uE?2wWYDbhcem#RYrbdh3##K; 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%0ABwI%351 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 YAdZ3lvp@9}*&D*&-oXD~hgj(U1IF!@_y7O^ literal 0 HcmV?d00001 diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ba31b0a..aee70466 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/). the metadata `requirement` adds a PASS/FAIL verdict (a higher SII passes). `verbose=True` adds the equivalent disturbance spectrum level `Di` column; `language="es"` renders the Spanish fiche. +- Noise-control performance reports via `.report()` on the three + `noise_control` result types, each a one-page PDF laid out with a per-band + table beside the result's own plot, a boxed single-number performance figure + and an optional PASS/FAIL verdict: + - `EnclosureResult.report()`: a machine-enclosure insertion-loss fiche (Bies, + Hansen & Howard, Engineering Noise Control 5th ed., section 7.4.2). The + per-band table lists the supplied panel transmission loss `R`, the interior + build-up correction `C` and the net insertion loss `IL = R - C`; the boxed + figure is the mean insertion loss over the analysis bands with the external + and internal surface areas. A declared minimum via the metadata + `requirement` passes when the mean insertion loss meets it (more is + better); `verbose=True` adds the interior room constant `R_i` column. + - `ReactiveSilencerResult.report()`: a reactive-silencer transmission-loss + fiche (Munjal, Acoustics of Ducts and Mufflers 2nd ed., Eq. (3.27); Bies, + Hansen & Howard, sections 8.8-8.9). The per-band table lists the + transmission loss `TL` and, when end impedances were supplied, the + insertion loss `IL`; the boxed figure is the mean transmission loss with + the peak transmission loss and the device kind. A declared minimum passes + when the mean transmission loss meets it (more is better). + - `HvacSpectrumResult.report()`: an HVAC duct-noise-spectrum fiche (Bies, + Hansen & Howard, Chapter 8; VDI 2081-1). A regenerated-noise spectrum boxes + the A-weighted sound power level `L_WA` (dB(A) re 1 pW) with the overall + unweighted total, and a declared limit passes at or below it (lower is + better); an attenuation spectrum boxes the mean attenuation, and a declared + minimum passes at or above it. `verbose=True` adds the A-weighting + correction and A-weighted band-level columns for a regenerated-noise + spectrum. + + All three accept an optional metadata header (client, equipment, test + environment, instrumentation, climate, date), state their method basis, and + render in English or Spanish (`language="es"`). - `StructureBornePowerResult.report()`: a one-page PDF structure-borne sound power characterization fiche for the power a piece of building service equipment injects into a reception plate (EN 15657:2018 reception-plate diff --git a/scripts/generate_reports.py b/scripts/generate_reports.py index 24503102..1697d3c5 100644 --- a/scripts/generate_reports.py +++ b/scripts/generate_reports.py @@ -2414,6 +2414,110 @@ def _sii_example() -> Tuple[object, ReportMetadata, str]: requirement=0.75, # SII = 0.851 >= 0.75 -> PASS (good audibility) ) return result, metadata, "ansi_s3_5_sii_example.pdf" +def _enclosure_example() -> Tuple[object, ReportMetadata, str]: + """Enclosure fiche: the insertion loss of a machine enclosure (Bies 7.4.2). + + A documented clean-room case combining a supplied octave-band panel + transmission loss R = [18, 22, 28, 33, 38, 42, 45] dB (a sheet-steel + enclosure) with an interior of mean absorption alpha_i = 0.30, external + surface area S_E = 24 m2 and internal surface area S_i = 30 m2. The interior + room constant R_i = S_i alpha_i / (1 - alpha_i) = 30 x 0.3 / 0.7 = 12.86 m2, + the build-up correction C = 10 lg(0.3 + S_E / R_i) = 10 lg(0.3 + 24/12.86) + = 3.4 dB and the net insertion loss IL = R - C (Bies, Hansen & Howard, + Engineering Noise Control 5th ed., Eqs. (7.103), (7.111)), giving a mean + insertion loss of 28.9 dB over the seven octave bands. The requirement is a + plausible minimum mean insertion loss the example clears (more is better). + """ + freqs = np.array([63, 125, 250, 500, 1000, 2000, 4000], dtype=float) + panel_r = np.array([18, 22, 28, 33, 38, 42, 45], dtype=float) + result = ph.enclosure_insertion_loss( + panel_r, 24.0, 30.0, 0.30, frequencies=freqs + ) + metadata = ReportMetadata( + specimen="Sheet-steel close-fitting machine enclosure", + client="Example client", + manufacturer="Example enclosures", + test_room="Machine hall, line 3 (example)", + instrumentation="Class 1 SLM (IEC 61672-1), octave bank", + measurement_standard="Bies & Hansen 7.4.2", + temperature=21.0, + relative_humidity=45.0, + pressure=101.2, + test_date="2026-07-22", + laboratory="Phonometry reference example", + operator="phonometry", + report_id="EXAMPLE-ENCLOSURE", + requirement=20.0, + ) + return result, metadata, "enclosure_insertion_loss_example.pdf" + + +def _silencer_example() -> Tuple[object, ReportMetadata, str]: + """Silencer fiche: the transmission loss of an expansion chamber (four-pole). + + A documented clean-room case: a simple expansion chamber of length L = 0.5 m + and area S_exp = 0.08 m2 between pipes of area S_duct = 0.01 m2 (area ratio + m = 8), sampled at the octave-band centres 63 Hz to 4 kHz by the plane-wave + four-pole method (Munjal, Acoustics of Ducts and Mufflers 2nd ed., Eq. + (3.27); Bies, Hansen & Howard, Engineering Noise Control 5th ed., Eq. + (8.111)). The transmission loss matches the closed form + TL = 10 lg[1 + (1/4)(m - 1/m)^2 sin^2(kL)], peaking near + 10 lg[1 + (1/4)(8 - 1/8)^2] = 12.2 dB, with a mean of 8.9 dB over the seven + bands. The requirement is a plausible minimum mean transmission loss the + example clears (more is better). + """ + freqs = np.array([63, 125, 250, 500, 1000, 2000, 4000], dtype=float) + result = ph.noise_control.silencers.expansion_chamber( + freqs, 0.5, 0.08, 0.01 + ) + metadata = ReportMetadata( + specimen="Simple expansion-chamber muffler (m = 8)", + client="Example client", + manufacturer="Example silencers", + test_room="Duct acoustics rig (example)", + instrumentation="Two-microphone transfer-matrix bench", + measurement_standard="Munjal Eq. (3.27)", + temperature=20.0, + pressure=101.3, + test_date="2026-07-22", + laboratory="Phonometry reference example", + operator="phonometry", + report_id="EXAMPLE-SILENCER", + requirement=6.0, + ) + return result, metadata, "reactive_silencer_example.pdf" + + +def _hvac_example() -> Tuple[object, ReportMetadata, str]: + """HVAC fiche: the flow-generated noise of a straight duct (VDI 2081-1). + + A documented clean-room case: the flow-generated octave-band sound power + level of a straight duct carrying air at U = 12 m/s in a cross-section of + S = 0.04 m2, L_WB = 7 + 50 lg U + 10 lg S - 2 - 26 lg(1.14 + 0.02 f / U) + dB re 1 pW (VDI 2081-1; Bies, Hansen & Howard, Engineering Noise Control + 5th ed., Eq. (8.251)). Combining the seven octave bands with the ISO 3744 + Annex E A-weighting corrections gives the A-weighted sound power level + L_WA = 38.8 dB(A) re 1 pW (overall unweighted L_W = 47.0 dB). The + requirement is a plausible maximum A-weighted level the example clears + (lower is better). + """ + freqs = np.array([63, 125, 250, 500, 1000, 2000, 4000], dtype=float) + result = ph.noise_control.hvac.flow_noise_straight_duct(freqs, 12.0, 0.04) + metadata = ReportMetadata( + specimen="Straight supply duct, 0.04 m2 cross-section", + client="Example client", + test_room="Air-handling plant room (example)", + instrumentation="In-duct sound power (ISO 5136 method)", + measurement_standard="VDI 2081-1", + temperature=21.0, + pressure=101.2, + test_date="2026-07-22", + laboratory="Phonometry reference example", + operator="phonometry", + report_id="EXAMPLE-HVAC", + requirement=45.0, + ) + return result, metadata, "hvac_duct_noise_example.pdf" #: Every example fiche the repository keeps rendered. New report kinds append @@ -2465,6 +2569,9 @@ def _sii_example() -> Tuple[object, ReportMetadata, str]: _flanking_impact_level_example, _sti_example, _sii_example, + _enclosure_example, + _silencer_example, + _hvac_example, ] diff --git a/site/src/content/docs/reference/api/noise_control/enclosures.md b/site/src/content/docs/reference/api/noise_control/enclosures.md index fd9f224b..c6cf0b5a 100644 --- a/site/src/content/docs/reference/api/noise_control/enclosures.md +++ b/site/src/content/docs/reference/api/noise_control/enclosures.md @@ -111,3 +111,49 @@ Plot the panel `R`, correction `C` and net insertion loss. Requires matplotlib (`pip install phonometry[plot]`); returns the `Axes`. + +### EnclosureResult.report() + +```python +EnclosureResult.report( + path: str, + *, + metadata: ReportMetadata | None = None, + engine: str = 'reportlab', + verbose: bool = False, + language: str = 'en', +) -> str +``` + +Render a machine-enclosure insertion-loss fiche to `path`. + +Writes a one-page enclosure-performance sheet: the method-basis line +naming the Bies, Hansen & Howard insertion-loss model +(Engineering Noise Control 5th ed., section 7.4.2), an optional metadata +header (client, enclosed machine, test environment, instrumentation, +climate, date), a per-band table (nominal frequency, the supplied panel +transmission loss `R`, the interior build-up correction `C` and the +net insertion loss `IL = R - C`) beside the `R`, `C` and `IL` +curves, the boxed mean insertion loss over the analysis bands with the +external and internal surface areas, an optional verdict row against a +declared minimum, and a method-basis strip stating +`IL = R - C` with `C = 10 lg(0.3 + S_E / R_i)`. + +**Parameters** + +| Name | Description | +| :--- | :--- | +| `path` | Destination path of the PDF file. | +| `metadata` | Optional [`ReportMetadata`](/phonometry/reference/api/building/insulation/#reportmetadata) supplying the header (`client`, `specimen` the enclosed machine, `test_room` the test environment, `instrumentation`, `temperature`, `relative_humidity`, `pressure`, `test_date`), the footer identity (`laboratory`, `operator`, `report_id`, `notes`) and, via `requirement`, a declared minimum mean insertion loss (more insertion loss is better). The surface areas come from the result itself. | +| `engine` | Rendering back end; only `"reportlab"` is supported. | +| `verbose` | When `True` the per-band table adds the interior room constant `R_i` column. | +| `language` | Fiche language: `"en"` (default) or `"es"`. | + +**Returns:** The written `path` as a `str`. + +**Raises** + +| Exception | When | +| :--- | :--- | +| ValueError | If `engine` is not `"reportlab"` or `language` is unknown. | +| ImportError | If reportlab (or, for the figure, matplotlib) is not installed (`pip install phonometry[report]`). | diff --git a/site/src/content/docs/reference/api/noise_control/hvac.md b/site/src/content/docs/reference/api/noise_control/hvac.md index 0d3bfa42..80c2313c 100644 --- a/site/src/content/docs/reference/api/noise_control/hvac.md +++ b/site/src/content/docs/reference/api/noise_control/hvac.md @@ -191,6 +191,52 @@ Plot the quantity against a continuous log-frequency axis. Requires matplotlib (`pip install phonometry[plot]`). +### HvacSpectrumResult.report() + +```python +HvacSpectrumResult.report( + path: str, + *, + metadata: ReportMetadata | None = None, + engine: str = 'reportlab', + verbose: bool = False, + language: str = 'en', +) -> str +``` + +Render an HVAC duct-noise-spectrum fiche to `path`. + +Writes a one-page HVAC-noise sheet: the method-basis line naming the +reported quantity and the Bies, Hansen & Howard chapter (Engineering +Noise Control 5th ed., Chapter 8), an optional metadata header (client, +duct element, test environment, instrumentation, climate, date), a +per-band table (nominal frequency and the reported quantity) beside the +spectrum, the boxed single-number result (for a regenerated-noise +spectrum the A-weighted sound power level `L_WA` re 1 pW with the +overall unweighted total; for an attenuation spectrum the mean +attenuation with its band range), an optional verdict row against a +declared limit, and a method-basis strip stating the reported quantity's +relation. + +**Parameters** + +| Name | Description | +| :--- | :--- | +| `path` | Destination path of the PDF file. | +| `metadata` | Optional [`ReportMetadata`](/phonometry/reference/api/building/insulation/#reportmetadata) supplying the header (`client`, `specimen` the duct element, `test_room` the test environment, `instrumentation`, `temperature`, `relative_humidity`, `pressure`, `test_date`), the footer identity (`laboratory`, `operator`, `report_id`, `notes`) and, via `requirement`, a declared maximum A-weighted sound power level for a regenerated-noise spectrum (lower is better) or a declared minimum mean attenuation for an attenuation spectrum (more is better). | +| `engine` | Rendering back end; only `"reportlab"` is supported. | +| `verbose` | When `True` a regenerated-noise table adds the A-weighting correction and the A-weighted band level columns. | +| `language` | Fiche language: `"en"` (default) or `"es"`. | + +**Returns:** The written `path` as a `str`. + +**Raises** + +| Exception | When | +| :--- | :--- | +| ValueError | If `engine` is not `"reportlab"` or `language` is unknown. | +| ImportError | If reportlab (or, for the figure, matplotlib) is not installed (`pip install phonometry[report]`). | + ## plenum_attenuation ```python diff --git a/site/src/content/docs/reference/api/noise_control/silencers.md b/site/src/content/docs/reference/api/noise_control/silencers.md index 68f94f3a..51c212a8 100644 --- a/site/src/content/docs/reference/api/noise_control/silencers.md +++ b/site/src/content/docs/reference/api/noise_control/silencers.md @@ -256,3 +256,50 @@ Plot the transmission (and insertion) loss against frequency. Requires matplotlib (`pip install phonometry[plot]`); returns the `Axes`. + +### ReactiveSilencerResult.report() + +```python +ReactiveSilencerResult.report( + path: str, + *, + metadata: ReportMetadata | None = None, + engine: str = 'reportlab', + verbose: bool = False, + language: str = 'en', +) -> str +``` + +Render a reactive-silencer transmission-loss fiche to `path`. + +Writes a one-page silencer-performance sheet: the method-basis line +naming the plane-wave four-pole (transfer-matrix) method (Munjal, +Acoustics of Ducts and Mufflers 2nd ed., Eq. (3.27); Bies, Hansen & +Howard, Engineering Noise Control 5th ed., sections 8.8-8.9), an +optional metadata header (client, device, test environment, +instrumentation, climate, date), a per-band table (nominal frequency, +the transmission loss `TL` and, when computed, the insertion loss +`IL`) beside the `TL` (and `IL`) curves, the boxed mean +transmission loss over the analysis bands with the peak transmission +loss and the device kind, an optional verdict row against a declared +minimum, and a method-basis strip stating the four-pole +transmission-loss relation. + +**Parameters** + +| Name | Description | +| :--- | :--- | +| `path` | Destination path of the PDF file. | +| `metadata` | Optional [`ReportMetadata`](/phonometry/reference/api/building/insulation/#reportmetadata) supplying the header (`client`, `specimen` the device, `test_room` the test environment, `instrumentation`, `temperature`, `relative_humidity`, `pressure`, `test_date`), the footer identity (`laboratory`, `operator`, `report_id`, `notes`) and, via `requirement`, a declared minimum mean transmission loss (more transmission loss is better). | +| `engine` | Rendering back end; only `"reportlab"` is supported. | +| `verbose` | Accepted for signature symmetry with the other fiches; the silencer table already shows the insertion loss when it was computed. | +| `language` | Fiche language: `"en"` (default) or `"es"`. | + +**Returns:** The written `path` as a `str`. + +**Raises** + +| Exception | When | +| :--- | :--- | +| ValueError | If `engine` is not `"reportlab"` or `language` is unknown. | +| ImportError | If reportlab (or, for the figure, matplotlib) is not installed (`pip install phonometry[report]`). | diff --git a/src/phonometry/_report/_i18n.py b/src/phonometry/_report/_i18n.py index b0ce6e98..4fbf3b5c 100644 --- a/src/phonometry/_report/_i18n.py +++ b/src/phonometry/_report/_i18n.py @@ -697,6 +697,47 @@ "No single-number Kij (no bands in the Annex A range)": "Sin número único Kij (no hay bandas en el intervalo del anexo A)", "Single-number Kij = {value} dB": "Número único Kij = {value} dB", "Values in brackets are bracketed bands, excluded from the single number.": "Los valores entre corchetes son bandas excluidas del número único.", + # --- noise-control performance fiches (enclosure / silencer / HVAC) --- + "Machine enclosure insertion loss": "Pérdida por inserción de encapsulado de máquina", + "Reactive silencer transmission loss": "Pérdida por transmisión de silenciador reactivo", + "HVAC duct noise spectrum": "Espectro de ruido de conducto de climatización", + "Determination of the insertion loss of a machine enclosure from the panel transmission loss and the interior build-up correction (Bies, Hansen & Howard, Engineering Noise Control 5th ed., section 7.4.2, Eqs. (7.103) and (7.111)).": "Determinación de la pérdida por inserción de un encapsulado de máquina a partir de la pérdida por transmisión del panel y la corrección por reverberación interior (Bies, Hansen & Howard, Engineering Noise Control 5th ed., apartado 7.4.2, Ecs. (7.103) y (7.111)).", + "Determination of the transmission loss of a reactive silencer by the plane-wave four-pole (transfer-matrix) method (Munjal, Acoustics of Ducts and Mufflers 2nd ed., Eq. (3.27); Bies, Hansen & Howard, Engineering Noise Control 5th ed., sections 8.8 to 8.9).": "Determinación de la pérdida por transmisión de un silenciador reactivo por el método de cuatro polos (matriz de transferencia) de onda plana (Munjal, Acoustics of Ducts and Mufflers 2nd ed., Ec. (3.27); Bies, Hansen & Howard, Engineering Noise Control 5th ed., apartados 8.8 a 8.9).", + "Determination of the flow-generated (regenerated) octave-band sound power level of a duct element (Bies, Hansen & Howard, Engineering Noise Control 5th ed., Chapter 8, section 8.15; VDI 2081-1).": "Determinación del nivel de potencia acústica en bandas de octava generado por el flujo (ruido regenerado) de un elemento de conducto (Bies, Hansen & Howard, Engineering Noise Control 5th ed., Capítulo 8, apartado 8.15; VDI 2081-1).", + "Determination of the octave-band attenuation of a duct element (Bies, Hansen & Howard, Engineering Noise Control 5th ed., Chapter 8).": "Determinación de la atenuación en bandas de octava de un elemento de conducto (Bies, Hansen & Howard, Engineering Noise Control 5th ed., Capítulo 8).", + "Insertion loss per band": "Pérdida por inserción por banda", + "Octave-band insertion loss": "Pérdida por inserción en bandas de octava", + "One-third-octave-band insertion loss": "Pérdida por inserción en bandas de tercio de octava", + "Transmission loss per band": "Pérdida por transmisión por banda", + "Octave-band transmission loss": "Pérdida por transmisión en bandas de octava", + "One-third-octave-band transmission loss": "Pérdida por transmisión en bandas de tercio de octava", + "Octave-band regenerated sound power levels": "Niveles de potencia acústica regenerada en bandas de octava", + "One-third-octave-band regenerated sound power levels": "Niveles de potencia acústica regenerada en bandas de tercio de octava", + "Regenerated sound power levels per band": "Niveles de potencia acústica regenerada por banda", + "Octave-band attenuation": "Atenuación en bandas de octava", + "One-third-octave-band attenuation": "Atenuación en bandas de tercio de octava", + "Attenuation per band": "Atenuación por banda", + "Mean insertion loss IL = {value} dB": "Pérdida por inserción media IL = {value} dB", + "Mean panel transmission loss R = {value} dB": "Pérdida por transmisión media del panel R = {value} dB", + "External surface area SE = {value} m2": "Superficie externa SE = {value} m2", + "Internal surface area Si = {value} m2": "Superficie interna Si = {value} m2", + "Mean transmission loss TL = {value} dB": "Pérdida por transmisión media TL = {value} dB", + "Peak transmission loss = {value} dB": "Pérdida por transmisión máxima = {value} dB", + "Device: {kind}": "Dispositivo: {kind}", + "Mean insertion loss IL = {value} dB": "Pérdida por inserción media IL = {value} dB", + "Resonance frequencies: {values} Hz": "Frecuencias de resonancia: {values} Hz", + "A-weighted sound power level LWA = {value} dB(A) re {ref}": "Nivel de potencia acústica ponderado A LWA = {value} dB(A) re {ref}", + "Overall sound power level LW = {value} dB re {ref}": "Nivel de potencia acústica total LW = {value} dB re {ref}", + "Overall sound power level LW = {value} dB re {ref}": "Nivel de potencia acústica total LW = {value} dB re {ref}", + "Mean attenuation D = {value} dB": "Atenuación media D = {value} dB", + "Band attenuation range {lo} to {hi} dB": "Intervalo de atenuación por banda de {lo} a {hi} dB", + "{sym} = {value} {unit}, required ≥ {req} {unit}": "{sym} = {value} {unit}, requerido ≥ {req} {unit}", + "{sym} = {value} {unit}, required ≤ {req} {unit}": "{sym} = {value} {unit}, requerido ≤ {req} {unit}", + "IL = R - C with the interior build-up correction C = 10 lg(0.3 + SE / Ri) and the interior room constant Ri = Si αi / (1 - αi) (Eqs. (7.103) and (7.111)). The panel transmission loss R is supplied by the caller (measured or predicted); this evaluation combines it with the interior build-up correction only.": "IL = R - C con la corrección por reverberación interior C = 10 lg(0,3 + SE / Ri) y la constante de sala interior Ri = Si αi / (1 - αi) (Ecs. (7.103) y (7.111)). La pérdida por transmisión del panel R la aporta el usuario (medida o predicha); esta evaluación solo la combina con la corrección por reverberación interior.", + "TL = 10 lg[(Zn/Z1) (1/4) |T11 + T12/Zn + Z1 T21 + (Z1/Zn) T22|2] from the compound four-pole matrix T, with the characteristic impedances Z1 = ρc/Sin and Zn = ρc/Sout (Munjal Eq. (3.27), no flow). TL is the intrinsic attenuation for an anechoic termination; the insertion loss adds the source and radiation impedance mismatch.": "TL = 10 lg[(Zn/Z1) (1/4) |T11 + T12/Zn + Z1 T21 + (Z1/Zn) T22|2] a partir de la matriz de cuatro polos compuesta T, con las impedancias características Z1 = ρc/Sin y Zn = ρc/Sout (Munjal Ec. (3.27), sin flujo). TL es la atenuación intrínseca para una terminación anecoica; la pérdida por inserción añade el desajuste de impedancia de fuente y radiación.", + "LW is the flow-generated octave-band sound power level radiated by the element (Chapter 8, section 8.15; VDI 2081-1), referenced to the reference sound power 1 pW.": "LW es el nivel de potencia acústica en bandas de octava generado por el flujo que radia el elemento (Capítulo 8, apartado 8.15; VDI 2081-1), referido a la potencia acústica de referencia 1 pW.", + "The A-weighted level LWA combines the band levels with the ISO 3744:2010 Annex E A-weighting corrections CA (Tables E.1/E.2).": "El nivel ponderado A LWA combina los niveles de banda con las correcciones de ponderación A CA de la Norma ISO 3744:2010 anexo E (Tablas E.1/E.2).", + "The octave-band attenuation is the passive insertion loss the element adds along the duct path (Chapter 8). Path attenuations add band by band; regenerated noise is added separately.": "La atenuación en bandas de octava es la pérdida por inserción pasiva que el elemento añade a lo largo del recorrido del conducto (Capítulo 8). Las atenuaciones del recorrido se suman banda a banda; el ruido regenerado se añade por separado.", } diff --git a/src/phonometry/_report/_noise_control_fiche.py b/src/phonometry/_report/_noise_control_fiche.py new file mode 100644 index 00000000..c18cbf91 --- /dev/null +++ b/src/phonometry/_report/_noise_control_fiche.py @@ -0,0 +1,198 @@ +# Copyright (c) 2026. Jose M. Requena-Plens +"""Shared renderer for the noise-control performance fiches. + +The machine-enclosure insertion loss (:mod:`.enclosure`), the reactive-silencer +transmission loss (:mod:`.silencer`) and the HVAC duct-noise spectrum +(:mod:`.hvac`) print the same one-page performance sheet: a title and +method-basis line, an optional metadata header, a two-panel body with the +per-band table on the left and the result's own ``plot`` on the right, a boxed +single-number performance figure, an optional requirement verdict and a +method-basis strip. Only the fixed text and the per-band table content differ +between them, so this module holds the common skeleton and each renderer +supplies only its specifics (the basis line, the table columns, the boxed +figure and the verdict direction). + +The quantity-independent flowable helpers live in :mod:`._layout`; the per-band +table builder, the nominal band labels and the one-decimal cell formatter are +shared with the sound-power fiches (:mod:`._sound_power_fiche`), and the header +grid reuses the sound-power source/environment layout. + +reportlab, matplotlib and svglib are soft dependencies imported lazily +(reportlab and svglib ship in the ``phonometry[report]`` extra, matplotlib in +``phonometry[plot]``); each is guarded with an actionable :class:`ImportError`. +""" + +from __future__ import annotations + +import math +from typing import Any, List, Tuple + +import numpy as np + +from ._i18n import format_number, t +from ._layout import ( + _ACCENT_HEX, + _REPORTLAB_HINT, + build_document, + display_round, + document_styles, + footer_flow, + grid_table, + measurement_basis_style, + render_figure_drawing, + result_box, + two_panel_body, + verdict_flow, +) +from ._sound_power_fiche import band_labels, d1, metadata_pairs, power_value_table +from .metadata import ReportMetadata + +__all__ = [ + "band_labels", + "d1", + "mean_finite", + "performance_verdict", + "power_value_table", + "render_noise_control_fiche", +] + + +def mean_finite(values: np.ndarray) -> float: + """Arithmetic mean of the finite entries of a per-band array (``nan`` if none).""" + arr = np.asarray(values, dtype=np.float64) + arr = arr[np.isfinite(arr)] + if arr.size == 0: + return float("nan") + return float(np.mean(arr)) + + +def performance_verdict( + value: float, + requirement: float, + symbol: str, + *, + higher_is_better: bool, + unit: str = "dB", + language: str = "en", +) -> Tuple[str, bool]: + """Verdict text and PASS flag for a performance figure against a requirement. + + ``higher_is_better`` selects the direction: an insertion or transmission + loss passes at or above the declared minimum, while a radiated noise level + passes at or below the declared maximum. The comparison uses the displayed + (one-decimal) value so the printed number cannot contradict the verdict at + the boundary. ``symbol`` is markup (e.g. ``IL``, ``LWA``) and + ``unit`` its unit symbol (``dB`` or ``dB(A)``), neither of which is + translated. + """ + rounded = display_round(value) + if higher_is_better: + passed = math.isfinite(value) and rounded >= requirement + template = t( + "{sym} = {value} {unit}, required ≥ {req} {unit}", language + ) + else: + passed = math.isfinite(value) and rounded <= requirement + template = t( + "{sym} = {value} {unit}, required ≤ {req} {unit}", language + ) + text = template.format( + sym=symbol, + value=d1(value, language), + req=format_number(requirement, language, decimals=1), + unit=unit, + ) + return text, passed + + +def render_noise_control_fiche( + result: Any, + path: str, + *, + title: str, + basis: str, + caption: str, + value_table: Any, + statement: str, + extended: List[str], + basis_strips: List[str], + metadata: ReportMetadata | None, + language: str, + verdict: Tuple[str, bool] | None = None, + left_width_mm: float = 64.0, + plot_width_mm: float = 110.0, + figure_width_mm: float = 108.0, +) -> str: + """Assemble the shared noise-control fiche flow and build the PDF at ``path``. + + The metadata header grid reuses the sound-power source/environment layout, + and the requirement verdict is supplied pre-computed by each renderer (its + quantity symbol and pass direction). The two-panel body puts the per-band + ``value_table`` on the left and the result's own ``plot`` on the right. + + :param result: The noise-control result; its ``plot`` draws the right panel. + :param title: The already-translated fiche title. + :param basis: The already-translated method-basis line. + :param caption: The already-translated band-set caption above the table. + :param value_table: The pre-built per-band reportlab table flowable. + :param statement: The boxed single-number statement (markup). + :param extended: The extended terms shown alongside the boxed statement. + :param basis_strips: The method-basis-strip paragraphs (markup). + :param metadata: Optional :class:`ReportMetadata` for the header, footer + identity and (via each renderer) the requirement verdict. + :param language: ``"en"`` (default) or ``"es"``. + :param verdict: Optional pre-computed ``(text, passed)`` verdict row. + :param left_width_mm: Width of the left (table) panel, in mm. + :param plot_width_mm: Width of the right (plot) panel, in mm. + :param figure_width_mm: Target width of the embedded vector figure, in mm. + :return: The written ``path`` as a :class:`str`. + :raises ImportError: If reportlab (or, for the figure, matplotlib) is not + installed. + """ + try: + from reportlab.lib import colors + from reportlab.lib.units import mm + from reportlab.platypus import Paragraph, Spacer + except ImportError as exc: + raise ImportError(_REPORTLAB_HINT) from exc + accent = colors.HexColor(_ACCENT_HEX) + + styles, title_style, basis_style, caption_style = document_styles(accent) + + flow: List[Any] = [ + Paragraph(title, title_style), + Paragraph(basis, basis_style), + ] + + if metadata is not None and not metadata.is_empty(): + header_pairs = metadata_pairs(metadata, language) + if header_pairs: + flow.append(Spacer(1, 3)) + flow.append(grid_table(header_pairs)) + flow.append(Spacer(1, 8)) + + left_cell = [Paragraph(caption, caption_style), value_table] + plot_drawing = render_figure_drawing( + result.plot, figure_width_mm * mm, y_top=None, language=language + ) + flow.append( + two_panel_body( + left_cell, + plot_drawing, + left_width_mm=left_width_mm, + plot_width_mm=plot_width_mm, + ) + ) + flow.append(Spacer(1, 8)) + + flow.append(result_box(statement, styles, accent, extended)) + if verdict is not None: + text, passed = verdict + flow.extend(verdict_flow(text, passed, styles, language)) + + basis_style_strip = measurement_basis_style() + for strip in basis_strips: + flow.append(Paragraph(strip, basis_style_strip)) + flow.extend(footer_flow(metadata, language)) + + return build_document(path, flow, title) diff --git a/src/phonometry/_report/enclosure.py b/src/phonometry/_report/enclosure.py new file mode 100644 index 00000000..fb2ff02f --- /dev/null +++ b/src/phonometry/_report/enclosure.py @@ -0,0 +1,206 @@ +# Copyright (c) 2026. Jose M. Requena-Plens +"""Machine-enclosure insertion-loss performance fiche (reportlab renderer). + +Renders a :class:`~phonometry.noise_control.enclosures.EnclosureResult` (the +net insertion loss of a close or free-standing machine enclosure, Bies, Hansen +& Howard, *Engineering Noise Control* 5th ed., section 7.4.2) to a one-page +enclosure-performance sheet: + +* a title and the method-basis line naming the Bies insertion-loss model; +* an optional metadata header (client, enclosed machine, test environment, + instrumentation, climate, date); +* a two-panel body with the per-band table on the left (nominal frequency, the + supplied panel transmission loss ``R``, the interior build-up correction + ``C`` and the net insertion loss ``IL = R - C``; with ``verbose=True`` the + interior room constant ``R_i`` is added) and the panel ``R``, correction + ``C`` and insertion-loss ``IL`` curves drawn by the result's own + ``plot(ax=...)`` on the right; +* a boxed single-number result, the mean insertion loss over the analysis + bands, with the external and internal surface areas alongside; +* an optional verdict row when a declared minimum is supplied via the metadata + ``requirement`` (more insertion loss is better); +* a method-basis strip stating ``IL = R - C`` with + ``C = 10 lg(0.3 + S_E / R_i)`` and the interior room constant. + +The quantity-independent skeleton and the two-panel assembly live in +:mod:`._layout` and :mod:`._noise_control_fiche`; this module only holds the +enclosure specifics. reportlab, matplotlib and svglib are soft dependencies +imported lazily (reportlab and svglib ship in the ``phonometry[report]`` extra, +matplotlib in ``phonometry[plot]``); each is guarded with an actionable +:class:`ImportError`. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, List, Tuple + +import numpy as np + +from ._i18n import format_number, t +from ._noise_control_fiche import ( + band_labels, + d1, + mean_finite, + performance_verdict, + power_value_table, + render_noise_control_fiche, +) +from .metadata import ReportMetadata + +if TYPE_CHECKING: + from ..noise_control.enclosures import EnclosureResult + + +def _basis(language: str = "en") -> str: + """The method-basis line naming the Bies enclosure insertion-loss model.""" + return t( + "Determination of the insertion loss of a machine enclosure from the " + "panel transmission loss and the interior build-up correction (Bies, " + "Hansen & Howard, Engineering Noise Control 5th ed., section 7.4.2, " + "Eqs. (7.103) and (7.111)).", + language, + ) + + +def _caption(result: Any, language: str = "en") -> str: + """The caption declaring the analysis band set above the table.""" + freqs = getattr(result, "frequencies", None) + n = np.asarray(result.insertion_loss, dtype=np.float64).size + if freqs is None: + return t("Insertion loss per band", language) + _, fraction = band_labels(freqs, n) + if fraction == 1: + return t("Octave-band insertion loss", language) + return t("One-third-octave-band insertion loss", language) + + +def _value_table(result: Any, verbose: bool, language: str = "en") -> Any: + """Build the per-band table (nominal frequency, R, C, IL; verbose adds R_i). + + Called only after the renderer has imported reportlab. + """ + r = np.asarray(result.panel_transmission_loss, dtype=np.float64) + c = np.asarray(result.correction, dtype=np.float64) + il = np.asarray(result.insertion_loss, dtype=np.float64) + n = il.size + labels, fraction = band_labels(getattr(result, "frequencies", None), n) + + if not verbose: + header = [ + t("f [Hz]", language), + "R [dB]", + "C [dB]", + "IL [dB]", + ] + widths = [16.0, 16.0, 16.0, 16.0] + rows_data = [ + [labels[i], d1(r[i], language), d1(c[i], language), d1(il[i], language)] + for i in range(n) + ] + return power_value_table(header, rows_data, widths, fraction) + + r_i = np.asarray(result.room_constant, dtype=np.float64) + header = [ + t("f [Hz]", language), + "R [dB]", + "C [dB]", + "Ri [m2]", + "IL [dB]", + ] + widths = [12.0, 13.0, 13.0, 14.0, 14.0] + rows_data = [ + [ + labels[i], + d1(r[i], language), + d1(c[i], language), + d1(r_i[i], language), + d1(il[i], language), + ] + for i in range(n) + ] + return power_value_table(header, rows_data, widths, fraction) + + +def _statement(result: Any, language: str = "en") -> Tuple[float, str, List[str]]: + """The boxed mean insertion loss and its extended enclosure terms.""" + mean_il = mean_finite(result.insertion_loss) + mean_r = mean_finite(result.panel_transmission_loss) + statement = t( + "Mean insertion loss IL = {value} dB", language + ).format(value=d1(mean_il, language)) + extended = [ + t("Mean panel transmission loss R = {value} dB", language).format( + value=d1(mean_r, language) + ), + t( + "External surface area SE = {value} m2", + language, + ).format(value=format_number(float(result.external_area), language, decimals=2)), + t( + "Internal surface area Si = {value} m2", + language, + ).format(value=format_number(float(result.internal_area), language, decimals=2)), + ] + return mean_il, statement, extended + + +def _basis_strip(language: str = "en") -> str: + """The IL = R - C relation line for the method-basis strip.""" + return t( + "IL = R - C with the interior build-up correction " + "C = 10 lg(0.3 + SE / Ri) and the interior room " + "constant Ri = Si αi / " + "(1 - αi) (Eqs. (7.103) and (7.111)). The panel " + "transmission loss R is supplied by the caller (measured or predicted); " + "this evaluation combines it with the interior build-up correction only.", + language, + ) + + +def render_enclosure_report( + result: "EnclosureResult", + path: str, + *, + metadata: ReportMetadata | None = None, + verbose: bool = False, + language: str = "en", +) -> str: + """Render a machine-enclosure insertion-loss fiche to a PDF at ``path``. + + :param result: An + :class:`~phonometry.noise_control.enclosures.EnclosureResult` carrying + the per-band panel transmission loss ``R``, the interior build-up + correction ``C``, the net insertion loss ``IL = R - C`` and the external + and internal surface areas. + :param path: Destination path of the PDF file. + :param metadata: Optional :class:`ReportMetadata`; ``None`` produces a bare + fiche (body + result + basis, no header). A supplied ``requirement`` is + read as a declared minimum mean insertion loss (more is better). + :param verbose: When ``True`` the per-band table adds the interior room + constant ``R_i`` column. + :param language: Fiche language: ``"en"`` (default) or ``"es"``. + :return: The written ``path`` as a :class:`str`. + :raises ImportError: If reportlab (or, for the figure, matplotlib) is not + installed. + """ + mean_il, statement, extended = _statement(result, language) + verdict = None + if metadata is not None and metadata.requirement is not None: + verdict = performance_verdict( + mean_il, metadata.requirement, "IL", + higher_is_better=True, language=language, + ) + return render_noise_control_fiche( + result, + path, + title=t("Machine enclosure insertion loss", language), + basis=_basis(language), + caption=_caption(result, language), + value_table=_value_table(result, verbose, language), + statement=statement, + extended=extended, + basis_strips=[_basis_strip(language)], + metadata=metadata, + language=language, + verdict=verdict, + ) diff --git a/src/phonometry/_report/hvac.py b/src/phonometry/_report/hvac.py new file mode 100644 index 00000000..b93f184f --- /dev/null +++ b/src/phonometry/_report/hvac.py @@ -0,0 +1,323 @@ +# Copyright (c) 2026. Jose M. Requena-Plens +"""HVAC duct-noise-spectrum performance fiche (reportlab renderer). + +Renders a :class:`~phonometry.noise_control.hvac.HvacSpectrumResult` (a +per-band HVAC duct quantity: the flow-generated (regenerated) sound power level +of a straight duct or bend, or the passive attenuation of an end reflection, +bend or plenum, Bies, Hansen & Howard, *Engineering Noise Control* 5th ed., +Chapter 8) to a one-page HVAC-noise sheet: + +* a title and the method-basis line naming the reported quantity and the Bies + chapter; +* an optional metadata header (client, duct element, test environment, + instrumentation, climate, date); +* a two-panel body with the per-band table on the left (nominal frequency and + the reported quantity; with ``verbose=True`` a regenerated-noise spectrum + adds the A-weighting correction and the A-weighted band level) and the + spectrum drawn by the result's own ``plot(ax=...)`` on the right; +* a boxed single-number result: for a regenerated-noise spectrum the A-weighted + sound power level ``L_WA`` (dB(A) re 1 pW) with the overall unweighted total; + for an attenuation spectrum the mean attenuation with its band range; +* an optional verdict row when a declared limit is supplied via the metadata + ``requirement`` (lower regenerated noise is better; more attenuation is + better); +* a method-basis strip stating the reported quantity's relation. + +The quantity-independent skeleton and the two-panel assembly live in +:mod:`._layout` and :mod:`._noise_control_fiche`; this module only holds the +HVAC specifics. reportlab, matplotlib and svglib are soft dependencies imported +lazily (reportlab and svglib ship in the ``phonometry[report]`` extra, +matplotlib in ``phonometry[plot]``); each is guarded with an actionable +:class:`ImportError`. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, List, Tuple + +import numpy as np + +from ._i18n import t +from ._noise_control_fiche import ( + band_labels, + d1, + mean_finite, + performance_verdict, + power_value_table, + render_noise_control_fiche, +) +from .metadata import ReportMetadata + +if TYPE_CHECKING: + from ..noise_control.hvac import HvacSpectrumResult + +#: Reference sound power for a regenerated-noise sound power level, 1 pW. +_POWER_REFERENCE = "1 pW" + + +def _is_power(result: Any) -> bool: + """Return ``True`` for a regenerated sound power spectrum, else attenuation.""" + return getattr(result, "quantity", "") == "sound_power_level" + + +def _a_weighting(frequencies: np.ndarray) -> np.ndarray | None: + """A-weighting band corrections at nominal band centres, or ``None``. + + Reuses the library's ISO 3744:2010 Annex E A-weighting table (the same + corrections the sound-power determination applies), so the fiche's + A-weighted level is consistent with the rest of the library. Returns + ``None`` when the spectrum is not on nominal octave/one-third-octave centres + (the table is undefined there), and the fiche then falls back to the + unweighted total. Imported lazily to keep this render leaf free of a + module-level domain import. + """ + try: + from ..emission.sound_power import _a_weighting_corrections + + return np.asarray( + _a_weighting_corrections(np.asarray(frequencies, dtype=np.float64)), + dtype=np.float64, + ) + except (ValueError, ImportError): + return None + + +def _overall_level(levels: np.ndarray) -> float: + """Energy-summed overall level, ``10 lg(sum 10^(L/10))``.""" + finite = levels[np.isfinite(levels)] + if finite.size == 0: + return float("nan") + return float(10.0 * np.log10(np.sum(10.0 ** (finite / 10.0)))) + + +def _a_weighted_total( + levels: np.ndarray, corrections: np.ndarray | None +) -> float | None: + """A-weighted energy-summed total, or ``None`` when no corrections apply.""" + if corrections is None: + return None + weighted = levels + corrections + return _overall_level(weighted) + + +def _basis(result: Any, language: str = "en") -> str: + """The method-basis line naming the reported quantity and the Bies chapter.""" + if _is_power(result): + return t( + "Determination of the flow-generated (regenerated) octave-band sound " + "power level of a duct element (Bies, Hansen & Howard, " + "Engineering Noise Control 5th ed., Chapter 8, section 8.15; " + "VDI 2081-1).", + language, + ) + return t( + "Determination of the octave-band attenuation of a duct element (Bies, " + "Hansen & Howard, Engineering Noise Control 5th ed., Chapter 8).", + language, + ) + + +def _caption(result: Any, language: str = "en") -> str: + """The caption declaring the analysis band set above the table.""" + n = np.asarray(result.values, dtype=np.float64).size + _, fraction = band_labels(getattr(result, "frequencies", None), n) + power = _is_power(result) + if fraction == 1: + return ( + t("Octave-band regenerated sound power levels", language) + if power + else t("Octave-band attenuation", language) + ) + if fraction == 3: + return ( + t("One-third-octave-band regenerated sound power levels", language) + if power + else t("One-third-octave-band attenuation", language) + ) + return ( + t("Regenerated sound power levels per band", language) + if power + else t("Attenuation per band", language) + ) + + +def _value_table( + result: Any, verbose: bool, corrections: np.ndarray | None, language: str = "en" +) -> Any: + """Build the per-band table (nominal frequency and the reported quantity). + + A verbose regenerated-noise table adds the A-weighting correction and the + A-weighted band level. Called only after the renderer has imported reportlab. + """ + values = np.asarray(result.values, dtype=np.float64) + n = values.size + labels, fraction = band_labels(getattr(result, "frequencies", None), n) + power = _is_power(result) + quantity_header = "LW [dB]" if power else "D [dB]" + + if not (verbose and power and corrections is not None): + header = [t("f [Hz]", language), quantity_header] + widths = [32.0, 32.0] + rows_data = [[labels[i], d1(values[i], language)] for i in range(n)] + return power_value_table(header, rows_data, widths, fraction) + + weighted = values + corrections + header = [ + t("f [Hz]", language), + "LW [dB]", + "CA [dB]", + "LWA [dB]", + ] + widths = [16.0, 16.0, 16.0, 16.0] + rows_data = [ + [ + labels[i], + d1(values[i], language), + d1(corrections[i], language), + d1(weighted[i], language), + ] + for i in range(n) + ] + return power_value_table(header, rows_data, widths, fraction) + + +def _statement( + result: Any, corrections: np.ndarray | None, language: str = "en" +) -> Tuple[float, bool, str, List[str]]: + """The boxed headline figure, its pass direction and the extended terms. + + Returns ``(value, higher_is_better, statement, extended)``. A + regenerated-noise spectrum boxes the A-weighted sound power level (lower is + better) with the overall unweighted total alongside; an attenuation spectrum + boxes the mean attenuation (more is better) with its band range. + """ + values = np.asarray(result.values, dtype=np.float64) + label = str(getattr(result, "label", "")) + if _is_power(result): + overall = _overall_level(values) + lwa = _a_weighted_total(values, corrections) + if lwa is not None: + statement = t( + "A-weighted sound power level LWA = " + "{value} dB(A) re {ref}", + language, + ).format(value=d1(lwa, language), ref=_POWER_REFERENCE) + extended = [ + t( + "Overall sound power level LW = {value} dB re {ref}", + language, + ).format(value=d1(overall, language), ref=_POWER_REFERENCE), + label, + ] + return lwa, False, statement, extended + statement = t( + "Overall sound power level LW = {value} dB re {ref}", + language, + ).format(value=d1(overall, language), ref=_POWER_REFERENCE) + return overall, False, statement, [label] + + mean_att = mean_finite(values) + finite = values[np.isfinite(values)] + lo = float(np.min(finite)) if finite.size else float("nan") + hi = float(np.max(finite)) if finite.size else float("nan") + statement = t( + "Mean attenuation D = {value} dB", language + ).format(value=d1(mean_att, language)) + extended = [ + t("Band attenuation range {lo} to {hi} dB", language).format( + lo=d1(lo, language), hi=d1(hi, language) + ), + label, + ] + return mean_att, True, statement, extended + + +def _basis_strip( + result: Any, corrections: np.ndarray | None, language: str = "en" +) -> List[str]: + """The method-basis strip(s) for the reported quantity.""" + if _is_power(result): + strips = [ + t( + "LW is the flow-generated octave-band sound power " + "level radiated by the element (Chapter 8, section 8.15; " + "VDI 2081-1), referenced to the reference sound power 1 pW.", + language, + ) + ] + if corrections is not None: + strips.append( + t( + "The A-weighted level LWA combines the band levels " + "with the ISO 3744:2010 Annex E A-weighting corrections " + "CA (Tables E.1/E.2).", + language, + ) + ) + return strips + return [ + t( + "The octave-band attenuation is the passive insertion loss the " + "element adds along the duct path (Chapter 8). Path attenuations " + "add band by band; regenerated noise is added separately.", + language, + ) + ] + + +def render_hvac_report( + result: "HvacSpectrumResult", + path: str, + *, + metadata: ReportMetadata | None = None, + verbose: bool = False, + language: str = "en", +) -> str: + """Render an HVAC duct-noise-spectrum fiche to a PDF at ``path``. + + :param result: An + :class:`~phonometry.noise_control.hvac.HvacSpectrumResult` carrying the + per-band quantity (a regenerated sound power level or a passive + attenuation), its band frequencies and a short element label. + :param path: Destination path of the PDF file. + :param metadata: Optional :class:`ReportMetadata`; ``None`` produces a bare + fiche (body + result + basis, no header). A supplied ``requirement`` is + read as a declared maximum A-weighted level for a regenerated-noise + spectrum (lower is better) or a declared minimum mean attenuation for an + attenuation spectrum (more is better). + :param verbose: When ``True`` a regenerated-noise table adds the A-weighting + correction and the A-weighted band level columns. + :param language: Fiche language: ``"en"`` (default) or ``"es"``. + :return: The written ``path`` as a :class:`str`. + :raises ImportError: If reportlab (or, for the figure, matplotlib) is not + installed. + """ + freqs = np.asarray(result.frequencies, dtype=np.float64) + corrections = _a_weighting(freqs) if _is_power(result) else None + value, higher_is_better, statement, extended = _statement( + result, corrections, language + ) + verdict = None + if metadata is not None and metadata.requirement is not None: + symbol = "LWA" if _is_power(result) and corrections is not None else ( + "LW" if _is_power(result) else "D" + ) + unit = "dB(A)" if _is_power(result) and corrections is not None else "dB" + verdict = performance_verdict( + value, metadata.requirement, symbol, + higher_is_better=higher_is_better, unit=unit, language=language, + ) + return render_noise_control_fiche( + result, + path, + title=t("HVAC duct noise spectrum", language), + basis=_basis(result, language), + caption=_caption(result, language), + value_table=_value_table(result, verbose, corrections, language), + statement=statement, + extended=extended, + basis_strips=_basis_strip(result, corrections, language), + metadata=metadata, + language=language, + verdict=verdict, + ) diff --git a/src/phonometry/_report/silencer.py b/src/phonometry/_report/silencer.py new file mode 100644 index 00000000..d0b51c71 --- /dev/null +++ b/src/phonometry/_report/silencer.py @@ -0,0 +1,204 @@ +# Copyright (c) 2026. Jose M. Requena-Plens +"""Reactive-silencer transmission-loss performance fiche (reportlab renderer). + +Renders a +:class:`~phonometry.noise_control.silencers.ReactiveSilencerResult` (the +transmission and, when end impedances are given, insertion loss of a reactive +silencer computed by the plane-wave four-pole method, Munjal, *Acoustics of +Ducts and Mufflers* 2nd ed.; Bies, Hansen & Howard, *Engineering Noise Control* +5th ed., sections 8.8-8.9) to a one-page silencer-performance sheet: + +* a title and the method-basis line naming the four-pole (transfer-matrix) + method and the device kind; +* an optional metadata header (client, device, test environment, + instrumentation, climate, date); +* a two-panel body with the per-band table on the left (nominal frequency, the + transmission loss ``TL`` and, when computed, the insertion loss ``IL``) and + the ``TL`` (and ``IL``) curves drawn by the result's own ``plot(ax=...)`` on + the right; +* a boxed single-number result, the mean transmission loss over the analysis + bands, with the peak transmission loss and the device kind alongside; +* an optional verdict row when a declared minimum is supplied via the metadata + ``requirement`` (more transmission loss is better); +* a method-basis strip stating the four-pole transmission-loss relation. + +The quantity-independent skeleton and the two-panel assembly live in +:mod:`._layout` and :mod:`._noise_control_fiche`; this module only holds the +silencer specifics. reportlab, matplotlib and svglib are soft dependencies +imported lazily (reportlab and svglib ship in the ``phonometry[report]`` extra, +matplotlib in ``phonometry[plot]``); each is guarded with an actionable +:class:`ImportError`. +""" + +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, List, Tuple + +import numpy as np + +from ._i18n import format_number, t +from ._noise_control_fiche import ( + band_labels, + d1, + mean_finite, + performance_verdict, + power_value_table, + render_noise_control_fiche, +) +from .metadata import ReportMetadata + +if TYPE_CHECKING: + from ..noise_control.silencers import ReactiveSilencerResult + + +def _basis(language: str = "en") -> str: + """The method-basis line naming the four-pole transmission-loss method.""" + return t( + "Determination of the transmission loss of a reactive silencer by the " + "plane-wave four-pole (transfer-matrix) method (Munjal, Acoustics of " + "Ducts and Mufflers 2nd ed., Eq. (3.27); Bies, Hansen & Howard, " + "Engineering Noise Control 5th ed., sections 8.8 to 8.9).", + language, + ) + + +def _caption(result: Any, language: str = "en") -> str: + """The caption declaring the analysis band set above the table.""" + freqs = getattr(result, "frequencies", None) + n = np.asarray(result.transmission_loss, dtype=np.float64).size + if freqs is None: + return t("Transmission loss per band", language) + _, fraction = band_labels(freqs, n) + if fraction == 1: + return t("Octave-band transmission loss", language) + return t("One-third-octave-band transmission loss", language) + + +def _value_table(result: Any, language: str = "en") -> Any: + """Build the per-band table (nominal frequency, TL, and IL when computed). + + Called only after the renderer has imported reportlab. + """ + tl = np.asarray(result.transmission_loss, dtype=np.float64) + n = tl.size + labels, fraction = band_labels(getattr(result, "frequencies", None), n) + + if result.insertion_loss is None: + header = [t("f [Hz]", language), "TL [dB]"] + widths = [32.0, 32.0] + rows_data = [[labels[i], d1(tl[i], language)] for i in range(n)] + return power_value_table(header, rows_data, widths, fraction) + + il = np.asarray(result.insertion_loss, dtype=np.float64) + header = [t("f [Hz]", language), "TL [dB]", "IL [dB]"] + widths = [22.0, 21.0, 21.0] + rows_data = [ + [labels[i], d1(tl[i], language), d1(il[i], language)] for i in range(n) + ] + return power_value_table(header, rows_data, widths, fraction) + + +def _resonance_term(result: Any, language: str = "en") -> str | None: + """The extended term naming the resonance frequencies, or ``None``.""" + resonances = getattr(result, "resonances", None) + if resonances is None: + return None + res = np.atleast_1d(np.asarray(resonances, dtype=np.float64)) + res = res[np.isfinite(res)] + if res.size == 0: + return None + listed = ", ".join(format_number(float(fr), language, decimals=0) for fr in res) + return t("Resonance frequencies: {values} Hz", language).format(values=listed) + + +def _statement(result: Any, language: str = "en") -> Tuple[float, str, List[str]]: + """The boxed mean transmission loss and its extended silencer terms.""" + tl = np.asarray(result.transmission_loss, dtype=np.float64) + mean_tl = mean_finite(tl) + finite = tl[np.isfinite(tl)] + peak_tl = float(np.max(finite)) if finite.size else float("nan") + statement = t( + "Mean transmission loss TL = {value} dB", language + ).format(value=d1(mean_tl, language)) + extended = [ + t("Peak transmission loss = {value} dB", language).format( + value=d1(peak_tl, language) + ), + t("Device: {kind}", language).format(kind=str(result.kind)), + ] + if result.insertion_loss is not None: + mean_il = mean_finite(result.insertion_loss) + extended.append( + t("Mean insertion loss IL = {value} dB", language).format( + value=d1(mean_il, language) + ) + ) + resonance = _resonance_term(result, language) + if resonance is not None: + extended.append(resonance) + return mean_tl, statement, extended + + +def _basis_strip(language: str = "en") -> str: + """The four-pole transmission-loss relation line for the method-basis strip.""" + return t( + "TL = 10 lg[(Zn/Z1) (1/4) |T11 + " + "T12/Zn + Z1 T21 + " + "(Z1/Zn) T22|2] from the " + "compound four-pole matrix T, with the characteristic impedances " + "Z1 = ρc/Sin and Zn = " + "ρc/Sout (Munjal Eq. (3.27), no flow). TL is the " + "intrinsic attenuation for an anechoic termination; the insertion loss " + "adds the source and radiation impedance mismatch.", + language, + ) + + +def render_reactive_silencer_report( + result: "ReactiveSilencerResult", + path: str, + *, + metadata: ReportMetadata | None = None, + verbose: bool = False, + language: str = "en", +) -> str: + """Render a reactive-silencer transmission-loss fiche to a PDF at ``path``. + + :param result: A + :class:`~phonometry.noise_control.silencers.ReactiveSilencerResult` + carrying the per-band transmission loss ``TL`` and, when end impedances + were supplied, the insertion loss ``IL``, the device ``kind`` and any + resonance frequencies. + :param path: Destination path of the PDF file. + :param metadata: Optional :class:`ReportMetadata`; ``None`` produces a bare + fiche (body + result + basis, no header). A supplied ``requirement`` is + read as a declared minimum mean transmission loss (more is better). + :param verbose: Accepted for signature symmetry with the other fiches; the + silencer table already shows the insertion loss when it was computed. + :param language: Fiche language: ``"en"`` (default) or ``"es"``. + :return: The written ``path`` as a :class:`str`. + :raises ImportError: If reportlab (or, for the figure, matplotlib) is not + installed. + """ + del verbose # the silencer table has no extra verbose column + mean_tl, statement, extended = _statement(result, language) + verdict = None + if metadata is not None and metadata.requirement is not None: + verdict = performance_verdict( + mean_tl, metadata.requirement, "TL", + higher_is_better=True, language=language, + ) + return render_noise_control_fiche( + result, + path, + title=t("Reactive silencer transmission loss", language), + basis=_basis(language), + caption=_caption(result, language), + value_table=_value_table(result, language), + statement=statement, + extended=extended, + basis_strips=[_basis_strip(language)], + metadata=metadata, + language=language, + verdict=verdict, + ) diff --git a/src/phonometry/noise_control/enclosures.py b/src/phonometry/noise_control/enclosures.py index 366d84b7..019baaa9 100644 --- a/src/phonometry/noise_control/enclosures.py +++ b/src/phonometry/noise_control/enclosures.py @@ -47,6 +47,8 @@ if TYPE_CHECKING: from matplotlib.axes import Axes + from .._report.metadata import ReportMetadata + @dataclass(frozen=True) class EnclosureResult: @@ -83,6 +85,61 @@ def plot(self, ax: "Axes | None" = None, *, language: str = "en", **kwargs: Any) check_language(language) return plot_enclosure(self, ax=ax, language=language, **kwargs) + def report( + self, + path: str, + *, + metadata: "ReportMetadata | None" = None, + engine: str = "reportlab", + verbose: bool = False, + language: str = "en", + ) -> str: + """Render a machine-enclosure insertion-loss fiche to ``path``. + + Writes a one-page enclosure-performance sheet: the method-basis line + naming the Bies, Hansen & Howard insertion-loss model + (Engineering Noise Control 5th ed., section 7.4.2), an optional metadata + header (client, enclosed machine, test environment, instrumentation, + climate, date), a per-band table (nominal frequency, the supplied panel + transmission loss ``R``, the interior build-up correction ``C`` and the + net insertion loss ``IL = R - C``) beside the ``R``, ``C`` and ``IL`` + curves, the boxed mean insertion loss over the analysis bands with the + external and internal surface areas, an optional verdict row against a + declared minimum, and a method-basis strip stating + ``IL = R - C`` with ``C = 10 lg(0.3 + S_E / R_i)``. + + :param path: Destination path of the PDF file. + :param metadata: Optional :class:`~phonometry.ReportMetadata` supplying + the header (``client``, ``specimen`` the enclosed machine, + ``test_room`` the test environment, ``instrumentation``, + ``temperature``, ``relative_humidity``, ``pressure``, ``test_date``), + the footer identity (``laboratory``, ``operator``, ``report_id``, + ``notes``) and, via ``requirement``, a declared minimum mean + insertion loss (more insertion loss is better). The surface areas + come from the result itself. + :param engine: Rendering back end; only ``"reportlab"`` is supported. + :param verbose: When ``True`` the per-band table adds the interior room + constant ``R_i`` column. + :param language: Fiche language: ``"en"`` (default) or ``"es"``. + :return: The written ``path`` as a :class:`str`. + :raises ValueError: If ``engine`` is not ``"reportlab"`` or ``language`` + is unknown. + :raises ImportError: If reportlab (or, for the figure, matplotlib) is + not installed (``pip install phonometry[report]``). + """ + from .._i18n import check_language + + check_language(language) + if engine != "reportlab": + raise ValueError( + f"Unknown report engine {engine!r}; only 'reportlab' is supported." + ) + from .._report.enclosure import render_enclosure_report + + return render_enclosure_report( + self, path, metadata=metadata, verbose=verbose, language=language + ) + class PanelTransmissionResult(Protocol): """A panel prediction result exposing a per-band transmission loss. diff --git a/src/phonometry/noise_control/hvac.py b/src/phonometry/noise_control/hvac.py index f2825989..3db5df34 100644 --- a/src/phonometry/noise_control/hvac.py +++ b/src/phonometry/noise_control/hvac.py @@ -36,6 +36,8 @@ if TYPE_CHECKING: from matplotlib.axes import Axes + from .._report.metadata import ReportMetadata + _C_AIR = 343.0 # --------------------------------------------------------------------------- @@ -144,6 +146,62 @@ def plot(self, ax: "Axes | None" = None, *, language: str = "en", **kwargs: Any) check_language(language) return plot_hvac_spectrum(self, ax=ax, language=language, **kwargs) + def report( + self, + path: str, + *, + metadata: "ReportMetadata | None" = None, + engine: str = "reportlab", + verbose: bool = False, + language: str = "en", + ) -> str: + """Render an HVAC duct-noise-spectrum fiche to ``path``. + + Writes a one-page HVAC-noise sheet: the method-basis line naming the + reported quantity and the Bies, Hansen & Howard chapter (Engineering + Noise Control 5th ed., Chapter 8), an optional metadata header (client, + duct element, test environment, instrumentation, climate, date), a + per-band table (nominal frequency and the reported quantity) beside the + spectrum, the boxed single-number result (for a regenerated-noise + spectrum the A-weighted sound power level ``L_WA`` re 1 pW with the + overall unweighted total; for an attenuation spectrum the mean + attenuation with its band range), an optional verdict row against a + declared limit, and a method-basis strip stating the reported quantity's + relation. + + :param path: Destination path of the PDF file. + :param metadata: Optional :class:`~phonometry.ReportMetadata` supplying + the header (``client``, ``specimen`` the duct element, ``test_room`` + the test environment, ``instrumentation``, ``temperature``, + ``relative_humidity``, ``pressure``, ``test_date``), the footer + identity (``laboratory``, ``operator``, ``report_id``, ``notes``) + and, via ``requirement``, a declared maximum A-weighted sound power + level for a regenerated-noise spectrum (lower is better) or a + declared minimum mean attenuation for an attenuation spectrum (more + is better). + :param engine: Rendering back end; only ``"reportlab"`` is supported. + :param verbose: When ``True`` a regenerated-noise table adds the + A-weighting correction and the A-weighted band level columns. + :param language: Fiche language: ``"en"`` (default) or ``"es"``. + :return: The written ``path`` as a :class:`str`. + :raises ValueError: If ``engine`` is not ``"reportlab"`` or ``language`` + is unknown. + :raises ImportError: If reportlab (or, for the figure, matplotlib) is + not installed (``pip install phonometry[report]``). + """ + from .._i18n import check_language + + check_language(language) + if engine != "reportlab": + raise ValueError( + f"Unknown report engine {engine!r}; only 'reportlab' is supported." + ) + from .._report.hvac import render_hvac_report + + return render_hvac_report( + self, path, metadata=metadata, verbose=verbose, language=language + ) + def end_reflection_loss( frequencies: ArrayLike, diff --git a/src/phonometry/noise_control/silencers.py b/src/phonometry/noise_control/silencers.py index a91d482f..ca1bec55 100644 --- a/src/phonometry/noise_control/silencers.py +++ b/src/phonometry/noise_control/silencers.py @@ -75,6 +75,8 @@ if TYPE_CHECKING: from matplotlib.axes import Axes + from .._report.metadata import ReportMetadata + #: Reference air properties at 20 degC, 101.325 kPa. _C_AIR = 343.0 _RHO_AIR = 1.206 @@ -354,6 +356,62 @@ def plot(self, ax: "Axes | None" = None, *, language: str = "en", **kwargs: Any) check_language(language) return plot_reactive_silencer(self, ax=ax, language=language, **kwargs) + def report( + self, + path: str, + *, + metadata: "ReportMetadata | None" = None, + engine: str = "reportlab", + verbose: bool = False, + language: str = "en", + ) -> str: + """Render a reactive-silencer transmission-loss fiche to ``path``. + + Writes a one-page silencer-performance sheet: the method-basis line + naming the plane-wave four-pole (transfer-matrix) method (Munjal, + Acoustics of Ducts and Mufflers 2nd ed., Eq. (3.27); Bies, Hansen & + Howard, Engineering Noise Control 5th ed., sections 8.8-8.9), an + optional metadata header (client, device, test environment, + instrumentation, climate, date), a per-band table (nominal frequency, + the transmission loss ``TL`` and, when computed, the insertion loss + ``IL``) beside the ``TL`` (and ``IL``) curves, the boxed mean + transmission loss over the analysis bands with the peak transmission + loss and the device kind, an optional verdict row against a declared + minimum, and a method-basis strip stating the four-pole + transmission-loss relation. + + :param path: Destination path of the PDF file. + :param metadata: Optional :class:`~phonometry.ReportMetadata` supplying + the header (``client``, ``specimen`` the device, ``test_room`` the + test environment, ``instrumentation``, ``temperature``, + ``relative_humidity``, ``pressure``, ``test_date``), the footer + identity (``laboratory``, ``operator``, ``report_id``, ``notes``) + and, via ``requirement``, a declared minimum mean transmission loss + (more transmission loss is better). + :param engine: Rendering back end; only ``"reportlab"`` is supported. + :param verbose: Accepted for signature symmetry with the other fiches; + the silencer table already shows the insertion loss when it was + computed. + :param language: Fiche language: ``"en"`` (default) or ``"es"``. + :return: The written ``path`` as a :class:`str`. + :raises ValueError: If ``engine`` is not ``"reportlab"`` or ``language`` + is unknown. + :raises ImportError: If reportlab (or, for the figure, matplotlib) is + not installed (``pip install phonometry[report]``). + """ + from .._i18n import check_language + + check_language(language) + if engine != "reportlab": + raise ValueError( + f"Unknown report engine {engine!r}; only 'reportlab' is supported." + ) + from .._report.silencer import render_reactive_silencer_report + + return render_reactive_silencer_report( + self, path, metadata=metadata, verbose=verbose, language=language + ) + def _result( f: NDArray[np.float64], diff --git a/tests/noise_control/test_enclosure_report.py b/tests/noise_control/test_enclosure_report.py new file mode 100644 index 00000000..a38cd317 --- /dev/null +++ b/tests/noise_control/test_enclosure_report.py @@ -0,0 +1,215 @@ +# Copyright (c) 2026. Jose M. Requena-Plens +""" +Tests for the machine-enclosure insertion-loss ``.report()`` fiche. + +The rendered values are checked against a clean-room oracle derived from the +Bies, Hansen & Howard model (Engineering Noise Control 5th ed., section 7.4.2), +independent of the library's own combination path: the interior room constant +``R_i = S_i alpha_i / (1 - alpha_i)`` (Eq. (7.103)), the build-up correction +``C = 10 lg(0.3 + S_E / R_i)`` (Eq. (7.111)) and the net insertion loss +``IL = R - C``. The tests recompute the mean insertion loss and a couple of band +values from these closed forms and assert they appear in the PDF, along with the +nominal band labels, the method-basis prose and the surface areas. Values are +read back via pypdf text extraction; structural facts (one page, rejected +engines/languages) complete the rendering contract. +""" + +from __future__ import annotations + +import math +import os + +import numpy as np +import pytest + +from phonometry import ReportMetadata, enclosure_insertion_loss + +_PDF_MAGIC = b"%PDF" + +_FREQS = np.array([63, 125, 250, 500, 1000, 2000, 4000], dtype=float) +_PANEL_R = np.array([18, 22, 28, 33, 38, 42, 45], dtype=float) +_S_E = 24.0 # external surface area, m^2 +_S_I = 30.0 # internal surface area, m^2 +_ALPHA = 0.30 # mean interior absorption + + +def _assert_one_page(path: str) -> None: + from pypdf import PdfReader + + with open(path, "rb") as handle: + assert handle.read(4) == _PDF_MAGIC + assert os.path.getsize(path) > 0 + assert len(PdfReader(path).pages) == 1 + + +def _extract_text(path: str) -> str: + from pypdf import PdfReader + + raw = "\n".join(page.extract_text() for page in PdfReader(path).pages) + return " ".join(raw.split()) + + +def _result(): + return enclosure_insertion_loss(_PANEL_R, _S_E, _S_I, _ALPHA, frequencies=_FREQS) + + +def _oracle_correction() -> np.ndarray: + """Closed-form build-up correction C = 10 lg(0.3 + S_E / R_i) (Eq. (7.111)).""" + r_i = _S_I * _ALPHA / (1.0 - _ALPHA) + return 10.0 * np.log10(0.3 + _S_E / r_i) * np.ones_like(_PANEL_R) + + +def _oracle_il() -> np.ndarray: + """Closed-form net insertion loss IL = R - C.""" + return _PANEL_R - _oracle_correction() + + +def _oracle_mean_il() -> float: + return float(np.mean(_oracle_il())) + + +def test_hand_oracle_matches_library() -> None: + """The library IL and C equal the closed-form Bies values.""" + res = _result() + np.testing.assert_allclose(res.correction, _oracle_correction(), atol=1e-9) + np.testing.assert_allclose(res.insertion_loss, _oracle_il(), atol=1e-9) + + +def test_report_renders_oracle_values(tmp_path) -> None: + """The fiche prints the mean IL and a couple of band R/C/IL values.""" + pytest.importorskip("reportlab") + pytest.importorskip("svglib") + pytest.importorskip("matplotlib") + res = _result() + out = tmp_path / "enclosure.pdf" + returned = res.report(str(out), metadata=ReportMetadata(requirement=20.0)) + assert returned == str(out) + _assert_one_page(str(out)) + text = _extract_text(str(out)) + + # Mean insertion loss (boxed) to one decimal. + assert f"{_oracle_mean_il():.1f}" in text + # Two band IL values (250 Hz and 1 kHz) to one decimal. + il = _oracle_il() + assert f"{il[2]:.1f}" in text + assert f"{il[4]:.1f}" in text + # The supplied panel R heads its column. + assert f"{_PANEL_R[2]:.1f}" in text + # The build-up correction C to one decimal. + assert f"{_oracle_correction()[0]:.1f}" in text + # Nominal band labels and the caption. + assert "63" in text and "4000" in text + assert "Octave-band insertion loss" in text + # Method basis prose and the surface areas in the boxed result. + assert "Bies" in text + assert "IL = R - C" in text + assert "24.00" in text # external surface area S_E + assert "30.00" in text # internal surface area S_i + + +def test_verbose_adds_room_constant_column(tmp_path) -> None: + """verbose=True adds the interior room constant R_i column.""" + pytest.importorskip("reportlab") + pytest.importorskip("svglib") + pytest.importorskip("matplotlib") + res = _result() + out = tmp_path / "verbose.pdf" + res.report(str(out), verbose=True) + _assert_one_page(str(out)) + text = _extract_text(str(out)) + r_i = _S_I * _ALPHA / (1.0 - _ALPHA) # = 12.857... -> 12.9 + assert f"{r_i:.1f}" in text + + +def test_third_octave_labels_and_caption(tmp_path) -> None: + """A one-third-octave set is labelled by nominal centres and captioned.""" + pytest.importorskip("reportlab") + pytest.importorskip("svglib") + pytest.importorskip("matplotlib") + freqs = np.array([100, 125, 160, 200, 250, 315, 400, 500, 630], dtype=float) + r = np.linspace(20.0, 40.0, freqs.size) + res = enclosure_insertion_loss(r, _S_E, _S_I, _ALPHA, frequencies=freqs) + out = tmp_path / "third.pdf" + res.report(str(out)) + _assert_one_page(str(out)) + text = _extract_text(str(out)) + assert "One-third-octave-band insertion loss" in text + for label in ("100", "125", "160", "630"): + assert label in text + + +@pytest.mark.parametrize( + ("limit", "verdict"), + [(20.0, "PASS"), (40.0, "FAIL")], +) +def test_verdict_against_declared_minimum(tmp_path, limit: float, verdict: str) -> None: + """A declared minimum yields a PASS/FAIL verdict (more insertion loss is better).""" + pytest.importorskip("reportlab") + pytest.importorskip("svglib") + pytest.importorskip("matplotlib") + res = _result() + out = tmp_path / f"verdict_{limit}.pdf" + res.report(str(out), metadata=ReportMetadata(requirement=limit)) + text = _extract_text(str(out)) + assert verdict in text + assert "required" in text + # Mean IL (28.9) passes a 20 dB minimum, fails a 40 dB one. + assert (_oracle_mean_il() >= limit) == (verdict == "PASS") + assert math.isfinite(_oracle_mean_il()) + + +def test_metadata_header_renders(tmp_path) -> None: + """Supplied metadata renders the machine, environment and identity fields.""" + pytest.importorskip("reportlab") + pytest.importorskip("svglib") + pytest.importorskip("matplotlib") + res = _result() + metadata = ReportMetadata( + client="Example works", + specimen="Reciprocating compressor", + test_room="Machine hall, line 3", + instrumentation="Class 1 SLM, octave bank", + laboratory="Acoustics lab", + report_id="ENC-01", + ) + out = tmp_path / "meta.pdf" + res.report(str(out), metadata=metadata) + _assert_one_page(str(out)) + text = _extract_text(str(out)) + for token in ( + "Example works", "Reciprocating compressor", "Machine hall, line 3", + "Class 1 SLM, octave bank", "Acoustics lab", + ): + assert token in text + + +def test_spanish_report_renders_translated_fiche(tmp_path) -> None: + """language="es" renders the enclosure vocabulary and comma decimals.""" + pytest.importorskip("reportlab") + pytest.importorskip("svglib") + pytest.importorskip("matplotlib") + res = _result() + out = tmp_path / "es.pdf" + res.report(str(out), language="es") + _assert_one_page(str(out)) + text = _extract_text(str(out)) + assert "Pérdida por inserción de encapsulado de máquina" in text + assert "Pérdida por inserción media" in text + # Comma decimal separator on the mean insertion loss. + assert f"{_oracle_mean_il():.1f}".replace(".", ",") in text + + +def test_unknown_engine_rejected(tmp_path) -> None: + """An unknown rendering engine raises ValueError.""" + res = _result() + out = str(tmp_path / "x.pdf") + with pytest.raises(ValueError, match="engine"): + res.report(out, engine="weasyprint") + + +def test_unknown_language_rejected(tmp_path) -> None: + """An unknown fiche language raises ValueError.""" + res = _result() + out = str(tmp_path / "bad.pdf") + with pytest.raises(ValueError, match="language"): + res.report(out, language="xx") diff --git a/tests/noise_control/test_hvac_report.py b/tests/noise_control/test_hvac_report.py new file mode 100644 index 00000000..e9193a9a --- /dev/null +++ b/tests/noise_control/test_hvac_report.py @@ -0,0 +1,193 @@ +# Copyright (c) 2026. Jose M. Requena-Plens +""" +Tests for the HVAC duct-noise-spectrum ``.report()`` fiche. + +The rendered values are checked against a clean-room oracle independent of the +library's own path. For a regenerated-noise spectrum the band sound power level +follows the VDI 2081-1 straight-duct formula +``L_W = 7 + 50 lg U + 10 lg S - 2 - 26 lg(1.14 + 0.02 f / U)`` (Bies, Hansen & +Howard, Engineering Noise Control 5th ed., Eq. (8.251)); the A-weighted total +combines the bands with the published octave A-weighting corrections (IEC +61672-1 / ISO 3744 Annex E Table E.2). The tests recompute the A-weighted and +overall levels and a couple of band values and assert they appear in the PDF, +along with the nominal band labels, the method-basis prose and the reported +quantity. An attenuation spectrum exercises the more-is-better direction. +Values are read back via pypdf text extraction; structural facts complete the +rendering contract. +""" + +from __future__ import annotations + +import math +import os + +import numpy as np +import pytest + +from phonometry import ReportMetadata +from phonometry.noise_control import hvac + +_PDF_MAGIC = b"%PDF" + +_FREQS = np.array([63, 125, 250, 500, 1000, 2000, 4000], dtype=float) +_U = 12.0 # flow velocity, m/s +_S = 0.04 # duct area, m^2 + +#: Published octave-band A-weighting corrections (IEC 61672-1 / ISO 3744 +#: Annex E Table E.2), the clean-room oracle for the A-weighted total. +_A_WEIGHT = np.array([-26.2, -16.1, -8.6, -3.2, 0.0, 1.2, 1.0]) + + +def _assert_one_page(path: str) -> None: + from pypdf import PdfReader + + with open(path, "rb") as handle: + assert handle.read(4) == _PDF_MAGIC + assert os.path.getsize(path) > 0 + assert len(PdfReader(path).pages) == 1 + + +def _extract_text(path: str) -> str: + from pypdf import PdfReader + + raw = "\n".join(page.extract_text() for page in PdfReader(path).pages) + return " ".join(raw.split()) + + +def _result(): + return hvac.flow_noise_straight_duct(_FREQS, _U, _S) + + +def _oracle_lw() -> np.ndarray: + """Closed-form VDI 2081-1 straight-duct band sound power level.""" + return ( + 7.0 + 50.0 * np.log10(_U) + 10.0 * np.log10(_S) - 2.0 + - 26.0 * np.log10(1.14 + 0.02 * _FREQS / _U) + ) + + +def _oracle_overall() -> float: + lw = _oracle_lw() + return float(10.0 * np.log10(np.sum(10.0 ** (lw / 10.0)))) + + +def _oracle_lwa() -> float: + lw = _oracle_lw() + _A_WEIGHT + return float(10.0 * np.log10(np.sum(10.0 ** (lw / 10.0)))) + + +def test_hand_oracle_matches_library() -> None: + """The library band L_W equals the closed-form VDI values.""" + res = _result() + np.testing.assert_allclose(res.values, _oracle_lw(), atol=1e-9) + + +def test_report_renders_oracle_values(tmp_path) -> None: + """The fiche prints the A-weighted total, the overall L_W and band values.""" + pytest.importorskip("reportlab") + pytest.importorskip("svglib") + pytest.importorskip("matplotlib") + res = _result() + out = tmp_path / "hvac.pdf" + returned = res.report(str(out), metadata=ReportMetadata(requirement=45.0)) + assert returned == str(out) + _assert_one_page(str(out)) + text = _extract_text(str(out)) + + assert f"{_oracle_lwa():.1f}" in text # A-weighted total (boxed) + assert "dB(A)" in text + assert f"{_oracle_overall():.1f}" in text # overall L_W (extended) + assert "re 1 pW" in text + # Two band L_W values (125 Hz and 1 kHz). + lw = _oracle_lw() + assert f"{lw[1]:.1f}" in text + assert f"{lw[4]:.1f}" in text + # Nominal band labels, caption and method basis. + assert "63" in text and "4000" in text + assert "Octave-band regenerated sound power levels" in text + assert "VDI 2081-1" in text + + +def test_verbose_adds_a_weighting_columns(tmp_path) -> None: + """verbose=True adds the A-weighting correction and A-weighted band columns.""" + pytest.importorskip("reportlab") + pytest.importorskip("svglib") + pytest.importorskip("matplotlib") + res = _result() + out = tmp_path / "verbose.pdf" + res.report(str(out), verbose=True) + _assert_one_page(str(out)) + text = _extract_text(str(out)) + # The 63 Hz and 2 kHz A-weighting corrections to one decimal. + assert "-26.2" in text + assert "1.2" in text + + +@pytest.mark.parametrize( + ("limit", "verdict"), + [(45.0, "PASS"), (30.0, "FAIL")], +) +def test_power_verdict_lower_is_better(tmp_path, limit: float, verdict: str) -> None: + """A regenerated-noise limit passes at or below the A-weighted level.""" + pytest.importorskip("reportlab") + pytest.importorskip("svglib") + pytest.importorskip("matplotlib") + res = _result() + out = tmp_path / f"verdict_{limit}.pdf" + res.report(str(out), metadata=ReportMetadata(requirement=limit)) + text = _extract_text(str(out)) + assert verdict in text + assert "required" in text + assert (_oracle_lwa() <= limit) == (verdict == "PASS") + assert math.isfinite(_oracle_lwa()) + + +def test_attenuation_report_mean_and_direction(tmp_path) -> None: + """An attenuation spectrum boxes the mean and passes when more is better.""" + pytest.importorskip("reportlab") + pytest.importorskip("svglib") + pytest.importorskip("matplotlib") + bands = np.array([63, 125, 250, 500, 1000, 2000], dtype=float) + res = hvac.end_reflection_loss(bands, 0.3, termination="flush") + mean_att = float(np.mean(res.values)) + out = tmp_path / "atten.pdf" + res.report(str(out), metadata=ReportMetadata(requirement=1.0)) + _assert_one_page(str(out)) + text = _extract_text(str(out)) + assert "Octave-band attenuation" in text + assert "Mean attenuation D" in text + assert f"{mean_att:.1f}" in text + # More attenuation is better: mean (>1 dB) clears the 1 dB minimum. + assert "PASS" in text + assert mean_att >= 1.0 + + +def test_spanish_report_renders_translated_fiche(tmp_path) -> None: + """language="es" renders the HVAC vocabulary and comma decimals.""" + pytest.importorskip("reportlab") + pytest.importorskip("svglib") + pytest.importorskip("matplotlib") + res = _result() + out = tmp_path / "es.pdf" + res.report(str(out), language="es") + _assert_one_page(str(out)) + text = _extract_text(str(out)) + assert "Espectro de ruido de conducto de climatización" in text + assert "Nivel de potencia acústica ponderado A" in text + assert f"{_oracle_lwa():.1f}".replace(".", ",") in text + + +def test_unknown_engine_rejected(tmp_path) -> None: + """An unknown rendering engine raises ValueError.""" + res = _result() + out = str(tmp_path / "x.pdf") + with pytest.raises(ValueError, match="engine"): + res.report(out, engine="weasyprint") + + +def test_unknown_language_rejected(tmp_path) -> None: + """An unknown fiche language raises ValueError.""" + res = _result() + out = str(tmp_path / "bad.pdf") + with pytest.raises(ValueError, match="language"): + res.report(out, language="xx") diff --git a/tests/noise_control/test_silencer_report.py b/tests/noise_control/test_silencer_report.py new file mode 100644 index 00000000..a3274204 --- /dev/null +++ b/tests/noise_control/test_silencer_report.py @@ -0,0 +1,177 @@ +# Copyright (c) 2026. Jose M. Requena-Plens +""" +Tests for the reactive-silencer transmission-loss ``.report()`` fiche. + +The rendered values are checked against a clean-room oracle derived from the +simple-expansion-chamber closed form (Bies, Hansen & Howard, Engineering Noise +Control 5th ed., Eq. (8.111)), independent of the library's four-pole path: +``TL = 10 lg[1 + (1/4)(m - 1/m)^2 sin^2(kL)]`` with the area ratio +``m = S_exp / S_duct`` and ``k = 2 pi f / c``. The tests recompute the mean and +peak transmission loss and a couple of band values from this closed form and +assert they appear in the PDF, along with the nominal band labels, the +four-pole method basis prose and the device kind. Values are read back via pypdf +text extraction; structural facts (one page, rejected engines/languages) +complete the rendering contract. +""" + +from __future__ import annotations + +import os + +import numpy as np +import pytest + +from phonometry.noise_control import silencers as sl + +_PDF_MAGIC = b"%PDF" + +_FREQS = np.array([63, 125, 250, 500, 1000, 2000, 4000], dtype=float) +_LENGTH = 0.5 +_S_EXP = 0.08 +_S_DUCT = 0.01 +_C = 343.0 + + +def _assert_one_page(path: str) -> None: + from pypdf import PdfReader + + with open(path, "rb") as handle: + assert handle.read(4) == _PDF_MAGIC + assert os.path.getsize(path) > 0 + assert len(PdfReader(path).pages) == 1 + + +def _extract_text(path: str) -> str: + from pypdf import PdfReader + + raw = "\n".join(page.extract_text() for page in PdfReader(path).pages) + return " ".join(raw.split()) + + +def _result(): + return sl.expansion_chamber(_FREQS, _LENGTH, _S_EXP, _S_DUCT) + + +def _oracle_tl() -> np.ndarray: + """Closed-form expansion-chamber TL (Bies Eq. (8.111)).""" + m = _S_EXP / _S_DUCT + k = 2.0 * np.pi * _FREQS / _C + return 10.0 * np.log10(1.0 + 0.25 * (m - 1.0 / m) ** 2 * np.sin(k * _LENGTH) ** 2) + + +def test_hand_oracle_matches_library() -> None: + """The library TL equals the closed-form expansion-chamber values.""" + res = _result() + np.testing.assert_allclose(res.transmission_loss, _oracle_tl(), atol=1e-9) + + +def test_report_renders_oracle_values(tmp_path) -> None: + """The fiche prints the mean and peak TL and a couple of band TL values.""" + pytest.importorskip("reportlab") + pytest.importorskip("svglib") + pytest.importorskip("matplotlib") + res = _result() + out = tmp_path / "silencer.pdf" + returned = res.report(str(out), metadata=None) + assert returned == str(out) + _assert_one_page(str(out)) + text = _extract_text(str(out)) + + tl = _oracle_tl() + assert f"{float(np.mean(tl)):.1f}" in text # mean TL (boxed) + assert f"{float(np.max(tl)):.1f}" in text # peak TL (extended) + # Two band TL values (125 Hz and 500 Hz). + assert f"{tl[1]:.1f}" in text + assert f"{tl[3]:.1f}" in text + # Nominal band labels and caption. + assert "63" in text and "4000" in text + assert "Octave-band transmission loss" in text + # Method basis prose and the device kind. + assert "Munjal" in text + assert "four-pole" in text + assert "expansion chamber" in text + + +def test_insertion_loss_column_when_impedances_given(tmp_path) -> None: + """A result with end impedances renders the insertion-loss column.""" + pytest.importorskip("reportlab") + pytest.importorskip("svglib") + pytest.importorskip("matplotlib") + z = 1.206 * _C / _S_DUCT # anechoic reference -> IL equals TL + res = sl.expansion_chamber( + _FREQS, _LENGTH, _S_EXP, _S_DUCT, + source_impedance=z, radiation_impedance=z, + ) + out = tmp_path / "with_il.pdf" + res.report(str(out)) + _assert_one_page(str(out)) + text = _extract_text(str(out)) + assert "IL [dB]" in text + # For the anechoic reference the insertion loss equals the transmission loss. + assert "Mean insertion loss IL" in text + + +def test_resonator_reports_resonances(tmp_path) -> None: + """A tuned resonator lists its resonance frequencies in the boxed terms.""" + pytest.importorskip("reportlab") + pytest.importorskip("svglib") + pytest.importorskip("matplotlib") + f = np.array([50, 63, 80, 100, 125, 160, 200], dtype=float) + res = sl.helmholtz_resonator(f, 0.01, 1e-4, 0.02, 1e-3) + out = tmp_path / "helmholtz.pdf" + res.report(str(out)) + _assert_one_page(str(out)) + text = _extract_text(str(out)) + assert "Helmholtz resonator" in text + assert "Resonance frequencies" in text + + +@pytest.mark.parametrize( + ("limit", "verdict"), + [(6.0, "PASS"), (12.0, "FAIL")], +) +def test_verdict_against_declared_minimum(tmp_path, limit: float, verdict: str) -> None: + """A declared minimum yields a PASS/FAIL verdict (more TL is better).""" + pytest.importorskip("reportlab") + pytest.importorskip("svglib") + pytest.importorskip("matplotlib") + from phonometry import ReportMetadata + + res = _result() + out = tmp_path / f"verdict_{limit}.pdf" + res.report(str(out), metadata=ReportMetadata(requirement=limit)) + text = _extract_text(str(out)) + assert verdict in text + assert "required" in text + assert (float(np.mean(_oracle_tl())) >= limit) == (verdict == "PASS") + + +def test_spanish_report_renders_translated_fiche(tmp_path) -> None: + """language="es" renders the silencer vocabulary and comma decimals.""" + pytest.importorskip("reportlab") + pytest.importorskip("svglib") + pytest.importorskip("matplotlib") + res = _result() + out = tmp_path / "es.pdf" + res.report(str(out), language="es") + _assert_one_page(str(out)) + text = _extract_text(str(out)) + assert "Pérdida por transmisión de silenciador reactivo" in text + assert "Pérdida por transmisión media" in text + assert f"{float(np.mean(_oracle_tl())):.1f}".replace(".", ",") in text + + +def test_unknown_engine_rejected(tmp_path) -> None: + """An unknown rendering engine raises ValueError.""" + res = _result() + out = str(tmp_path / "x.pdf") + with pytest.raises(ValueError, match="engine"): + res.report(out, engine="weasyprint") + + +def test_unknown_language_rejected(tmp_path) -> None: + """An unknown fiche language raises ValueError.""" + res = _result() + out = str(tmp_path / "bad.pdf") + with pytest.raises(ValueError, match="language"): + res.report(out, language="xx") From 89d27e5d447427bda2fb4c3758bb46070224b551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20M=2E=20Requena=20Plens?= Date: Thu, 23 Jul 2026 00:10:14 +0200 Subject: [PATCH 2/3] Address SonarCloud findings on the noise-control renderers Reduce render_noise_control_fiche below the parameter-count threshold by fixing the two-panel split widths internally (the three renderers never overrode them), and lift the HVAC verdict symbol/unit selection out of a nested conditional into an explicit if/elif/else. No change to rendered output; the committed example fiches are unaffected. --- src/phonometry/_report/_noise_control_fiche.py | 12 +++++------- src/phonometry/_report/hvac.py | 12 ++++++++---- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/phonometry/_report/_noise_control_fiche.py b/src/phonometry/_report/_noise_control_fiche.py index c18cbf91..3707acd9 100644 --- a/src/phonometry/_report/_noise_control_fiche.py +++ b/src/phonometry/_report/_noise_control_fiche.py @@ -119,16 +119,14 @@ def render_noise_control_fiche( metadata: ReportMetadata | None, language: str, verdict: Tuple[str, bool] | None = None, - left_width_mm: float = 64.0, - plot_width_mm: float = 110.0, - figure_width_mm: float = 108.0, ) -> str: """Assemble the shared noise-control fiche flow and build the PDF at ``path``. The metadata header grid reuses the sound-power source/environment layout, and the requirement verdict is supplied pre-computed by each renderer (its quantity symbol and pass direction). The two-panel body puts the per-band - ``value_table`` on the left and the result's own ``plot`` on the right. + ``value_table`` on the left (a compact ~64 mm cell that fits the widest + four-column enclosure/HVAC table) and the result's own ``plot`` on the right. :param result: The noise-control result; its ``plot`` draws the right panel. :param title: The already-translated fiche title. @@ -142,13 +140,13 @@ def render_noise_control_fiche( identity and (via each renderer) the requirement verdict. :param language: ``"en"`` (default) or ``"es"``. :param verdict: Optional pre-computed ``(text, passed)`` verdict row. - :param left_width_mm: Width of the left (table) panel, in mm. - :param plot_width_mm: Width of the right (plot) panel, in mm. - :param figure_width_mm: Target width of the embedded vector figure, in mm. :return: The written ``path`` as a :class:`str`. :raises ImportError: If reportlab (or, for the figure, matplotlib) is not installed. """ + # Fixed two-panel split, summing to the 174 mm content width: a compact + # table cell beside the plot, with the embedded figure just inside its cell. + left_width_mm, plot_width_mm, figure_width_mm = 64.0, 110.0, 108.0 try: from reportlab.lib import colors from reportlab.lib.units import mm diff --git a/src/phonometry/_report/hvac.py b/src/phonometry/_report/hvac.py index b93f184f..8bcd446a 100644 --- a/src/phonometry/_report/hvac.py +++ b/src/phonometry/_report/hvac.py @@ -299,10 +299,14 @@ def render_hvac_report( ) verdict = None if metadata is not None and metadata.requirement is not None: - symbol = "LWA" if _is_power(result) and corrections is not None else ( - "LW" if _is_power(result) else "D" - ) - unit = "dB(A)" if _is_power(result) and corrections is not None else "dB" + a_weighted = _is_power(result) and corrections is not None + if a_weighted: + symbol = "LWA" + elif _is_power(result): + symbol = "LW" + else: + symbol = "D" + unit = "dB(A)" if a_weighted else "dB" verdict = performance_verdict( value, metadata.requirement, symbol, higher_is_better=higher_is_better, unit=unit, language=language, From 2d4739d9632185792c508dfce1138ee83ac306a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20M=2E=20Requena=20Plens?= Date: Thu, 23 Jul 2026 00:29:04 +0200 Subject: [PATCH 3/3] Round the requirement to display precision and fit the verbose table Compare the declared requirement at the same one-decimal precision as the measured value in the noise-control verdict, so the printed comparison can never contradict the verdict at the boundary. Also trim the verbose enclosure table columns to sum to the 64 mm left panel width. --- src/phonometry/_report/_noise_control_fiche.py | 15 ++++++++------- src/phonometry/_report/enclosure.py | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/phonometry/_report/_noise_control_fiche.py b/src/phonometry/_report/_noise_control_fiche.py index 3707acd9..f791e463 100644 --- a/src/phonometry/_report/_noise_control_fiche.py +++ b/src/phonometry/_report/_noise_control_fiche.py @@ -79,20 +79,21 @@ def performance_verdict( ``higher_is_better`` selects the direction: an insertion or transmission loss passes at or above the declared minimum, while a radiated noise level - passes at or below the declared maximum. The comparison uses the displayed - (one-decimal) value so the printed number cannot contradict the verdict at - the boundary. ``symbol`` is markup (e.g. ``IL``, ``LWA``) and - ``unit`` its unit symbol (``dB`` or ``dB(A)``), neither of which is - translated. + passes at or below the declared maximum. Both the measured value and the + requirement are compared at the displayed (one-decimal) precision so the + printed numbers cannot contradict the verdict at the boundary. ``symbol`` is + markup (e.g. ``IL``, ``LWA``) and ``unit`` its unit symbol + (``dB`` or ``dB(A)``), neither of which is translated. """ rounded = display_round(value) + rounded_requirement = display_round(requirement) if higher_is_better: - passed = math.isfinite(value) and rounded >= requirement + passed = math.isfinite(value) and rounded >= rounded_requirement template = t( "{sym} = {value} {unit}, required ≥ {req} {unit}", language ) else: - passed = math.isfinite(value) and rounded <= requirement + passed = math.isfinite(value) and rounded <= rounded_requirement template = t( "{sym} = {value} {unit}, required ≤ {req} {unit}", language ) diff --git a/src/phonometry/_report/enclosure.py b/src/phonometry/_report/enclosure.py index fb2ff02f..9ee29126 100644 --- a/src/phonometry/_report/enclosure.py +++ b/src/phonometry/_report/enclosure.py @@ -107,7 +107,7 @@ def _value_table(result: Any, verbose: bool, language: str = "en") -> Any: "Ri [m2]", "IL [dB]", ] - widths = [12.0, 13.0, 13.0, 14.0, 14.0] + widths = [12.0, 13.0, 13.0, 13.0, 13.0] rows_data = [ [ labels[i],