Skip to content

Keep a data sheet's absorption and a laboratory's insulation as rows of their own, each rated again from its bands, and a guide to reading a material datasheet - #890

Open
jmrplens wants to merge 6 commits into
catalogues/csvfrom
catalogues/fiche-types
Open

jmrplens wants to merge 6 commits into
catalogues/csvfrom
catalogues/fiche-types

Conversation

@jmrplens

Copy link
Copy Markdown
Owner

A data sheet, a declaration of performance or a laboratory report prints quantities that a book's table does not, and until now no row class held them: a catalogue of your own had nowhere to put a practical absorption coefficient, a one-third-octave coefficient, a laboratory sound reduction index or a covering's weighted reduction of impact level without writing it into a class meant for something else. Four row classes now hold them, each read by io.read_catalogue from JSON or CSV and each with the function of the library that rates it.

materials.PracticalAbsorptionSpectrum holds the practical sound absorption coefficient of ISO 11654 in the six octaves from 125 Hz to 4 kHz, and materials.ThirdOctaveAbsorptionSpectrum the sound absorption coefficient of ISO 354 in one-third octaves from 50 Hz to 10 kHz, kept above 1 as measured (ISO 354 3.9 NOTE 2 gives diffraction effects as the reason). Both carry what the sheet prints beside the bands: the weighted coefficient, the shape indicators, the class, the NRC, the mounting (A, E-200, as ISO 354 Annex B names them), the thickness and the depth of construction of ISO 11654 Clause 5.4. rating() works the weighted coefficient out again with weighted_absorption (250 Hz to 4 kHz; the 125 Hz band is held and never rated, as Clause 1 says) or weighted_absorption_from_third_octave. practical() turns one-third octaves into practical coefficients by Clause 4.1, each octave marked in derived with the bands it comes from, and the bases of those bands named when they mix; an octave missing one of its three bands stays empty and says it does not follow.

A negative one-third-octave coefficient, which a measurement can give in a band where the specimen adds almost nothing to the room's absorption, is never read as 0 nor left out of a mean. rating() refuses it, naming the row, the band and the value, as practical_absorption_coefficient refuses it; practical() leaves the octave it falls in empty and says why in not_derivable, so practical().rating() refuses the same rating band, and a negative band below 200 Hz only empties the 125 Hz octave, which is not rated.

building.SoundReductionSpectrum holds the sound reduction index of ISO 10140-2 in 21 one-third octaves from 50 Hz to 5 kHz, with Rw, C, Ctr and the six adaptation terms of ISO 717-1 Annex B, the surface density, the thickness and the construction; rating() rates every band it prints with weighted_rating_extended, whose core is the weighted_rating of 100 Hz to 3150 Hz, and an Annex B term whose range has a band missing is None. building.ImpactImprovementSpectrum holds in the same bands the reduction of impact sound pressure level ΔL that ISO 10140-1 Annex H defines (Equation (H.1), ΔL = Ln0 − Ln on a reference floor, the levels measured by ISO 10140-3), with its weighted value, CI,r and CI,Δ; rating() returns the new building.ImpactImprovementRatingResult, which carries ΔLw from weighted_impact_improvement, CI,Δ from impact_improvement_adaptation_term and CI,r = −11 − CI,Δ dB (ISO 717-2:2020 Clause A.2.2, Formula (A.4)). Its weighted value has a field of its own and is never read from ImpactInsulation.impact_sound_improvement_db, an average over frequency; predicted_impact_insulation takes it through printed(), or refuses with what the sheet printed.

ImpactImprovementRatingResult.plot() draws ΔL per band with the rating in the title, in the form of the other ISO 717 plots and with the typographic minus: "ISO 717-2 ΔLw (CI,Δ=−9; CI,r=−2) = 15 dB". Its axis starts at 0 dB only when no band is below it, so a floating floor whose mass-spring resonance makes ΔL negative in its lowest bands keeps them in view; the ISO 16251-1 improvement plot shares that code and gains the same. The enlarged range of the ISO 717-1 and ISO 717-2 extended rating plots is now shaded with an opaque wash that stays visible on a dark page as on a light one.

When a catalogue file is read, each class notes what only it can judge, and never changes a cell: a practical coefficient above 1.00 or off the steps of 0.05, and a weighted coefficient off them, checked on the digits the sheet prints; and a printed rating (the weighted coefficient, the shape indicator, the class, Rw, C, Ctr, an Annex B term, ΔLw, CI,Δ, CI,r) that the bands do not give. A class is compared on its casefolded word and a shape indicator on its letters, so "Class C", "c", "not classified" or "(mh)" printed where the bands give the same leave no note. rating() answers with what the bands give and does not warn again. A unit alias or an x- column notes nothing and warns nothing.

weighted_rating, weighted_impact_rating, weighted_impact_improvement and impact_improvement_adaptation_term also take a mapping of band centre in hertz to value, such as a row's spectrum(): a mapping that holds a one-third-octave band that is not an octave centre is read as one-third octaves, any other as octaves unless bands= says, and a rating band it lacks is refused, naming the band, rather than rated as if the spectrum had no gap.

A new guide, "Reading a material datasheet" ("Cómo leer la hoja de características de un material"), sits first among the materials guides, in both languages and in docs/. It says what each number on a sheet is before it is typed: the practical coefficient against the one-third-octave one, the grid, the cap and the 125 Hz band; a level declared under CE marking, read from EN 13162:2012+A1:2015 (clauses 4.3.9, 4.3.11, 4.3.12 and 6: an AFr or AP level is a lower bound, an SD level an upper one), written as a bound with basis "declared"; measured against calculated or estimated; the mounting and the depth of construction, which is not the cavity; the revision and the day the sheet was read; the decimal comma; a PDF's corrupt text layer; and the sound reduction index and the impact improvement of a laboratory report. Its examples turn a test report into practical coefficients and a rating, read a sheet's octave table from a CSV file with the three notes one of its rows earns, rate a glazed partition over 50 Hz to 5 kHz, rate a floor covering's ΔL to 15 dB with CI,Δ = −9 dB and CI,r = −2 dB, and refuse a declared impact improvement a prediction cannot take. Each of the three ratings comes with its figure, drawn by the result's own plot(), and the code for it. The catalogues guide, the Files overview, the materials overview and the published catalogues page link it, and no longer say that no row class holds these quantities.

What breaks: nothing a caller wrote. The four rating functions take what they took before; a mapping is new, and so are the four row classes and ImpactImprovementRatingResult. The ISO 16251-1 improvement plot and the extended rating plots look slightly different, as described above; their data and titles are unchanged.

How it was checked. The oracles are the standards' own printed examples: ISO 11654:1997 Figures A.1 and A.2 (PDF page 14, printed folio 4) rate their practical coefficients to 0.60 and 0.60(M); the eighteen one-third-octave coefficients of its Annex C (PDF page 16, folio 6) give, worked by hand from Clause 4.1 (PDF page 12, folio 2), the practical coefficients 0.15, 0.35, 0.75, 1.00, 1.00 and 0.90 and the rating 0.65(MH), class C, both straight from the one-third octaves and through practical(); ISO 717-1:2020 Tables C.1 and C.2 rate the element to 30(−2;−3) dB with C50-5000 = −2 dB and Ctr,50-5000 = −4 dB; ISO 717-2:2020 Table C.2 rates the covering to ΔLw = 15 dB with CI,Δ = −9 dB from the Table 4 reference floor, so CI,r = −2 dB and ΔLlin = 6 dB (Formulae (A.4) and (A.5), read on PDF page 18, folio 12). The definition of ΔL was read on BS EN ISO 10140-1:2010+A2:2014, Annex H, PDF page 29, folio 20, and the scope of ISO 10140-3:2010 (PDF page 9, folio 1), which sends floor coverings there. The notes are held to each case: a coefficient of 1.05 kept and noted, 0.83 noted, an off-grid weighted coefficient noted with no band printed, a disagreeing weighted coefficient, class, shape indicator, Rw, Annex B term and CI,r each noted, agreeing ones in any case and a one-third-octave value above 1 left without a note, and nothing noted or warned for an alias or an x- column. A negative band is refused by rating() and by practical().rating() alike, and one below the rating range leaves the rating as it was. The improvement plot keeps a negative band inside its axis, signs its terms with U+2212 and fits its title in the default figure in both languages. The mapping readers refuse a missing band in each of the four functions and read float keys as integer ones. Every class is written as JSON and as CSV and read back, and the guards over every published row class (read from a one-row JSON document and a one-row sheet, every field a CSV column or sent where it is written) cover the four new ones. Every printed output in the guide was checked by running its blocks in order, and the English page, the Spanish page and the docs/ mirror print the same.

Gates: ruff check and format, mypy over src and scripts, bandit, the full test suite, every documentation snippet run, the site type check, build and HTML validation, the conformance report with no drift, the API reference and llms files regenerated, catalogue data current, the figure checks on the three new figures in their four variants (legends, tick and text clearance, minus sign, fill contrast, decimal point, annotations, tick labels and Spanish text), and the related checks (frozen constants, parameter units, published sources, published catalogues, API reference, em dashes, digit grouping, decimal comma, markdown hazards, fence names, control characters, Spanish accents, docstring math, mathtext, language forwarding, plot style defaults).

…ratory's sound reduction index and a covering's impact improvement as rows of their own, each rated again from its bands

PracticalAbsorptionSpectrum holds the practical coefficients of ISO 11654 from 125 Hz to 4 kHz and ThirdOctaveAbsorptionSpectrum the ISO 354 coefficients from 50 Hz to 10 kHz, both with the weighted coefficient, shape indicators, class, NRC, mounting, thickness and depth of construction the sheet prints. rating() works the weighted coefficient out again from the bands, and practical() turns one-third octaves into practical coefficients, each marked as derived and never borrowed from a neighbouring band.

SoundReductionSpectrum holds the ISO 10140-2 sound reduction index in 21 one-third octaves with Rw, C, Ctr and the Annex B terms of ISO 717-1; ImpactImprovementSpectrum holds the ISO 10140-3 reduction of impact level with Delta Lw, CI,r and CI,Delta. Their rating() calls weighted_rating_extended and the ISO 717-2 improvement functions; the new ImpactImprovementRatingResult carries Delta Lw with both adaptation terms and plots the spectrum.

Reading a catalogue file notes a practical coefficient above 1.00 or off the steps of 0.05, and a printed rating the bands do not give, without changing any cell. weighted_rating, weighted_impact_rating, weighted_impact_improvement and impact_improvement_adaptation_term take a mapping of band to value and refuse a missing band.
…es the row classes that now hold a sheet's absorption and a laboratory's insulation

"Reading a material datasheet" (EN, ES and the docs mirror) sits first among the materials guides and says what each number on a data sheet or a test report is before it is typed: the practical coefficient of ISO 11654 against the one-third-octave coefficient of ISO 354, the steps of 0.05, the cap of 1.00 and the 125 Hz band that is held and not rated; a level declared under CE marking, read from EN 13162, as a bound and never a value; measured against declared, calculated or estimated; the mounting and the depth of construction; the revision and the day it was read; the decimal comma and a corrupt text layer; and the sound reduction index and the impact improvement of a laboratory report. Its examples turn a test report into practical coefficients, read a sheet's octave table from CSV with the notes it earns, and rate a wall and refuse a declared impact improvement a prediction cannot take.

The catalogues guide, the Files overview, the materials overview and the published catalogues page link it, and no longer say that no row class holds these quantities. The guides index counts 146.
…, and a covering's improvement plot keeps a negative band in view

ThirdOctaveAbsorptionSpectrum.rating() refuses a negative one-third-octave
coefficient, naming the row, the band and the value, as
practical_absorption_coefficient does; practical() leaves the octave it
falls in empty and says why in not_derivable, so practical().rating()
refuses the same rating band and a negative band below 200 Hz only empties
the unrated 125 Hz octave. Nothing is floored to 0.00 any more.

A printed absorption class is compared with the one the bands give on its
casefolded word, so "not classified", "c" and "Class C" agree with the
bands that give them. A coefficient above 1 is explained as ISO 354 3.9
NOTE 2 does, by diffraction effects.

ImpactImprovementSpectrum cites the definition of Delta L where it is, ISO
10140-1 Annex H, Equation (H.1), with the levels measured by ISO 10140-3.

The ISO 717-2 improvement plot starts its axis at 0 dB only when no band is
below it, and its title reads "ISO 717-2 Delta Lw (CI,Delta=-9; CI,r=-2) =
15 dB" with the typographic minus of the other rating plots, short enough
for the default figure in both languages. The enlarged range of the ISO
717-1 and ISO 717-2 extended rating plots is shaded with an opaque wash
that stays visible on a dark page.
…ering's report, and cites ISO 10140-1 for the impact improvement

The guide on reading a material datasheet now shows the figure of every
rating its examples work out: the ISO 11654 rating of a test report's
one-third octaves, the ISO 717-1 rating of a laboratory's sound reduction
index over 50 Hz to 5 kHz, and a new example that reads a floor covering's
Delta L from its report and rates it to Delta Lw 15 dB with CI,Delta -9 dB
and CI,r -2 dB. Each figure is the result's own plot() with the code behind
it, in English and Spanish.

Delta L is cited to ISO 10140-1 Annex H, which defines it, with ISO 10140-3
as the measurement; a coefficient above 1 is explained by diffraction, as
ISO 354 does; the glazed partition of the example is a 4 mm pane, which is
where its coincidence dip at 3.15 kHz puts it; the guide says what happens
to a negative coefficient; and two Spanish sentences read as the English
ones do.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sorry @jmrplens, your pull request is larger than the review limit of 150,000 diff characters

@coderabbitai

coderabbitai Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 59 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 2 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository: jmrplens/phonometry/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: e7db96b4-bbe3-48a5-91be-2306374ed0ad

📥 Commits

Reviewing files that changed from the base of the PR and between 9d33a98 and d2cafb3.

⛔ Files ignored due to path filters (13)
  • .github/images/datasheet_absorption_rating.svg is excluded by !**/*.svg
  • .github/images/datasheet_absorption_rating_dark.svg is excluded by !**/*.svg
  • .github/images/datasheet_absorption_rating_es.svg is excluded by !**/*.svg
  • .github/images/datasheet_absorption_rating_es_dark.svg is excluded by !**/*.svg
  • .github/images/datasheet_impact_improvement_rating.svg is excluded by !**/*.svg
  • .github/images/datasheet_impact_improvement_rating_dark.svg is excluded by !**/*.svg
  • .github/images/datasheet_impact_improvement_rating_es.svg is excluded by !**/*.svg
  • .github/images/datasheet_impact_improvement_rating_es_dark.svg is excluded by !**/*.svg
  • .github/images/datasheet_sound_reduction_rating.svg is excluded by !**/*.svg
  • .github/images/datasheet_sound_reduction_rating_dark.svg is excluded by !**/*.svg
  • .github/images/datasheet_sound_reduction_rating_es.svg is excluded by !**/*.svg
  • .github/images/datasheet_sound_reduction_rating_es_dark.svg is excluded by !**/*.svg
  • site/src/generated/api-sidebar.mjs is excluded by !**/generated/**
📒 Files selected for processing (44)
  • CHANGELOG.md
  • docs/README.md
  • docs/io/index.md
  • docs/io/material-catalogues.md
  • docs/materials/index.md
  • docs/materials/reading-a-datasheet.md
  • docs/reference/api/index.md
  • llms-full.txt
  • llms.txt
  • scripts/api_taxonomy.py
  • scripts/figures/datasheets.py
  • scripts/figures/registry.py
  • site/public/llms/llms-io.txt
  • site/public/llms/llms-materials.txt
  • site/src/content/docs/es/io/index.mdx
  • site/src/content/docs/es/io/material-catalogues.mdx
  • site/src/content/docs/es/materials/index.mdx
  • site/src/content/docs/es/materials/reading-a-datasheet.mdx
  • site/src/content/docs/es/reference/catalogues.mdx
  • site/src/content/docs/es/start/guides.md
  • site/src/content/docs/io/index.mdx
  • site/src/content/docs/io/material-catalogues.mdx
  • site/src/content/docs/materials/index.mdx
  • site/src/content/docs/materials/reading-a-datasheet.mdx
  • site/src/content/docs/reference/api/building/datasheets.md
  • site/src/content/docs/reference/api/building/ratings.md
  • site/src/content/docs/reference/api/index.md
  • site/src/content/docs/reference/api/materials/datasheets.md
  • site/src/content/docs/reference/catalogues.mdx
  • site/src/content/docs/start/guides.md
  • site/src/data/topics.mjs
  • src/phonometry/_plot/building.py
  • src/phonometry/building/__init__.py
  • src/phonometry/building/datasheets.py
  • src/phonometry/building/measurement/__init__.py
  • src/phonometry/building/measurement/ratings.py
  • src/phonometry/materials/__init__.py
  • src/phonometry/materials/absorbers/__init__.py
  • src/phonometry/materials/absorbers/datasheets.py
  • tests/building/test_insulation_datasheets.py
  • tests/io/test_catalogue_fiche_types.py
  • tests/io/test_catalogue_units.py
  • tests/materials/absorbers/test_absorption_datasheets.py
  • tests/test_result_plots.py

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

❤️ Share

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

@jmrplens
jmrplens added this pull request to stack #892 September 26, 2026 00:26
@github-actions github-actions Bot added documentation Improvements or additions to documentation api Public API surface, naming and deprecations figures Generated plots, diagrams and animations site Documentation website i18n English and Spanish translations area: building Sound insulation and building acoustics area: materials Absorption, impedance and material properties area: core Shared internals and cross-cutting code every domain depends on labels Sep 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Numerical conformance

All 1447 conformance checks pass, across 97 domains and 477 standards

1447/1447 checks pass across 97 domains and 477 standards (196 normative designations, 114 further published sources).

Used in the tables below is how much of that clause's published tolerance the deviation consumes: 100 % sits exactly on the limit, 5 % uses a twentieth of the allowance, and a dash means the clause states no two-sided tolerance for the quantity, so there is no budget to spend. It is reported and never used to decide a verdict, which is settled at full precision before any rounding.

Nothing moved: same 1447 checks, same verdicts, same numbers.

Closest to their published limit (top 5)

The rows with the least room left, so the ones a change is most likely to push over.

Standard Quantity Deviation Used
ISO/TR 17534-3:2015 Table 3 Ground-projected path length dp, m 0.005 m 100 %
DIN 4150-2:1999-06 Annex C, Example 5 KB_FTr with hammer b) in the rest hours, Formula (5) -0.005 100 %
DIN 4150-2:1999-06 Annex C, Example 8 KB_FTm over the record with the passage maxima alone -0.0005 100 %
E DIN 4150-2:2023-08 Annex B, Table B.1 KB_FTm,Zug of the metro north by Formula (5) -0.0005 100 %
Long 2e Table 14.9 (worked duct-borne sheet, supply path) Fan to room, 8 octave bands -> 52/42/30/18/9/-2/-2/-1 dB at the receiver 1 dB 100 %

Fail Tests & coverage: 128394 tests, 6 failures (6 failing)
Python Version Tests Failures Coverage Status
macos-latest-3.13 21399 0 96.9% Pass Passed
macos-latest-3.14 21399 1 96.9% Fail Failed
ubuntu-latest-3.13 21399 0 96.9% Pass Passed
ubuntu-latest-3.14 21399 1 96.9% Fail Failed
windows-latest-3.13 21399 2 96.9% Fail Failed
windows-latest-3.14 21399 2 96.9% Fail Failed

Full report at this commit: docs/CONFORMANCE.md · docs/conformance.json · full CI artifacts

@codecov

codecov Bot commented Sep 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (catalogues/csv@9d33a98). Learn more about missing BASE report.

Additional details and impacted files
@@                Coverage Diff                @@
##             catalogues/csv     #890   +/-   ##
=================================================
  Coverage                  ?   96.85%           
=================================================
  Files                     ?      397           
  Lines                     ?    66732           
  Branches                  ?        0           
=================================================
  Hits                      ?    64635           
  Misses                    ?     2097           
  Partials                  ?        0           

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

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

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Public API surface, naming and deprecations area: building Sound insulation and building acoustics area: core Shared internals and cross-cutting code every domain depends on area: materials Absorption, impedance and material properties documentation Improvements or additions to documentation figures Generated plots, diagrams and animations i18n English and Spanish translations site Documentation website

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant