Bayesian Earthquake Location with a Neural Travel-Time Surrogate
February 21, 2026 · View on GitHub
Bayesian Earthquake Location with a Neural Travel-Time Surrogate
Code for:
“Bayesian Earthquake Location with a Neural Travel-Time Surrogate: Fast, Robust, and Fully Probabilistic Inference in 3-D Media”
Yu Ziye et al., 2025
arXiv: 2512.06407
Also related (under submission):
“Toward Trustworthy Earthquake Catalogs in the Era of Automated Detection: A Probabilistic Framework for Robust Earthquake Location”
Copyright: © 2025, yuziye@cea-igp.ac.cn. All rights reserved.
1. Overview
This repository contains a reference implementation of the Bayesian earthquake-location framework described in the paper:
Bayesian Earthquake Location with a Neural Travel-Time Surrogate: Fast, Robust, and Fully Probabilistic Inference in 3-D Media (arXiv:2512.06407).
The key idea is to replace numerical ray tracing in a 3-D heterogeneous velocity model with a neural travel-time surrogate, and to embed this fast forward model inside a Bayesian sampler. This yields:
- Fast: orders-of-magnitude speedup in forward evaluations.
- Robust: optional heavy-tailed, Student-t-like modeling of outliers.
- Fully probabilistic: full posterior samples of hypocenter, origin time, and phase-specific uncertainties.
This code focuses on 3-D regional earthquake location using P and S first-arrival times, with:
- A pre-trained neural travel-time model
PINNTravelTime. - A multi-event Gibbs + random-walk Metropolis–Hastings sampler.
- Support for missing phases and per-event noise variances.
- Optional GMM-based spatial prior (through
make_log_prior_xs).
2. Repository Naming Conventions and Key Scripts
This repository uses filename prefixes and suffixes to indicate task types and dataset/model variants:
-
location*: earthquake location programs..crop: processing raw, unassociated picks.synth: synthetic-data experiments.real: real-data experiments.pnsn: travel-time model configured to handle four phase labels: Pn, Sn, Pg, Sg.
-
travel_time*: scripts for training/evaluating travel-time surrogate models..pinn: PINN-based travel-time model training/testing..real: workflows using real datasets.
-
scripts/: data-generation and preprocessing utilities.gen_data_v5*variants generate different datasets:gen_data_v5.forloc.py: data for location workflows.gen_data_v5.fortest.py: data for travel-time model testing.gen_data_v5.fortrain.py: data for model training.
- Velocity models are generated from
scripts/run_nonlinloc/, which contains a six-step NonLinLoc pipeline (step1.pytostep6.export_hyp_catalog.py).
3. Main Script and Functionality
The main script is:
bayes_location.py
Core components:
-
Neural travel-time surrogate
PINNTravelTimeloaded fromckpt/travel_time.ps.v2.pth.- Evaluated via:
Returns predictedforward_tps(xs: Tensor, xr: Tensor) -> Tensor forward_tps_multi(xs_batch: Tensor, xr: Tensor, event_ids: Tensor) -> Tensor(Tp, Ts)for arbitrary source–receiver combinations in a 3-D velocity model.
-
Likelihood and masking
- Supports missing data using a special value:
MISSING_VAL = -12345.0 - Masks P/S observations event-by-event:
build_phase_masks(...) log_lik_per_event(...)
- Supports missing data using a special value:
-
Bayesian sampler
- Main entry point:
gibbs_mh_location_multi(...) - For NC events and N total observations, jointly samples:
- Source locations:
xs ∈ ℝ^{NC×3} - Origin times:
t0 ∈ ℝ^{NC} - Phase standard deviations:
σ_P,σ_Sper event
- Source locations:
- Uses:
- Random-walk Metropolis–Hastings in location space.
- Gibbs updates for
t0,σ_P²,σ_S²(Inverse-Gamma priors). - Optional Student-t scale-mixture via per-observation latent weights
λ.
- Main entry point:
-
Prior on locations
make_log_prior_xs(...)supports:- Wide 3-D Gaussian prior.
- Optional GMM-based prior (if a GMM is fitted externally and passed in).
- Or a mixture of both.
-
Input / output wrapper
read_station_file(...)parses station metadata.read_event_file(...)parses an event catalog with phases.- The
__main__block:- Reads events and stations.
- Builds the concatenated vectors
Tp_obs,Ts_obs,xr, andevent_ids. - Runs the sampler.
- Writes relocated results and uncertainties to:
odata/reloc.raw.v3.2.txt
4. Data and File Structure
The example script expects the following files:
-
Neural travel-time model checkpoint
ckpt/travel_time.ps.v2.pth
Pre-trainedPINNTravelTimemodel (PyTorch) for the target 3-D velocity model.
-
Velocity model & projection
data/vel.py.model
A pickle file containing:grid_vp, grid_vs, grid_x, grid_y, grid_z, proj, *rest = pickle.load(...)proj: a cartographic projection object with a callable interface:x, y = proj(lon, lat)lon, lat = proj(x, y, inverse=True)
-
Station file
ayrdata/china.loc
Plain-text file with (per line, whitespace-separated):
Example:NETWORK STATION_CODE NETWORK_ID LON LAT ELEV(m) ...
The reader builds a station dictionary:SC JLO 0001 101.8684 29.8570 1234 ...stations["SCJLO"] = np.array([lon, lat, -elev_km])
-
Event / phase file
data/Real.txt
A NLLoc-style catalog with:- Header lines starting with an integer event ID, followed by:
- Origin time (year, month, day, hour, minute, second)
- Julian day or base time
- Hypocenter (lat, lon, depth)
- Magnitudes, etc.
- Followed by phase lines:
NET STATION PHASE TRAVELTIME WEIGHT ...
- Header lines starting with an integer event ID, followed by:
The parser:
- Extracts event origin time, latitude, longitude, depth, and magnitudes.
- For each event:
- Builds a receiver array
rcvwith 3-D projected station coordinates. - Fills
T_p,T_svectors with P/S travel times, usingMISSING_VALfor missing phases.
- Builds a receiver array
5. Installation and Requirements
5.1. Dependencies
- Python 3.9+ (recommended)
- PyTorch (CPU or GPU)
- NumPy
- tqdm (for progress bars)
- Your own projection object (e.g.
pyproj) insidevel.py.model
Install the basic dependencies with:
pip install torch numpy tqdm
(You may need a specific PyTorch build for CUDA / MPS depending on your hardware.)
5.2. Clone and setup
git clone <this-repo-url>.git
cd <this-repo-name>
Place or link the required data:
ckpt/travel_time.ps.v2.pth
data/vel.py.model
data/Real.txt
ayrdata/china.loc
6. Quick Start
Once all required files are in place, simply run:
python bayes_location.py
The script will:
-
Read the velocity model and projection from
data/vel.py.model. -
Read stations from
ayrdata/china.loc. -
Read and parse events and phases from
data/Real.txt. -
Construct concatenated arrays
Tp_obs,Ts_obs,xr, andevent_ids. -
Run the multi-event Gibbs+MH sampler:
out = gibbs_mh_location_multi( Tp_obs, Ts_obs, xr, event_ids=event_ids, NC=num_events, n_samples=4000, burn=2000, thin=2, gmm_prior=None, prior_mix=None, prop_scale=2.0, device_=device, dtype=dtype, verbose=True, alpha0=alpha0, beta0=beta0, use_student_t=False, # set True to enable heavy-tailed likelihood ) -
Save relocated events and uncertainties to:
odata/reloc.raw.v3.2.txt
6. Output Format
The main output file:
odata/reloc.raw.v3.2.txt
For each event, the script writes:
-
A summary header line:
#EVENT,<origin_time_with_t0_correction>,<lon>,<lat>,<depth>, <x>,<y>,<z>, <std_x>,<std_y>,<std_z>, <IQR_x>,<IQR_y>,<IQR_z>Where:
<origin_time_with_t0_correction>= catalog origin time + posterior meant0.<x>,<y>,<z>= posterior mean source location in projected coordinates.<std_*>= posterior standard deviation of each coordinate.<IQR_*>= width of the 5–95% interval for each coordinate.
-
The original catalog location (for comparison):
<x_cat>,<y_cat>,<z_cat>,<lon_cat>,<lat_cat>,<z_cat>,<mag1>,<mag2> -
95% credible intervals for each coordinate:
x: [lo_x, hi_x], range: hi_x - lo_x y: [lo_y, hi_y], range: hi_y - hi_y z: [lo_z, hi_z], range: hi_z - lo_z
This file can be post-processed to:
- Plot posterior clouds and credible ellipsoids.
- Compare Bayesian locations and catalog locations.
- Compute magnitude-dependent error statistics, etc.
7. Advanced Options
You can customize:
-
Number of samples / burn-in / thinning
n_samples=4000, burn=2000, thin=2 -
Student-t robustness
- Set
use_student_t=Trueto activate the scale-mixture updates for per-observationλ, down-weighting outliers.
- Set
-
Location prior
-
Use a wide Gaussian only:
gmm_prior=None prior_mix=None wide_sigma=1000.0 # km in projected coordinates -
Or include a GMM prior (fitted externally from a catalog) by passing a dictionary:
gmm_prior = { "w": ..., # (K,) "mu": ..., # (K,3) "L": ..., # (K,3,3) Cholesky factors "log_det": ..., # (K,) } prior_mix = 0.5
-
-
RW step-size adaptation
-
Controlled by:
adapt_steps=1000 target_accept_rw=0.3 adapt_eta=0.05 prop_scale=2.0
-
8. Citation
If you use this code or ideas from this work in your research, please cite:
@article{Yu2025BayesNeuralTTLocation,
title = {Bayesian Earthquake Location with a Neural Travel-Time Surrogate: Fast, Robust, and Fully Probabilistic Inference in 3-D Media},
author = {Yu, Ziye and coauthors},
journal = {arXiv preprint},
eprint = {2512.06407},
archivePrefix = {arXiv},
primaryClass = {physics.geo-ph},
year = {2025}
}
9. License and Copyright
All code in this repository is provided for research use only unless otherwise stated.
- Copyright: © 2025, Yu Ziye (yuziye@cea-igp.ac.cn). All rights reserved.
Please contact the author for questions about licensing, redistribution, or commercial use.
10. Contact
For questions, bug reports, or collaboration inquiries, please contact:
- Email: yuziye@cea-igp.ac.cn
- Affiliation: Institute of Geophysics, China Earthquake Administration (CEA-IGP)
::contentReference[oaicite:0]{index=0}