FA-71791 / Seismic magnitude estimation / Open access
S-P nomogram local magnitude: arrival order · case 01
Swapped phase picks still produce a magnitude.
ROOT CAUSE
The S-P interval takes an absolute value, accepting an S pick before P.
VERIFIED REPAIR
Use tS - tP and reject non-positive intervals.
Unsuccessful approach: Subtracting in the opposite order rejects every valid pick pair.
Case contract
Zero-to-peak amplitude in mm and P and S arrival times in s. dt = tS - tP must be positive and amplitude positive, else None. ML = log10 A + 3 log10(8 dt) - 2.92, rounded 0.01.
Why this case matters
Field seismologists read ML from the S-P interval and amplitude nomogram.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(amp_mm, t_p, t_s):
dt = abs(t_s - t_p)
if dt <= 0 or amp_mm <= 0:
return None
ml = math.log10(amp_mm) + 3 * math.log10(8 * dt) - 2.92
return round(ml, 2)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['A 0.001 mm P 10.0 S 12.5', [0.001, 10.0, 12.5], -2.02], ['A 0.001 mm P 3.2 S 8.7', [0.001, 3.2, 8.7], -0.99], ['A 0.001 mm P 100.0 S 160.0', [0.001, 100.0, 160.0], 2.12], ['A 0.001 mm P 5.0 S 5.0', [0.001, 5.0, 5.0], None], ['A 0.001 mm P 7.0 S 6.0', [0.001, 7.0, 6.0], None], ['A 0.001 mm P 0.0 S 1.0', [0.001, 0.0, 1.0], -3.21], ['A 0.5 mm P 10.0 S 12.5', [0.5, 10.0, 12.5], 0.68], ['A 0.5 mm P 3.2 S 8.7', [0.5, 3.2, 8.7], 1.71]], [['A 0.001 mm P 7.0 S 6.0', [0.001, 7.0, 6.0], None], ['A 0.5 mm P 3.2 S 8.7', [0.5, 3.2, 8.7], 1.71], ['A 0.5 mm P 100.0 S 160.0', [0.5, 100.0, 160.0], 4.82], ['A 0.5 mm P 5.0 S 5.0', [0.5, 5.0, 5.0], None], ['A 0.5 mm P 7.0 S 6.0', [0.5, 7.0, 6.0], None], ['A 0.5 mm P 0.0 S 1.0', [0.5, 0.0, 1.0], -0.51], ['A 23.0 mm P 10.0 S 12.5', [23.0, 10.0, 12.5], 2.34], ['A 23.0 mm P 3.2 S 8.7', [23.0, 3.2, 8.7], 3.37]], [['A 0.001 mm P 10.0 S 12.5', [0.001, 10.0, 12.5], -2.02], ['A 0.001 mm P 7.0 S 6.0', [0.001, 7.0, 6.0], None], ['A 23.0 mm P 3.2 S 8.7', [23.0, 3.2, 8.7], 3.37], ['A 23.0 mm P 100.0 S 160.0', [23.0, 100.0, 160.0], 6.49], ['A 23.0 mm P 5.0 S 5.0', [23.0, 5.0, 5.0], None], ['A 23.0 mm P 7.0 S 6.0', [23.0, 7.0, 6.0], None], ['A 23.0 mm P 0.0 S 1.0', [23.0, 0.0, 1.0], 1.15], ['zero amplitude', [0.0, 1.0, 3.0], None]], [['A 0.001 mm P 3.2 S 8.7', [0.001, 3.2, 8.7], -0.99], ['A 0.001 mm P 100.0 S 160.0', [0.001, 100.0, 160.0], 2.12], ['A 0.001 mm P 5.0 S 5.0', [0.001, 5.0, 5.0], None], ['A 0.001 mm P 7.0 S 6.0', [0.001, 7.0, 6.0], None], ['A 0.001 mm P 0.0 S 1.0', [0.001, 0.0, 1.0], -3.21], ['A 0.5 mm P 10.0 S 12.5', [0.5, 10.0, 12.5], 0.68], ['A 0.5 mm P 3.2 S 8.7', [0.5, 3.2, 8.7], 1.71], ['A 0.5 mm P 100.0 S 160.0', [0.5, 100.0, 160.0], 4.82]], [['A 0.001 mm P 7.0 S 6.0', [0.001, 7.0, 6.0], None], ['A 0.5 mm P 3.2 S 8.7', [0.5, 3.2, 8.7], 1.71], ['A 0.5 mm P 5.0 S 5.0', [0.5, 5.0, 5.0], None], ['A 0.5 mm P 7.0 S 6.0', [0.5, 7.0, 6.0], None], ['A 0.5 mm P 0.0 S 1.0', [0.5, 0.0, 1.0], -0.51], ['A 23.0 mm P 10.0 S 12.5', [23.0, 10.0, 12.5], 2.34], ['A 23.0 mm P 3.2 S 8.7', [23.0, 3.2, 8.7], 3.37], ['A 23.0 mm P 100.0 S 160.0', [23.0, 100.0, 160.0], 6.49]]]
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 |
|---|---|---|---|
| A 0.001 mm P 10.0 S 12.5 | -2.02 | -2.02 | Passed |
| A 0.001 mm P 3.2 S 8.7 | -0.99 | -0.99 | Passed |
| A 0.001 mm P 100.0 S 160.0 | 2.12 | 2.12 | Passed |
| A 0.001 mm P 5.0 S 5.0 | None | None | Passed |
| A 0.001 mm P 7.0 S 6.0 | -3.21 | None | Failed |
| A 0.001 mm P 0.0 S 1.0 | -3.21 | -3.21 | Passed |
| A 0.5 mm P 10.0 S 12.5 | 0.68 | 0.68 | Passed |
| A 0.5 mm P 3.2 S 8.7 | 1.71 | 1.71 | Passed |
SHA-256 / 1632766ca295fbecad447773ce17e7b3d4461a6a5f860d968a381383854176b9
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(amp_mm, t_p, t_s):
dt = t_p - t_s
if dt <= 0 or amp_mm <= 0:
return None
ml = math.log10(amp_mm) + 3 * math.log10(8 * dt) - 2.92
return round(ml, 2)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['A 0.001 mm P 10.0 S 12.5', [0.001, 10.0, 12.5], -2.02], ['A 0.001 mm P 3.2 S 8.7', [0.001, 3.2, 8.7], -0.99], ['A 0.001 mm P 100.0 S 160.0', [0.001, 100.0, 160.0], 2.12], ['A 0.001 mm P 5.0 S 5.0', [0.001, 5.0, 5.0], None], ['A 0.001 mm P 7.0 S 6.0', [0.001, 7.0, 6.0], None], ['A 0.001 mm P 0.0 S 1.0', [0.001, 0.0, 1.0], -3.21], ['A 0.5 mm P 10.0 S 12.5', [0.5, 10.0, 12.5], 0.68], ['A 0.5 mm P 3.2 S 8.7', [0.5, 3.2, 8.7], 1.71]], [['A 0.001 mm P 7.0 S 6.0', [0.001, 7.0, 6.0], None], ['A 0.5 mm P 3.2 S 8.7', [0.5, 3.2, 8.7], 1.71], ['A 0.5 mm P 100.0 S 160.0', [0.5, 100.0, 160.0], 4.82], ['A 0.5 mm P 5.0 S 5.0', [0.5, 5.0, 5.0], None], ['A 0.5 mm P 7.0 S 6.0', [0.5, 7.0, 6.0], None], ['A 0.5 mm P 0.0 S 1.0', [0.5, 0.0, 1.0], -0.51], ['A 23.0 mm P 10.0 S 12.5', [23.0, 10.0, 12.5], 2.34], ['A 23.0 mm P 3.2 S 8.7', [23.0, 3.2, 8.7], 3.37]], [['A 0.001 mm P 10.0 S 12.5', [0.001, 10.0, 12.5], -2.02], ['A 0.001 mm P 7.0 S 6.0', [0.001, 7.0, 6.0], None], ['A 23.0 mm P 3.2 S 8.7', [23.0, 3.2, 8.7], 3.37], ['A 23.0 mm P 100.0 S 160.0', [23.0, 100.0, 160.0], 6.49], ['A 23.0 mm P 5.0 S 5.0', [23.0, 5.0, 5.0], None], ['A 23.0 mm P 7.0 S 6.0', [23.0, 7.0, 6.0], None], ['A 23.0 mm P 0.0 S 1.0', [23.0, 0.0, 1.0], 1.15], ['zero amplitude', [0.0, 1.0, 3.0], None]], [['A 0.001 mm P 3.2 S 8.7', [0.001, 3.2, 8.7], -0.99], ['A 0.001 mm P 100.0 S 160.0', [0.001, 100.0, 160.0], 2.12], ['A 0.001 mm P 5.0 S 5.0', [0.001, 5.0, 5.0], None], ['A 0.001 mm P 7.0 S 6.0', [0.001, 7.0, 6.0], None], ['A 0.001 mm P 0.0 S 1.0', [0.001, 0.0, 1.0], -3.21], ['A 0.5 mm P 10.0 S 12.5', [0.5, 10.0, 12.5], 0.68], ['A 0.5 mm P 3.2 S 8.7', [0.5, 3.2, 8.7], 1.71], ['A 0.5 mm P 100.0 S 160.0', [0.5, 100.0, 160.0], 4.82]], [['A 0.001 mm P 7.0 S 6.0', [0.001, 7.0, 6.0], None], ['A 0.5 mm P 3.2 S 8.7', [0.5, 3.2, 8.7], 1.71], ['A 0.5 mm P 5.0 S 5.0', [0.5, 5.0, 5.0], None], ['A 0.5 mm P 7.0 S 6.0', [0.5, 7.0, 6.0], None], ['A 0.5 mm P 0.0 S 1.0', [0.5, 0.0, 1.0], -0.51], ['A 23.0 mm P 10.0 S 12.5', [23.0, 10.0, 12.5], 2.34], ['A 23.0 mm P 3.2 S 8.7', [23.0, 3.2, 8.7], 3.37], ['A 23.0 mm P 100.0 S 160.0', [23.0, 100.0, 160.0], 6.49]]]
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 |
|---|---|---|---|
| A 0.001 mm P 10.0 S 12.5 | None | -2.02 | Failed |
| A 0.001 mm P 3.2 S 8.7 | None | -0.99 | Failed |
| A 0.001 mm P 100.0 S 160.0 | None | 2.12 | Failed |
| A 0.001 mm P 5.0 S 5.0 | None | None | Passed |
| A 0.001 mm P 7.0 S 6.0 | -3.21 | None | Failed |
| A 0.001 mm P 0.0 S 1.0 | None | -3.21 | Failed |
| A 0.5 mm P 10.0 S 12.5 | None | 0.68 | Failed |
| A 0.5 mm P 3.2 S 8.7 | None | 1.71 | Failed |
SHA-256 / 7dc467e8662f9f1f65066a50e2ed10d1a04b4224806caf9b19f7448a4a07354e
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(amp_mm, t_p, t_s):
dt = t_s - t_p
if dt <= 0 or amp_mm <= 0:
return None
ml = math.log10(amp_mm) + 3 * math.log10(8 * dt) - 2.92
return round(ml, 2)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['A 0.001 mm P 10.0 S 12.5', [0.001, 10.0, 12.5], -2.02], ['A 0.001 mm P 3.2 S 8.7', [0.001, 3.2, 8.7], -0.99], ['A 0.001 mm P 100.0 S 160.0', [0.001, 100.0, 160.0], 2.12], ['A 0.001 mm P 5.0 S 5.0', [0.001, 5.0, 5.0], None], ['A 0.001 mm P 7.0 S 6.0', [0.001, 7.0, 6.0], None], ['A 0.001 mm P 0.0 S 1.0', [0.001, 0.0, 1.0], -3.21], ['A 0.5 mm P 10.0 S 12.5', [0.5, 10.0, 12.5], 0.68], ['A 0.5 mm P 3.2 S 8.7', [0.5, 3.2, 8.7], 1.71]], [['A 0.001 mm P 7.0 S 6.0', [0.001, 7.0, 6.0], None], ['A 0.5 mm P 3.2 S 8.7', [0.5, 3.2, 8.7], 1.71], ['A 0.5 mm P 100.0 S 160.0', [0.5, 100.0, 160.0], 4.82], ['A 0.5 mm P 5.0 S 5.0', [0.5, 5.0, 5.0], None], ['A 0.5 mm P 7.0 S 6.0', [0.5, 7.0, 6.0], None], ['A 0.5 mm P 0.0 S 1.0', [0.5, 0.0, 1.0], -0.51], ['A 23.0 mm P 10.0 S 12.5', [23.0, 10.0, 12.5], 2.34], ['A 23.0 mm P 3.2 S 8.7', [23.0, 3.2, 8.7], 3.37]], [['A 0.001 mm P 10.0 S 12.5', [0.001, 10.0, 12.5], -2.02], ['A 0.001 mm P 7.0 S 6.0', [0.001, 7.0, 6.0], None], ['A 23.0 mm P 3.2 S 8.7', [23.0, 3.2, 8.7], 3.37], ['A 23.0 mm P 100.0 S 160.0', [23.0, 100.0, 160.0], 6.49], ['A 23.0 mm P 5.0 S 5.0', [23.0, 5.0, 5.0], None], ['A 23.0 mm P 7.0 S 6.0', [23.0, 7.0, 6.0], None], ['A 23.0 mm P 0.0 S 1.0', [23.0, 0.0, 1.0], 1.15], ['zero amplitude', [0.0, 1.0, 3.0], None]], [['A 0.001 mm P 3.2 S 8.7', [0.001, 3.2, 8.7], -0.99], ['A 0.001 mm P 100.0 S 160.0', [0.001, 100.0, 160.0], 2.12], ['A 0.001 mm P 5.0 S 5.0', [0.001, 5.0, 5.0], None], ['A 0.001 mm P 7.0 S 6.0', [0.001, 7.0, 6.0], None], ['A 0.001 mm P 0.0 S 1.0', [0.001, 0.0, 1.0], -3.21], ['A 0.5 mm P 10.0 S 12.5', [0.5, 10.0, 12.5], 0.68], ['A 0.5 mm P 3.2 S 8.7', [0.5, 3.2, 8.7], 1.71], ['A 0.5 mm P 100.0 S 160.0', [0.5, 100.0, 160.0], 4.82]], [['A 0.001 mm P 7.0 S 6.0', [0.001, 7.0, 6.0], None], ['A 0.5 mm P 3.2 S 8.7', [0.5, 3.2, 8.7], 1.71], ['A 0.5 mm P 5.0 S 5.0', [0.5, 5.0, 5.0], None], ['A 0.5 mm P 7.0 S 6.0', [0.5, 7.0, 6.0], None], ['A 0.5 mm P 0.0 S 1.0', [0.5, 0.0, 1.0], -0.51], ['A 23.0 mm P 10.0 S 12.5', [23.0, 10.0, 12.5], 2.34], ['A 23.0 mm P 3.2 S 8.7', [23.0, 3.2, 8.7], 3.37], ['A 23.0 mm P 100.0 S 160.0', [23.0, 100.0, 160.0], 6.49]]]
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 |
|---|---|---|---|
| A 0.001 mm P 10.0 S 12.5 | -2.02 | -2.02 | Passed |
| A 0.001 mm P 3.2 S 8.7 | -0.99 | -0.99 | Passed |
| A 0.001 mm P 100.0 S 160.0 | 2.12 | 2.12 | Passed |
| A 0.001 mm P 5.0 S 5.0 | None | None | Passed |
| A 0.001 mm P 7.0 S 6.0 | None | None | Passed |
| A 0.001 mm P 0.0 S 1.0 | -3.21 | -3.21 | Passed |
| A 0.5 mm P 10.0 S 12.5 | 0.68 | 0.68 | Passed |
| A 0.5 mm P 3.2 S 8.7 | 1.71 | 1.71 | Passed |
SHA-256 / e418fefbd8c27064dd41b57d009d80aa10735247b64240a5a5196e5a125afc59
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:32.827860+00:00.
Case digest / e163a56eeef28599be994b7928e98725f7335b23c0c057c4d22f5e52900ea6ff