CoolFace
Apppublic

Building-science/Building-Acoustic-Analysis-v3

sourceHugging Facemitupdated 2mo agoView on Hugging Face
0likes
App README

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:

python
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:

python
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 with DataFrame.map.
  • pandas pinned to >=2.2.3,<3.0.
  • Frequency headers now parse case-insensitively: 1kHz, 1KHz, 125 Hz and 125 all resolve. Previously only the capital-K form worked, so a sheet exported with the assignment brief's own 1kHz heading failed to load.

Tests

bash
python tests/test_frequency_band_handling.py