FA-71441 / Seismic magnitude estimation / Open access
Teleseismic body-wave magnitude: distance validity range · case 01
Stations at exactly 100 degrees are rejected.
ROOT CAUSE
The upper distance limit is exclusive.
VERIFIED REPAIR
Accept 20 <= delta <= 100.
Unsuccessful approach: Making the lower limit exclusive rejects 20-degree stations.
Case contract
P amplitude in micrometres, period in s, epicentral distance in degrees. Valid only for 20 <= delta <= 100 and 0 < period <= 3.0 (else None). Q(delta) is linearly interpolated from [(20,6.0),(30,6.5),(40,6.8),(60,6.9),(80,7.0),(100,7.4)]. mb = log10(A/T) + Q, rounded 0.01.
Why this case matters
mb is the first teleseismic magnitude available for global events.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(amp_um, period_s, delta_deg):
table = [(20, 6.0), (30, 6.5), (40, 6.8), (60, 6.9), (80, 7.0), (100, 7.4)]
if not (20 <= delta_deg < 100):
return None
if period_s <= 0 or period_s > 3.0:
return None
q = None
for (d0, q0), (d1, q1) in zip(table, table[1:]):
if d0 <= delta_deg <= d1:
q = q0 + (q1 - q0) * (delta_deg - d0) / (d1 - d0)
break
return round(math.log10(amp_um / period_s) + q, 2)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['0.05 um 0.5 s at 15 deg', [0.05, 0.5, 15], None], ['0.05 um 0.5 s at 20 deg', [0.05, 0.5, 20], 5.0], ['0.05 um 0.5 s at 25 deg', [0.05, 0.5, 25], 5.25], ['0.05 um 0.5 s at 45 deg', [0.05, 0.5, 45], 5.83], ['0.05 um 0.5 s at 70 deg', [0.05, 0.5, 70], 5.95], ['0.05 um 0.5 s at 99 deg', [0.05, 0.5, 99], 6.38], ['0.05 um 0.5 s at 100 deg', [0.05, 0.5, 100], 6.4], ['0.05 um 1.0 s at 20 deg', [0.05, 1.0, 20], 4.7]], [['0.05 um 0.5 s at 101 deg', [0.05, 0.5, 101], None], ['0.05 um 1.0 s at 15 deg', [0.05, 1.0, 15], None], ['0.05 um 1.0 s at 20 deg', [0.05, 1.0, 20], 4.7], ['0.05 um 1.0 s at 25 deg', [0.05, 1.0, 25], 4.95], ['0.05 um 1.0 s at 45 deg', [0.05, 1.0, 45], 5.52], ['0.05 um 1.0 s at 70 deg', [0.05, 1.0, 70], 5.65], ['0.05 um 3.0 s at 100 deg', [0.05, 3.0, 100], 5.62], ['0.4 um 2.0 s at 20 deg', [0.4, 2.0, 20], 5.3]], [['0.05 um 1.0 s at 100 deg', [0.05, 1.0, 100], 6.1], ['0.05 um 1.0 s at 101 deg', [0.05, 1.0, 101], None], ['0.05 um 2.0 s at 15 deg', [0.05, 2.0, 15], None], ['0.05 um 2.0 s at 20 deg', [0.05, 2.0, 20], 4.4], ['0.05 um 2.0 s at 25 deg', [0.05, 2.0, 25], 4.65], ['0.05 um 2.0 s at 45 deg', [0.05, 2.0, 45], 5.22], ['0.4 um 2.0 s at 100 deg', [0.4, 2.0, 100], 6.7], ['2.5 um 3.0 s at 20 deg', [2.5, 3.0, 20], 5.92]], [['0.05 um 2.0 s at 99 deg', [0.05, 2.0, 99], 5.78], ['0.05 um 2.0 s at 100 deg', [0.05, 2.0, 100], 5.8], ['0.05 um 2.0 s at 101 deg', [0.05, 2.0, 101], None], ['0.05 um 3.0 s at 15 deg', [0.05, 3.0, 15], None], ['0.05 um 3.0 s at 20 deg', [0.05, 3.0, 20], 4.22], ['0.05 um 3.0 s at 25 deg', [0.05, 3.0, 25], 4.47], ['0.4 um 0.5 s at 20 deg', [0.4, 0.5, 20], 5.9], ['2.5 um 1.0 s at 100 deg', [2.5, 1.0, 100], 7.8]], [['0.05 um 0.5 s at 100 deg', [0.05, 0.5, 100], 6.4], ['0.05 um 3.0 s at 70 deg', [0.05, 3.0, 70], 5.17], ['0.05 um 3.0 s at 99 deg', [0.05, 3.0, 99], 5.6], ['0.05 um 3.0 s at 100 deg', [0.05, 3.0, 100], 5.62], ['0.05 um 3.0 s at 101 deg', [0.05, 3.0, 101], None], ['0.05 um 3.5 s at 15 deg', [0.05, 3.5, 15], None], ['0.05 um 3.5 s at 20 deg', [0.05, 3.5, 20], None], ['2.5 um 1.0 s at 20 deg', [2.5, 1.0, 20], 6.4]]]
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 |
|---|---|---|---|
| 0.05 um 0.5 s at 15 deg | None | None | Passed |
| 0.05 um 0.5 s at 20 deg | 5.0 | 5.0 | Passed |
| 0.05 um 0.5 s at 25 deg | 5.25 | 5.25 | Passed |
| 0.05 um 0.5 s at 45 deg | 5.83 | 5.83 | Passed |
| 0.05 um 0.5 s at 70 deg | 5.95 | 5.95 | Passed |
| 0.05 um 0.5 s at 99 deg | 6.38 | 6.38 | Passed |
| 0.05 um 0.5 s at 100 deg | None | 6.4 | Failed |
| 0.05 um 1.0 s at 20 deg | 4.7 | 4.7 | Passed |
SHA-256 / f7ba60b8f586b5a5cc7defcfd4b3d7ad92eef27dd04a0be80ab250681f2d7753
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(amp_um, period_s, delta_deg):
table = [(20, 6.0), (30, 6.5), (40, 6.8), (60, 6.9), (80, 7.0), (100, 7.4)]
if not (20 < delta_deg <= 100):
return None
if period_s <= 0 or period_s > 3.0:
return None
q = None
for (d0, q0), (d1, q1) in zip(table, table[1:]):
if d0 <= delta_deg <= d1:
q = q0 + (q1 - q0) * (delta_deg - d0) / (d1 - d0)
break
return round(math.log10(amp_um / period_s) + q, 2)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['0.05 um 0.5 s at 15 deg', [0.05, 0.5, 15], None], ['0.05 um 0.5 s at 20 deg', [0.05, 0.5, 20], 5.0], ['0.05 um 0.5 s at 25 deg', [0.05, 0.5, 25], 5.25], ['0.05 um 0.5 s at 45 deg', [0.05, 0.5, 45], 5.83], ['0.05 um 0.5 s at 70 deg', [0.05, 0.5, 70], 5.95], ['0.05 um 0.5 s at 99 deg', [0.05, 0.5, 99], 6.38], ['0.05 um 0.5 s at 100 deg', [0.05, 0.5, 100], 6.4], ['0.05 um 1.0 s at 20 deg', [0.05, 1.0, 20], 4.7]], [['0.05 um 0.5 s at 101 deg', [0.05, 0.5, 101], None], ['0.05 um 1.0 s at 15 deg', [0.05, 1.0, 15], None], ['0.05 um 1.0 s at 20 deg', [0.05, 1.0, 20], 4.7], ['0.05 um 1.0 s at 25 deg', [0.05, 1.0, 25], 4.95], ['0.05 um 1.0 s at 45 deg', [0.05, 1.0, 45], 5.52], ['0.05 um 1.0 s at 70 deg', [0.05, 1.0, 70], 5.65], ['0.05 um 3.0 s at 100 deg', [0.05, 3.0, 100], 5.62], ['0.4 um 2.0 s at 20 deg', [0.4, 2.0, 20], 5.3]], [['0.05 um 1.0 s at 100 deg', [0.05, 1.0, 100], 6.1], ['0.05 um 1.0 s at 101 deg', [0.05, 1.0, 101], None], ['0.05 um 2.0 s at 15 deg', [0.05, 2.0, 15], None], ['0.05 um 2.0 s at 20 deg', [0.05, 2.0, 20], 4.4], ['0.05 um 2.0 s at 25 deg', [0.05, 2.0, 25], 4.65], ['0.05 um 2.0 s at 45 deg', [0.05, 2.0, 45], 5.22], ['0.4 um 2.0 s at 100 deg', [0.4, 2.0, 100], 6.7], ['2.5 um 3.0 s at 20 deg', [2.5, 3.0, 20], 5.92]], [['0.05 um 2.0 s at 99 deg', [0.05, 2.0, 99], 5.78], ['0.05 um 2.0 s at 100 deg', [0.05, 2.0, 100], 5.8], ['0.05 um 2.0 s at 101 deg', [0.05, 2.0, 101], None], ['0.05 um 3.0 s at 15 deg', [0.05, 3.0, 15], None], ['0.05 um 3.0 s at 20 deg', [0.05, 3.0, 20], 4.22], ['0.05 um 3.0 s at 25 deg', [0.05, 3.0, 25], 4.47], ['0.4 um 0.5 s at 20 deg', [0.4, 0.5, 20], 5.9], ['2.5 um 1.0 s at 100 deg', [2.5, 1.0, 100], 7.8]], [['0.05 um 0.5 s at 100 deg', [0.05, 0.5, 100], 6.4], ['0.05 um 3.0 s at 70 deg', [0.05, 3.0, 70], 5.17], ['0.05 um 3.0 s at 99 deg', [0.05, 3.0, 99], 5.6], ['0.05 um 3.0 s at 100 deg', [0.05, 3.0, 100], 5.62], ['0.05 um 3.0 s at 101 deg', [0.05, 3.0, 101], None], ['0.05 um 3.5 s at 15 deg', [0.05, 3.5, 15], None], ['0.05 um 3.5 s at 20 deg', [0.05, 3.5, 20], None], ['2.5 um 1.0 s at 20 deg', [2.5, 1.0, 20], 6.4]]]
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 |
|---|---|---|---|
| 0.05 um 0.5 s at 15 deg | None | None | Passed |
| 0.05 um 0.5 s at 20 deg | None | 5.0 | Failed |
| 0.05 um 0.5 s at 25 deg | 5.25 | 5.25 | Passed |
| 0.05 um 0.5 s at 45 deg | 5.83 | 5.83 | Passed |
| 0.05 um 0.5 s at 70 deg | 5.95 | 5.95 | Passed |
| 0.05 um 0.5 s at 99 deg | 6.38 | 6.38 | Passed |
| 0.05 um 0.5 s at 100 deg | 6.4 | 6.4 | Passed |
| 0.05 um 1.0 s at 20 deg | None | 4.7 | Failed |
SHA-256 / fdb129fbfe21abece1e71bad615b8824cc8043468aa9af569026b2d4e2a629da
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(amp_um, period_s, delta_deg):
table = [(20, 6.0), (30, 6.5), (40, 6.8), (60, 6.9), (80, 7.0), (100, 7.4)]
if not (20 <= delta_deg <= 100):
return None
if period_s <= 0 or period_s > 3.0:
return None
q = None
for (d0, q0), (d1, q1) in zip(table, table[1:]):
if d0 <= delta_deg <= d1:
q = q0 + (q1 - q0) * (delta_deg - d0) / (d1 - d0)
break
return round(math.log10(amp_um / period_s) + q, 2)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['0.05 um 0.5 s at 15 deg', [0.05, 0.5, 15], None], ['0.05 um 0.5 s at 20 deg', [0.05, 0.5, 20], 5.0], ['0.05 um 0.5 s at 25 deg', [0.05, 0.5, 25], 5.25], ['0.05 um 0.5 s at 45 deg', [0.05, 0.5, 45], 5.83], ['0.05 um 0.5 s at 70 deg', [0.05, 0.5, 70], 5.95], ['0.05 um 0.5 s at 99 deg', [0.05, 0.5, 99], 6.38], ['0.05 um 0.5 s at 100 deg', [0.05, 0.5, 100], 6.4], ['0.05 um 1.0 s at 20 deg', [0.05, 1.0, 20], 4.7]], [['0.05 um 0.5 s at 101 deg', [0.05, 0.5, 101], None], ['0.05 um 1.0 s at 15 deg', [0.05, 1.0, 15], None], ['0.05 um 1.0 s at 20 deg', [0.05, 1.0, 20], 4.7], ['0.05 um 1.0 s at 25 deg', [0.05, 1.0, 25], 4.95], ['0.05 um 1.0 s at 45 deg', [0.05, 1.0, 45], 5.52], ['0.05 um 1.0 s at 70 deg', [0.05, 1.0, 70], 5.65], ['0.05 um 3.0 s at 100 deg', [0.05, 3.0, 100], 5.62], ['0.4 um 2.0 s at 20 deg', [0.4, 2.0, 20], 5.3]], [['0.05 um 1.0 s at 100 deg', [0.05, 1.0, 100], 6.1], ['0.05 um 1.0 s at 101 deg', [0.05, 1.0, 101], None], ['0.05 um 2.0 s at 15 deg', [0.05, 2.0, 15], None], ['0.05 um 2.0 s at 20 deg', [0.05, 2.0, 20], 4.4], ['0.05 um 2.0 s at 25 deg', [0.05, 2.0, 25], 4.65], ['0.05 um 2.0 s at 45 deg', [0.05, 2.0, 45], 5.22], ['0.4 um 2.0 s at 100 deg', [0.4, 2.0, 100], 6.7], ['2.5 um 3.0 s at 20 deg', [2.5, 3.0, 20], 5.92]], [['0.05 um 2.0 s at 99 deg', [0.05, 2.0, 99], 5.78], ['0.05 um 2.0 s at 100 deg', [0.05, 2.0, 100], 5.8], ['0.05 um 2.0 s at 101 deg', [0.05, 2.0, 101], None], ['0.05 um 3.0 s at 15 deg', [0.05, 3.0, 15], None], ['0.05 um 3.0 s at 20 deg', [0.05, 3.0, 20], 4.22], ['0.05 um 3.0 s at 25 deg', [0.05, 3.0, 25], 4.47], ['0.4 um 0.5 s at 20 deg', [0.4, 0.5, 20], 5.9], ['2.5 um 1.0 s at 100 deg', [2.5, 1.0, 100], 7.8]], [['0.05 um 0.5 s at 100 deg', [0.05, 0.5, 100], 6.4], ['0.05 um 3.0 s at 70 deg', [0.05, 3.0, 70], 5.17], ['0.05 um 3.0 s at 99 deg', [0.05, 3.0, 99], 5.6], ['0.05 um 3.0 s at 100 deg', [0.05, 3.0, 100], 5.62], ['0.05 um 3.0 s at 101 deg', [0.05, 3.0, 101], None], ['0.05 um 3.5 s at 15 deg', [0.05, 3.5, 15], None], ['0.05 um 3.5 s at 20 deg', [0.05, 3.5, 20], None], ['2.5 um 1.0 s at 20 deg', [2.5, 1.0, 20], 6.4]]]
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 |
|---|---|---|---|
| 0.05 um 0.5 s at 15 deg | None | None | Passed |
| 0.05 um 0.5 s at 20 deg | 5.0 | 5.0 | Passed |
| 0.05 um 0.5 s at 25 deg | 5.25 | 5.25 | Passed |
| 0.05 um 0.5 s at 45 deg | 5.83 | 5.83 | Passed |
| 0.05 um 0.5 s at 70 deg | 5.95 | 5.95 | Passed |
| 0.05 um 0.5 s at 99 deg | 6.38 | 6.38 | Passed |
| 0.05 um 0.5 s at 100 deg | 6.4 | 6.4 | Passed |
| 0.05 um 1.0 s at 20 deg | 4.7 | 4.7 | Passed |
SHA-256 / 5dd8b2a35286be0193323441bc019af98865928e0c60970650b03c72dc7a5c40
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:29.716365+00:00.
Case digest / 4cdcac085851fad7b3a2c1d43718a6814a03f3fc752d985d07f2eb72362067bb