FA-71651 / Seismic magnitude estimation / Open access
GNSS peak ground displacement magnitude: hypocentral distance · case 01
Nearby stations of deep events give inflated magnitudes.
ROOT CAUSE
Epicentral distance is used instead of hypocentral.
THE FAILURE
Epicentral distance is used instead of hypocentral.
Unsuccessful approach: Adding depth linearly overstates R.
Case contract
obs are [PGD in m, epicentral km]. Per station PGD in cm, R = hypocentral distance; skip PGD < 2 cm or R > 1000 km. log10(PGD) = A + B M + C M log10 R with A=-4.434, B=1.047, C=-0.138, solved for M. Return [mean M rounded 0.01, stations used] or None.
Why this case matters
GNSS PGD magnitudes do not saturate for great earthquakes in early warning.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(obs, depth_km):
A, B, C = -4.434, 1.047, -0.138
ms = []
for pgd_m, epi in obs:
pgd_cm = pgd_m * 100.0
r = epi
if pgd_cm < 2.0 or r > 1000:
continue
ms.append((math.log10(pgd_cm) - A) / (B + C * math.log10(r)))
if not ms:
return None
return [round(sum(ms) / len(ms), 2), len(ms)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['GNSS set 0', [[[0.005, 700], [0.05, 1100], [0.02, 995], [0.02, 700]], 25], [7.36, 2]], ['GNSS set 1', [[[0.005, 200], [0.005, 10], [1.2, 995], [0.005, 995], [0.02, 995]], 10], [8.88, 2]], ['GNSS set 2', [[[1.2, 200]], 10], [8.93, 1]], ['GNSS set 3', [[[1.2, 1100]], 10], None], ['GNSS set 4', [[[0.005, 995], [0.02, 200], [0.005, 1100], [1.2, 995], [1.2, 60]], 10], [8.3, 3]], ['GNSS set 5', [[[0.005, 10], [0.3, 60], [0.3, 1100], [0.3, 10]], 60], [7.48, 2]], ['GNSS set 6', [[[0.3, 10], [0.005, 200], [1.2, 1100], [0.005, 1100], [0.02, 60]], 60], [6.72, 2]], ['GNSS set 7', [[[0.005, 700], [1.2, 1100]], 25], None]], [['GNSS set 7', [[[0.005, 700], [1.2, 1100]], 25], None], ['GNSS set 8', [[[1.2, 700], [0.005, 10]], 10], [9.95, 1]], ['GNSS set 9', [[[1.2, 60], [0.3, 10], [0.05, 60]], 25], [7.19, 3]], ['GNSS set 10', [[[0.3, 700], [0.02, 1100]], 60], [9.04, 1]], ['GNSS set 11', [[[1.2, 1100], [0.02, 200], [0.02, 200], [0.005, 1100], [0.05, 10]], 25], [6.34, 3]], ['GNSS set 12', [[[0.3, 200]], 25], [8.11, 1]], ['GNSS set 13', [[[0.005, 700], [0.05, 700], [1.2, 995], [0.3, 700]], 25], [9.05, 3]], ['GNSS set 14', [[[1.2, 700], [0.02, 200], [0.02, 700]], 10], [7.89, 3]]], [['GNSS set 13', [[[0.005, 700], [0.05, 700], [1.2, 995], [0.3, 700]], 25], [9.05, 3]], ['GNSS set 14', [[[1.2, 700], [0.02, 200], [0.02, 700]], 10], [7.89, 3]], ['GNSS set 15', [[[0.005, 60]], 10], None], ['GNSS set 16', [[[1.2, 200], [0.005, 200], [0.02, 10], [0.3, 700]], 25], [7.85, 3]], ['GNSS set 17', [[[0.3, 200], [0.05, 995]], 60], [8.12, 2]], ['GNSS set 18', [[[0.02, 10], [0.3, 1100], [1.2, 200], [0.005, 700], [1.2, 995]], 10], [8.18, 3]], ['GNSS set 19', [[[0.02, 700], [0.02, 60]], 60], [6.65, 2]], ['GNSS set 20', [[[1.2, 60], [0.3, 700], [0.3, 200], [0.3, 995], [0.02, 995]], 60], [8.46, 5]]], [['GNSS set 19', [[[0.02, 700], [0.02, 60]], 60], [6.65, 2]], ['GNSS set 21', [[[1.2, 200], [0.02, 1100], [0.005, 700], [0.3, 995]], 10], [9.13, 2]], ['GNSS set 22', [[[0.05, 700], [1.2, 200], [1.2, 10], [1.2, 1100], [0.3, 1100]], 10], [8.04, 3]], ['GNSS set 23', [[[0.3, 700], [0.05, 995], [1.2, 200], [0.005, 10]], 25], [8.69, 3]], ['GNSS set 24', [[[0.02, 1100], [1.2, 200], [0.02, 1100], [0.3, 1100]], 60], [8.96, 1]], ['GNSS set 25', [[[0.005, 1100], [0.3, 60], [1.2, 10], [0.05, 700], [1.2, 60]], 25], [7.78, 4]], ['GNSS set 26', [[[0.05, 995]], 60], [8.11, 1]], ['GNSS set 27', [[[0.3, 10]], 60], [7.38, 1]]], [['GNSS set 24', [[[0.02, 1100], [1.2, 200], [0.02, 1100], [0.3, 1100]], 60], [8.96, 1]], ['GNSS set 28', [[[0.02, 1100], [0.005, 200], [0.05, 200]], 10], [7.04, 1]], ['GNSS set 29', [[[0.3, 60], [0.02, 1100], [0.3, 995], [1.2, 60]], 60], [8.42, 3]], ['GNSS set 30', [[[0.3, 200], [1.2, 10], [0.3, 1100]], 60], [8.13, 2]], ['GNSS set 31', [[[0.05, 200], [0.05, 700]], 10], [7.44, 2]], ['GNSS set 32', [[[1.2, 1100]], 10], None], ['GNSS set 33', [[[0.02, 10], [0.3, 995], [1.2, 1100], [0.02, 700]], 60], [7.5, 3]], ['noise floor station', [[[0.02, 100]], 10], [6.14, 1]]]]
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 |
|---|---|---|---|
| GNSS set 0 | [7.36, 2] | [7.36, 2] | Passed |
| GNSS set 1 | [8.88, 2] | [8.88, 2] | Passed |
| GNSS set 2 | [8.93, 1] | [8.93, 1] | Passed |
| GNSS set 3 | None | None | Passed |
| GNSS set 4 | [8.3, 3] | [8.3, 3] | Passed |
| GNSS set 5 | [6.94, 2] | [7.48, 2] | Failed |
| GNSS set 6 | [6.2, 2] | [6.72, 2] | Failed |
| GNSS set 7 | None | None | Passed |
SHA-256 / 38e5865ceedbf7b4ce873cb3183c1d8628de24870213d2a340459519f0f43a62
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(obs, depth_km):
A, B, C = -4.434, 1.047, -0.138
ms = []
for pgd_m, epi in obs:
pgd_cm = pgd_m * 100.0
r = epi + depth_km
if pgd_cm < 2.0 or r > 1000:
continue
ms.append((math.log10(pgd_cm) - A) / (B + C * math.log10(r)))
if not ms:
return None
return [round(sum(ms) / len(ms), 2), len(ms)]
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['GNSS set 0', [[[0.005, 700], [0.05, 1100], [0.02, 995], [0.02, 700]], 25], [7.36, 2]], ['GNSS set 1', [[[0.005, 200], [0.005, 10], [1.2, 995], [0.005, 995], [0.02, 995]], 10], [8.88, 2]], ['GNSS set 2', [[[1.2, 200]], 10], [8.93, 1]], ['GNSS set 3', [[[1.2, 1100]], 10], None], ['GNSS set 4', [[[0.005, 995], [0.02, 200], [0.005, 1100], [1.2, 995], [1.2, 60]], 10], [8.3, 3]], ['GNSS set 5', [[[0.005, 10], [0.3, 60], [0.3, 1100], [0.3, 10]], 60], [7.48, 2]], ['GNSS set 6', [[[0.3, 10], [0.005, 200], [1.2, 1100], [0.005, 1100], [0.02, 60]], 60], [6.72, 2]], ['GNSS set 7', [[[0.005, 700], [1.2, 1100]], 25], None]], [['GNSS set 7', [[[0.005, 700], [1.2, 1100]], 25], None], ['GNSS set 8', [[[1.2, 700], [0.005, 10]], 10], [9.95, 1]], ['GNSS set 9', [[[1.2, 60], [0.3, 10], [0.05, 60]], 25], [7.19, 3]], ['GNSS set 10', [[[0.3, 700], [0.02, 1100]], 60], [9.04, 1]], ['GNSS set 11', [[[1.2, 1100], [0.02, 200], [0.02, 200], [0.005, 1100], [0.05, 10]], 25], [6.34, 3]], ['GNSS set 12', [[[0.3, 200]], 25], [8.11, 1]], ['GNSS set 13', [[[0.005, 700], [0.05, 700], [1.2, 995], [0.3, 700]], 25], [9.05, 3]], ['GNSS set 14', [[[1.2, 700], [0.02, 200], [0.02, 700]], 10], [7.89, 3]]], [['GNSS set 13', [[[0.005, 700], [0.05, 700], [1.2, 995], [0.3, 700]], 25], [9.05, 3]], ['GNSS set 14', [[[1.2, 700], [0.02, 200], [0.02, 700]], 10], [7.89, 3]], ['GNSS set 15', [[[0.005, 60]], 10], None], ['GNSS set 16', [[[1.2, 200], [0.005, 200], [0.02, 10], [0.3, 700]], 25], [7.85, 3]], ['GNSS set 17', [[[0.3, 200], [0.05, 995]], 60], [8.12, 2]], ['GNSS set 18', [[[0.02, 10], [0.3, 1100], [1.2, 200], [0.005, 700], [1.2, 995]], 10], [8.18, 3]], ['GNSS set 19', [[[0.02, 700], [0.02, 60]], 60], [6.65, 2]], ['GNSS set 20', [[[1.2, 60], [0.3, 700], [0.3, 200], [0.3, 995], [0.02, 995]], 60], [8.46, 5]]], [['GNSS set 19', [[[0.02, 700], [0.02, 60]], 60], [6.65, 2]], ['GNSS set 21', [[[1.2, 200], [0.02, 1100], [0.005, 700], [0.3, 995]], 10], [9.13, 2]], ['GNSS set 22', [[[0.05, 700], [1.2, 200], [1.2, 10], [1.2, 1100], [0.3, 1100]], 10], [8.04, 3]], ['GNSS set 23', [[[0.3, 700], [0.05, 995], [1.2, 200], [0.005, 10]], 25], [8.69, 3]], ['GNSS set 24', [[[0.02, 1100], [1.2, 200], [0.02, 1100], [0.3, 1100]], 60], [8.96, 1]], ['GNSS set 25', [[[0.005, 1100], [0.3, 60], [1.2, 10], [0.05, 700], [1.2, 60]], 25], [7.78, 4]], ['GNSS set 26', [[[0.05, 995]], 60], [8.11, 1]], ['GNSS set 27', [[[0.3, 10]], 60], [7.38, 1]]], [['GNSS set 24', [[[0.02, 1100], [1.2, 200], [0.02, 1100], [0.3, 1100]], 60], [8.96, 1]], ['GNSS set 28', [[[0.02, 1100], [0.005, 200], [0.05, 200]], 10], [7.04, 1]], ['GNSS set 29', [[[0.3, 60], [0.02, 1100], [0.3, 995], [1.2, 60]], 60], [8.42, 3]], ['GNSS set 30', [[[0.3, 200], [1.2, 10], [0.3, 1100]], 60], [8.13, 2]], ['GNSS set 31', [[[0.05, 200], [0.05, 700]], 10], [7.44, 2]], ['GNSS set 32', [[[1.2, 1100]], 10], None], ['GNSS set 33', [[[0.02, 10], [0.3, 995], [1.2, 1100], [0.02, 700]], 60], [7.5, 3]], ['noise floor station', [[[0.02, 100]], 10], [6.14, 1]]]]
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 |
|---|---|---|---|
| GNSS set 0 | [7.26, 1] | [7.36, 2] | Failed |
| GNSS set 1 | None | [8.88, 2] | Failed |
| GNSS set 2 | [8.96, 1] | [8.93, 1] | Failed |
| GNSS set 3 | None | None | Passed |
| GNSS set 4 | [7.37, 2] | [8.3, 3] | Failed |
| GNSS set 5 | [7.62, 2] | [7.48, 2] | Failed |
| GNSS set 6 | [6.84, 2] | [6.72, 2] | Failed |
| GNSS set 7 | None | None | Passed |
SHA-256 / 4161958e366f9adbec532cc79d3f10b539426b9e512b653220bf5cd45630a3ce
HELD IN THE MEMBER ARCHIVE
The verified repair and its recorded checks are member-only.
This mechanism has 8 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.
Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.
Member access is invitation-based. Sign in with your invited account to inspect the repair.
Sign in to the archive ↗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:31.599552+00:00.
Case digest / 060df81f0c915f6407057e79754f96696039af66b878d769cb1ae231b91a1694