FA-71831 / Seismic magnitude estimation / Open access
Magnitude from surface rupture length: slip type coefficients · case 01
Rupture-length magnitudes are nonsensical, around 1 to 6 units off.
ROOT CAUSE
Intercept and slope are unpacked in the wrong order.
VERIFIED REPAIR
Unpack (a, b) as intercept and slope.
Unsuccessful approach: Always using the ALL coefficients ignores the slip type.
Case contract
Regression M = a + b log10(L km) by slip type: SS (5.16, 1.12), R (5.00, 1.22), N (4.86, 1.32), ALL (5.08, 1.16); unknown type or non-positive length returns None. Round to 0.01.
Why this case matters
Paleoseismic studies estimate prehistoric magnitudes from mapped rupture lengths.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(kind, length_km):
coef = {"SS": (5.16, 1.12), "R": (5.00, 1.22), "N": (4.86, 1.32), "ALL": (5.08, 1.16)}
if kind not in coef or length_km <= 0:
return None
b, a = coef[kind]
return round(a + b * math.log10(length_km), 2)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['SS rupture 0.5 km', ['SS', 0.5], 4.82], ['SS rupture 5.0 km', ['SS', 5.0], 5.94], ['SS rupture 40.0 km', ['SS', 40.0], 6.95], ['SS rupture 350.0 km', ['SS', 350.0], 8.01], ['SS rupture 0.0 km', ['SS', 0.0], None], ['R rupture 0.5 km', ['R', 0.5], 4.63], ['R rupture 5.0 km', ['R', 5.0], 5.85], ['R rupture 40.0 km', ['R', 40.0], 6.95]], [['SS rupture 350.0 km', ['SS', 350.0], 8.01], ['R rupture 40.0 km', ['R', 40.0], 6.95], ['R rupture 350.0 km', ['R', 350.0], 8.1], ['R rupture 0.0 km', ['R', 0.0], None], ['N rupture 0.5 km', ['N', 0.5], 4.46], ['N rupture 5.0 km', ['N', 5.0], 5.78], ['N rupture 40.0 km', ['N', 40.0], 6.97], ['N rupture 350.0 km', ['N', 350.0], 8.22]], [['R rupture 40.0 km', ['R', 40.0], 6.95], ['N rupture 350.0 km', ['N', 350.0], 8.22], ['N rupture 0.0 km', ['N', 0.0], None], ['ALL rupture 0.5 km', ['ALL', 0.5], 4.73], ['ALL rupture 5.0 km', ['ALL', 5.0], 5.89], ['ALL rupture 40.0 km', ['ALL', 40.0], 6.94], ['ALL rupture 350.0 km', ['ALL', 350.0], 8.03], ['ALL rupture 0.0 km', ['ALL', 0.0], None]], [['SS rupture 0.5 km', ['SS', 0.5], 4.82], ['SS rupture 5.0 km', ['SS', 5.0], 5.94], ['R rupture 0.5 km', ['R', 0.5], 4.63], ['N rupture 5.0 km', ['N', 5.0], 5.78], ['oblique rupture 5.0 km', ['oblique', 5.0], None], ['oblique rupture 40.0 km', ['oblique', 40.0], None], ['oblique rupture 350.0 km', ['oblique', 350.0], None], ['oblique rupture 0.0 km', ['oblique', 0.0], None]], [['SS rupture 350.0 km', ['SS', 350.0], 8.01], ['SS rupture 0.0 km', ['SS', 0.0], None], ['R rupture 0.5 km', ['R', 0.5], 4.63], ['R rupture 5.0 km', ['R', 5.0], 5.85], ['R rupture 40.0 km', ['R', 40.0], 6.95], ['R rupture 350.0 km', ['R', 350.0], 8.1], ['N rupture 5.0 km', ['N', 5.0], 5.78], ['ALL rupture 0.5 km', ['ALL', 0.5], 4.73]]]
for label, args, expected in fixtures[N - 1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| SS rupture 0.5 km | -0.43 | 4.82 | Failed |
| SS rupture 5.0 km | 4.73 | 5.94 | Failed |
| SS rupture 40.0 km | 9.39 | 6.95 | Failed |
| SS rupture 350.0 km | 14.25 | 8.01 | Failed |
| SS rupture 0.0 km | None | None | Passed |
| R rupture 0.5 km | -0.29 | 4.63 | Failed |
| R rupture 5.0 km | 4.71 | 5.85 | Failed |
| R rupture 40.0 km | 9.23 | 6.95 | Failed |
SHA-256 / 72d01dab3a03562eb51116c2def702ef1226894ac80676730c22f569b8018426
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(kind, length_km):
coef = {"SS": (5.16, 1.12), "R": (5.00, 1.22), "N": (4.86, 1.32), "ALL": (5.08, 1.16)}
if kind not in coef or length_km <= 0:
return None
a, b = coef["ALL"]
return round(a + b * math.log10(length_km), 2)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['SS rupture 0.5 km', ['SS', 0.5], 4.82], ['SS rupture 5.0 km', ['SS', 5.0], 5.94], ['SS rupture 40.0 km', ['SS', 40.0], 6.95], ['SS rupture 350.0 km', ['SS', 350.0], 8.01], ['SS rupture 0.0 km', ['SS', 0.0], None], ['R rupture 0.5 km', ['R', 0.5], 4.63], ['R rupture 5.0 km', ['R', 5.0], 5.85], ['R rupture 40.0 km', ['R', 40.0], 6.95]], [['SS rupture 350.0 km', ['SS', 350.0], 8.01], ['R rupture 40.0 km', ['R', 40.0], 6.95], ['R rupture 350.0 km', ['R', 350.0], 8.1], ['R rupture 0.0 km', ['R', 0.0], None], ['N rupture 0.5 km', ['N', 0.5], 4.46], ['N rupture 5.0 km', ['N', 5.0], 5.78], ['N rupture 40.0 km', ['N', 40.0], 6.97], ['N rupture 350.0 km', ['N', 350.0], 8.22]], [['R rupture 40.0 km', ['R', 40.0], 6.95], ['N rupture 350.0 km', ['N', 350.0], 8.22], ['N rupture 0.0 km', ['N', 0.0], None], ['ALL rupture 0.5 km', ['ALL', 0.5], 4.73], ['ALL rupture 5.0 km', ['ALL', 5.0], 5.89], ['ALL rupture 40.0 km', ['ALL', 40.0], 6.94], ['ALL rupture 350.0 km', ['ALL', 350.0], 8.03], ['ALL rupture 0.0 km', ['ALL', 0.0], None]], [['SS rupture 0.5 km', ['SS', 0.5], 4.82], ['SS rupture 5.0 km', ['SS', 5.0], 5.94], ['R rupture 0.5 km', ['R', 0.5], 4.63], ['N rupture 5.0 km', ['N', 5.0], 5.78], ['oblique rupture 5.0 km', ['oblique', 5.0], None], ['oblique rupture 40.0 km', ['oblique', 40.0], None], ['oblique rupture 350.0 km', ['oblique', 350.0], None], ['oblique rupture 0.0 km', ['oblique', 0.0], None]], [['SS rupture 350.0 km', ['SS', 350.0], 8.01], ['SS rupture 0.0 km', ['SS', 0.0], None], ['R rupture 0.5 km', ['R', 0.5], 4.63], ['R rupture 5.0 km', ['R', 5.0], 5.85], ['R rupture 40.0 km', ['R', 40.0], 6.95], ['R rupture 350.0 km', ['R', 350.0], 8.1], ['N rupture 5.0 km', ['N', 5.0], 5.78], ['ALL rupture 0.5 km', ['ALL', 0.5], 4.73]]]
for label, args, expected in fixtures[N - 1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| SS rupture 0.5 km | 4.73 | 4.82 | Failed |
| SS rupture 5.0 km | 5.89 | 5.94 | Failed |
| SS rupture 40.0 km | 6.94 | 6.95 | Failed |
| SS rupture 350.0 km | 8.03 | 8.01 | Failed |
| SS rupture 0.0 km | None | None | Passed |
| R rupture 0.5 km | 4.73 | 4.63 | Failed |
| R rupture 5.0 km | 5.89 | 5.85 | Failed |
| R rupture 40.0 km | 6.94 | 6.95 | Failed |
SHA-256 / 749863e2c4f483ef69111206fb2ade573ef66110bdc436cdca91b55839506942
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(kind, length_km):
coef = {"SS": (5.16, 1.12), "R": (5.00, 1.22), "N": (4.86, 1.32), "ALL": (5.08, 1.16)}
if kind not in coef or length_km <= 0:
return None
a, b = coef[kind]
return round(a + b * math.log10(length_km), 2)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['SS rupture 0.5 km', ['SS', 0.5], 4.82], ['SS rupture 5.0 km', ['SS', 5.0], 5.94], ['SS rupture 40.0 km', ['SS', 40.0], 6.95], ['SS rupture 350.0 km', ['SS', 350.0], 8.01], ['SS rupture 0.0 km', ['SS', 0.0], None], ['R rupture 0.5 km', ['R', 0.5], 4.63], ['R rupture 5.0 km', ['R', 5.0], 5.85], ['R rupture 40.0 km', ['R', 40.0], 6.95]], [['SS rupture 350.0 km', ['SS', 350.0], 8.01], ['R rupture 40.0 km', ['R', 40.0], 6.95], ['R rupture 350.0 km', ['R', 350.0], 8.1], ['R rupture 0.0 km', ['R', 0.0], None], ['N rupture 0.5 km', ['N', 0.5], 4.46], ['N rupture 5.0 km', ['N', 5.0], 5.78], ['N rupture 40.0 km', ['N', 40.0], 6.97], ['N rupture 350.0 km', ['N', 350.0], 8.22]], [['R rupture 40.0 km', ['R', 40.0], 6.95], ['N rupture 350.0 km', ['N', 350.0], 8.22], ['N rupture 0.0 km', ['N', 0.0], None], ['ALL rupture 0.5 km', ['ALL', 0.5], 4.73], ['ALL rupture 5.0 km', ['ALL', 5.0], 5.89], ['ALL rupture 40.0 km', ['ALL', 40.0], 6.94], ['ALL rupture 350.0 km', ['ALL', 350.0], 8.03], ['ALL rupture 0.0 km', ['ALL', 0.0], None]], [['SS rupture 0.5 km', ['SS', 0.5], 4.82], ['SS rupture 5.0 km', ['SS', 5.0], 5.94], ['R rupture 0.5 km', ['R', 0.5], 4.63], ['N rupture 5.0 km', ['N', 5.0], 5.78], ['oblique rupture 5.0 km', ['oblique', 5.0], None], ['oblique rupture 40.0 km', ['oblique', 40.0], None], ['oblique rupture 350.0 km', ['oblique', 350.0], None], ['oblique rupture 0.0 km', ['oblique', 0.0], None]], [['SS rupture 350.0 km', ['SS', 350.0], 8.01], ['SS rupture 0.0 km', ['SS', 0.0], None], ['R rupture 0.5 km', ['R', 0.5], 4.63], ['R rupture 5.0 km', ['R', 5.0], 5.85], ['R rupture 40.0 km', ['R', 40.0], 6.95], ['R rupture 350.0 km', ['R', 350.0], 8.1], ['N rupture 5.0 km', ['N', 5.0], 5.78], ['ALL rupture 0.5 km', ['ALL', 0.5], 4.73]]]
for label, args, expected in fixtures[N - 1]:
check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
| Boundary fixture | Actual | Expected | Outcome |
|---|---|---|---|
| SS rupture 0.5 km | 4.82 | 4.82 | Passed |
| SS rupture 5.0 km | 5.94 | 5.94 | Passed |
| SS rupture 40.0 km | 6.95 | 6.95 | Passed |
| SS rupture 350.0 km | 8.01 | 8.01 | Passed |
| SS rupture 0.0 km | None | None | Passed |
| R rupture 0.5 km | 4.63 | 4.63 | Passed |
| R rupture 5.0 km | 5.85 | 5.85 | Passed |
| R rupture 40.0 km | 6.95 | 6.95 | Passed |
SHA-256 / d377411708fde793f36d44e5f38023f67c891070888c3f9a41a18f6a0b79b88f
Verification & scope
Stipulated deterministic teaching model of a seismological magnitude procedure; constants and tables are fixed by the contract and no claim of agency or standards conformance is made. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.
Observations recorded using Python 3.12.14 at 2026-09-29T14:48:33.115706+00:00.
Case digest / c22d40acf335e4e65bb7c04dc38165c06096e228b3b2167606be396be12e3af9