Building-science/Building-Acoustic-Analysis-v3
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
Change log
3. Final compliance reads the post-retrofit materials table alone (2026-07-13)
The New Materials table on the Acoustic Treatment tab is now the COMPLETE post-retrofit room: a row for every retained existing material, edited rows for replacements, and rows for new treatments. Final Compliance Checks (RT60, background noise, speech intelligibility) are computed from that table alone — previously the app summed it with the existing-materials upload, which made replacement modelling confusing. The Initial Data Entry uploads describe the existing room and are never altered by a retrofit iteration. Retained rows carry a unit rate of 0 so only actual works are costed.
Earlier changes (deployed 2025-07-10)
1. Reverberant-level reduction is now computed per octave band
The Final Compliance → Speech Intelligibility tab previously summed absorption across the six frequency bands and applied one scalar reduction to every band:
before = sum(current_absorption.values()) # Σ over 125 Hz … 4 kHz
after = sum(combined.values())
nr_db = 10 * np.log10(after / before) # one number
df_new_spl = df_spl - nr_db # same shift in every bandΣ of per-band absorptions is not a room absorption, and the Articulation Index dot count is spectral — a scalar shift flattens exactly the frequency detail the AI method exists to resolve. It is now:
NR(f) = 10 * log10( A_after(f) / A_before(f) )For a 60 m² bass trap on the class-demo boardroom the old code under-credited 125 Hz by 2.2 dB and over-credited 4 kHz by 1.1 dB.
2. The broadband dB(A) facade model uses a mid-frequency absorption
facade_indoor_level() evaluates L_in = L_out − Rw + 10·log10(S / A), which needs a single-figure room absorption. It was being passed sum(...) over the six bands — roughly 6× too large, depressing the facade path by about 10·log10(6) ≈ 7.8 dB and systematically making HVAC look dominant. It now receives the mean of the 500 Hz and 1 kHz bands, the mid-frequency convention AS/NZS 2107 already uses for reverberation time. New helper: mid_frequency_absorption().
This changes student-facing numbers. On the class-demo boardroom the facade path moves from 31.9 to 39.2 dB(A). Review before deploying mid-trimester.
3. Forward compatibility and input robustness
pd.to_numeric(..., errors="ignore")(deprecated in pandas 2.2, removed in 3.0) replaced with an explicit all-or-nothing cast.DataFrame.applymap(deprecated in pandas 2.1) replaced withDataFrame.map.pandaspinned to>=2.2.3,<3.0.- Frequency headers now parse case-insensitively:
1kHz,1KHz,125 Hzand125all resolve. Previously only the capital-K form worked, so a sheet exported with the assignment brief's own1kHzheading failed to load.
Tests
python tests/test_frequency_band_handling.py