The unit of critical_angle depended on which function you called (#757)
* The unit of critical_angle depended on which function you called
#755 closed the bare names of the geometry. These are the compounds built
on the same words, and one of them is worse than anything the first pass
found: in weston_regimes.py, WestonRegimeBoundaries.critical_angle is in
radians and weston_regime_boundaries(critical_angle=...) one screen below
it takes degrees, while seabed_reflection.py has it in degrees again. The
same name, 57 times apart. The field is critical_angle_rad now and the two
overrides critical_angle_deg, which is what the function converts to
anyway.
The rest, read off each docstring: degrees for bank_angle, path_angle(s),
grazing_angle, launch_angles, arrival_angles, source_angle and
limiting_angle; radians for incidence_angle and angle_limit; metres for
the thirteen diameters; steradians for solid_angle; per second for
sound_speed_gradient; nepers per radian for reflection_loss_gradient and
its override. runway_gradient becomes runway_gradient_ratio, because its
own docstring says dimensionless.
Two public functions were caught by the sweep and put back:
critical_angle(c1, c2) and reflection_loss_gradient(seabed). The rule is
about parameters; what a function returns is said by its return type.
element_diameter and pitch_diameter stay bare in the guard's exemptions,
because the bearing formulae use them only as the ratio d/D.
The guard matches the geometric quantities as whole words inside a name
now, so critical_angle and duct_diameter are held to the rule and
triangles is not, and the two tuples of the first pass collapse into one.
No value changes: the same 995 conformance checks with the same numbers.
One clip is re-rendered, because its scene reaches the renamed parameters.
* The geometric conditions with a default are written by name too
The rule of #756 now reaches the names #755 and this branch renamed.
Thirteen more conditions carry a default and could still be passed as a
bare number.
piston_directivity_pattern and hydrophone_depths take a star before
their angle argument, which keeps the quantity the call is about
positional.
Nine result dataclasses take KW_ONLY after the fields they are about,
among them ApproachStep and DepartureStep, whose ANP steps were being
written as five numbers in a row against a column of sheet C-6.2.
* Say both halves of the rule in the guard's own docstring
Twenty-nine surfaces at three angles, computed rather than measured (#840)
* Twenty-nine surfaces at three angles, computed rather than measured, and a width its own geometry contradicts
Cox & D'Antonio 3e Appendix B is the diffusion half of ISO 17497: how even a
surface's polar response is, which is a different question from how much
energy left the specular direction and can answer the other way round for the
same surface. So `materials.diffusers.PUBLISHED_DIFFUSION` is a catalogue of
its own rather than more rows of the scattering one, and its numbers were
computed with a two-dimensional boundary element model, not measured.
The page prints three lines per surface, headed 0, 57 and Random, so a surface
is three rows here. The random one carries no angle at all: it is an
arithmetic mean over ten angles, without the weighting a measurement standard
would apply, and zero degrees already means the normal incidence row this same
table prints. Asking it for the angle gets that sentence, not a number.
The table's argument is in its numbers, and the tests pin two of them. One
semicylinder scores 0.77 at 1 kHz at random incidence and twelve of the same
semicylinder score 0.22, so an array is not one device repeated. Six
semiellipses go from 0.02 to 0.65 at 5 kHz as they deepen from 1 cm to 30 cm.
One surface is printed twice, in two sections, with the same fifty-four values,
because six semicylinders spanning 3.66 m and a 30 cm deep semicylinder array
are the same object read into two series. Both rows stay.
The first width of the first section reads "0.61 cm" where the other four of
its series are in metres, where the doubling series requires 0.61 m, where the
heading's own geometry gives 0.61 m, and where Table C.3 of the next appendix
prints the same surface as "0.61 m". That is in the errata register, with both
pages cited, and the row keeps what the page says.
Read twice from the pages by readers who never saw each other's work: 1566
cells, no difference, and the same twenty-nine descriptions and seven section
headings on both sides. Five deliberate defects were injected to watch the
tests fail against them, including an angle given to the random row and two
angle lines swapped.
The five catalogues of this library that hold a spectrum each kept their own
copy of the same three methods, and this would have been a sixth. They now
declare their bands and how their band fields are spelled, and inherit the
rest. Nothing about any of them changed from the outside.
* The errata page carries the width entry too
* The reference stopped documenting the methods a row inherits
When the five catalogue classes that hold a spectrum moved their three shared
methods onto a private base, the methods left the reference with them.
`bands()` and `spectrum()` had been on every one of those pages; afterwards
they were on none, while the curated index went on promising `.bands()` five
times and `.spectrum()` ten.
The generator collected methods from `vars(cls)`, which is what a class
defines and not what it carries. It now also walks the bases whose module a
reader cannot open, because those have no page to link to: a method inherited
from a published class is one click away, and a method inherited from a
private one is nowhere.
That restores what the refactor took and adds what was never there:
`why_missing()` and `printed()` come from `CatalogueRow` and had never been
documented on a single catalogue page, although telling an empty cell from a
cell holding a word is the whole point of these rows.
The unit goes in the name, where the caller writes the number (#752)
* The unit goes in the name, where the caller writes the number
A static pressure of 101 325 and a static pressure of 101.325 are both
legitimate values in this tree: the ISO 3740 family prints kilopascals,
IEC 61094-2 and ISO 15186-3 Annex A print pascals. Nothing separates them
by magnitude, because either reading is a real duty somewhere else, and
the result of the mix-up is still a float.
146 public parameters take their unit as a suffix. No value changes:
every function keeps the unit it already documented, so no oracle, no
printed figure and no conformance row moves.
temperature -> temperature_c across 39 callables, with temperature1_c,
temperature2_c, temperatures_c and temperature_celsius folded into the
same spelling; GasStream.inlet_temperature, which IEC 60534-8-3 states in
kelvin, becomes inlet_temperature_k. relative_humidity and the ISO 354
humidity both become relative_humidity_percent. The ambient pressure of
the propagation and aircraft chains becomes atmospheric_pressure_kpa, the
name air_density_astm and air_density_iso10534 already used; the ISO 3740
family takes static_pressure_kpa and the pascals of ISO 15186-3 Annex A,
ISO 9053-2 and ISO 7235 take static_pressure_pa, matching fluids.air.
Every other member of the family takes _pa.
Acoustic pressure keeps its bare name: a waveform is always in pascals
and a Signal carries its own calibration, so a suffix would restate the
type rather than resolve an ambiguity.
scripts/check_parameter_units.py holds the rule from here on. It walks
the imported package, not the source tree, because ReportMetadata is
published from the root and defined in a private module. Against main it
reports 154 offenders; here it reports none.
* Regenerate the API reference and the llms artifacts after the rewrap
* Pin the renamed argument in the four refusals nothing was reading
A hundred and nineteen rows a solver produced, filed where nobody can mistake them for measurements (#841)
* A hundred and nineteen rows a solver produced, filed where nobody can mistake them for measurements
Cox & D'Antonio 3e Appendix C is three tables of correlation scattering
coefficients, and none of them was measured. Two are three-dimensional
predictions of 3 m by 3 m single-plane diffusers, at normal and at random
incidence, over the bands from 250 Hz upward because the book says the
coefficient below that should be taken as zero and prints nothing there. The
third is two-dimensional, covers 100 Hz to 5 kHz, and prints three lines per
surface at 0, 56.9 and random incidence.
They go in `PUBLISHED_PREDICTED_SCATTERING` and not in the measured catalogue
next to them. A row that reads 0.45 because a solver said so and a row that
reads 0.45 because a reverberation room said so are not interchangeable, and a
caller who mixed them would have no way of finding out afterwards, so the two
have a class each, no key in common, and a test that says so.
`PredictedScatteringSpectrum.model` names the solver on every row.
The book is unusually frank about what these are worth, and the `about` of
each table quotes it with the page: the coefficient reads absorption as
scattering, so the formulation needs revising for a surface that absorbs; the
random incidence values of the two-dimensional table run high at low
frequencies; and the coefficient reads a redirection as a dispersion, so a
45 degree triangle that sends a strong reflection straight back scores as if
it had scattered.
Three things the tables do that a reader has to be told about, and all three
are kept as printed. Each group of the three-dimensional tables closes with a
row labelled "h/L = 20" or "h/L = 40", which cannot be read at face value
since every surface of every group has L = 20 cm and h at most 10 cm; read as
a percentage they resolve, and three of the six carry exactly the values of a
row of their own group, which is what settled the reading. The book explains
them nowhere. One row of Table C.2 is printed twice on one page, as the
reference of two comparisons. And one surface appears in two sections of
Table C.3 with the same fifty-four values, the way the same surface appears
twice in Appendix B.
The two three-dimensional tables print a source line under their last group,
which the appendix's one-item reference list resolves to Lee and Sakuma
(2015). That reference and the source line disagree about the page range,
129-36 against 129-136; the reference list's is the one carried here.
Read twice from the pages by readers who never saw each other's work: 1942
cells, no difference, and the same sixty-seven descriptions and headings on
both sides. Six deliberate defects were injected to watch the tests fail
against them, including the four empty low bands filled with zeros and the
two-dimensional table relabelled with the three-dimensional solver.
* The eighteen band fields were declared twice, and Sonar counted them
The measured catalogue and the computed one carry the same eighteen optional
fields, because a scattering coefficient is a scattering coefficient whoever
produced it. Declaring them in both classes put the duplication of new lines
at 3.9% against a gate of 3, and the gate is right: two copies of a field
list are how the two classes drift apart, one gaining a band or a docstring
that the other never gets.
They now come from one private declaration that both inherit. What the two
public classes keep is what is actually theirs: which kind of number the row
holds, and, on the predicted side, the angle it was computed at and the
solver that computed it.
Neither inherits from the other, which is the point of having two. A caller
narrowing on the type still gets a straight answer about whether a turntable
or a solver produced the row, and the test that says so is unchanged and
still passes.
* The solver reaches the table, and the repeated row says it is the repeat
Two things the layer promised and did not deliver, both found in review.
The prose says every predicted row identifies the solver that produced it,
and the rendered table could not show it: `model` never left the library. It
travels now, as text and never through the cell formatter, which expects
numbers, and it has a column of its own headed "Computed with" that appears
only where a catalogue has computed rows. A coefficient a boundary element
model produced and one a reverberation room measured are the same number and
not the same evidence, and that has to be visible before the number is used.
And the note of the data file says the second printing of one batten row
carries a note saying it is the repeat. It did not. The two rows are
identical in name, group and all thirteen values, so without it a reader has
no way to tell them apart, which is the one thing the note existed to do.
* Sixteen characters broke the solver into six lines, one word each
Forty-six surfaces measured with a turntable, and the two rows the book cannot tell apart (#839)
* Forty-six surfaces measured with a turntable, and the two rows the book cannot tell apart
Cox & D'Antonio 3e Appendix D is the only one of that book's four appendices
whose numbers were measured rather than computed: random incidence scattering
coefficients under ISO 17497-1, in one-third octave bands from 100 Hz to 5 kHz,
for corrugation, battens, blocks, pyramids, grooves cut into rubber, wooden
hemispheres and hedges. A geometric room model wants one of these per surface
per band and cannot derive it, so `materials.diffusers.PUBLISHED_SCATTERING`
holds the forty-six rows with the paper each one is credited to, spelled out
instead of the superscript that means nothing away from the page.
Nothing is smoothed. Ten rows print a dash at 5 kHz and twenty leave the column
blank, which are two different statements and are kept apart. One cell reads
1.17, which is what the standard's ratio gives and not a slipped digit. The
same battens measured by two teams are two rows, 0.28 and 0.44 at 630 Hz.
Two rows of the Pyramids group carry the same description, the same
continuation line and different spectra, on two different pages, so nothing
printed beside either one identifies it. They stay two rows, their keys carry
the folio that separates them, and the errata register says what the page does
without guessing what it meant to say.
The transcription was made twice from the rendered pages by readers who never
saw each other's work: 808 cells, no difference. Five deliberate defects were
injected to prove the tests fail against them, including a credit moved from
one row to the next, which the first version of the suite did not catch.
Two tools learned something on the way. The site's band headings could not
spell a one-third octave: 1250 Hz came out as "1 kHz", and 1.25 kHz needs a
decimal separator that Spanish writes with a comma, so the heading is now
per language. And the group heading a book prints above a block of rows now
travels to the published tables, where 622 rows across four catalogues were
already carrying one that nobody could see.
* The errata page carries the entry the register gained
* Thirteen bands, not fourteen: the two raised-pyramid rows agree in five