Earthquake ground motion (BSSA14 GMPE ShakeMap)
Full description: Read the full narrative
The scenario is a 2D seismic-hazard computation, not a wave-physics animation: the kernel evaluates the median ground-motion prediction equation (GMPE) of Boore, Stewart, Seyhan & Atkinson (NGA-West2 base case, BSSA14 / PEER 2013/05) on a regular grid around a user-pinned epicentre, applies linear and nonlinear site response for the chosen Vs30, converts to Modified Mercalli Intensity with the USGS instrumental rules, and writes PGA / PGV / Sa(1 s) / MMI grids plus an animated PGA series timed by S-wave arrival.
- Execution mode
- Local CPU (python3) — no Kaggle token required server/kaggle/simRunner.ts:126-141 (LOCAL_SIM_TYPES)
- Verification
- MEASURED — executed directly and end-to-end through the job API
- Wire scenario type
earthquake_swarm— contract at src/services/kaggleSim.ts:28-240; job API at Simulation job API
MEASURED marks values produced by executing the actual code on this machine (commands in Reproduction; raw logs summarised in Methodology → Evidence runs).
Governing equations and coefficients
Source attribution as stated in the kernel header (verbatim):
PGA, PGV and Sa(1.0 s): the Boore, Stewart, Seyhan & Atkinson NGA-West2 GMPE (BSSA14; PEER 2013/05, published as Boore et al. 2014, BSSA 104(2), doi:10.1785/0120130065). … ln Y = FE(M,mech) + FP(R,M) + FS(VS30,M,R) with the full linear + nonlinear site response; unspecified fault mechanism; base-case (no regional anelastic / basin-depth terms). Validity: M 3-9.7, shallow crustal, VS30 150-1500 m/s.
Coefficients and named constants
| IM | e0 | e4 | e5 | e6 | Mh | c1 | c2 | c3 | Mref | Rref | h |
|---|---|---|---|---|---|---|---|---|---|---|---|
| PGA | 0.4473 | 1.431 | 0.05053 | −0.1662 | 5.5 | −1.134 | 0.1917 | −0.00809 | 4.5 | 1.0 | 4.5 |
| PGV | 5.037 | 1.073 | −0.1536 | 0.2252 | 6.2 | −1.243 | 0.1489 | −0.00344 | 4.5 | 1.0 | 5.3 |
| Sa(1 s) | 0.3932 | 1.5004 | −0.18983 | 0.17895 | 6.2 | −1.193 | 0.10248 | −0.00121 | 4.5 | 1.0 | 5.74 |
| IM | c | Vc | Vref | f1 | f3 | f4 | f5 |
|---|---|---|---|---|---|---|---|
| PGA | −0.5150 | 925.00 | 760.0 | 0.0 | 0.1 | −0.1500 | −0.00701 |
| PGV | −0.8050 | 950.00 | 760.0 | 0.0 | 0.1 | −0.1000 | −0.00844 |
| Sa(1 s) | −1.0361 | 967.51 | 760.0 | 0.0 | 0.1 | −0.1052 | −0.00844 |
| Quantity | Values |
|---|---|
| PGA upper bounds, MMI 2…10 [g] | 0.000464, 0.00135, 0.00297, 0.0276, 0.115, 0.215, 0.401, 0.747, 1.39 |
| PGV upper bounds, MMI 2…10 [cm/s] | 0.0215, 0.135, 1.41, 4.65, 9.64, 20.0, 41.4, 85.8, 178.0 |
| PGV medians, MMI 1…10 [cm/s] | 0.010, 0.054, 0.437, 2.56, 6.70, 13.9, 28.8, 59.6, 123.6, 267.0 |
Parameter contract
Earthquake parameters: UI control → wire field → unit → valid range → default → physical meaning. Shared request envelope (validated at the client boundary before dispatch).
| UI control | Wire field | Unit | Valid range (UI · wire · kernel) | Default | Physical meaning | Source |
|---|---|---|---|---|---|---|
| Mag (mainshock) slider | magnitude | M (moment/local) | UI 3.0–9.5 step 0.1, default 8.0; wire 3.0–9.7; kernel raises outside 3.0–9.7 | UI 8.0 · kernel 6.5 | Mainshock magnitude driving GMPE magnitude scaling | src/components/scenarios/ScenarioEditor.tsx:62-68 src/services/kaggleSim.ts:94 kaggle-kernels/earthquake-sim/main.py:238,244-245 |
| Depth (mainshock) slider | depth_km | km | UI 1–300 (auto-overwritten to clamp(5, 50, 5·M) by the form derivation); wire 0.5–700; kernel validates 0.5–700 | UI 30 · kernel 12 | Hypocentral depth; enters R_hyp | src/components/scenarios/ScenarioEditor.tsx:62-68 src/services/kaggleSim.ts:95,600 kaggle-kernels/earthquake-sim/main.py:239,246-247 |
| Site Vs30 (NEHRP) slider | vs30 (optional) | m/s | 150–1500 step 10 | 760 | Time-averaged shear velocity to 30 m; drives linear + nonlinear site amplification | src/components/scenarios/ScenarioEditor.tsx:62-68 src/services/kaggleSim.ts:97 kaggle-kernels/earthquake-sim/main.py:242,248-249 |
| Min Magnitude / Min Depth sliders | — (not sent) | M / km | 1–8 / 0–100 | 2.5 / 5 | Catalog context shown in the panel; the wire carries only the mainshock pair | src/components/scenarios/ScenarioEditor.tsx:62-68 src/services/kaggleSim.ts:455-464 |
| Epicentre (globe click) | epi_frac_x, epi_frac_y (optional) | fraction of box | 0–1, clamped | 0.5, 0.5 | Column = x eastward, row = y southward; GMPE distance field radiates from this cell | src/services/kaggleSim.ts:98-106 kaggle-kernels/earthquake-sim/main.py:262-267 |
Outputs
| Field | Unit | Meaning | Source |
|---|---|---|---|
pga_cm_s2.npy | cm/s² | Peak ground acceleration grid (median prediction) | kaggle-kernels/earthquake-sim/main.py:409-420 |
pgv_cm_s.npy | cm/s | Peak ground velocity grid | kaggle-kernels/earthquake-sim/main.py:409-420 |
sa_1s_cm_s2.npy | cm/s² | 5 %-damped spectral acceleration at T = 1.0 s | kaggle-kernels/earthquake-sim/main.py:409-420 |
mmi.npy | MMI 1–10 (float) | Instrumental Modified Mercalli intensity grid (max of PGA- and PGV-derived) | kaggle-kernels/earthquake-sim/main.py:282,409-420 |
snapshots_pga.npy + snapshot_times.npy | cm/s²; s | PGA reveal frames timed by S-arrival (t = R_hyp / Vs, Vs = 3.5 km/s, smoothstep onset) | kaggle-kernels/earthquake-sim/main.py:297-314,303 |
metadata.json | — | params (incl. cell_size_m, epi fracs), model/source strings, final_stats, validation results | kaggle-kernels/earthquake-sim/main.py:319-335,425-433 |
Spatial-origin semantics
Simulation domain: a square of side extent_km centred on the study-box centroid; dx = extent_km·1000/grid_size m (default 500 m without extent). Rows run north→south (row 0 = north edge), columns west→east; the epi-fraction point (x = east, y = south) receives the distance origin so the strongest shaking sits on the clicked trace. lat/lon enter metadata only — never the physics. kaggle-kernels/earthquake-sim/main.py:251-270,319,330
Documented validity limits (verbatim from the code)
'point-source hypocentral distance used for the GMPE Rjb term — no fault-geometry directivity or finite-rupture effects' · 'unspecified fault mechanism; base-case only (no regional anelastic attenuation or basin-depth z1 terms)' · 'Sa reported at T=1.0 s only' · 'Worden-2012/Caprio-2015 intensity relations calibrated on California/global datasets and saturate for great-earthquake near-fields'
Before emitting any field the kernel runs a GMPE sanity gate (attenuation monotonicity, M6.5 @ 10 km PGA in (100, 500) cm/s², soft-site amplification > 1, PGV/PGA ratio 0.05–0.2 s, MMI band round-trip). On failure it refuses to emit: "GMPE sanity gate failed — refusing to emit a ShakeMap from mis-wired attenuation relations." kaggle-kernels/earthquake-sim/main.py:194-232,400-404
Measured runs and timings
| Run / check | Measured result |
|---|---|
| Kernel, M 7.5 · 12 km · Vs30 760 · 100 km box · 256² | max PGA 251.0 cm/s², max PGV 27.5 cm/s, max MMI 7.0, area(MMI ≥ 6) 4,439 km²; kernel compute 0.0083 s; total wall 0.12 s (incl. interpreter start) |
| Boundary cases | M 3.0 / 0.5 km / Vs30 150 and M 9.7 / 700 km / Vs30 1500 both complete; M 2.9 rejected with "magnitude 2.9 outside the 3.0-9.7 GMPE validity range"; depth 750 km rejected with "depth_km 750.0 outside 0.5-700 km" |
| End-to-end via POST /api/kaggle/simulate | job sim_44d5c7d7 (M 7.2, 128², 100 km box): status running→complete 166 ms after submission; result metadata cites "BSSA14 … doi:10.1785/0120130065"; grid + GeoTIFF endpoints returned HTTP 200 (296,648-byte npy; valid 128×128 TIFF) |
| DOI resolvability | https://doi.org/10.1785/0120130065 responds 302 (resolvable) |
Reproduction
Commands
# 1) via the running server (same path the web UI uses):
npm run dev:server # Express on :3001
curl -s -X POST http://localhost:3001/api/kaggle/simulate \
-H 'Content-Type: application/json' -d '{
"type":"earthquake_swarm","lat":36.1,"lon":139.7,
"grid_size":128,"extent_km":100,"magnitude":7.2,
"depth_km":15,"vs30":760,"epi_frac_x":0.4,"epi_frac_y":0.5 }'
# → {"jobId":"sim_…","status":"running","streamUrl":"/api/kaggle/simulate/…/stream"}
curl -s http://localhost:3001/api/kaggle/simulate/<jobId>/results
curl -s -o pga.npy http://localhost:3001/api/kaggle/simulate/<jobId>/grid/pga_cm_s2
# 2) kernel directly (honours TERRANOETIS_OUT_DIR):
cd kaggle-kernels/earthquake-sim && mkdir -p /tmp/eq && \
echo '{"grid_size":128,"magnitude":7.5,"depth_km":12,"vs30":760,"extent_km":100}' > /tmp/eq/params.json && \
(cd /tmp/eq && TERRANOETIS_OUT_DIR=/tmp/eq python3 <repo>/kaggle-kernels/earthquake-sim/main.py)