feat: normative ISO 717 rating report (.report() PDF fiche) (#238)
* feat(building): ISO 717 Annex C rating report (.report() -> PDF)
Add a report(path) method that renders an ISO 717 Annex C sound-insulation
fiche to a one-page PDF. WeightedRatingResult.report() renders the airborne
ISO 717-1 layout (the Rw (C; Ctr) statement, the measured-versus-shifted
reference plot and the Table C.1 evaluation table with the sum of unfavourable
deviations), and ImpactRatingResult.report() renders the impact ISO 717-2
counterpart with the Ln,w (CI) statement and the opposite deviation sign.
SoundReductionResult.report() is a convenience that rates the predicted R(f)
and writes its fiche in one call.
Rendering uses reportlab, added as the optional phonometry[report] extra so it
stays out of the runtime dependencies; a missing reportlab raises a clear
ImportError with the install command, mirroring the matplotlib guard behind
.plot(). The rating results gain a quantity field ("airborne"/"impact") that
selects the report labels and standard reference.
* test(building): verify the ISO 717 fiche against the Annex C worked examples
Pins the report content to the printed worked examples: ISO 717-1 Annex C
Table C.1 (Rw(C;Ctr) = 30(-2;-3) dB, unfavourable sum 31,8 dB, reference shifted
by -22 dB and the per-band deviations) and ISO 717-2 Annex C Table C.1
(Ln,w = 79 dB, CI = -11 dB, sum 28,0 dB).
* feat(building): one-page ISO 717 fiche with a vector (SVG) plot
Embeds the ISO 717 plot as vector graphics via svglib (svg2rlg, text as paths)
so the curve stays crisp at any resolution, tightens the layout to a single
A4 page, and reduces the single-number statement line. Adds svglib to the
optional 'report' extra.
* feat(building): two-column ISO 717 fiche (plot beside condensed table)
Places the vector plot and the condensed ISO 717 Annex C evaluation table
side by side (datasheet layout) and drops the plot's redundant title, since
the header already states the single number and the unfavourable-deviation sum.
* feat(building): accredited-laboratory ISO 717 report fiche + ReportMetadata
Rework the ISO 717 `.report()` PDF into an accredited-laboratory test-report
layout modelled on ISO 10140-2 / ISO 16283 lab reports rated per ISO 717:
a standard-basis line, an optional metadata header block, the one-third-octave
table beside the measured-versus-shifted-reference plot, a boxed single-number
result, an optional PASS/FAIL verdict row and a footer with a fixed disclaimer.
Report metadata is now a shared frozen `ReportMetadata` dataclass (specimen,
client, room and climatic conditions, laboratory identity and an optional
requirement); all fields optional and only the supplied ones render, so the
same object drives a full accredited fiche or, with metadata=None, a prediction
fiche. `report()` gains `metadata` and `verbose` keywords; `verbose=True` keeps
the ISO 717 Annex C evaluation columns. The rating results keep their vector
(SVG) plot. `ReportMetadata` is exported at the top level and documented.
* test: add pypdf dev dependency for the report one-page assertion
* feat(building): enlarge the report plot and narrow the table to match the accredited reference
* feat(building): fixed report plot axis, legend above, per-room climate metadata
* feat: generate committed example ISO 717 report fiches (make reports)
Adds scripts/generate_reports.py and a 'reports' Make target that render the
example .report() fiches into .github/reports/ (airborne and impact), linked
from the documentation as normative-report examples, mirroring the figure
pipeline. Not byte-checked in CI (the vector plot differs by ~1 ULP across
CPUs); tests/test_generate_reports.py checks the generator still yields valid
one-page PDFs.
* test(architecture): treat _report as a rendering leaf like _plot
The report renderer mirrors _plot: domain modules import it lazily inside
.report() and it references the rating result types only under TYPE_CHECKING,
so the whitelist exempts the _report edges exactly as it does _plot, and the
TYPE_CHECKING-only guarantee now covers _report too.
* refactor(_report): address Sonar findings on the ISO 717 renderer
Imports reportlab names directly per function instead of via a dict alias
(clears the capitalized-local warnings), extracts the result box and verdict
into helpers to lower the render function's cognitive complexity, switches the
doc kwargs to a dict literal, and hoists the path construction out of the
report tests' pytest.raises blocks.
* fix(_report): address PR review (XML escaping, temperature/humidity ranges, extras)
- Escape user-supplied metadata strings before rendering them in reportlab
Paragraphs so a '&', '<' or '>' can no longer crash the XML parser.
- ReportMetadata now validates by physical range: dimensions/mass/volume/
pressure/requirement stay strictly positive, temperatures may be zero or
negative (cold test conditions), relative humidity must be 0..100 %.
- Add svglib to the 'full' extra (it is a real report dependency).
- Use a comma decimal separator consistently across the fiche, enclose the
verbose sum row in the table border, and assert equal-length band arrays.
- Rename the render-leaf architecture test for its _plot + _report scope.
* fix(_report): use a period decimal separator (English fiche)
The fiche text is English, so numbers use a period separator throughout
(metadata grid and one-third-octave table alike), matching accredited English
lab reports. A locale-aware separator will come with the planned EN/ES i18n.
* docs: regenerate API reference after the ReportMetadata docstring update
* refactor(_report): lower ReportMetadata validation complexity
Extract a _require helper so __post_init__ is three short field loops,
dropping the cognitive complexity flagged by Sonar.
* docs(_report): describe ReportMetadata validation accurately in the summary
The class summary now states the actual per-range validation (positive
dimensions/mass/volume/pressure/requirement, finite temperatures allowing 0 C
or below, humidity within 0..100 %) instead of a blanket strictly-positive
claim; the :raises: note and __post_init__ behaviour are unchanged.
Impedance tube: complete circular, rectangular and square cross-section support (#380)
* Impedance tube: complete circular, rectangular and square cross-section support
The ISO 10534-2 branch already distinguished circular from rectangular
tubes; the ASTM E2611 branch ignored the cross-section entirely. Both
branches now cover it end to end:
- Accept "square" as a cross-section alias (the rectangular bound with
d the side length) in plane_wave_frequency_range() and
two_microphone_impedance().
- New plane_wave_frequency_range_astm(): ASTM E2611-19 working range
with the unrounded circular constant (fu d < 0.586 c, 6.2.4.1), the
rectangular bound (0.500 c, 6.2.5), the spacing bound (fu s < 0.40 c,
6.5.4) and the 1 % of wavelength lower limit (6.2.3).
- wave_decomposition(), transfer_matrix_two_load() and
transfer_matrix_one_load() accept diameter/shape and emit an
ImpedanceTubeWarning outside the plane-wave range (wavenumber-space
check, no speed of sound needed).
- New hydraulic_diameter(width, height) helper (4A/P) for the
tube_attenuation_constant() rectangular case (ISO 10534-2 A.2.1.5).
- ImpedanceTubeResult retains spacing/x1/diameter/shape and
TransferMatrix retains l1/s1/l2/s2/thickness/diameter/shape plus the
frequency vector and air characteristic impedance, so
TransferMatrix.plot() now works without arguments on solver-built
matrices.
- ReportMetadata.tube_shape prints a translated cross-section row on
the ISO 10534-2 fiche.
- Tests for every new path; materials guide (EN/ES), api-reference and
generated API pages updated.
* Address review: field order, spacing guard, plot docstring, message constant
- Append ReportMetadata.tube_shape after the original fields so the
public positional constructor order is unchanged.
- Validate s1/s2 inside _warn_astm_plane_wave so a zero spacing raises
ValueError instead of ZeroDivisionError from the two transfer-matrix
solvers.
- Reword TransferMatrix.plot() docstring: solver-built matrices retain
frequency and rho c, only hand-built ones must pass them.
- Hoist the duplicated diameter validation message into a module
constant (SonarCloud S1192).
Building insulation: formula, fiche and citation fixes against the source standards (#357)
* Correct the ISO 15186-1 Formula (8) N-term and complete the fiche's Clause 8 content
The printed Formula (8) subtracts its 10 lg(N) term, which cannot be
derived: ISO 10140-2:2010 Formula (6) adds the multi-unit correction and
ISO 15186-2:2010 Formula (12) prints the same relation without an N term.
intensity_element_normalized_difference() now returns the derivable
per-unit value (+10 lg N), warns whenever n > 1 deviates from the print,
and the defect is registered in docs/ERRATA.md.
Clause 8 completeness of the intensity fiches: the method statement now
states the test-object and measurement-surface areas S / Sm carried by
the result (Clause 8 g), and report() accepts optional per-band FpI and
pressure-residual intensity index spectra annexed as table columns
(Clause 8 i). The 6.4.2 qualification wording is corrected to 'must not
exceed 10 dB' (the clause flags FpI > 10 dB), the band-set captions now
cite ISO 717-1:2020 Clause 5.3 (statement of results) instead of 4.4,
and the Table B.1 Kc oracle gains the three printed rows 3150/4000/5000
Hz (0,1 dB each) so all 21 rows are pinned.
* Label the road-traffic facade fiche R'tr,s instead of R'45
FacadeInsulationResult now carries the measurement method
(loudspeaker or road_traffic), and the ISO 16283-3 r_prime fiche
selects its labels from it: the road-traffic apparent index is the
distinct quantity R'tr,s (Clause 3.13, -3 dB all-angle correction),
so its report no longer prints the R'45 loudspeaker basis line
(Clause 3.12) over road-traffic numbers.
* Make the ISO 10848 fiche part selectable and register the Formula (20) misprint
The Dn,f / Ln,f quantities are defined in the ISO 10848-1:2006 frame
document (Formulas (4)/(5)); which part governs a measurement depends on
the construction under test, so hardcoding 'ISO 10848-2:2006' in the
basis line mislabelled Part 3 and Part 4 measurements. report() now
accepts part=2/3/4 (default 2) and names ISO 10848-2:2006,
ISO 10848-3:2006 or ISO 10848-4:2010 accordingly, in both languages.
ISO 10848-1:2006 Clause 8.1.1 Formula (20) prints the thin-plate
critical frequency with a spurious extra pi in the denominator (the 1,8
constant already carries 2 pi / sqrt(12)); the implementation was
already pi-free, and the defect is now registered in docs/ERRATA.md
with a misprint note in the critical_frequency docstring, corroborated
by ISO 12354-1:2017 and Hopkins Eq. 2.201.
* Normalize the K24 mass-ratio convention and correct the K24 errata entry
EN 12354-1:2000 prints its two K24 lines in two different mass-ratio
conventions without saying so: the E.5 line follows the annex's own
per-path definition M = lg(m'perp,i/m'i), while the Figure E.9 (E.7)
line is stated in the figure-axis variable lg(m2/m1). Read with the
declared per-path M, the E.9 print contradicts its own curve;
ISO 12354-1:2017 E.3.5 prints the same relation consistently in the
per-path convention (+14,1 M). Re-deriving both editions against the
figures shows the earlier errata entry misread this recast as a 2017
sign misprint; the entry is rewritten accordingly.
junction_vibration_reduction() now applies the documented per-path
mass_ratio = m'perp,i/m'i to every branch: the E.7 double-leaf branch
takes leaf-over-homogeneous ratios (validity m2/m1 > 3 reads
mass_ratio < 1/3) and evaluates 3,0 + 14,1 M + 5,7 M^2, numerically
identical to the 2000 figure. Also cites Kij,min as Formula (29)
(Clause 4.4.2) and documents the ISO 12354-1:2017 both-negative
lining-combination rule next to the 2000 form combine_linings()
implements.
* Broadcast a single-number source level across the EN 12354-5 path bands
installed_source_prediction() derived its band count from the source
levels alone, so a single-number characteristic power with per-band
path data either raised a spurious band-count error or produced a
one-element installed_power_level that crashed the fiche table with an
IndexError. The band count is now the widest per-band input, every
per-band input is validated against it (one value broadcasts), and the
result's installed_power_level is broadcast to the band axis; a fiche
regression test covers the scalar-source case.
Also corrects the coupling-term docstrings: D_C is not guaranteed
non-negative, since near a mounting resonance with comparable,
opposite-phase source and receiver mobilities the |Ys + Yi|^2 numerator
collapses (counterexample in the docstring).
* Use a prediction-aware footer disclaimer on the EN 12354 fiches
The shared footer printed 'The results relate only to the tested
specimen.' on every fiche, including prediction sheets that have no
tested specimen. footer_flow() now takes predicted=True (also exposed
through the shared sound-power renderer) and prints 'Predicted result:
the values relate only to the modelled configuration, not to a tested
specimen.' instead; the EN 12354-1/-2/-3 and EN 12354-5 prediction
fiches use it, in both languages.
Also corrects the dated designations on the prediction basis lines:
the 2000 editions are EN 12354-1/-2/-3:2000 (there was no ISO 12354 in
2000), so 'EN/ISO 12354-x:2000' is replaced by 'EN 12354-x:2000'.
* Declare the actual band set on the ISO 10052 basis line and align ES impact terms
The survey fiches accept both the octave and the one-third-octave band
sets, but their standard-basis lines hardcoded '(survey method, octave
bands)'; the line now follows the band set the reported curve actually
carries, in both languages (ISO 717-1:2020 Clause 5.3 / ISO 717-2:2020
Clause 4.4 require stating it). The remaining comments citing the
band-set statement as ISO 717-1 Clause 4.4 now cite 5.3 (717-2 keeps
4.4), and the ISO 10140 fiche docstring cites the test-report clause as
Clause 9 (Clause 6 is the test arrangement).
Spanish terminology of the field impact quantities is aligned with the
UNE editions: UNE-EN ISO 16283-2:2016 defines 'nivel de presión
acústica estandarizado/normalizado de ruido de impactos' (3.13/3.14),
now used by the ISO 16283-2 and ISO 10052 basis lines; the ISO 10140-3
and ISO 12354-2 strings already match their own UNE editions
(UNE-EN ISO 10140-3:2011 3.2, UNE-EN ISO 12354-2:2018 3.1.1/3.1.2) and
stay unchanged.
* Qualify a background-limited ISO 16251-1 result as a lower bound
When any band sits at the 1,3 dB limit of measurement (Formula (2), the
per-band values already reported as > delta-L), the fiche now prints
the boxed delta-Lw with a >= qualifier and a note stating it is a lower
bound, in both languages. A manually built result without CI,delta
prints the bare delta-Lw instead of fabricating a (+0) adaptation term.
The ISO 717-2:2020 Annex C.2 errata entry is extended with the second,
independent print defect: the example's 'Ln,sum = 75,2527 = 75 dB'
reproduces to all printed digits only as the energy sum of the wrong
column over the wrong range (the measured floor with covering, 16 bands
100-3150 Hz), while the A.2.1 sum of the covered reference floor over
100-2500 Hz rounds to 76 dB with either 800 Hz value, so CI,r = -2,
CI,delta = -9 and delta-Llin = 6 dB; the earlier claim that the 800 Hz
misprint alone shifted the CI chain is corrected.
* Regenerate the conformance report, API docs and affected fiche examples
The Kc Table B.1 conformance row now covers all 21 printed rows, the
building API pages pick up the revised docstrings, and the EN 12354
prediction and ISO 15186-1 example fiches are re-rendered with the
prediction footer, the corrected designations and the Clause 8 areas
statement (kept to one page). CHANGELOG entries under [Unreleased].
* Validate the frequency axis and the facade method on the building results
The installed structure-borne prediction now rejects a frequency axis whose
length differs from the resolved band count, so a result can no longer carry
an inconsistent per-band table. FacadeInsulationResult validates its method
on construction, closing the direct-construction path that would render an
unknown method as the loudspeaker quantity. The band-count note also names
the characteristic level and coupling term as width-setting inputs.
Correct the framing and the guards of the perception and noise-control fiches (#355)
A review pass over the psychoacoustics, hearing, speech, environmental and
noise-control fiches. The numerics held up; what did not were the statements
printed around them, plus one wrong table lookup.
ISO 1999 validated domain. nipts()/htlan() applied Formula (2) wherever they
were asked to: L_EX,8h = 130 dB over 60 years at the 0,99 fractile returned a
357,9 dB threshold shift with nothing marking it as an extrapolation. Since the
formula is quadratic in (L_EX,8h - L0) that number is meaningless, not merely
uncertain. Both now warn (NoiseInducedHearingLossWarning) outside the stated
ranges while still computing: durations outside 1-40 years (clause 6.3.1
validates Formula (2) over 10-40 and Formula (3) over 1-10), fractiles in the
tails clause 6.3.2 says "should not be estimated" (Q below 5 % or above 95 %),
and levels above the 100 dB of Annex D that the Scope's NOTE 4 restricts
validity to. The fiches print the caveat when the conditions sit outside.
ISO 1999 Q. The fiches printed the library's fractile under ISO 1999's symbol,
inverting its meaning: in Formulae (4)/(5) Q is the percentage with worse
hearing, so the most-susceptible tenth is Q = 10 %, not the "Q = 0.9" the fiche
showed while citing 6.3.2. They now print ISO's Q as ISO defines it; the guides
note the difference from the fractile argument. Two further disclosures on the
same fiches: the age component H is evaluated from ISO 7029:2017 (the edition
ISO 1999 references undated in 6.2.2), which departs from the illustrative
Table A.3 selection by up to about 7 dB at the median, and the 2/3/4 kHz
average is the user's own choice, the Scope's NOTE 1 specifying no frequency
combination. The footer states a population scope rather than "the results
relate only to the tested specimen", which describes a laboratory specimen.
ISO 1999 Annex C is wired in as an independent oracle: its worked example (male
population aged 50, 90 dB for 30 years, 1/2/4 kHz at Q = 10 %) reproduces the
Table D.2 shifts it consumes (0, 9, 19 dB), the 13,3 dB left of the 4 kHz shift
after the Formula (1) compression (C.5) and the 31,1 dB combined threshold
(C.11). The composition it exercises is now exposed as combine_age_and_noise(),
which clause 6.2 wants available on its own: 6.2.3 recommends a database B
collected on a control population of the country under consideration, and this
applies Formula (1) to whichever database the user brings.
Verdict precision. The STI and SII fiches printed the requirement with one
decimal beside a measured value at full precision, so a verdict could contradict
itself: "STI = 0.50, required >= 0.5 -> FAIL" against a 0,52 requirement, and an
SII minimum of 0,75 printed as "0.8" (the committed example said so). Both now
print the requirement at the quantity's own precision. IEC 60268-16 Annex M
joins the conformance report as an end-to-end oracle: its printed MTF matrix,
speech spectrum and ambient noise give back its published MTI row and
STI = 0,76, exercising the whole A.5.3 to A.5.8 chain.
Noise-control prediction framing. The enclosure, silencer and HVAC fiches
compute design models but read as measurements: no prediction statement,
measurement headers, a footer scoped to a tested specimen, and committed
examples citing instrumentation that never existed ("Two-microphone
transfer-matrix bench"). They now follow the EN/ISO 12354 prediction exemplar
already in the repo, with a prediction-basis line, a statement naming what each
model does not represent, and a prediction footer. Their verdicts also decided
on the half-away-from-zero display rounding while printing Python's
round-half-to-even, so 0,25 printed 0.2 against a verdict taken on 0,3; both
now use the display rounding.
ISO/PAS 1996-3. With every onset rate at or below 10 dB/s the fiche withheld
the adjustment on the onset-rate gate (clauses 4.5/8) but justified it with "no
prominent impulse is present (governing P = 6.01 <= 5)", contradicting its own
boxed P. The note now states whichever gate governs. The assessment period is
read from the result instead of being hardcoded: 30 min is the Clause 5
*default*, now the default of the new assessment_period_min argument.
Smaller corrections:
- the HVAC elbow insertion loss took the wrong row of Bies Table 8.11 for a
W/lambda exactly on a bin edge; the rows read "a <= W/lambda < b", so an edge
opens its row (1 dB at 0,14, not 0 dB);
- the wind-turbine tonality fiche cited "subclauses 9.5.2-9.5.5" of
IEC 61400-11 for a chain running through 9.5.6 to 9.5.8 (Formulae 31-34);
- the ISO 1996-2 tonal fiche notes that Table J.1 keys on the mean audibility
of the J assessed spectra (ISO/PAS 20065 Clause 5.3.9), which a
single-spectrum assessment stands in for;
- the shared 10-90 % fractile band carried a hardcoded English legend in
Spanish figures, and the Spanish silencer and HVAC fiches printed the device
kind and duct-element label in English.
docs/ERRATA.md records two more source defects found on the way: ISO/PAS
1996-3:2022 Clause 5 swaps the 3.4/3.5 cross-references of the onset rate and
the level difference (its own units contradict the clause numbers printed with
them), and ISO 9613-2:1996 Table 2 prints 4,1 dB/km at 15 C / 80 % / 1 kHz
where ISO 9613-1 gives 4,1511, the neighbouring cells rounding correctly. The
library computes that coefficient from ISO 9613-1 directly, so it is unaffected.
Committed example fiches, the conformance report, the API reference and the
llms files are regenerated.
Correct the framing and the guards of the perception and noise-control fiches (#355)
A review pass over the psychoacoustics, hearing, speech, environmental and
noise-control fiches. The numerics held up; what did not were the statements
printed around them, plus one wrong table lookup.
ISO 1999 validated domain. nipts()/htlan() applied Formula (2) wherever they
were asked to: L_EX,8h = 130 dB over 60 years at the 0,99 fractile returned a
357,9 dB threshold shift with nothing marking it as an extrapolation. Since the
formula is quadratic in (L_EX,8h - L0) that number is meaningless, not merely
uncertain. Both now warn (NoiseInducedHearingLossWarning) outside the stated
ranges while still computing: durations outside 1-40 years (clause 6.3.1
validates Formula (2) over 10-40 and Formula (3) over 1-10), fractiles in the
tails clause 6.3.2 says "should not be estimated" (Q below 5 % or above 95 %),
and levels above the 100 dB of Annex D that the Scope's NOTE 4 restricts
validity to. The fiches print the caveat when the conditions sit outside.
ISO 1999 Q. The fiches printed the library's fractile under ISO 1999's symbol,
inverting its meaning: in Formulae (4)/(5) Q is the percentage with worse
hearing, so the most-susceptible tenth is Q = 10 %, not the "Q = 0.9" the fiche
showed while citing 6.3.2. They now print ISO's Q as ISO defines it; the guides
note the difference from the fractile argument. Two further disclosures on the
same fiches: the age component H is evaluated from ISO 7029:2017 (the edition
ISO 1999 references undated in 6.2.2), which departs from the illustrative
Table A.3 selection by up to about 7 dB at the median, and the 2/3/4 kHz
average is the user's own choice, the Scope's NOTE 1 specifying no frequency
combination. The footer states a population scope rather than "the results
relate only to the tested specimen", which describes a laboratory specimen.
ISO 1999 Annex C is wired in as an independent oracle: its worked example (male
population aged 50, 90 dB for 30 years, 1/2/4 kHz at Q = 10 %) reproduces the
Table D.2 shifts it consumes (0, 9, 19 dB), the 13,3 dB left of the 4 kHz shift
after the Formula (1) compression (C.5) and the 31,1 dB combined threshold
(C.11). The composition it exercises is now exposed as combine_age_and_noise(),
which clause 6.2 wants available on its own: 6.2.3 recommends a database B
collected on a control population of the country under consideration, and this
applies Formula (1) to whichever database the user brings.
Verdict precision. The STI and SII fiches printed the requirement with one
decimal beside a measured value at full precision, so a verdict could contradict
itself: "STI = 0.50, required >= 0.5 -> FAIL" against a 0,52 requirement, and an
SII minimum of 0,75 printed as "0.8" (the committed example said so). Both now
print the requirement at the quantity's own precision. IEC 60268-16 Annex M
joins the conformance report as an end-to-end oracle: its printed MTF matrix,
speech spectrum and ambient noise give back its published MTI row and
STI = 0,76, exercising the whole A.5.3 to A.5.8 chain.
Noise-control prediction framing. The enclosure, silencer and HVAC fiches
compute design models but read as measurements: no prediction statement,
measurement headers, a footer scoped to a tested specimen, and committed
examples citing instrumentation that never existed ("Two-microphone
transfer-matrix bench"). They now follow the EN/ISO 12354 prediction exemplar
already in the repo, with a prediction-basis line, a statement naming what each
model does not represent, and a prediction footer. Their verdicts also decided
on the half-away-from-zero display rounding while printing Python's
round-half-to-even, so 0,25 printed 0.2 against a verdict taken on 0,3; both
now use the display rounding.
ISO/PAS 1996-3. With every onset rate at or below 10 dB/s the fiche withheld
the adjustment on the onset-rate gate (clauses 4.5/8) but justified it with "no
prominent impulse is present (governing P = 6.01 <= 5)", contradicting its own
boxed P. The note now states whichever gate governs. The assessment period is
read from the result instead of being hardcoded: 30 min is the Clause 5
*default*, now the default of the new assessment_period_min argument.
Smaller corrections:
- the HVAC elbow insertion loss took the wrong row of Bies Table 8.11 for a
W/lambda exactly on a bin edge; the rows read "a <= W/lambda < b", so an edge
opens its row (1 dB at 0,14, not 0 dB);
- the wind-turbine tonality fiche cited "subclauses 9.5.2-9.5.5" of
IEC 61400-11 for a chain running through 9.5.6 to 9.5.8 (Formulae 31-34);
- the ISO 1996-2 tonal fiche notes that Table J.1 keys on the mean audibility
of the J assessed spectra (ISO/PAS 20065 Clause 5.3.9), which a
single-spectrum assessment stands in for;
- the shared 10-90 % fractile band carried a hardcoded English legend in
Spanish figures, and the Spanish silencer and HVAC fiches printed the device
kind and duct-element label in English.
docs/ERRATA.md records two more source defects found on the way: ISO/PAS
1996-3:2022 Clause 5 swaps the 3.4/3.5 cross-references of the onset rate and
the level difference (its own units contradict the clause numbers printed with
them), and ISO 9613-2:1996 Table 2 prints 4,1 dB/km at 15 C / 80 % / 1 kHz
where ISO 9613-1 gives 4,1511, the neighbouring cells rounding correctly. The
library computes that coefficient from ISO 9613-1 directly, so it is unaffected.
Committed example fiches, the conformance report, the API reference and the
llms files are regenerated.
Building insulation: formula, fiche and citation fixes against the source standards (#357)
* Correct the ISO 15186-1 Formula (8) N-term and complete the fiche's Clause 8 content
The printed Formula (8) subtracts its 10 lg(N) term, which cannot be
derived: ISO 10140-2:2010 Formula (6) adds the multi-unit correction and
ISO 15186-2:2010 Formula (12) prints the same relation without an N term.
intensity_element_normalized_difference() now returns the derivable
per-unit value (+10 lg N), warns whenever n > 1 deviates from the print,
and the defect is registered in docs/ERRATA.md.
Clause 8 completeness of the intensity fiches: the method statement now
states the test-object and measurement-surface areas S / Sm carried by
the result (Clause 8 g), and report() accepts optional per-band FpI and
pressure-residual intensity index spectra annexed as table columns
(Clause 8 i). The 6.4.2 qualification wording is corrected to 'must not
exceed 10 dB' (the clause flags FpI > 10 dB), the band-set captions now
cite ISO 717-1:2020 Clause 5.3 (statement of results) instead of 4.4,
and the Table B.1 Kc oracle gains the three printed rows 3150/4000/5000
Hz (0,1 dB each) so all 21 rows are pinned.
* Label the road-traffic facade fiche R'tr,s instead of R'45
FacadeInsulationResult now carries the measurement method
(loudspeaker or road_traffic), and the ISO 16283-3 r_prime fiche
selects its labels from it: the road-traffic apparent index is the
distinct quantity R'tr,s (Clause 3.13, -3 dB all-angle correction),
so its report no longer prints the R'45 loudspeaker basis line
(Clause 3.12) over road-traffic numbers.
* Make the ISO 10848 fiche part selectable and register the Formula (20) misprint
The Dn,f / Ln,f quantities are defined in the ISO 10848-1:2006 frame
document (Formulas (4)/(5)); which part governs a measurement depends on
the construction under test, so hardcoding 'ISO 10848-2:2006' in the
basis line mislabelled Part 3 and Part 4 measurements. report() now
accepts part=2/3/4 (default 2) and names ISO 10848-2:2006,
ISO 10848-3:2006 or ISO 10848-4:2010 accordingly, in both languages.
ISO 10848-1:2006 Clause 8.1.1 Formula (20) prints the thin-plate
critical frequency with a spurious extra pi in the denominator (the 1,8
constant already carries 2 pi / sqrt(12)); the implementation was
already pi-free, and the defect is now registered in docs/ERRATA.md
with a misprint note in the critical_frequency docstring, corroborated
by ISO 12354-1:2017 and Hopkins Eq. 2.201.
* Normalize the K24 mass-ratio convention and correct the K24 errata entry
EN 12354-1:2000 prints its two K24 lines in two different mass-ratio
conventions without saying so: the E.5 line follows the annex's own
per-path definition M = lg(m'perp,i/m'i), while the Figure E.9 (E.7)
line is stated in the figure-axis variable lg(m2/m1). Read with the
declared per-path M, the E.9 print contradicts its own curve;
ISO 12354-1:2017 E.3.5 prints the same relation consistently in the
per-path convention (+14,1 M). Re-deriving both editions against the
figures shows the earlier errata entry misread this recast as a 2017
sign misprint; the entry is rewritten accordingly.
junction_vibration_reduction() now applies the documented per-path
mass_ratio = m'perp,i/m'i to every branch: the E.7 double-leaf branch
takes leaf-over-homogeneous ratios (validity m2/m1 > 3 reads
mass_ratio < 1/3) and evaluates 3,0 + 14,1 M + 5,7 M^2, numerically
identical to the 2000 figure. Also cites Kij,min as Formula (29)
(Clause 4.4.2) and documents the ISO 12354-1:2017 both-negative
lining-combination rule next to the 2000 form combine_linings()
implements.
* Broadcast a single-number source level across the EN 12354-5 path bands
installed_source_prediction() derived its band count from the source
levels alone, so a single-number characteristic power with per-band
path data either raised a spurious band-count error or produced a
one-element installed_power_level that crashed the fiche table with an
IndexError. The band count is now the widest per-band input, every
per-band input is validated against it (one value broadcasts), and the
result's installed_power_level is broadcast to the band axis; a fiche
regression test covers the scalar-source case.
Also corrects the coupling-term docstrings: D_C is not guaranteed
non-negative, since near a mounting resonance with comparable,
opposite-phase source and receiver mobilities the |Ys + Yi|^2 numerator
collapses (counterexample in the docstring).
* Use a prediction-aware footer disclaimer on the EN 12354 fiches
The shared footer printed 'The results relate only to the tested
specimen.' on every fiche, including prediction sheets that have no
tested specimen. footer_flow() now takes predicted=True (also exposed
through the shared sound-power renderer) and prints 'Predicted result:
the values relate only to the modelled configuration, not to a tested
specimen.' instead; the EN 12354-1/-2/-3 and EN 12354-5 prediction
fiches use it, in both languages.
Also corrects the dated designations on the prediction basis lines:
the 2000 editions are EN 12354-1/-2/-3:2000 (there was no ISO 12354 in
2000), so 'EN/ISO 12354-x:2000' is replaced by 'EN 12354-x:2000'.
* Declare the actual band set on the ISO 10052 basis line and align ES impact terms
The survey fiches accept both the octave and the one-third-octave band
sets, but their standard-basis lines hardcoded '(survey method, octave
bands)'; the line now follows the band set the reported curve actually
carries, in both languages (ISO 717-1:2020 Clause 5.3 / ISO 717-2:2020
Clause 4.4 require stating it). The remaining comments citing the
band-set statement as ISO 717-1 Clause 4.4 now cite 5.3 (717-2 keeps
4.4), and the ISO 10140 fiche docstring cites the test-report clause as
Clause 9 (Clause 6 is the test arrangement).
Spanish terminology of the field impact quantities is aligned with the
UNE editions: UNE-EN ISO 16283-2:2016 defines 'nivel de presión
acústica estandarizado/normalizado de ruido de impactos' (3.13/3.14),
now used by the ISO 16283-2 and ISO 10052 basis lines; the ISO 10140-3
and ISO 12354-2 strings already match their own UNE editions
(UNE-EN ISO 10140-3:2011 3.2, UNE-EN ISO 12354-2:2018 3.1.1/3.1.2) and
stay unchanged.
* Qualify a background-limited ISO 16251-1 result as a lower bound
When any band sits at the 1,3 dB limit of measurement (Formula (2), the
per-band values already reported as > delta-L), the fiche now prints
the boxed delta-Lw with a >= qualifier and a note stating it is a lower
bound, in both languages. A manually built result without CI,delta
prints the bare delta-Lw instead of fabricating a (+0) adaptation term.
The ISO 717-2:2020 Annex C.2 errata entry is extended with the second,
independent print defect: the example's 'Ln,sum = 75,2527 = 75 dB'
reproduces to all printed digits only as the energy sum of the wrong
column over the wrong range (the measured floor with covering, 16 bands
100-3150 Hz), while the A.2.1 sum of the covered reference floor over
100-2500 Hz rounds to 76 dB with either 800 Hz value, so CI,r = -2,
CI,delta = -9 and delta-Llin = 6 dB; the earlier claim that the 800 Hz
misprint alone shifted the CI chain is corrected.
* Regenerate the conformance report, API docs and affected fiche examples
The Kc Table B.1 conformance row now covers all 21 printed rows, the
building API pages pick up the revised docstrings, and the EN 12354
prediction and ISO 15186-1 example fiches are re-rendered with the
prediction footer, the corrected designations and the Clause 8 areas
statement (kept to one page). CHANGELOG entries under [Unreleased].
* Validate the frequency axis and the facade method on the building results
The installed structure-borne prediction now rejects a frequency axis whose
length differs from the resolved band count, so a result can no longer carry
an inconsistent per-band table. FacadeInsulationResult validates its method
on construction, closing the direct-construction path that would render an
unknown method as the loudspeaker quantity. The band-count note also names
the characteristic level and coupling term as width-setting inputs.
Building insulation: formula, fiche and citation fixes against the source standards (#357)
* Correct the ISO 15186-1 Formula (8) N-term and complete the fiche's Clause 8 content
The printed Formula (8) subtracts its 10 lg(N) term, which cannot be
derived: ISO 10140-2:2010 Formula (6) adds the multi-unit correction and
ISO 15186-2:2010 Formula (12) prints the same relation without an N term.
intensity_element_normalized_difference() now returns the derivable
per-unit value (+10 lg N), warns whenever n > 1 deviates from the print,
and the defect is registered in docs/ERRATA.md.
Clause 8 completeness of the intensity fiches: the method statement now
states the test-object and measurement-surface areas S / Sm carried by
the result (Clause 8 g), and report() accepts optional per-band FpI and
pressure-residual intensity index spectra annexed as table columns
(Clause 8 i). The 6.4.2 qualification wording is corrected to 'must not
exceed 10 dB' (the clause flags FpI > 10 dB), the band-set captions now
cite ISO 717-1:2020 Clause 5.3 (statement of results) instead of 4.4,
and the Table B.1 Kc oracle gains the three printed rows 3150/4000/5000
Hz (0,1 dB each) so all 21 rows are pinned.
* Label the road-traffic facade fiche R'tr,s instead of R'45
FacadeInsulationResult now carries the measurement method
(loudspeaker or road_traffic), and the ISO 16283-3 r_prime fiche
selects its labels from it: the road-traffic apparent index is the
distinct quantity R'tr,s (Clause 3.13, -3 dB all-angle correction),
so its report no longer prints the R'45 loudspeaker basis line
(Clause 3.12) over road-traffic numbers.
* Make the ISO 10848 fiche part selectable and register the Formula (20) misprint
The Dn,f / Ln,f quantities are defined in the ISO 10848-1:2006 frame
document (Formulas (4)/(5)); which part governs a measurement depends on
the construction under test, so hardcoding 'ISO 10848-2:2006' in the
basis line mislabelled Part 3 and Part 4 measurements. report() now
accepts part=2/3/4 (default 2) and names ISO 10848-2:2006,
ISO 10848-3:2006 or ISO 10848-4:2010 accordingly, in both languages.
ISO 10848-1:2006 Clause 8.1.1 Formula (20) prints the thin-plate
critical frequency with a spurious extra pi in the denominator (the 1,8
constant already carries 2 pi / sqrt(12)); the implementation was
already pi-free, and the defect is now registered in docs/ERRATA.md
with a misprint note in the critical_frequency docstring, corroborated
by ISO 12354-1:2017 and Hopkins Eq. 2.201.
* Normalize the K24 mass-ratio convention and correct the K24 errata entry
EN 12354-1:2000 prints its two K24 lines in two different mass-ratio
conventions without saying so: the E.5 line follows the annex's own
per-path definition M = lg(m'perp,i/m'i), while the Figure E.9 (E.7)
line is stated in the figure-axis variable lg(m2/m1). Read with the
declared per-path M, the E.9 print contradicts its own curve;
ISO 12354-1:2017 E.3.5 prints the same relation consistently in the
per-path convention (+14,1 M). Re-deriving both editions against the
figures shows the earlier errata entry misread this recast as a 2017
sign misprint; the entry is rewritten accordingly.
junction_vibration_reduction() now applies the documented per-path
mass_ratio = m'perp,i/m'i to every branch: the E.7 double-leaf branch
takes leaf-over-homogeneous ratios (validity m2/m1 > 3 reads
mass_ratio < 1/3) and evaluates 3,0 + 14,1 M + 5,7 M^2, numerically
identical to the 2000 figure. Also cites Kij,min as Formula (29)
(Clause 4.4.2) and documents the ISO 12354-1:2017 both-negative
lining-combination rule next to the 2000 form combine_linings()
implements.
* Broadcast a single-number source level across the EN 12354-5 path bands
installed_source_prediction() derived its band count from the source
levels alone, so a single-number characteristic power with per-band
path data either raised a spurious band-count error or produced a
one-element installed_power_level that crashed the fiche table with an
IndexError. The band count is now the widest per-band input, every
per-band input is validated against it (one value broadcasts), and the
result's installed_power_level is broadcast to the band axis; a fiche
regression test covers the scalar-source case.
Also corrects the coupling-term docstrings: D_C is not guaranteed
non-negative, since near a mounting resonance with comparable,
opposite-phase source and receiver mobilities the |Ys + Yi|^2 numerator
collapses (counterexample in the docstring).
* Use a prediction-aware footer disclaimer on the EN 12354 fiches
The shared footer printed 'The results relate only to the tested
specimen.' on every fiche, including prediction sheets that have no
tested specimen. footer_flow() now takes predicted=True (also exposed
through the shared sound-power renderer) and prints 'Predicted result:
the values relate only to the modelled configuration, not to a tested
specimen.' instead; the EN 12354-1/-2/-3 and EN 12354-5 prediction
fiches use it, in both languages.
Also corrects the dated designations on the prediction basis lines:
the 2000 editions are EN 12354-1/-2/-3:2000 (there was no ISO 12354 in
2000), so 'EN/ISO 12354-x:2000' is replaced by 'EN 12354-x:2000'.
* Declare the actual band set on the ISO 10052 basis line and align ES impact terms
The survey fiches accept both the octave and the one-third-octave band
sets, but their standard-basis lines hardcoded '(survey method, octave
bands)'; the line now follows the band set the reported curve actually
carries, in both languages (ISO 717-1:2020 Clause 5.3 / ISO 717-2:2020
Clause 4.4 require stating it). The remaining comments citing the
band-set statement as ISO 717-1 Clause 4.4 now cite 5.3 (717-2 keeps
4.4), and the ISO 10140 fiche docstring cites the test-report clause as
Clause 9 (Clause 6 is the test arrangement).
Spanish terminology of the field impact quantities is aligned with the
UNE editions: UNE-EN ISO 16283-2:2016 defines 'nivel de presión
acústica estandarizado/normalizado de ruido de impactos' (3.13/3.14),
now used by the ISO 16283-2 and ISO 10052 basis lines; the ISO 10140-3
and ISO 12354-2 strings already match their own UNE editions
(UNE-EN ISO 10140-3:2011 3.2, UNE-EN ISO 12354-2:2018 3.1.1/3.1.2) and
stay unchanged.
* Qualify a background-limited ISO 16251-1 result as a lower bound
When any band sits at the 1,3 dB limit of measurement (Formula (2), the
per-band values already reported as > delta-L), the fiche now prints
the boxed delta-Lw with a >= qualifier and a note stating it is a lower
bound, in both languages. A manually built result without CI,delta
prints the bare delta-Lw instead of fabricating a (+0) adaptation term.
The ISO 717-2:2020 Annex C.2 errata entry is extended with the second,
independent print defect: the example's 'Ln,sum = 75,2527 = 75 dB'
reproduces to all printed digits only as the energy sum of the wrong
column over the wrong range (the measured floor with covering, 16 bands
100-3150 Hz), while the A.2.1 sum of the covered reference floor over
100-2500 Hz rounds to 76 dB with either 800 Hz value, so CI,r = -2,
CI,delta = -9 and delta-Llin = 6 dB; the earlier claim that the 800 Hz
misprint alone shifted the CI chain is corrected.
* Regenerate the conformance report, API docs and affected fiche examples
The Kc Table B.1 conformance row now covers all 21 printed rows, the
building API pages pick up the revised docstrings, and the EN 12354
prediction and ISO 15186-1 example fiches are re-rendered with the
prediction footer, the corrected designations and the Clause 8 areas
statement (kept to one page). CHANGELOG entries under [Unreleased].
* Validate the frequency axis and the facade method on the building results
The installed structure-borne prediction now rejects a frequency axis whose
length differs from the resolved band count, so a result can no longer carry
an inconsistent per-band table. FacadeInsulationResult validates its method
on construction, closing the direct-construction path that would render an
unknown method as the loudspeaker quantity. The band-count note also names
the characteristic level and coupling term as width-setting inputs.
Impedance tube: complete circular, rectangular and square cross-section support (#380)
* Impedance tube: complete circular, rectangular and square cross-section support
The ISO 10534-2 branch already distinguished circular from rectangular
tubes; the ASTM E2611 branch ignored the cross-section entirely. Both
branches now cover it end to end:
- Accept "square" as a cross-section alias (the rectangular bound with
d the side length) in plane_wave_frequency_range() and
two_microphone_impedance().
- New plane_wave_frequency_range_astm(): ASTM E2611-19 working range
with the unrounded circular constant (fu d < 0.586 c, 6.2.4.1), the
rectangular bound (0.500 c, 6.2.5), the spacing bound (fu s < 0.40 c,
6.5.4) and the 1 % of wavelength lower limit (6.2.3).
- wave_decomposition(), transfer_matrix_two_load() and
transfer_matrix_one_load() accept diameter/shape and emit an
ImpedanceTubeWarning outside the plane-wave range (wavenumber-space
check, no speed of sound needed).
- New hydraulic_diameter(width, height) helper (4A/P) for the
tube_attenuation_constant() rectangular case (ISO 10534-2 A.2.1.5).
- ImpedanceTubeResult retains spacing/x1/diameter/shape and
TransferMatrix retains l1/s1/l2/s2/thickness/diameter/shape plus the
frequency vector and air characteristic impedance, so
TransferMatrix.plot() now works without arguments on solver-built
matrices.
- ReportMetadata.tube_shape prints a translated cross-section row on
the ISO 10534-2 fiche.
- Tests for every new path; materials guide (EN/ES), api-reference and
generated API pages updated.
* Address review: field order, spacing guard, plot docstring, message constant
- Append ReportMetadata.tube_shape after the original fields so the
public positional constructor order is unchanged.
- Validate s1/s2 inside _warn_astm_plane_wave so a zero spacing raises
ValueError instead of ZeroDivisionError from the two transfer-matrix
solvers.
- Reword TransferMatrix.plot() docstring: solver-built matrices retain
frequency and rho c, only hand-built ones must pass them.
- Hoist the duplicated diameter validation message into a module
constant (SonarCloud S1192).
Building insulation: formula, fiche and citation fixes against the source standards (#357)
* Correct the ISO 15186-1 Formula (8) N-term and complete the fiche's Clause 8 content
The printed Formula (8) subtracts its 10 lg(N) term, which cannot be
derived: ISO 10140-2:2010 Formula (6) adds the multi-unit correction and
ISO 15186-2:2010 Formula (12) prints the same relation without an N term.
intensity_element_normalized_difference() now returns the derivable
per-unit value (+10 lg N), warns whenever n > 1 deviates from the print,
and the defect is registered in docs/ERRATA.md.
Clause 8 completeness of the intensity fiches: the method statement now
states the test-object and measurement-surface areas S / Sm carried by
the result (Clause 8 g), and report() accepts optional per-band FpI and
pressure-residual intensity index spectra annexed as table columns
(Clause 8 i). The 6.4.2 qualification wording is corrected to 'must not
exceed 10 dB' (the clause flags FpI > 10 dB), the band-set captions now
cite ISO 717-1:2020 Clause 5.3 (statement of results) instead of 4.4,
and the Table B.1 Kc oracle gains the three printed rows 3150/4000/5000
Hz (0,1 dB each) so all 21 rows are pinned.
* Label the road-traffic facade fiche R'tr,s instead of R'45
FacadeInsulationResult now carries the measurement method
(loudspeaker or road_traffic), and the ISO 16283-3 r_prime fiche
selects its labels from it: the road-traffic apparent index is the
distinct quantity R'tr,s (Clause 3.13, -3 dB all-angle correction),
so its report no longer prints the R'45 loudspeaker basis line
(Clause 3.12) over road-traffic numbers.
* Make the ISO 10848 fiche part selectable and register the Formula (20) misprint
The Dn,f / Ln,f quantities are defined in the ISO 10848-1:2006 frame
document (Formulas (4)/(5)); which part governs a measurement depends on
the construction under test, so hardcoding 'ISO 10848-2:2006' in the
basis line mislabelled Part 3 and Part 4 measurements. report() now
accepts part=2/3/4 (default 2) and names ISO 10848-2:2006,
ISO 10848-3:2006 or ISO 10848-4:2010 accordingly, in both languages.
ISO 10848-1:2006 Clause 8.1.1 Formula (20) prints the thin-plate
critical frequency with a spurious extra pi in the denominator (the 1,8
constant already carries 2 pi / sqrt(12)); the implementation was
already pi-free, and the defect is now registered in docs/ERRATA.md
with a misprint note in the critical_frequency docstring, corroborated
by ISO 12354-1:2017 and Hopkins Eq. 2.201.
* Normalize the K24 mass-ratio convention and correct the K24 errata entry
EN 12354-1:2000 prints its two K24 lines in two different mass-ratio
conventions without saying so: the E.5 line follows the annex's own
per-path definition M = lg(m'perp,i/m'i), while the Figure E.9 (E.7)
line is stated in the figure-axis variable lg(m2/m1). Read with the
declared per-path M, the E.9 print contradicts its own curve;
ISO 12354-1:2017 E.3.5 prints the same relation consistently in the
per-path convention (+14,1 M). Re-deriving both editions against the
figures shows the earlier errata entry misread this recast as a 2017
sign misprint; the entry is rewritten accordingly.
junction_vibration_reduction() now applies the documented per-path
mass_ratio = m'perp,i/m'i to every branch: the E.7 double-leaf branch
takes leaf-over-homogeneous ratios (validity m2/m1 > 3 reads
mass_ratio < 1/3) and evaluates 3,0 + 14,1 M + 5,7 M^2, numerically
identical to the 2000 figure. Also cites Kij,min as Formula (29)
(Clause 4.4.2) and documents the ISO 12354-1:2017 both-negative
lining-combination rule next to the 2000 form combine_linings()
implements.
* Broadcast a single-number source level across the EN 12354-5 path bands
installed_source_prediction() derived its band count from the source
levels alone, so a single-number characteristic power with per-band
path data either raised a spurious band-count error or produced a
one-element installed_power_level that crashed the fiche table with an
IndexError. The band count is now the widest per-band input, every
per-band input is validated against it (one value broadcasts), and the
result's installed_power_level is broadcast to the band axis; a fiche
regression test covers the scalar-source case.
Also corrects the coupling-term docstrings: D_C is not guaranteed
non-negative, since near a mounting resonance with comparable,
opposite-phase source and receiver mobilities the |Ys + Yi|^2 numerator
collapses (counterexample in the docstring).
* Use a prediction-aware footer disclaimer on the EN 12354 fiches
The shared footer printed 'The results relate only to the tested
specimen.' on every fiche, including prediction sheets that have no
tested specimen. footer_flow() now takes predicted=True (also exposed
through the shared sound-power renderer) and prints 'Predicted result:
the values relate only to the modelled configuration, not to a tested
specimen.' instead; the EN 12354-1/-2/-3 and EN 12354-5 prediction
fiches use it, in both languages.
Also corrects the dated designations on the prediction basis lines:
the 2000 editions are EN 12354-1/-2/-3:2000 (there was no ISO 12354 in
2000), so 'EN/ISO 12354-x:2000' is replaced by 'EN 12354-x:2000'.
* Declare the actual band set on the ISO 10052 basis line and align ES impact terms
The survey fiches accept both the octave and the one-third-octave band
sets, but their standard-basis lines hardcoded '(survey method, octave
bands)'; the line now follows the band set the reported curve actually
carries, in both languages (ISO 717-1:2020 Clause 5.3 / ISO 717-2:2020
Clause 4.4 require stating it). The remaining comments citing the
band-set statement as ISO 717-1 Clause 4.4 now cite 5.3 (717-2 keeps
4.4), and the ISO 10140 fiche docstring cites the test-report clause as
Clause 9 (Clause 6 is the test arrangement).
Spanish terminology of the field impact quantities is aligned with the
UNE editions: UNE-EN ISO 16283-2:2016 defines 'nivel de presión
acústica estandarizado/normalizado de ruido de impactos' (3.13/3.14),
now used by the ISO 16283-2 and ISO 10052 basis lines; the ISO 10140-3
and ISO 12354-2 strings already match their own UNE editions
(UNE-EN ISO 10140-3:2011 3.2, UNE-EN ISO 12354-2:2018 3.1.1/3.1.2) and
stay unchanged.
* Qualify a background-limited ISO 16251-1 result as a lower bound
When any band sits at the 1,3 dB limit of measurement (Formula (2), the
per-band values already reported as > delta-L), the fiche now prints
the boxed delta-Lw with a >= qualifier and a note stating it is a lower
bound, in both languages. A manually built result without CI,delta
prints the bare delta-Lw instead of fabricating a (+0) adaptation term.
The ISO 717-2:2020 Annex C.2 errata entry is extended with the second,
independent print defect: the example's 'Ln,sum = 75,2527 = 75 dB'
reproduces to all printed digits only as the energy sum of the wrong
column over the wrong range (the measured floor with covering, 16 bands
100-3150 Hz), while the A.2.1 sum of the covered reference floor over
100-2500 Hz rounds to 76 dB with either 800 Hz value, so CI,r = -2,
CI,delta = -9 and delta-Llin = 6 dB; the earlier claim that the 800 Hz
misprint alone shifted the CI chain is corrected.
* Regenerate the conformance report, API docs and affected fiche examples
The Kc Table B.1 conformance row now covers all 21 printed rows, the
building API pages pick up the revised docstrings, and the EN 12354
prediction and ISO 15186-1 example fiches are re-rendered with the
prediction footer, the corrected designations and the Clause 8 areas
statement (kept to one page). CHANGELOG entries under [Unreleased].
* Validate the frequency axis and the facade method on the building results
The installed structure-borne prediction now rejects a frequency axis whose
length differs from the resolved band count, so a result can no longer carry
an inconsistent per-band table. FacadeInsulationResult validates its method
on construction, closing the direct-construction path that would render an
unknown method as the loudspeaker quantity. The band-count note also names
the characteristic level and coupling term as width-setting inputs.
Building insulation: formula, fiche and citation fixes against the source standards (#357)
* Correct the ISO 15186-1 Formula (8) N-term and complete the fiche's Clause 8 content
The printed Formula (8) subtracts its 10 lg(N) term, which cannot be
derived: ISO 10140-2:2010 Formula (6) adds the multi-unit correction and
ISO 15186-2:2010 Formula (12) prints the same relation without an N term.
intensity_element_normalized_difference() now returns the derivable
per-unit value (+10 lg N), warns whenever n > 1 deviates from the print,
and the defect is registered in docs/ERRATA.md.
Clause 8 completeness of the intensity fiches: the method statement now
states the test-object and measurement-surface areas S / Sm carried by
the result (Clause 8 g), and report() accepts optional per-band FpI and
pressure-residual intensity index spectra annexed as table columns
(Clause 8 i). The 6.4.2 qualification wording is corrected to 'must not
exceed 10 dB' (the clause flags FpI > 10 dB), the band-set captions now
cite ISO 717-1:2020 Clause 5.3 (statement of results) instead of 4.4,
and the Table B.1 Kc oracle gains the three printed rows 3150/4000/5000
Hz (0,1 dB each) so all 21 rows are pinned.
* Label the road-traffic facade fiche R'tr,s instead of R'45
FacadeInsulationResult now carries the measurement method
(loudspeaker or road_traffic), and the ISO 16283-3 r_prime fiche
selects its labels from it: the road-traffic apparent index is the
distinct quantity R'tr,s (Clause 3.13, -3 dB all-angle correction),
so its report no longer prints the R'45 loudspeaker basis line
(Clause 3.12) over road-traffic numbers.
* Make the ISO 10848 fiche part selectable and register the Formula (20) misprint
The Dn,f / Ln,f quantities are defined in the ISO 10848-1:2006 frame
document (Formulas (4)/(5)); which part governs a measurement depends on
the construction under test, so hardcoding 'ISO 10848-2:2006' in the
basis line mislabelled Part 3 and Part 4 measurements. report() now
accepts part=2/3/4 (default 2) and names ISO 10848-2:2006,
ISO 10848-3:2006 or ISO 10848-4:2010 accordingly, in both languages.
ISO 10848-1:2006 Clause 8.1.1 Formula (20) prints the thin-plate
critical frequency with a spurious extra pi in the denominator (the 1,8
constant already carries 2 pi / sqrt(12)); the implementation was
already pi-free, and the defect is now registered in docs/ERRATA.md
with a misprint note in the critical_frequency docstring, corroborated
by ISO 12354-1:2017 and Hopkins Eq. 2.201.
* Normalize the K24 mass-ratio convention and correct the K24 errata entry
EN 12354-1:2000 prints its two K24 lines in two different mass-ratio
conventions without saying so: the E.5 line follows the annex's own
per-path definition M = lg(m'perp,i/m'i), while the Figure E.9 (E.7)
line is stated in the figure-axis variable lg(m2/m1). Read with the
declared per-path M, the E.9 print contradicts its own curve;
ISO 12354-1:2017 E.3.5 prints the same relation consistently in the
per-path convention (+14,1 M). Re-deriving both editions against the
figures shows the earlier errata entry misread this recast as a 2017
sign misprint; the entry is rewritten accordingly.
junction_vibration_reduction() now applies the documented per-path
mass_ratio = m'perp,i/m'i to every branch: the E.7 double-leaf branch
takes leaf-over-homogeneous ratios (validity m2/m1 > 3 reads
mass_ratio < 1/3) and evaluates 3,0 + 14,1 M + 5,7 M^2, numerically
identical to the 2000 figure. Also cites Kij,min as Formula (29)
(Clause 4.4.2) and documents the ISO 12354-1:2017 both-negative
lining-combination rule next to the 2000 form combine_linings()
implements.
* Broadcast a single-number source level across the EN 12354-5 path bands
installed_source_prediction() derived its band count from the source
levels alone, so a single-number characteristic power with per-band
path data either raised a spurious band-count error or produced a
one-element installed_power_level that crashed the fiche table with an
IndexError. The band count is now the widest per-band input, every
per-band input is validated against it (one value broadcasts), and the
result's installed_power_level is broadcast to the band axis; a fiche
regression test covers the scalar-source case.
Also corrects the coupling-term docstrings: D_C is not guaranteed
non-negative, since near a mounting resonance with comparable,
opposite-phase source and receiver mobilities the |Ys + Yi|^2 numerator
collapses (counterexample in the docstring).
* Use a prediction-aware footer disclaimer on the EN 12354 fiches
The shared footer printed 'The results relate only to the tested
specimen.' on every fiche, including prediction sheets that have no
tested specimen. footer_flow() now takes predicted=True (also exposed
through the shared sound-power renderer) and prints 'Predicted result:
the values relate only to the modelled configuration, not to a tested
specimen.' instead; the EN 12354-1/-2/-3 and EN 12354-5 prediction
fiches use it, in both languages.
Also corrects the dated designations on the prediction basis lines:
the 2000 editions are EN 12354-1/-2/-3:2000 (there was no ISO 12354 in
2000), so 'EN/ISO 12354-x:2000' is replaced by 'EN 12354-x:2000'.
* Declare the actual band set on the ISO 10052 basis line and align ES impact terms
The survey fiches accept both the octave and the one-third-octave band
sets, but their standard-basis lines hardcoded '(survey method, octave
bands)'; the line now follows the band set the reported curve actually
carries, in both languages (ISO 717-1:2020 Clause 5.3 / ISO 717-2:2020
Clause 4.4 require stating it). The remaining comments citing the
band-set statement as ISO 717-1 Clause 4.4 now cite 5.3 (717-2 keeps
4.4), and the ISO 10140 fiche docstring cites the test-report clause as
Clause 9 (Clause 6 is the test arrangement).
Spanish terminology of the field impact quantities is aligned with the
UNE editions: UNE-EN ISO 16283-2:2016 defines 'nivel de presión
acústica estandarizado/normalizado de ruido de impactos' (3.13/3.14),
now used by the ISO 16283-2 and ISO 10052 basis lines; the ISO 10140-3
and ISO 12354-2 strings already match their own UNE editions
(UNE-EN ISO 10140-3:2011 3.2, UNE-EN ISO 12354-2:2018 3.1.1/3.1.2) and
stay unchanged.
* Qualify a background-limited ISO 16251-1 result as a lower bound
When any band sits at the 1,3 dB limit of measurement (Formula (2), the
per-band values already reported as > delta-L), the fiche now prints
the boxed delta-Lw with a >= qualifier and a note stating it is a lower
bound, in both languages. A manually built result without CI,delta
prints the bare delta-Lw instead of fabricating a (+0) adaptation term.
The ISO 717-2:2020 Annex C.2 errata entry is extended with the second,
independent print defect: the example's 'Ln,sum = 75,2527 = 75 dB'
reproduces to all printed digits only as the energy sum of the wrong
column over the wrong range (the measured floor with covering, 16 bands
100-3150 Hz), while the A.2.1 sum of the covered reference floor over
100-2500 Hz rounds to 76 dB with either 800 Hz value, so CI,r = -2,
CI,delta = -9 and delta-Llin = 6 dB; the earlier claim that the 800 Hz
misprint alone shifted the CI chain is corrected.
* Regenerate the conformance report, API docs and affected fiche examples
The Kc Table B.1 conformance row now covers all 21 printed rows, the
building API pages pick up the revised docstrings, and the EN 12354
prediction and ISO 15186-1 example fiches are re-rendered with the
prediction footer, the corrected designations and the Clause 8 areas
statement (kept to one page). CHANGELOG entries under [Unreleased].
* Validate the frequency axis and the facade method on the building results
The installed structure-borne prediction now rejects a frequency axis whose
length differs from the resolved band count, so a result can no longer carry
an inconsistent per-band table. FacadeInsulationResult validates its method
on construction, closing the direct-construction path that would render an
unknown method as the loudspeaker quantity. The band-count note also names
the characteristic level and coupling term as width-setting inputs.
Align the sound power determinations and noise declarations with their standards' clauses (#353)
- ISO 3741:2010, 9.1.2/9.1.3: apply the background correction at each
microphone position (K1i, Eq. 14), correct the position levels first
(Eq. 15) and only then energy-average (Eq. 16). Pre-averaged 1D spectra
keep the single-K1 path, documented as an approximation.
- ISO 9614-2:1996, 10.6 b: omit the bands failing criteria 1 and/or 2 from
the A-weighted total, flag them in the new a_weighting_omitted_bands field
and name them in the fiche basis strip (EN/ES); warn when the criteria
inputs are absent and the screening cannot run.
- ISO 9614-3:2002, C.1.6.2: a band satisfying criterion 5 qualifies as a
final result even if FS(2) >= 2.
- ISO 3745:2012: bands above 10 kHz no longer abort the determination; only
the A-weighted total (outside the ISO 3744 Annex E table) is NaN.
- ISO 3744:2010, 8.2.3 / ISO 3746:2010, 8.3.3: K1 = 0 only strictly above
the upper criterion; Equation (16) still applies at exactly 15 dB / 10 dB.
- ISO 4871:1996, 3.16/6.2: verify dual-number declarations against the sum
of the separately rounded declared values (verified_dual), and lay the
dual-number fiche out exactly as Annex B.2 (no derived L_WAd row).
- Cite clause 8.4 for the apparent directivity indices and note that the
4.3.2 validity limit concerns K2A (per-band check kept, conservative).
Hand-derived oracles cover each correction; the ISO 4871 and ISO 9614-2
example fiches, the API reference pages and the llms text are regenerated.
Impedance tube: complete circular, rectangular and square cross-section support (#380)
* Impedance tube: complete circular, rectangular and square cross-section support
The ISO 10534-2 branch already distinguished circular from rectangular
tubes; the ASTM E2611 branch ignored the cross-section entirely. Both
branches now cover it end to end:
- Accept "square" as a cross-section alias (the rectangular bound with
d the side length) in plane_wave_frequency_range() and
two_microphone_impedance().
- New plane_wave_frequency_range_astm(): ASTM E2611-19 working range
with the unrounded circular constant (fu d < 0.586 c, 6.2.4.1), the
rectangular bound (0.500 c, 6.2.5), the spacing bound (fu s < 0.40 c,
6.5.4) and the 1 % of wavelength lower limit (6.2.3).
- wave_decomposition(), transfer_matrix_two_load() and
transfer_matrix_one_load() accept diameter/shape and emit an
ImpedanceTubeWarning outside the plane-wave range (wavenumber-space
check, no speed of sound needed).
- New hydraulic_diameter(width, height) helper (4A/P) for the
tube_attenuation_constant() rectangular case (ISO 10534-2 A.2.1.5).
- ImpedanceTubeResult retains spacing/x1/diameter/shape and
TransferMatrix retains l1/s1/l2/s2/thickness/diameter/shape plus the
frequency vector and air characteristic impedance, so
TransferMatrix.plot() now works without arguments on solver-built
matrices.
- ReportMetadata.tube_shape prints a translated cross-section row on
the ISO 10534-2 fiche.
- Tests for every new path; materials guide (EN/ES), api-reference and
generated API pages updated.
* Address review: field order, spacing guard, plot docstring, message constant
- Append ReportMetadata.tube_shape after the original fields so the
public positional constructor order is unchanged.
- Validate s1/s2 inside _warn_astm_plane_wave so a zero spacing raises
ValueError instead of ZeroDivisionError from the two transfer-matrix
solvers.
- Reword TransferMatrix.plot() docstring: solver-built matrices retain
frequency and rho c, only hand-built ones must pass them.
- Hoist the duplicated diameter validation message into a module
constant (SonarCloud S1192).
Correct the framing and the guards of the perception and noise-control fiches (#355)
A review pass over the psychoacoustics, hearing, speech, environmental and
noise-control fiches. The numerics held up; what did not were the statements
printed around them, plus one wrong table lookup.
ISO 1999 validated domain. nipts()/htlan() applied Formula (2) wherever they
were asked to: L_EX,8h = 130 dB over 60 years at the 0,99 fractile returned a
357,9 dB threshold shift with nothing marking it as an extrapolation. Since the
formula is quadratic in (L_EX,8h - L0) that number is meaningless, not merely
uncertain. Both now warn (NoiseInducedHearingLossWarning) outside the stated
ranges while still computing: durations outside 1-40 years (clause 6.3.1
validates Formula (2) over 10-40 and Formula (3) over 1-10), fractiles in the
tails clause 6.3.2 says "should not be estimated" (Q below 5 % or above 95 %),
and levels above the 100 dB of Annex D that the Scope's NOTE 4 restricts
validity to. The fiches print the caveat when the conditions sit outside.
ISO 1999 Q. The fiches printed the library's fractile under ISO 1999's symbol,
inverting its meaning: in Formulae (4)/(5) Q is the percentage with worse
hearing, so the most-susceptible tenth is Q = 10 %, not the "Q = 0.9" the fiche
showed while citing 6.3.2. They now print ISO's Q as ISO defines it; the guides
note the difference from the fractile argument. Two further disclosures on the
same fiches: the age component H is evaluated from ISO 7029:2017 (the edition
ISO 1999 references undated in 6.2.2), which departs from the illustrative
Table A.3 selection by up to about 7 dB at the median, and the 2/3/4 kHz
average is the user's own choice, the Scope's NOTE 1 specifying no frequency
combination. The footer states a population scope rather than "the results
relate only to the tested specimen", which describes a laboratory specimen.
ISO 1999 Annex C is wired in as an independent oracle: its worked example (male
population aged 50, 90 dB for 30 years, 1/2/4 kHz at Q = 10 %) reproduces the
Table D.2 shifts it consumes (0, 9, 19 dB), the 13,3 dB left of the 4 kHz shift
after the Formula (1) compression (C.5) and the 31,1 dB combined threshold
(C.11). The composition it exercises is now exposed as combine_age_and_noise(),
which clause 6.2 wants available on its own: 6.2.3 recommends a database B
collected on a control population of the country under consideration, and this
applies Formula (1) to whichever database the user brings.
Verdict precision. The STI and SII fiches printed the requirement with one
decimal beside a measured value at full precision, so a verdict could contradict
itself: "STI = 0.50, required >= 0.5 -> FAIL" against a 0,52 requirement, and an
SII minimum of 0,75 printed as "0.8" (the committed example said so). Both now
print the requirement at the quantity's own precision. IEC 60268-16 Annex M
joins the conformance report as an end-to-end oracle: its printed MTF matrix,
speech spectrum and ambient noise give back its published MTI row and
STI = 0,76, exercising the whole A.5.3 to A.5.8 chain.
Noise-control prediction framing. The enclosure, silencer and HVAC fiches
compute design models but read as measurements: no prediction statement,
measurement headers, a footer scoped to a tested specimen, and committed
examples citing instrumentation that never existed ("Two-microphone
transfer-matrix bench"). They now follow the EN/ISO 12354 prediction exemplar
already in the repo, with a prediction-basis line, a statement naming what each
model does not represent, and a prediction footer. Their verdicts also decided
on the half-away-from-zero display rounding while printing Python's
round-half-to-even, so 0,25 printed 0.2 against a verdict taken on 0,3; both
now use the display rounding.
ISO/PAS 1996-3. With every onset rate at or below 10 dB/s the fiche withheld
the adjustment on the onset-rate gate (clauses 4.5/8) but justified it with "no
prominent impulse is present (governing P = 6.01 <= 5)", contradicting its own
boxed P. The note now states whichever gate governs. The assessment period is
read from the result instead of being hardcoded: 30 min is the Clause 5
*default*, now the default of the new assessment_period_min argument.
Smaller corrections:
- the HVAC elbow insertion loss took the wrong row of Bies Table 8.11 for a
W/lambda exactly on a bin edge; the rows read "a <= W/lambda < b", so an edge
opens its row (1 dB at 0,14, not 0 dB);
- the wind-turbine tonality fiche cited "subclauses 9.5.2-9.5.5" of
IEC 61400-11 for a chain running through 9.5.6 to 9.5.8 (Formulae 31-34);
- the ISO 1996-2 tonal fiche notes that Table J.1 keys on the mean audibility
of the J assessed spectra (ISO/PAS 20065 Clause 5.3.9), which a
single-spectrum assessment stands in for;
- the shared 10-90 % fractile band carried a hardcoded English legend in
Spanish figures, and the Spanish silencer and HVAC fiches printed the device
kind and duct-element label in English.
docs/ERRATA.md records two more source defects found on the way: ISO/PAS
1996-3:2022 Clause 5 swaps the 3.4/3.5 cross-references of the onset rate and
the level difference (its own units contradict the clause numbers printed with
them), and ISO 9613-2:1996 Table 2 prints 4,1 dB/km at 15 C / 80 % / 1 kHz
where ISO 9613-1 gives 4,1511, the neighbouring cells rounding correctly. The
library computes that coefficient from ISO 9613-1 directly, so it is unaffected.
Committed example fiches, the conformance report, the API reference and the
llms files are regenerated.