FAILURE MAP
← Case archive

FA-71491 / Seismic magnitude estimation / Open access

Aki maximum-likelihood b-value: completeness filter · case 01

Events exactly at the completeness magnitude are dropped and b is biased low.

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

ROOT CAUSE

The completeness filter is exclusive.

VERIFIED REPAIR

Keep events with M >= Mc.

Unsuccessful approach: Lowering the cut by a bin admits the incomplete bin.

Case contract

Magnitudes, completeness and bin width in tenths. Use events with M >= Mc; fewer than 2 returns None. b = log10(e) / (mean(M) - (Mc - dM/2)); non-positive denominator returns None. Return [b rounded 0.001, n, sigma = b/sqrt(n) rounded 0.001].

Why this case matters

Gutenberg-Richter b-values feed hazard rates and foreshock studies.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(mags_x10, mc_x10, dm_x10):
    sel = [m for m in mags_x10 if m > mc_x10]
    n = len(sel)
    if n < 2:
        return None
    mean = sum(sel) / n / 10.0
    denom = mean - (mc_x10 - dm_x10 / 2.0) / 10.0
    if denom <= 0:
        return None
    b = math.log10(math.e) / denom
    return [round(b, 3), n, round(b / math.sqrt(n), 3)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['catalogue 0', [[10, 41, 21, 20, 12], 20, 1], [0.554, 3, 0.32]], ['catalogue 1', [[18, 21, 15, 10, 25, 41, 34, 20, 20, 34, 30], 15, 1], [0.384, 10, 0.122]], ['catalogue 2', [[25, 25, 22], 15, 1], [0.457, 3, 0.264]], ['catalogue 3', [[15, 15, 25, 12, 22, 34, 20, 25], 15, 1], [0.558, 7, 0.211]], ['catalogue 4', [[25, 41, 25, 15, 25, 25, 30], 15, 1], [0.36, 7, 0.136]], ['catalogue 5', [[30, 12], 20, 1], None], ['catalogue 6', [[22, 25, 10], 15, 1], [0.483, 2, 0.341]], ['half-unit bins', [[15, 20, 20, 25, 35], 20, 5], [0.579, 4, 0.29]]], [['catalogue 4', [[25, 41, 25, 15, 25, 25, 30], 15, 1], [0.36, 7, 0.136]], ['catalogue 7', [[34], 20, 1], None], ['catalogue 8', [[25, 25, 18, 15, 34], 15, 1], [0.488, 5, 0.218]], ['catalogue 9', [[34, 15, 20, 12, 15], 20, 1], [0.579, 2, 0.409]], ['catalogue 10', [[22, 21, 25, 30, 20, 15, 22], 15, 1], [0.568, 7, 0.215]], ['catalogue 11', [[30, 21, 25], 20, 1], [0.745, 3, 0.43]], ['catalogue 12', [[25, 15, 18, 25, 22, 15, 20, 12], 20, 1], [1.241, 4, 0.62]], ['event one bin below Mc', [[19, 20, 25, 30], 20, 1], [0.79, 3, 0.456]]], [['catalogue 10', [[22, 21, 25, 30, 20, 15, 22], 15, 1], [0.568, 7, 0.215]], ['catalogue 14', [[15], 15, 1], None], ['catalogue 15', [[20, 12, 25, 25, 22, 25, 20, 21, 30, 10, 41, 25], 15, 1], [0.398, 10, 0.126]], ['catalogue 16', [[10, 15, 20, 22], 20, 1], [2.895, 2, 2.047]], ['catalogue 17', [[22, 10, 20, 18, 25, 10, 15], 20, 1], [1.533, 3, 0.885]], ['catalogue 18', [[22, 34, 20, 18], 15, 1], [0.483, 4, 0.241]], ['catalogue 19', [[20, 41, 25, 30], 15, 1], [0.3, 4, 0.15]], ['half-unit bins', [[15, 20, 20, 25, 35], 20, 5], [0.579, 4, 0.29]]], [['catalogue 16', [[10, 15, 20, 22], 20, 1], [2.895, 2, 2.047]], ['catalogue 21', [[20], 15, 1], None], ['catalogue 22', [[15, 25, 15, 21, 22, 41, 18, 20, 10, 10], 15, 1], [0.57, 8, 0.201]], ['catalogue 23', [[21, 34, 18], 20, 1], [0.543, 2, 0.384]], ['catalogue 24', [[20], 20, 1], None], ['catalogue 25', [[25, 34, 34, 20, 12], 20, 1], [0.496, 4, 0.248]], ['catalogue 26', [[25, 18, 25, 10, 10, 41, 20, 12, 34, 25], 15, 1], [0.351, 7, 0.133]], ['event one bin below Mc', [[19, 20, 25, 30], 20, 1], [0.79, 3, 0.456]]], [['catalogue 25', [[25, 34, 34, 20, 12], 20, 1], [0.496, 4, 0.248]], ['catalogue 28', [[22, 18, 21, 25, 20, 15], 15, 1], [0.766, 6, 0.313]], ['catalogue 29', [[12, 25, 15, 20, 22, 41], 15, 1], [0.43, 5, 0.192]], ['catalogue 30', [[22], 20, 1], None], ['catalogue 31', [[10, 18, 22, 41, 30, 18, 41, 20, 25, 10, 22, 34], 15, 1], [0.345, 10, 0.109]], ['catalogue 32', [[20, 20, 25], 15, 1], [0.606, 3, 0.35]], ['catalogue 33', [[34, 18, 15, 12, 25, 34, 21, 30, 15, 41], 15, 1], [0.381, 9, 0.127]], ['half-unit bins', [[15, 20, 20, 25, 35], 20, 5], [0.579, 4, 0.29]]]]
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
catalogue 0[0.378, 2, 0.267][0.554, 3, 0.32]Failed
catalogue 1[0.347, 9, 0.116][0.384, 10, 0.122]Failed
catalogue 2[0.457, 3, 0.264][0.457, 3, 0.264]Passed
catalogue 3[0.406, 5, 0.182][0.558, 7, 0.211]Failed
catalogue 4[0.31, 6, 0.127][0.36, 7, 0.136]Failed
catalogue 5NoneNonePassed
catalogue 6[0.483, 2, 0.341][0.483, 2, 0.341]Passed
half-unit bins[0.347, 2, 0.246][0.579, 4, 0.29]Failed

SHA-256 / 288f406ca9fffa42419af4f441a2031b68e234dce0529de64021e8d03805575b

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(mags_x10, mc_x10, dm_x10):
    sel = [m for m in mags_x10 if m >= mc_x10 - dm_x10]
    n = len(sel)
    if n < 2:
        return None
    mean = sum(sel) / n / 10.0
    denom = mean - (mc_x10 - dm_x10 / 2.0) / 10.0
    if denom <= 0:
        return None
    b = math.log10(math.e) / denom
    return [round(b, 3), n, round(b / math.sqrt(n), 3)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['catalogue 0', [[10, 41, 21, 20, 12], 20, 1], [0.554, 3, 0.32]], ['catalogue 1', [[18, 21, 15, 10, 25, 41, 34, 20, 20, 34, 30], 15, 1], [0.384, 10, 0.122]], ['catalogue 2', [[25, 25, 22], 15, 1], [0.457, 3, 0.264]], ['catalogue 3', [[15, 15, 25, 12, 22, 34, 20, 25], 15, 1], [0.558, 7, 0.211]], ['catalogue 4', [[25, 41, 25, 15, 25, 25, 30], 15, 1], [0.36, 7, 0.136]], ['catalogue 5', [[30, 12], 20, 1], None], ['catalogue 6', [[22, 25, 10], 15, 1], [0.483, 2, 0.341]], ['half-unit bins', [[15, 20, 20, 25, 35], 20, 5], [0.579, 4, 0.29]]], [['catalogue 4', [[25, 41, 25, 15, 25, 25, 30], 15, 1], [0.36, 7, 0.136]], ['catalogue 7', [[34], 20, 1], None], ['catalogue 8', [[25, 25, 18, 15, 34], 15, 1], [0.488, 5, 0.218]], ['catalogue 9', [[34, 15, 20, 12, 15], 20, 1], [0.579, 2, 0.409]], ['catalogue 10', [[22, 21, 25, 30, 20, 15, 22], 15, 1], [0.568, 7, 0.215]], ['catalogue 11', [[30, 21, 25], 20, 1], [0.745, 3, 0.43]], ['catalogue 12', [[25, 15, 18, 25, 22, 15, 20, 12], 20, 1], [1.241, 4, 0.62]], ['event one bin below Mc', [[19, 20, 25, 30], 20, 1], [0.79, 3, 0.456]]], [['catalogue 10', [[22, 21, 25, 30, 20, 15, 22], 15, 1], [0.568, 7, 0.215]], ['catalogue 14', [[15], 15, 1], None], ['catalogue 15', [[20, 12, 25, 25, 22, 25, 20, 21, 30, 10, 41, 25], 15, 1], [0.398, 10, 0.126]], ['catalogue 16', [[10, 15, 20, 22], 20, 1], [2.895, 2, 2.047]], ['catalogue 17', [[22, 10, 20, 18, 25, 10, 15], 20, 1], [1.533, 3, 0.885]], ['catalogue 18', [[22, 34, 20, 18], 15, 1], [0.483, 4, 0.241]], ['catalogue 19', [[20, 41, 25, 30], 15, 1], [0.3, 4, 0.15]], ['half-unit bins', [[15, 20, 20, 25, 35], 20, 5], [0.579, 4, 0.29]]], [['catalogue 16', [[10, 15, 20, 22], 20, 1], [2.895, 2, 2.047]], ['catalogue 21', [[20], 15, 1], None], ['catalogue 22', [[15, 25, 15, 21, 22, 41, 18, 20, 10, 10], 15, 1], [0.57, 8, 0.201]], ['catalogue 23', [[21, 34, 18], 20, 1], [0.543, 2, 0.384]], ['catalogue 24', [[20], 20, 1], None], ['catalogue 25', [[25, 34, 34, 20, 12], 20, 1], [0.496, 4, 0.248]], ['catalogue 26', [[25, 18, 25, 10, 10, 41, 20, 12, 34, 25], 15, 1], [0.351, 7, 0.133]], ['event one bin below Mc', [[19, 20, 25, 30], 20, 1], [0.79, 3, 0.456]]], [['catalogue 25', [[25, 34, 34, 20, 12], 20, 1], [0.496, 4, 0.248]], ['catalogue 28', [[22, 18, 21, 25, 20, 15], 15, 1], [0.766, 6, 0.313]], ['catalogue 29', [[12, 25, 15, 20, 22, 41], 15, 1], [0.43, 5, 0.192]], ['catalogue 30', [[22], 20, 1], None], ['catalogue 31', [[10, 18, 22, 41, 30, 18, 41, 20, 25, 10, 22, 34], 15, 1], [0.345, 10, 0.109]], ['catalogue 32', [[20, 20, 25], 15, 1], [0.606, 3, 0.35]], ['catalogue 33', [[34, 18, 15, 12, 25, 34, 21, 30, 15, 41], 15, 1], [0.381, 9, 0.127]], ['half-unit bins', [[15, 20, 20, 25, 35], 20, 5], [0.579, 4, 0.29]]]]
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
catalogue 0[0.554, 3, 0.32][0.554, 3, 0.32]Passed
catalogue 1[0.384, 10, 0.122][0.384, 10, 0.122]Passed
catalogue 2[0.457, 3, 0.264][0.457, 3, 0.264]Passed
catalogue 3[0.558, 7, 0.211][0.558, 7, 0.211]Passed
catalogue 4[0.36, 7, 0.136][0.36, 7, 0.136]Passed
catalogue 5NoneNonePassed
catalogue 6[0.483, 2, 0.341][0.483, 2, 0.341]Passed
half-unit bins[0.79, 5, 0.353][0.579, 4, 0.29]Failed

SHA-256 / 554fec74a6dfc4dbb03116b97db7287cfdf429326ae65184d3ba267640568844

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(mags_x10, mc_x10, dm_x10):
    sel = [m for m in mags_x10 if m >= mc_x10]
    n = len(sel)
    if n < 2:
        return None
    mean = sum(sel) / n / 10.0
    denom = mean - (mc_x10 - dm_x10 / 2.0) / 10.0
    if denom <= 0:
        return None
    b = math.log10(math.e) / denom
    return [round(b, 3), n, round(b / math.sqrt(n), 3)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['catalogue 0', [[10, 41, 21, 20, 12], 20, 1], [0.554, 3, 0.32]], ['catalogue 1', [[18, 21, 15, 10, 25, 41, 34, 20, 20, 34, 30], 15, 1], [0.384, 10, 0.122]], ['catalogue 2', [[25, 25, 22], 15, 1], [0.457, 3, 0.264]], ['catalogue 3', [[15, 15, 25, 12, 22, 34, 20, 25], 15, 1], [0.558, 7, 0.211]], ['catalogue 4', [[25, 41, 25, 15, 25, 25, 30], 15, 1], [0.36, 7, 0.136]], ['catalogue 5', [[30, 12], 20, 1], None], ['catalogue 6', [[22, 25, 10], 15, 1], [0.483, 2, 0.341]], ['half-unit bins', [[15, 20, 20, 25, 35], 20, 5], [0.579, 4, 0.29]]], [['catalogue 4', [[25, 41, 25, 15, 25, 25, 30], 15, 1], [0.36, 7, 0.136]], ['catalogue 7', [[34], 20, 1], None], ['catalogue 8', [[25, 25, 18, 15, 34], 15, 1], [0.488, 5, 0.218]], ['catalogue 9', [[34, 15, 20, 12, 15], 20, 1], [0.579, 2, 0.409]], ['catalogue 10', [[22, 21, 25, 30, 20, 15, 22], 15, 1], [0.568, 7, 0.215]], ['catalogue 11', [[30, 21, 25], 20, 1], [0.745, 3, 0.43]], ['catalogue 12', [[25, 15, 18, 25, 22, 15, 20, 12], 20, 1], [1.241, 4, 0.62]], ['event one bin below Mc', [[19, 20, 25, 30], 20, 1], [0.79, 3, 0.456]]], [['catalogue 10', [[22, 21, 25, 30, 20, 15, 22], 15, 1], [0.568, 7, 0.215]], ['catalogue 14', [[15], 15, 1], None], ['catalogue 15', [[20, 12, 25, 25, 22, 25, 20, 21, 30, 10, 41, 25], 15, 1], [0.398, 10, 0.126]], ['catalogue 16', [[10, 15, 20, 22], 20, 1], [2.895, 2, 2.047]], ['catalogue 17', [[22, 10, 20, 18, 25, 10, 15], 20, 1], [1.533, 3, 0.885]], ['catalogue 18', [[22, 34, 20, 18], 15, 1], [0.483, 4, 0.241]], ['catalogue 19', [[20, 41, 25, 30], 15, 1], [0.3, 4, 0.15]], ['half-unit bins', [[15, 20, 20, 25, 35], 20, 5], [0.579, 4, 0.29]]], [['catalogue 16', [[10, 15, 20, 22], 20, 1], [2.895, 2, 2.047]], ['catalogue 21', [[20], 15, 1], None], ['catalogue 22', [[15, 25, 15, 21, 22, 41, 18, 20, 10, 10], 15, 1], [0.57, 8, 0.201]], ['catalogue 23', [[21, 34, 18], 20, 1], [0.543, 2, 0.384]], ['catalogue 24', [[20], 20, 1], None], ['catalogue 25', [[25, 34, 34, 20, 12], 20, 1], [0.496, 4, 0.248]], ['catalogue 26', [[25, 18, 25, 10, 10, 41, 20, 12, 34, 25], 15, 1], [0.351, 7, 0.133]], ['event one bin below Mc', [[19, 20, 25, 30], 20, 1], [0.79, 3, 0.456]]], [['catalogue 25', [[25, 34, 34, 20, 12], 20, 1], [0.496, 4, 0.248]], ['catalogue 28', [[22, 18, 21, 25, 20, 15], 15, 1], [0.766, 6, 0.313]], ['catalogue 29', [[12, 25, 15, 20, 22, 41], 15, 1], [0.43, 5, 0.192]], ['catalogue 30', [[22], 20, 1], None], ['catalogue 31', [[10, 18, 22, 41, 30, 18, 41, 20, 25, 10, 22, 34], 15, 1], [0.345, 10, 0.109]], ['catalogue 32', [[20, 20, 25], 15, 1], [0.606, 3, 0.35]], ['catalogue 33', [[34, 18, 15, 12, 25, 34, 21, 30, 15, 41], 15, 1], [0.381, 9, 0.127]], ['half-unit bins', [[15, 20, 20, 25, 35], 20, 5], [0.579, 4, 0.29]]]]
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
catalogue 0[0.554, 3, 0.32][0.554, 3, 0.32]Passed
catalogue 1[0.384, 10, 0.122][0.384, 10, 0.122]Passed
catalogue 2[0.457, 3, 0.264][0.457, 3, 0.264]Passed
catalogue 3[0.558, 7, 0.211][0.558, 7, 0.211]Passed
catalogue 4[0.36, 7, 0.136][0.36, 7, 0.136]Passed
catalogue 5NoneNonePassed
catalogue 6[0.483, 2, 0.341][0.483, 2, 0.341]Passed
half-unit bins[0.579, 4, 0.29][0.579, 4, 0.29]Passed

SHA-256 / 7e35c44e748aef13890fdcaabee88b00d013819c53a111eeb9812b9c9484d3e5

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

Case digest / 873ab7392edab837462b386ecd922c63564c1cee83529963cebd98ec951cd444