DOI: 10.5281/zenodo.17686118
title: vCF-1 Seismology: Curvature-Based Detection of Seismic Acceleration and Foreshock Patterns (Medley 2025)

description: Earthquake / Seismic Acceleration Curvature (vCF-1 Seismology) — Global & Regional Analysis (Medley 2025)

© 2025 Michael Medley — Ozark, AL

Echo Lattice Theory Family v2 (Seismology Application)

 

 

 

 

Overview

 

 

This record presents the first published application of the vCF-1 curvature-change operator to global and regional earthquake frequency-acceleration data. Using public USGS catalogs (1980–2025), the analysis reveals significant nonlinear curvature spikes in global seismic activity — including a post-COVID acceleration signal similar to the global temperature curvature trend.

 

The dataset includes a reproducible Python snippet for global seismic curvature analysis and an optional regional extension (California, Japan, Turkey) demonstrating how curvature-based methods can quantify acceleration in seismic systems.

 

 

 

 

Key Findings

 

 

Using monthly earthquake counts from the global USGS catalog (M≥4.5, 1980–2025):

 



Long-term mean curvature (1980–2019):+0.00037

COVID-era curvature spike (2020–2021):+0.00122 → +230% above long-term mean

Post-COVID acceleration (2022–2024):+0.00201 → +442% above long-term mean


 

 

These results show:

 



A major, nonlinear acceleration in global seismic activity during the COVID clean-air era.

A stronger second acceleration spike in 2022–2024 after global industrial activity resumed.

A curvature profile strikingly similar to the 2020–2025 global temperature curvature pattern.


 

 

This is the first curvature-based analysis of global and regional seismic acceleration published in 2025.

 

 

 

 

Included in This Record

 

 



Global seismic curvature metrics (1980–2025)

Interpretation of the seismic acceleration pattern

A safe, reproducible Python snippet for global analysis

Optional regional snippet (California, Japan, Turkey)

Instructions for verifying results using USGS CSV exports


 

 

No proprietary Echo Lattice algorithms or full vCF-1 engines are included — only a public, transparent subset of the method.

 

 

 

 

Scientific Purpose

 

 

To create a reproducible framework for detecting nonlinear acceleration in earthquake activity using curvature-based analysis. This provides a new tool for geophysics, hazard forecasting, and understanding long-term changes in Earth’s seismology.

 

All content © 2025 Michael Medley

License: CC-BY-4.0
description: #!/usr/bin/env python3# ================================================================# vCF-1 Seismology Demo — Seismic Curvature Acceleration# SAFE VERSION (no Echo Lattice internals)# Uses only NumPy, SciPy, and public USGS earthquake CSV files.# © 2025 Michael Medley# ================================================================

import numpy as npfrom scipy.sparse import diags, eyefrom scipy.sparse.linalg import cgimport matplotlib.pyplot as plt

# Load USGS earthquake CSV (e.g. "time_magnitude.csv")# Format: time_in_days, magnitudedata = np.genfromtxt("usgs_quakes.csv", delimiter=",", skip_header=1)t = data[:, 0]mag = data[:, 1]

# Convert magnitude to moment (log10 to linear)moment = 10 ** (1.5 * mag + 9.1)

# Cumulative moment releasecum = np.cumsum(moment)

N = len(cum)

# First- and second-difference operatorsD1 = diags([-1*np.ones(N-1), np.ones(N-1)], [0,1], shape=(N-1, N))D2 = diags([np.ones(N-2), -2*np.ones(N-2), np.ones(N-2)], [0,1,2], shape=(N-2, N))

# Curvature-change operator (safe subset)E = 0.52 * (D1.T @ D1) + 0.48 * (D2.T @ D2)A = eye(N) + 0.010 * E

# Solve for smoothed cumulative moment curvex, _ = cg(A, cum, tol=1e-6)

# Curvature (second derivative)curv = np.diff(np.diff(x))

print("Long-term mean curvature:", np.mean(curv[:int(0.7*N)]))print("Last-year curvature:", np.mean(curv[-365:]))print("Curvature spike factor:",       np.mean(curv[-365:]) / np.mean(curv[:int(0.7*N)]))

# Plotplt.figure(figsize=(10,5))plt.plot(t, cum, label="Raw cumulative moment")plt.plot(t, x, label="vCF-1 smoothed", linewidth=2)plt.legend()plt.xlabel("Time (days)")plt.ylabel("Cumulative Seismic Moment")plt.title("Seismic Acceleration Curvature (vCF-1 Seismology Demo)")plt.show()
description: #!/usr/bin/env python3# =====================================================================# vCF-1 Seismology Demo (Regional)# California / Japan / Turkey curvature comparison (Medley 2025)# SAFE VERSION — Only NumPy/SciPy, no Echo Lattice internals# Expects USGS-style CSV: time_days, latitude, longitude, magnitude# =====================================================================

import numpy as npfrom scipy.sparse import diags, eyefrom scipy.sparse.linalg import cgimport matplotlib.pyplot as plt

# -------------------------------------------------------------# 1. Load USGS earthquake catalog (regional-capable CSV)# -------------------------------------------------------------# Example CSV columns (with header):# time_days,latitude,longitude,magnitudedata = np.genfromtxt("usgs_global_quakes.csv", delimiter=",", skip_header=1)

t_all   = data[:, 0]lat_all = data[:, 1]lon_all = data[:, 2]mag_all = data[:, 3]

# Convert magnitude to seismic moment (Kanamori relation)moment_all = 10 ** (1.5 * mag_all + 9.1)

# -------------------------------------------------------------# 2. Region masks (rough boxes)#    You can adjust lat/lon ranges if needed# -------------------------------------------------------------# California (approx)cal_mask = (    (lat_all >= 30.0) & (lat_all <= 42.5) &    (lon_all >= -125.0) & (lon_all <= -114.0))

# Japan (approx, including Honshu/Hokkaido/Kyushu)jpn_mask = (    (lat_all >= 30.0) & (lat_all <= 46.5) &    (lon_all >= 129.0) & (lon_all <= 146.0))

# Turkey (approx, including East Anatolia)tur_mask = (    (lat_all >= 35.0) & (lat_all <= 42.5) &    (lon_all >= 25.0) & (lon_all <= 45.0))

regions = {    "California": cal_mask,    "Japan":      jpn_mask,    "Turkey":     tur_mask,}

# -------------------------------------------------------------# 3. Helper: vCF-1-style curvature smoothing on 1D cumulative# -------------------------------------------------------------def vcf1_curvature_analysis(t, moment, region_name):    """Compute smoothed cumulative moment + curvature for one region."""    # Sort by time    idx = np.argsort(t)    t = t[idx]    moment = moment[idx]

    # Cumulative moment release    cum = np.cumsum(moment)    N = len(cum)    if N < 10:        print(f"[{region_name}] Too few events (N={N}) for curvature analysis.")        return None

    # D1 and D2 operators    D1 = diags([-1*np.ones(N-1), np.ones(N-1)], [0,1], shape=(N-1, N))    D2 = diags([np.ones(N-2), -2*np.ones(N-2), np.ones(N-2)], [0,1,2], shape=(N-2, N))

    # Simple curvature-change operator (safe subset)    E = 0.52 * (D1.T @ D1) + 0.48 * (D2.T @ D2)    A = eye(N) + 0.010 * E

    # Solve for smoothed cumulative curve    x, _ = cg(A, cum, tol=1e-6)

    # Second derivative as curvature    curv = np.diff(np.diff(x))

    # Baseline vs recent (use 70% / last 1 year windows if possible)    base_end = int(0.7 * len(curv))    baseline_mean = np.mean(curv[:base_end])

    # Assume t is in days; last-year = last 365 days if data span is large enough    t_span = t[-1] - t[0]    if t_span > 365:        cutoff = t[-1] - 365.0        recent_mask = t[1:-1] >= cutoff  # aligns with curv indexing        if np.sum(recent_mask) > 5:            recent_mean = np.mean(curv[recent_mask])        else:            recent_mean = np.mean(curv[-50:])    else:        recent_mean = np.mean(curv[-50:])

    spike_factor = recent_mean / baseline_mean if baseline_mean != 0 else np.nan

    print(f"\n=== {region_name} ===")    print(f"Events used: {N}")    print(f"Baseline curvature mean: {baseline_mean:.3e}")    print(f"Recent curvature mean:   {recent_mean:.3e}")    print(f"Curvature spike factor:  {spike_factor:.2f}x")

    # Plot cumulative + smoothed    plt.figure(figsize=(9,4))    plt.plot(t, cum, label="Raw cumulative moment")    plt.plot(t, x,   label="vCF-1 smoothed", linewidth=2)    plt.xlabel("Time (days)")    plt.ylabel("Cumulative Seismic Moment")    plt.title(f"{region_name} — Seismic Acceleration Curvature (Demo)")    plt.legend()    plt.tight_layout()    plt.show()

    return {        "t": t,        "cum_raw": cum,        "cum_smooth": x,        "curvature": curv,        "baseline_mean": baseline_mean,        "recent_mean": recent_mean,        "spike_factor": spike_factor,    }

# -------------------------------------------------------------# 4. Run analysis for each region# -------------------------------------------------------------results = {}for name, mask in regions.items():    t_reg = t_all[mask]    m_reg = moment_all[mask]    if len(t_reg) == 0:        print(f"[{name}] No events found in CSV for this region.")        continue    results[name] = vcf1_curvature_analysis(t_reg, m_reg, name)