FAILURE MAP
← Case archive

FA-71481 / Seismic magnitude estimation / Open access

Coda duration magnitude: termination search start · case 01

A quiet sample right after the pick terminates the coda before the S wave peak.

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

ROOT CAUSE

The termination scan starts at the P pick instead of the envelope peak.

VERIFIED REPAIR

Search for the coda end after the peak.

Unsuccessful approach: Stopping one sample early misses a coda that ends on the last sample.

Case contract

envelope is a list of amplitude samples, dt s per sample, p_index the P pick sample, noise the pre-event noise level. From the peak at or after the pick (first maximum), the coda ends at the first sample with amplitude <= 2*noise. tau = (end - p_index)*dt; Md = -0.87 + 2.0 log10(tau) + 0.0035 epi_km. Return [tau rounded 0.01, Md rounded 0.01] or None when no end or tau <= 0.

Why this case matters

Duration magnitude is robust for small events with clipped or noisy amplitudes.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(envelope, dt, p_index, noise, epi_km):
    if p_index >= len(envelope):
        return None
    peak = max(range(p_index, len(envelope)), key=lambda i: envelope[i])
    end = None
    for i in range(p_index, len(envelope)):
        if envelope[i] <= 2 * noise:
            end = i
            break
    if end is None:
        return None
    tau = (end - p_index) * dt
    if tau <= 0:
        return None
    md = -0.87 + 2.0 * math.log10(tau) + 0.0035 * epi_km
    return [round(tau, 2), round(md, 2)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['coda 0', [[1, 0, 1, 1, 19, 59, 29, 23, 13, 6, 4, 2, 1], 1.0, 4, 1, 30], [7.0, 0.93]], ['coda 1', [[0, 1, 3, 3, 1, 23, 70, 49, 39, 31, 21, 14, 7, 4, 2, 3, 3, 1], 0.5, 5, 3, 5], [4.0, 0.35]], ['coda 2', [[0, 2, 26, 78, 39, 27, 21, 14, 8, 4, 2, 0], 0.5, 2, 3, 5], [3.5, 0.24]], ['coda 3', [[0, 2, 2, 0, 1, 14, 44, 30, 21, 14, 9, 7, 5, 3, 1, 2, 0, 2], 0.5, 5, 2, 5], [4.0, 0.35]], ['coda 4', [[0, 1, 1, 19, 59, 35, 21, 12, 7, 5, 2, 1], 0.5, 3, 1, 5], [3.5, 0.24]], ['coda 5', [[2, 0, 0, 24, 72, 43, 25, 17, 13, 9, 4, 3, 1, 1, 1, 1], 2.0, 3, 2, 120], [14.0, 1.84]], ['coda 27', [[1, 1, 0, 8, 24, 16, 9, 5, 3, 1], 2.0, 3, 1, 120], [12.0, 1.71]], ['quiet gap before S peak', [[0, 0, 3, 1, 60, 30, 10, 2, 1], 1.0, 2, 1, 20], [5.0, 0.6]]], [['coda 7', [[0, 0, 1, 0, 0, 16, 50, 35, 21, 12, 8, 4, 2, 1, 1], 1.0, 5, 1, 30], [7.0, 0.93]], ['coda 8', [[0, 0, 1, 2, 9, 27, 18, 10, 7, 4, 2], 0.5, 4, 2, 5], [2.5, -0.06]], ['coda 9', [[1, 1, 17, 53, 42, 29, 23, 18, 14, 9, 6, 4, 2, 1, 1, 1, 1], 1.0, 2, 1, 30], [10.0, 1.23]], ['coda 10', [[1, 2, 0, 2, 10, 30, 18, 12, 7, 5, 2, 0, 1], 2.0, 4, 2, 120], [12.0, 1.71]], ['coda 11', [[1, 0, 10, 31, 24, 16, 8, 4, 2, 1, 0], 1.0, 2, 1, 30], [6.0, 0.79]], ['coda 12', [[2, 1, 9, 28, 22, 13, 9, 7, 5, 4, 2, 2], 1.0, 2, 2, 30], [7.0, 0.93]], ['ends on last sample', [[0, 50, 20, 8, 2], 1.0, 1, 1, 10], [3.0, 0.12]], ['emergent onset lull', [[1, 0, 8, 2, 4, 90, 50, 20, 6, 2], 0.5, 2, 1, 60], [3.5, 0.43]]], [['coda 14', [[0, 1, 0, 25, 75, 45, 36, 25, 17, 13, 6, 4, 2, 1, 0, 0], 0.5, 3, 1, 5], [4.5, 0.45]], ['coda 15', [[2, 1, 2, 1, 1, 25, 75, 60, 42, 25, 15, 12, 6, 3, 0], 0.5, 5, 3, 5], [3.5, 0.24]], ['coda 16', [[0, 1, 1, 1, 0, 23, 69, 55, 27, 21, 10, 6, 3, 1, 0], 1.0, 5, 1, 30], [8.0, 1.04]], ['coda 17', [[1, 2, 22, 68, 40, 28, 19, 15, 12, 8, 6, 4, 2, 0, 2], 2.0, 2, 2, 120], [18.0, 2.06]], ['coda 18', [[1, 1, 1, 1, 10, 31, 24, 12, 9, 7, 4, 2, 1, 1, 0, 1], 0.5, 4, 1, 5], [3.5, 0.24]], ['coda 19', [[1, 1, 11, 33, 16, 12, 6, 3, 2, 1], 2.0, 2, 3, 120], [8.0, 1.36]], ['quiet gap before S peak', [[0, 0, 3, 1, 60, 30, 10, 2, 1], 1.0, 2, 1, 20], [5.0, 0.6]], ['emergent onset lull', [[1, 0, 8, 2, 4, 90, 50, 20, 6, 2], 0.5, 2, 1, 60], [3.5, 0.43]]], [['coda 21', [[0, 1, 0, 8, 26, 18, 10, 6, 3, 2, 1], 0.5, 3, 1, 5], [3.0, 0.1]], ['coda 22', [[1, 1, 0, 0, 1, 23, 69, 34, 23, 13, 9, 5, 4, 3, 2, 1, 1, 0], 0.5, 5, 1, 5], [4.5, 0.45]], ['coda 23', [[0, 2, 0, 2, 1, 16, 48, 28, 19, 15, 9, 4, 3, 1, 1, 2], 1.0, 5, 2, 30], [6.0, 0.79]], ['coda 24', [[1, 0, 1, 1, 0, 11, 35, 24, 19, 15, 9, 7, 5, 3, 2, 1, 1, 1, 0], 2.0, 5, 1, 120], [18.0, 2.06]], ['coda 25', [[1, 0, 12, 36, 18, 14, 8, 4, 3, 1, 1, 1], 1.0, 2, 2, 30], [5.0, 0.63]], ['coda 26', [[0, 0, 1, 11, 34, 17, 11, 7, 3, 1], 2.0, 3, 1, 120], [12.0, 1.71]], ['coda 27', [[1, 1, 0, 8, 24, 16, 9, 5, 3, 1], 2.0, 3, 1, 120], [12.0, 1.71]], ['emergent onset lull', [[1, 0, 8, 2, 4, 90, 50, 20, 6, 2], 0.5, 2, 1, 60], [3.5, 0.43]]], [['coda 27', [[1, 1, 0, 8, 24, 16, 9, 5, 3, 1], 2.0, 3, 1, 120], [12.0, 1.71]], ['coda 28', [[1, 2, 3, 7, 21, 16, 12, 9, 5, 3, 1, 0, 0], 0.5, 3, 3, 5], [2.5, -0.06]], ['coda 29', [[0, 0, 1, 17, 53, 42, 33, 16, 12, 9, 6, 3, 2, 1], 2.0, 3, 1, 120], [18.0, 2.06]], ['coda 30', [[2, 2, 0, 1, 2, 19, 58, 34, 27, 16, 11, 7, 5, 4, 2, 1], 2.0, 5, 2, 120], [16.0, 1.96]], ['coda 31', [[2, 3, 1, 19, 59, 47, 23, 13, 10, 6, 3, 0, 1, 3], 0.5, 3, 3, 5], [3.0, 0.1]], ['coda 32', [[1, 0, 12, 38, 26, 15, 9, 4, 3, 2, 1], 0.5, 2, 2, 5], [2.5, -0.06]], ['coda 33', [[2, 0, 11, 34, 23, 16, 8, 4, 2, 1, 0, 3], 2.0, 2, 3, 120], [10.0, 1.55]], ['quiet gap before S peak', [[0, 0, 3, 1, 60, 30, 10, 2, 1], 1.0, 2, 1, 20], [5.0, 0.6]]]]
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
coda 0[7.0, 0.93][7.0, 0.93]Passed
coda 1[4.0, 0.35][4.0, 0.35]Passed
coda 2[3.5, 0.24][3.5, 0.24]Passed
coda 3[4.0, 0.35][4.0, 0.35]Passed
coda 4[3.5, 0.24][3.5, 0.24]Passed
coda 5[14.0, 1.84][14.0, 1.84]Passed
coda 27[12.0, 1.71][12.0, 1.71]Passed
quiet gap before S peak[1.0, -0.8][5.0, 0.6]Failed

SHA-256 / c1a94ff62619629f58ff0773ebd144ec21ed3d2d66b884814c25dbde8264a896

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(envelope, dt, p_index, noise, epi_km):
    if p_index >= len(envelope):
        return None
    peak = max(range(p_index, len(envelope)), key=lambda i: envelope[i])
    end = None
    for i in range(peak, len(envelope) - 1):
        if envelope[i] <= 2 * noise:
            end = i
            break
    if end is None:
        return None
    tau = (end - p_index) * dt
    if tau <= 0:
        return None
    md = -0.87 + 2.0 * math.log10(tau) + 0.0035 * epi_km
    return [round(tau, 2), round(md, 2)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['coda 0', [[1, 0, 1, 1, 19, 59, 29, 23, 13, 6, 4, 2, 1], 1.0, 4, 1, 30], [7.0, 0.93]], ['coda 1', [[0, 1, 3, 3, 1, 23, 70, 49, 39, 31, 21, 14, 7, 4, 2, 3, 3, 1], 0.5, 5, 3, 5], [4.0, 0.35]], ['coda 2', [[0, 2, 26, 78, 39, 27, 21, 14, 8, 4, 2, 0], 0.5, 2, 3, 5], [3.5, 0.24]], ['coda 3', [[0, 2, 2, 0, 1, 14, 44, 30, 21, 14, 9, 7, 5, 3, 1, 2, 0, 2], 0.5, 5, 2, 5], [4.0, 0.35]], ['coda 4', [[0, 1, 1, 19, 59, 35, 21, 12, 7, 5, 2, 1], 0.5, 3, 1, 5], [3.5, 0.24]], ['coda 5', [[2, 0, 0, 24, 72, 43, 25, 17, 13, 9, 4, 3, 1, 1, 1, 1], 2.0, 3, 2, 120], [14.0, 1.84]], ['coda 27', [[1, 1, 0, 8, 24, 16, 9, 5, 3, 1], 2.0, 3, 1, 120], [12.0, 1.71]], ['quiet gap before S peak', [[0, 0, 3, 1, 60, 30, 10, 2, 1], 1.0, 2, 1, 20], [5.0, 0.6]]], [['coda 7', [[0, 0, 1, 0, 0, 16, 50, 35, 21, 12, 8, 4, 2, 1, 1], 1.0, 5, 1, 30], [7.0, 0.93]], ['coda 8', [[0, 0, 1, 2, 9, 27, 18, 10, 7, 4, 2], 0.5, 4, 2, 5], [2.5, -0.06]], ['coda 9', [[1, 1, 17, 53, 42, 29, 23, 18, 14, 9, 6, 4, 2, 1, 1, 1, 1], 1.0, 2, 1, 30], [10.0, 1.23]], ['coda 10', [[1, 2, 0, 2, 10, 30, 18, 12, 7, 5, 2, 0, 1], 2.0, 4, 2, 120], [12.0, 1.71]], ['coda 11', [[1, 0, 10, 31, 24, 16, 8, 4, 2, 1, 0], 1.0, 2, 1, 30], [6.0, 0.79]], ['coda 12', [[2, 1, 9, 28, 22, 13, 9, 7, 5, 4, 2, 2], 1.0, 2, 2, 30], [7.0, 0.93]], ['ends on last sample', [[0, 50, 20, 8, 2], 1.0, 1, 1, 10], [3.0, 0.12]], ['emergent onset lull', [[1, 0, 8, 2, 4, 90, 50, 20, 6, 2], 0.5, 2, 1, 60], [3.5, 0.43]]], [['coda 14', [[0, 1, 0, 25, 75, 45, 36, 25, 17, 13, 6, 4, 2, 1, 0, 0], 0.5, 3, 1, 5], [4.5, 0.45]], ['coda 15', [[2, 1, 2, 1, 1, 25, 75, 60, 42, 25, 15, 12, 6, 3, 0], 0.5, 5, 3, 5], [3.5, 0.24]], ['coda 16', [[0, 1, 1, 1, 0, 23, 69, 55, 27, 21, 10, 6, 3, 1, 0], 1.0, 5, 1, 30], [8.0, 1.04]], ['coda 17', [[1, 2, 22, 68, 40, 28, 19, 15, 12, 8, 6, 4, 2, 0, 2], 2.0, 2, 2, 120], [18.0, 2.06]], ['coda 18', [[1, 1, 1, 1, 10, 31, 24, 12, 9, 7, 4, 2, 1, 1, 0, 1], 0.5, 4, 1, 5], [3.5, 0.24]], ['coda 19', [[1, 1, 11, 33, 16, 12, 6, 3, 2, 1], 2.0, 2, 3, 120], [8.0, 1.36]], ['quiet gap before S peak', [[0, 0, 3, 1, 60, 30, 10, 2, 1], 1.0, 2, 1, 20], [5.0, 0.6]], ['emergent onset lull', [[1, 0, 8, 2, 4, 90, 50, 20, 6, 2], 0.5, 2, 1, 60], [3.5, 0.43]]], [['coda 21', [[0, 1, 0, 8, 26, 18, 10, 6, 3, 2, 1], 0.5, 3, 1, 5], [3.0, 0.1]], ['coda 22', [[1, 1, 0, 0, 1, 23, 69, 34, 23, 13, 9, 5, 4, 3, 2, 1, 1, 0], 0.5, 5, 1, 5], [4.5, 0.45]], ['coda 23', [[0, 2, 0, 2, 1, 16, 48, 28, 19, 15, 9, 4, 3, 1, 1, 2], 1.0, 5, 2, 30], [6.0, 0.79]], ['coda 24', [[1, 0, 1, 1, 0, 11, 35, 24, 19, 15, 9, 7, 5, 3, 2, 1, 1, 1, 0], 2.0, 5, 1, 120], [18.0, 2.06]], ['coda 25', [[1, 0, 12, 36, 18, 14, 8, 4, 3, 1, 1, 1], 1.0, 2, 2, 30], [5.0, 0.63]], ['coda 26', [[0, 0, 1, 11, 34, 17, 11, 7, 3, 1], 2.0, 3, 1, 120], [12.0, 1.71]], ['coda 27', [[1, 1, 0, 8, 24, 16, 9, 5, 3, 1], 2.0, 3, 1, 120], [12.0, 1.71]], ['emergent onset lull', [[1, 0, 8, 2, 4, 90, 50, 20, 6, 2], 0.5, 2, 1, 60], [3.5, 0.43]]], [['coda 27', [[1, 1, 0, 8, 24, 16, 9, 5, 3, 1], 2.0, 3, 1, 120], [12.0, 1.71]], ['coda 28', [[1, 2, 3, 7, 21, 16, 12, 9, 5, 3, 1, 0, 0], 0.5, 3, 3, 5], [2.5, -0.06]], ['coda 29', [[0, 0, 1, 17, 53, 42, 33, 16, 12, 9, 6, 3, 2, 1], 2.0, 3, 1, 120], [18.0, 2.06]], ['coda 30', [[2, 2, 0, 1, 2, 19, 58, 34, 27, 16, 11, 7, 5, 4, 2, 1], 2.0, 5, 2, 120], [16.0, 1.96]], ['coda 31', [[2, 3, 1, 19, 59, 47, 23, 13, 10, 6, 3, 0, 1, 3], 0.5, 3, 3, 5], [3.0, 0.1]], ['coda 32', [[1, 0, 12, 38, 26, 15, 9, 4, 3, 2, 1], 0.5, 2, 2, 5], [2.5, -0.06]], ['coda 33', [[2, 0, 11, 34, 23, 16, 8, 4, 2, 1, 0, 3], 2.0, 2, 3, 120], [10.0, 1.55]], ['quiet gap before S peak', [[0, 0, 3, 1, 60, 30, 10, 2, 1], 1.0, 2, 1, 20], [5.0, 0.6]]]]
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
coda 0[7.0, 0.93][7.0, 0.93]Passed
coda 1[4.0, 0.35][4.0, 0.35]Passed
coda 2[3.5, 0.24][3.5, 0.24]Passed
coda 3[4.0, 0.35][4.0, 0.35]Passed
coda 4[3.5, 0.24][3.5, 0.24]Passed
coda 5[14.0, 1.84][14.0, 1.84]Passed
coda 27None[12.0, 1.71]Failed
quiet gap before S peak[5.0, 0.6][5.0, 0.6]Passed

SHA-256 / da04233313b1b196a8c5bd3e1d8684cf4e672c7e0204ca45a096c116bdf297e5

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(envelope, dt, p_index, noise, epi_km):
    if p_index >= len(envelope):
        return None
    peak = max(range(p_index, len(envelope)), key=lambda i: envelope[i])
    end = None
    for i in range(peak, len(envelope)):
        if envelope[i] <= 2 * noise:
            end = i
            break
    if end is None:
        return None
    tau = (end - p_index) * dt
    if tau <= 0:
        return None
    md = -0.87 + 2.0 * math.log10(tau) + 0.0035 * epi_km
    return [round(tau, 2), round(md, 2)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['coda 0', [[1, 0, 1, 1, 19, 59, 29, 23, 13, 6, 4, 2, 1], 1.0, 4, 1, 30], [7.0, 0.93]], ['coda 1', [[0, 1, 3, 3, 1, 23, 70, 49, 39, 31, 21, 14, 7, 4, 2, 3, 3, 1], 0.5, 5, 3, 5], [4.0, 0.35]], ['coda 2', [[0, 2, 26, 78, 39, 27, 21, 14, 8, 4, 2, 0], 0.5, 2, 3, 5], [3.5, 0.24]], ['coda 3', [[0, 2, 2, 0, 1, 14, 44, 30, 21, 14, 9, 7, 5, 3, 1, 2, 0, 2], 0.5, 5, 2, 5], [4.0, 0.35]], ['coda 4', [[0, 1, 1, 19, 59, 35, 21, 12, 7, 5, 2, 1], 0.5, 3, 1, 5], [3.5, 0.24]], ['coda 5', [[2, 0, 0, 24, 72, 43, 25, 17, 13, 9, 4, 3, 1, 1, 1, 1], 2.0, 3, 2, 120], [14.0, 1.84]], ['coda 27', [[1, 1, 0, 8, 24, 16, 9, 5, 3, 1], 2.0, 3, 1, 120], [12.0, 1.71]], ['quiet gap before S peak', [[0, 0, 3, 1, 60, 30, 10, 2, 1], 1.0, 2, 1, 20], [5.0, 0.6]]], [['coda 7', [[0, 0, 1, 0, 0, 16, 50, 35, 21, 12, 8, 4, 2, 1, 1], 1.0, 5, 1, 30], [7.0, 0.93]], ['coda 8', [[0, 0, 1, 2, 9, 27, 18, 10, 7, 4, 2], 0.5, 4, 2, 5], [2.5, -0.06]], ['coda 9', [[1, 1, 17, 53, 42, 29, 23, 18, 14, 9, 6, 4, 2, 1, 1, 1, 1], 1.0, 2, 1, 30], [10.0, 1.23]], ['coda 10', [[1, 2, 0, 2, 10, 30, 18, 12, 7, 5, 2, 0, 1], 2.0, 4, 2, 120], [12.0, 1.71]], ['coda 11', [[1, 0, 10, 31, 24, 16, 8, 4, 2, 1, 0], 1.0, 2, 1, 30], [6.0, 0.79]], ['coda 12', [[2, 1, 9, 28, 22, 13, 9, 7, 5, 4, 2, 2], 1.0, 2, 2, 30], [7.0, 0.93]], ['ends on last sample', [[0, 50, 20, 8, 2], 1.0, 1, 1, 10], [3.0, 0.12]], ['emergent onset lull', [[1, 0, 8, 2, 4, 90, 50, 20, 6, 2], 0.5, 2, 1, 60], [3.5, 0.43]]], [['coda 14', [[0, 1, 0, 25, 75, 45, 36, 25, 17, 13, 6, 4, 2, 1, 0, 0], 0.5, 3, 1, 5], [4.5, 0.45]], ['coda 15', [[2, 1, 2, 1, 1, 25, 75, 60, 42, 25, 15, 12, 6, 3, 0], 0.5, 5, 3, 5], [3.5, 0.24]], ['coda 16', [[0, 1, 1, 1, 0, 23, 69, 55, 27, 21, 10, 6, 3, 1, 0], 1.0, 5, 1, 30], [8.0, 1.04]], ['coda 17', [[1, 2, 22, 68, 40, 28, 19, 15, 12, 8, 6, 4, 2, 0, 2], 2.0, 2, 2, 120], [18.0, 2.06]], ['coda 18', [[1, 1, 1, 1, 10, 31, 24, 12, 9, 7, 4, 2, 1, 1, 0, 1], 0.5, 4, 1, 5], [3.5, 0.24]], ['coda 19', [[1, 1, 11, 33, 16, 12, 6, 3, 2, 1], 2.0, 2, 3, 120], [8.0, 1.36]], ['quiet gap before S peak', [[0, 0, 3, 1, 60, 30, 10, 2, 1], 1.0, 2, 1, 20], [5.0, 0.6]], ['emergent onset lull', [[1, 0, 8, 2, 4, 90, 50, 20, 6, 2], 0.5, 2, 1, 60], [3.5, 0.43]]], [['coda 21', [[0, 1, 0, 8, 26, 18, 10, 6, 3, 2, 1], 0.5, 3, 1, 5], [3.0, 0.1]], ['coda 22', [[1, 1, 0, 0, 1, 23, 69, 34, 23, 13, 9, 5, 4, 3, 2, 1, 1, 0], 0.5, 5, 1, 5], [4.5, 0.45]], ['coda 23', [[0, 2, 0, 2, 1, 16, 48, 28, 19, 15, 9, 4, 3, 1, 1, 2], 1.0, 5, 2, 30], [6.0, 0.79]], ['coda 24', [[1, 0, 1, 1, 0, 11, 35, 24, 19, 15, 9, 7, 5, 3, 2, 1, 1, 1, 0], 2.0, 5, 1, 120], [18.0, 2.06]], ['coda 25', [[1, 0, 12, 36, 18, 14, 8, 4, 3, 1, 1, 1], 1.0, 2, 2, 30], [5.0, 0.63]], ['coda 26', [[0, 0, 1, 11, 34, 17, 11, 7, 3, 1], 2.0, 3, 1, 120], [12.0, 1.71]], ['coda 27', [[1, 1, 0, 8, 24, 16, 9, 5, 3, 1], 2.0, 3, 1, 120], [12.0, 1.71]], ['emergent onset lull', [[1, 0, 8, 2, 4, 90, 50, 20, 6, 2], 0.5, 2, 1, 60], [3.5, 0.43]]], [['coda 27', [[1, 1, 0, 8, 24, 16, 9, 5, 3, 1], 2.0, 3, 1, 120], [12.0, 1.71]], ['coda 28', [[1, 2, 3, 7, 21, 16, 12, 9, 5, 3, 1, 0, 0], 0.5, 3, 3, 5], [2.5, -0.06]], ['coda 29', [[0, 0, 1, 17, 53, 42, 33, 16, 12, 9, 6, 3, 2, 1], 2.0, 3, 1, 120], [18.0, 2.06]], ['coda 30', [[2, 2, 0, 1, 2, 19, 58, 34, 27, 16, 11, 7, 5, 4, 2, 1], 2.0, 5, 2, 120], [16.0, 1.96]], ['coda 31', [[2, 3, 1, 19, 59, 47, 23, 13, 10, 6, 3, 0, 1, 3], 0.5, 3, 3, 5], [3.0, 0.1]], ['coda 32', [[1, 0, 12, 38, 26, 15, 9, 4, 3, 2, 1], 0.5, 2, 2, 5], [2.5, -0.06]], ['coda 33', [[2, 0, 11, 34, 23, 16, 8, 4, 2, 1, 0, 3], 2.0, 2, 3, 120], [10.0, 1.55]], ['quiet gap before S peak', [[0, 0, 3, 1, 60, 30, 10, 2, 1], 1.0, 2, 1, 20], [5.0, 0.6]]]]
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
coda 0[7.0, 0.93][7.0, 0.93]Passed
coda 1[4.0, 0.35][4.0, 0.35]Passed
coda 2[3.5, 0.24][3.5, 0.24]Passed
coda 3[4.0, 0.35][4.0, 0.35]Passed
coda 4[3.5, 0.24][3.5, 0.24]Passed
coda 5[14.0, 1.84][14.0, 1.84]Passed
coda 27[12.0, 1.71][12.0, 1.71]Passed
quiet gap before S peak[5.0, 0.6][5.0, 0.6]Passed

SHA-256 / fa676eee5cffc54a8f6a0d50cf15bd663936d7509f98acc7c94308b080160d8c

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

Case digest / ea2274a610b90f6eb1acbca232cb53b2c79e66cc4772699debe2712f953e6e30