FAILURE MAP
← Case archive

FA-71836 / Seismic magnitude estimation / Open access

Magnitude from surface rupture length: logarithm base · case 01

Long ruptures are assigned magnitudes above 11.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The regression is evaluated with the natural log.

VERIFIED REPAIR

Use log10 of length in km.

Unsuccessful approach: Converting to metres adds 3b to every magnitude.

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
    a, b = coef[kind]
    return round(a + b * math.log(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], ['SS rupture 40.0 km', ['SS', 40.0], 6.95], ['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], ['R rupture 0.0 km', ['R', 0.0], None], ['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 fixtureActualExpectedOutcome
SS rupture 0.5 km4.384.82Failed
SS rupture 5.0 km6.965.94Failed
SS rupture 40.0 km9.296.95Failed
SS rupture 350.0 km11.728.01Failed
SS rupture 0.0 kmNoneNonePassed
R rupture 0.5 km4.154.63Failed
R rupture 5.0 km6.965.85Failed
R rupture 40.0 km9.56.95Failed

SHA-256 / 88807f14bff17080bdbd24ebe0a0a56bd994ee3c9dbb11599d06c13f3e16df40

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[kind]
    return round(a + b * math.log10(length_km * 1000.0), 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], ['SS rupture 40.0 km', ['SS', 40.0], 6.95], ['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], ['R rupture 0.0 km', ['R', 0.0], None], ['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 fixtureActualExpectedOutcome
SS rupture 0.5 km8.184.82Failed
SS rupture 5.0 km9.35.94Failed
SS rupture 40.0 km10.316.95Failed
SS rupture 350.0 km11.378.01Failed
SS rupture 0.0 kmNoneNonePassed
R rupture 0.5 km8.294.63Failed
R rupture 5.0 km9.515.85Failed
R rupture 40.0 km10.616.95Failed

SHA-256 / da11b778396d21dabb2f1bd9e71572e6e569ef74714ba48410fa4df8d46e27b7

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], ['SS rupture 40.0 km', ['SS', 40.0], 6.95], ['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], ['R rupture 0.0 km', ['R', 0.0], None], ['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 fixtureActualExpectedOutcome
SS rupture 0.5 km4.824.82Passed
SS rupture 5.0 km5.945.94Passed
SS rupture 40.0 km6.956.95Passed
SS rupture 350.0 km8.018.01Passed
SS rupture 0.0 kmNoneNonePassed
R rupture 0.5 km4.634.63Passed
R rupture 5.0 km5.855.85Passed
R rupture 40.0 km6.956.95Passed

SHA-256 / 9c4187a9278d182df786e83a12816b25572a04fb92913b280b50d6e684b9eea7

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.130287+00:00.

Case digest / 7b3c083a63e0c649dcf32adcfe2d241bea798a660b0e0aaf079511c820ce587e