Real-time seismic P-wave detector using a streaming neural network ensemble, deployed to seismic.fib896.com.
A 3-seed ensemble of StreamingNet models (1D CNN + orbit-permuted Hebbian buffer) listens to live SeedLink feeds from GEOFON and supplementary networks. When N_CONSENSUS stations independently fire within a 60-second window, a detection is logged. Epicenters are estimated via a flat-earth P-wave arrival time inversion (Nelder-Mead). Detections are cross-checked against USGS and EMSC earthquake catalogs.
SeedLink stream → normalize → StreamingNet × 3 seeds → ensemble vote
→ consensus across stations → epicenter localization → catalog lookup → dashboard
StreamingNet — 3-channel 1D CNN with an orbit-permuted Hebbian buffer:
Input: (3, 100) — 3-component seismogram, 1 second at 100 Hz
→ ConvBlock(3→32) → ConvBlock(32→64) → ConvBlock(64→128) → AdaptiveAvgPool
→ orbit-permuted Hebbian buffer (CYCLES=1, DECAY=0.876, STRENGTH=1.429)
→ Linear(128, 2) — seismic / noise classifier
→ Linear(128, 1) — magnitude estimator
The buffer permutation is seeded per ensemble member, diversifying the feature basis across seeds. Pre-trained on the STEAD dataset (chunk2) with magnitude-stratified sampling, then fine-tuned on station-collected regional data.
Performance (STEAD holdout, threshold=0.835): 88.0% precision / 95.7% recall
Performance (after regional fine-tune, eval split): 94.4% / 93.2% / 93.2% precision across seeds, mean F1 = 0.919
| Network | Code | Location |
|---|---|---|
| GE | APE | Aegean, Greece |
| GE | MORC | Morava, Czech Republic |
| GE | KBS | Svalbard, Norway |
| GE | WLF | Walferdange, Luxembourg |
| GE | MATE | Matera, Italy |
| GE | KARP | Karpathos, Greece |
| CX | PSGCX | Paso Grande, Chile |
| CX | HMBCX | Humberstone, Chile |
| DK | GDH | Godhavn, Greenland |
| DK | SCO | Scoresbysund, Greenland |
Primary streams via geofon.gfz-potsdam.de:18000 (GEOFON).
IRIS note: rtserve.iris.washington.edu:18000 was upgraded to RingServer/4.5.6 (SeedLink v4.0 protocol) in 2026. obspy EasySeedLinkClient (v3.1) is incompatible — station SELECT and DATA commands are rejected. IRIS stations (IRIS_STATIONS in fly.toml) currently do not stream successfully; set to empty if you want a clean log.
# Deploy to Fly.io (requires fly CLI + authenticated account)
make deploy
# Force full rebuild (e.g. after Dockerfile changes)
make deploy-clean
# Tail live logs
make fly-logsRequires STEAD chunk2:
wget -c 'https://zenodo.org/records/3911667/files/chunk2.hdf5'
wget -c 'https://zenodo.org/records/3911667/files/chunk2.csv'
pip install torch numpy h5py scipy scikit-learn tqdm pandas
python train.py --data /data/training --checkpoints checkpoints/ --epochs 30GPU strongly recommended. CPU training for 3 seeds × 30 epochs takes several hours.
collect_regional.py fetches P-wave windows for M5.5+ events at Pacific/Australian stations (IU.NWAO, II.WRAB, IU.MAJO, IU.SNZO) via IRIS FDSN, using IASP91 travel times to window around the P arrival:
python collect_regional.py # saves .npz files to ./training/Then fine-tune the existing ensemble on the collected windows:
python train.py --data training --checkpoints checkpoints --epochs 30 --lr 1e-4
# checkpoints/seed_{n}_pretrain.pt backups are written before overwritingFine-tuning uses a two-phase schedule: classifier head only for the first half of epochs (higher LR), then all layers unfrozen at 10× lower LR. A class-balanced weighted sampler handles imbalanced positive/negative ratios.
cp .env.example .env
# edit .env — set SEEDLINK_SERVER, STATIONS, etc.
make dev # starts via docker compose
make logs # tail logs
make shell # bash into containerAll parameters are set via environment variables (see fly.toml and .env.example):
| Variable | Default | Description |
|---|---|---|
SEEDLINK_SERVER |
geofon.gfz-potsdam.de:18000 |
Primary SeedLink server |
IRIS_SERVER |
rtserve.iris.washington.edu:18000 |
Secondary SeedLink server (see IRIS note above) |
STATIONS |
GE.APE,... |
Comma-separated station list for primary server |
IRIS_STATIONS |
IU.COR,... |
Comma-separated station list for secondary server |
CHANNELS |
HHZ,HHN,HHE |
Seismic channels |
THRESHOLD |
0.835 |
Detection confidence threshold |
N_CONSENSUS |
4 |
Stations required to confirm a detection |
CONSENSUS_WINDOW |
60 |
Seconds within which consensus must occur |
N_SEEDS |
3 |
Ensemble size |
STALTA_ON |
1 |
Enable STA/LTA pre-filter (blocks low-energy noise) |
STALTA_SHORT_S |
0.5 |
STA window length (seconds) |
STALTA_LONG_S |
10.0 |
LTA window length (seconds) |
STALTA_THRESH |
2.5 |
Minimum STA/LTA ratio to pass to consensus |
AGPL-3.0-or-later — see LICENSE