TerraSignalEARTH SYSTEMS MONITOR
LIVE
--:--:-- UTC
// METHODOLOGY · ANOMALY INDEX
docMETHODS · v1
How the Anomaly Index is computed, what it sources, and what each component does and does not claim.
connecting…

The math behind the score

The TerraSignal Anomaly Index is a weighted 0 – 100 score combining five independent geophysical streams. The five components and their weights are derived from the precursor framework described by The Ethical Skeptic (ECDO / Dzhanibekov hypothesis); the scoring math is ours.

Not a prediction. Not peer-reviewed. Not a forecast. Every component is implemented in the Python files cited below — clone the repo and re-derive any value on this page.

// HOW TO READ A COMPOSITE SCORE
NOMINAL
0 – 24
Indicators within historical norms. No coordinated anomaly.
ELEVATED
25 – 49
One or more streams above typical range. Worth watching.
WARNING
50 – 74
Multiple streams elevated or accelerating simultaneously.
CRITICAL
75 – 100
Late-stage pattern: high coherence across independent streams.
01

MAGNETIC WEAKENING

30 PTS MAX

Total-field decline vs IGRF-2020, averaged across 16 INTERMAGNET observatories, with an acceleration bonus.

DATA SOURCE
  • 16 observatories (BOU, FRN, TUC, HON, SJG, NGK, WNG, CLF, KAK, MMB, HER, EYR, KDU, LRM, CMO, DED). Hourly cadence; canonical_only=True so only INTERMAGNET-provided rows enter the index.
  • Relay endpoint used by the magnetic collector.
  • Baseline reference field. Per-observatory expected total-field intensity at observatory coordinates.
COMPUTATION
  1. 1For each observatory and day, compute relative deviation: (current_F − baseline_F) / baseline_F × 100.
  2. 2Average those per-observatory percentages into a single daily weakening_index_pct (sparse-day floor: ≥ MIN_OBSERVATORIES_PER_DAY contributing).
  3. 3Compute 30-day and 90-day rates of change (%/day) from the weakening_index_pct timeseries.
  4. 4Flag accelerating when the 30-day rate is more negative than 1.5× the 90-day rate.
weakening_index_pct = mean_obs( (Fₜ − F_IGRF) / F_IGRF × 100 )
implutils/weakening_index.py + utils/threat_index.py::score_magnetic_weakening
SCORING
|pct| < 1%0 pts
1% ≤ |pct| < 3%0 – 15 pts (linear)
3% ≤ |pct| < 6%15 – 25 pts (linear)
|pct| ≥ 6%25 – 30 pts (capped)
+ accelerating (30d < 1.5× 90d)+ 5 pts
LIVE READING
Connecting to /api/threat-index…
does notDoes not predict reversal. Single-day low values may reflect sparse observatory days, not real drops — see sparse-day floor in utils/weakening_index.py.
02

ABYSSAL OCEAN HEATING

25 PTS MAX

Consensus warming across individual Argo floats below 4300 m, plus a magnitude bonus when median rates exceed historical norms.

DATA SOURCE
  • Per-float profile + metadata API (>4300 m depth filter). Daily cadence; per-float 365-day temperature trends written to derived_metrics.
  • Source program for the global float fleet.
COMPUTATION
  1. 1For each tracked float, regress 365 days of >4300 m temperature → slope (°C/yr).
  2. 2Aggregate to a daily consensus_pct: percentage of floats with positive trend (warming).
  3. 3Compute median warming rate across the warming subset.
implutils/abyssal_trends.py + utils/threat_index.py::score_abyssal_heating
SCORING
consensus < 60%0 pts
60% ≤ consensus < 75%0 – 8 pts (linear)
75% ≤ consensus < 90%8 – 15 pts (linear)
consensus ≥ 90%15 – 20 pts (linear)
+ median rate > 0.01 °C/yr+ up to 5 pts (cap 25)
LIVE READING
Connecting to /api/threat-index…
does notDoes not attribute cause. Surface-driven warming, deep-ocean mixing, and crustal heat flux all show here — separating them is not in scope.
03

SEISMIC CLUSTERING

20 PTS MAX

Simultaneous M6+/M7+ activity across geographically unrelated regions, with a deep-mantle (>300 km) bonus.

DATA SOURCE
  • Rolling-window event queries (m6plus_count_7d, m7plus_count_7d, active_regions_count, deep_mantle_count_7d). 15-minute collector cadence.
COMPUTATION
  1. 1Count distinct M6+ and M7+ events over a rolling 7-day window.
  2. 2Count distinct active regions (a coarse simultaneous-activation proxy).
  3. 3Count deep-mantle events (>300 km hypocentral depth) over the same window.
  4. 4Freshness gate: if every count is empty or the latest row is > 6 h old, score 0 with stale=true so the consumer can flag the dead feed.
implutils/threat_index.py::score_seismic_clustering
SCORING
M6+ count / 7dmin( max(0, n − 4) / 4 × 8, 8 ) pts
+ M7+ count / 7d+ min(n × 2, 4) pts
+ Active regions+ min( max(0, r − 2) / 3 × 8, 8 ) pts
+ Deep-mantle (>300 km)+ min(d / 3 × 4, 4) pts
Total cap20 pts
LIVE READING
Connecting to /api/threat-index…
does notDoes not infer mechanism. M6 vs. M7+ clustering is a statistical signal, not a tectonic identification — and aftershock sequences in one region can inflate counts.
04

GEC / Kp SUSTAINED ANOMALY

15 PTS MAX

Sustained space-weather activity — 30-day average Kp, sustained X-ray, Dst excursion, and elevated F10.7 solar flux.

DATA SOURCE
  • Canonical Kp source. Daily-archive fallback to NOAA when the GFZ nowcast file goes silent.
  • Real-time Kp + GOES X-ray flux + F10.7 solar flux feeds.
  • Canonical Dst; NOAA relays as fallback.
  • World Data Center for sunspot number (NOAA SESC as fallback).
COMPUTATION
  1. 1Kp: 30-day average over real-time Kp readings (falls back to daily-average archive if real-time is sparse).
  2. 2X-ray: 30-day average of GOES X-ray flux (W/m²); elevated when log₁₀(avg) > −7.
  3. 3Dst: 7-day minimum (the most negative excursion).
  4. 4F10.7: 30-day average solar radio flux at 10.7 cm.
implutils/threat_index.py::score_gec_anomaly
SCORING
Sustained Kp (30d avg > 2.0)min( (avg − 2.0) / 3.0 × 5, 5 ) pts
Sustained X-ray (log avg > −7)0 – 3 pts (capped)
Dst excursion (min < −30 nT)min( |min − 30| / 170 × 4, 4 ) pts
F10.7 elevated (avg > 100)min( (avg − 100) / 100 × 3, 3 ) pts
Total cap15 pts
LIVE READING
Connecting to /api/threat-index…
does notSolar — not terrestrial — driven. High scores during the solar cycle peak are baseline behavior, not anomalies vs the 11-year cycle.
05

MAGNETIC POLE DRIFT RATE

10 PTS MAX

Great-circle velocity of the north magnetic pole vs its pre-2000 baseline, with an acceleration bonus.

DATA SOURCE
  • gufm1 historical model snapshots, 1900 – 1980. Provides the pre-2000 baseline interval.
  • Most-recent generation, retrospectively revised. Snapshots from 1981 through 2020.
  • Official 2020.0+ snapshots, including the 2022.5 / 2023.5 / 2024.5 / 2025.0 quarterly points used for the recent-rate window.
COMPUTATION
  1. 1POLE_POSITIONS table holds (year, lat, lon) snapshots end-to-end across NCEI + IGRF + WMM2025.
  2. 2Interpolate to yearly resolution (linear in lat, antimeridian-aware in lon).
  3. 3Compute haversine great-circle distance between consecutive years → km/yr velocity.
  4. 4Recent rate = mean velocity of intervals starting ≥ 2015.
  5. 5Historical rate = mean velocity of intervals starting < 2000.
v_yr = 2R · arcsin( √( sin²(Δφ/2) + cos φ₁ cos φ₂ sin²(Δλ/2) ) )
implutils/pole_velocity.py + utils/threat_index.py::score_pole_drift
SCORING
recent < 30 km/yr0 pts
30 ≤ recent < 50 km/yr0 – 3 pts (linear)
50 ≤ recent < 70 km/yr3 – 7 pts (linear)
recent ≥ 70 km/yr7 – 10 pts (capped)
+ recent > 2× historical baseline+ 2 pts (cap 10)
LIVE READING
Connecting to /api/threat-index…
does notDoes not predict earthquakes. Does not measure the rotation axis (see /axis). Pole drift is a magnetic-field quantity, not a mechanical one.
LINEAGE & SCOPE
Framework

The five-component decomposition derives from the Exothermic Core-Mantle Decoupling — Dzhanibekov Oscillation (ECDO) precursor model described by The Ethical Skeptic. The choice of streams (magnetic, abyssal, seismic, GEC, pole drift) and rough weight ordering reflects that framework. The scoring math, thresholds, and acceleration bonuses are TerraSignal's implementation — see each section's impl reference.

What this index is

A weighted statistical summary of five independent geophysical streams. Updates after every collector cycle (15 min – daily depending on the stream). Designed to surface coherent multi-stream anomaly, not to predict any specific event.

What it is not

Not a prediction. Not a forecast. Not peer-reviewed. Not validated against ground-truth events at statistical-significance levels. High scores are an invitation to look at the components — not to act on them.

Find a flaw in the methodology? @TerraSignalIO · Reproducibility is the point of this page.