sfm/compliance.py renders the velocity-vs-frequency blasting compliance chart Blastware draws on its Event Report: - limit_at()/limit_curve() — the RI8507 Fig B-1 / 30 CFR 816.67 curve as data (Drywall 0.75 + plaster 0.50 lines): 0.030in low-freq bound, plateau, 0.008in rising diagonal to a 2.0 in/s cap at ~40 Hz, drawn continuous. - channel_compliance_points() — the per-cycle (freq, peak-velocity) scatter by the zero-crossing method (matches Blastware; cloud ceiling = channel PPV). - draw_compliance_chart() — matplotlib rendering (both lines + scatter, BW tick scales + channel markers). Verified against 7 BE12844 Blastware reports. docs/ri8507_compliance_curve.md captures the curve construction, the SHM basis, and the scatter method. Not yet wired into report_pdf.py — that placeholder is the next step. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YDXjZCr4RqT2U3QvMDhgzf
136 lines
6.0 KiB
Markdown
136 lines
6.0 KiB
Markdown
# USBM RI8507 / OSMRE Blasting Compliance Curve — Reference
|
||
|
||
Reference for the **velocity-vs-frequency blasting compliance chart** Blastware
|
||
draws on its Event Report ("USBM RI8507 And OSMRE"), and how seismo-relay
|
||
reproduces it. Implemented in [`sfm/compliance.py`](../sfm/compliance.py); the
|
||
spectral (FFT) side lives in [`waveform_fft.py`](../waveform_fft.py).
|
||
|
||
Reverse-engineered 2026-09-14 against 7 BE12844 (MiniMate Plus) events, each
|
||
with a Blastware Event Report + FFT Report as ground truth. Curve values from
|
||
USBM RI8507 Appendix B and 30 CFR 816.67.
|
||
|
||
---
|
||
|
||
## What it is
|
||
|
||
Two closely-related sources for the same limit curve:
|
||
|
||
- **USBM RI8507** — Bureau of Mines *Report of Investigations 8507* (Siskind
|
||
et al., 1980), *"Structure Response and Damage Produced by Ground Vibration
|
||
From Surface Mine Blasting."* The curve is **Figure B-1**, Appendix B
|
||
("Alternative Blasting Level Criteria"), p.73–74.
|
||
- **OSMRE / OSM** — the Office of Surface Mining Reclamation and Enforcement
|
||
codified it as **30 CFR 816.67, Figure 1**. "CFR" = the U.S. Code of Federal
|
||
Regulations. Same curve, regulatory force.
|
||
|
||
The chart plots each geophone channel's significant vibration cycles as
|
||
`(frequency, peak velocity)` points against this limit. A point **below** the
|
||
line passes; **above** fails.
|
||
|
||
---
|
||
|
||
## The limit curve
|
||
|
||
A structure has a resonance band (~4–12 Hz for whole structures) where it is
|
||
most vulnerable, so the safe velocity is **lower** at those frequencies and
|
||
**higher** away from them. The curve captures this by alternating two kinds of
|
||
bound:
|
||
|
||
- **Constant-velocity** segments — a flat horizontal line at a fixed PPV.
|
||
- **Constant-displacement** segments — a fixed peak *displacement* `d`. For
|
||
simple harmonic motion, peak velocity `v = 2πf·d`, so on a velocity-vs-
|
||
frequency **log-log** plot this is a straight line of slope +1 (velocity rises
|
||
with frequency). This is why the low- and high-frequency bounds are sloped.
|
||
|
||
### Two lines — structure type
|
||
|
||
RI8507 gives two lines for two interior-wall constructions (Table 13, p.67):
|
||
|
||
| line | construction | plateau PPV |
|
||
|---|---|---|
|
||
| **Drywall** (solid) | modern gypsum wallboard | **0.75 in/s** |
|
||
| **Plaster** (dashed) | older plaster on wood lath | **0.50 in/s** |
|
||
|
||
Plaster-on-lath is more damage-prone, hence the lower limit. You apply **one**
|
||
line depending on the monitored structure.
|
||
|
||
### The four segments (Figure B-1, p.74)
|
||
|
||
Going low → high frequency, each line is:
|
||
|
||
1. **Ultimate low-frequency bound** — constant displacement **0.030 in**
|
||
(`v = 2πf·0.030`). Only relevant below ~4 Hz.
|
||
2. **Plateau** — constant velocity **0.75** (Drywall) / **0.50** (plaster) in/s.
|
||
3. **Rising diagonal** — constant displacement **0.008 in** (`v = 2πf·0.008`),
|
||
climbing from the plateau up to the high-frequency cap.
|
||
4. **High-frequency cap** — constant velocity **2.0 in/s** above ~40 Hz.
|
||
|
||
The segments are drawn **continuous**: each bound is used over the frequency
|
||
range where it is the binding (lowest) limit, and consecutive bounds meet where
|
||
they are equal — so there are no vertical steps. Transition frequencies come
|
||
straight from the values (`f = V / (2π·d)`):
|
||
|
||
| transition | formula | Drywall | Plaster |
|
||
|---|---|---|---|
|
||
| 0.030 in → plateau | `V_mid / (2π·0.030)` | 3.98 Hz | 2.65 Hz |
|
||
| plateau → 0.008 in | `V_mid / (2π·0.008)` | 14.92 Hz | 9.95 Hz |
|
||
| 0.008 in → 2.0 in/s | `2.0 / (2π·0.008)` | 39.79 Hz | 39.79 Hz |
|
||
|
||
Because both lines share the same **0.008 in** rising diagonal, above ~15 Hz
|
||
they lie on the *same* line (both reach 2.0 in/s at ~40 Hz) — RI8507's literal
|
||
construction merges them there. Blastware renders the dashed line as a separate
|
||
parallel diagonal, but that is cosmetic: above ~15 Hz both structure types carry
|
||
the identical limit, so compliance is unaffected.
|
||
|
||
> ⚠ RI8507's *Table 13* is a simpler two-range criterion with a **sharp
|
||
> discontinuity at 40 Hz** (flat plateau, then a jump to 2.0). Figure B-1 is the
|
||
> **smoothed** version that adds the 0.008 in transition — that is the one drawn
|
||
> on reports and implemented here.
|
||
|
||
---
|
||
|
||
## The compliance scatter (the points)
|
||
|
||
The cloud is **not** the FFT spectrum. It is a per-cycle, time-domain measure by
|
||
the **zero-crossing method** (`channel_compliance_points`):
|
||
|
||
- Split the channel's waveform at its zero crossings.
|
||
- Each half-cycle contributes one point: **frequency** `= 1 / (2 · half-period)`
|
||
(from the samples between the two crossings), **velocity** `= peak |amplitude|`
|
||
in that half-cycle.
|
||
|
||
This yields ~90–110 points per channel, and — by construction — each channel's
|
||
**highest** point equals that channel's PPV. Verified against Blastware: the
|
||
cloud shape, density, and ceiling all match.
|
||
|
||
### Why not the FFT?
|
||
|
||
A broadband blast spreads its energy across many FFT bins, so no single bin
|
||
reaches the time-domain peak — the FFT amplitudes come out ~10× below the
|
||
compliance-chart velocities. The compliance chart is a *per-cycle peak* view;
|
||
the **FFT** is a separate analysis (Blastware's *FFT Report*), reproduced by
|
||
[`waveform_fft.py`](../waveform_fft.py) and used for the dominant-frequency
|
||
readout and the #10 FFT view — not for this scatter.
|
||
|
||
---
|
||
|
||
## Implementation
|
||
|
||
- `sfm/compliance.py`
|
||
- `limit_at(freq, curve)` — the limit PPV at a frequency (`curve` = `"Drywall"`
|
||
or `"Plaster"`); curves are data in `_CURVES`, so more standards can be added.
|
||
- `channel_compliance_points(samples, sps)` — the zero-crossing scatter.
|
||
- `draw_compliance_chart(ax, channels, sps)` — matplotlib rendering (both
|
||
limit lines + per-channel scatter, Blastware's tick scales and channel
|
||
markers: Tran `+` red, Vert `×` green, Long `o` blue).
|
||
- Tests: `tests/test_compliance.py`.
|
||
|
||
---
|
||
|
||
## Sources
|
||
|
||
- USBM **RI8507** (Siskind, Stagg, Kopp, Dowding, 1980), Appendix B / Figure B-1,
|
||
p.73–74; Table 13, p.67. (`ref-stuff/usbm-ri8507-ground_vibration.pdf`.)
|
||
- **30 CFR 816.67**, "Use of explosives: Control of adverse effects," Figure 1 —
|
||
<https://www.ecfr.gov/current/title-30/chapter-VII/subchapter-K/part-816/section-816.67>
|