EQTransformer: a multi-task detector and P/S picker for seismic waveforms
EQTransformer, a python package for earthquake signal detection and phase picking using AI.
At a glance
- What is it?
- EQTransformer is an MIT-licensed Python package that runs earthquake detection and phase picking in one pass over three-component waveforms, with pre-trained models, uncertainty estimates and a basic associator. It is a strong fit for catalog building on continuous data, provided you pin your Python and TensorFlow versions and understand which of the two released models you are running.
- Who is it for?
- Adopt EQTransformer if you are building an earthquake catalog from continuous three-component records and can commit to Python 3.6 or 3.7 with the matching TensorFlow build. Do not adopt it if you need a maintained dependency stack, a large contributor base, or an end-to-end location workflow, because the repository is a single-developer project and the README points elsewhere for phase association beyond a simple implementation.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 155 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The picking bottleneck EQTransformer was built to remove
Classical seismic phase picking is a per-trace, per-arrival task. An analyst or a short-term-average/long-term-average detector scans a waveform, decides whether something is an event, then marks the P and S onsets. On a regional network producing years of continuous three-component data, that work does not scale, and the two decisions (is there an event, where are the phases) are usually made by separate tools with separate tuning.
EQTransformer collapses those into one model pass. The README describes it as "an AI-based earthquake signal detector and phase (P&S) picker based on a deep neural network with an attention mechanism", with a hierarchical architecture "specifically designed for earthquake signals", trained on global seismic data, performing detection and arrival time picking "simultaneously". The intended user is a seismologist or observatory engineer who has continuous waveforms and wants a catalog, not a machine learning researcher. The package ships modules for downloading continuous data, preprocessing, detection and picking with pre-trained models, building and testing new models, and a simple phase association step, so the workflow from raw archive to associated picks sits inside one Python install.
Hierarchical attention over three-component windows
The architecture detail that matters operationally is the hierarchy. Rather than treating a three-component record as three independent channels, the model is organised to combine information across components, which is what makes a single-pass P and S decision plausible: S arrivals are often clearer on the transverse component while P is clearer on vertical. The attention mechanism sits inside that hierarchy, and the README states the network produces prediction probabilities plus estimated model uncertainties. Those uncertainties are the part most users underuse. They are not a confidence score bolted on afterwards; they come from the model itself and can be carried into downstream association as weights.
Two pre-trained models are distributed. The README is explicit that the difference is not architectural: "only 1 or 2 layers" separate them, and the real divergence is "the training procedure and the hyperparameters used for data augmentation during the training". The original model was optimised to minimise the false negative rate, so it detects more events and produces more false positives. The conservative model was optimised to minimise the false positive rate. That single sentence changes how you deploy the package, because the two models are not interchangeable at the same threshold.
Thresholds and window overlap decide your catalog
The README gives concrete numbers, and they are the most useful operational content in the repository. For the original model, it suggests "higher threshold values (~ 0.3 for P and S and 0.5 for detection)". For the conservative model, it says to use "a much lower threshold levels (0.03 for P and S)". A factor of ten between the two models on the same probability output is a strong hint that the output distributions are calibrated differently. If you swap models without swapping thresholds, you will either flood your catalog or empty it, and neither failure will look like a bug in the code.
The second knob is the moving window. EQTransformer processes continuous data in overlapping windows, and the README addresses one specific symptom: "If you feel some larger events are missed while smaller ones are detected", use a larger overlapping value, with 0.9 given as an example. The reasoning is not spelled out in the README, but the symptom is recognisable: a large event spans more than one window, and if the overlap is small, the portion of the waveform containing the onset may fall near a window edge where the model has less context. This is a tuning loop you have to run against your own data, because the right overlap depends on your dominant event duration and sampling rate.
For catalog building specifically, the README offers two recipes. Use the original model for detection and picking, then run a cross-correlation-based relocation at the end to clean up false positives. Or use the conservative model's detections as template events and run complementary template matching to find the rest. Both recipes accept that no single threshold gives you a clean catalog, and both push the cleanup into a separate stage.
Installing EQTransformer without fighting TensorFlow
The dependency situation is the first real constraint. The README states you need "Python 3.x (3.6 or 3.7)". That is an old ceiling, and it propagates: TensorFlow builds for 3.6 and 3.7 are themselves ageing, and on Apple silicon the README's workaround is to edit setup.py, replacing tensorflow with tensorflow-macos, then install tensorflow-deps from the apple channel before running python3 setup.py install under Python 3.10. That is a source install with a manual patch, not a supported configuration.
The recommended path is conda:
conda create -n eqt python=3.7 conda activate eqt conda install conda-forge::obspy conda install -c smousavi05 eqtransformer
The README adds a note that is worth taking literally: "sometimes you need to keep repeating executing the last line multiple time to succeed". A package manager that intermittently fails and succeeds on retry is a packaging problem, not a network problem, and it tells you the channel is not being continuously validated.
If ObsPy is already present, PyPI works:
pip install EQTransformer
The GitHub source is described as "modified for Tensorflow 2.5.0", so the source tree and the released package may not track the same TensorFlow version. Upgrades go through pip install EQTransformer -U. There is no configuration file, no environment variable and no model registry key documented in the README; model selection and thresholds are passed at call time in Python, which means your model choice lives in your scripts rather than in a declarative config you can diff.
When EQTransformer is the wrong tool
The most clearly documented failure mode is geographic and instrumental. The README points to QuakePhase as a package that "can be used to largely enhance the results of pre-trained EQT model for picking phases on traces recorded in epicentral distances > 100 km, different types of instruments, larger events, etc." Read that as the maintainer's own statement that the pre-trained model degrades in those conditions. If your network is sparse and most of your events sit beyond 100 km, or your stations are not the broadband sensors the training data favoured, you are running a model outside its design envelope and the README says so by pointing you at a different package.
The second boundary is maintenance. The repository is developed by one person, S. Mostafa Mousavi, and the README's contributing section is a heading with no described process. There is no release history in the supplied material, so there is nothing to indicate how often the pre-trained weights are revisited or how regressions would be caught. For a research group producing a catalog for a paper, that is acceptable. For an observatory that needs the picking service to come up every morning for the next five years, a Python 3.7 ceiling on a single-maintainer package is a staffing risk.
The third boundary is scope. The package includes "a simple phase association", and the word simple is doing work. If you need a full location and magnitude pipeline, EQTransformer gives you picks and probabilities and expects you to hand them to something else. It is a front end, not a catalog system.
SeisBench, and what a different design buys you
The obvious alternative in this space is SeisBench, which takes the opposite approach to packaging. Where EQTransformer ships one package with one architecture, two pre-trained weight sets and its own data-download and preprocessing modules, SeisBench is built as a common interface over multiple picking and detection models, with a shared data format and a shared evaluation harness. The practical difference is in what you can compare. With EQTransformer, evaluating the original against the conservative model means writing your own scoring loop. With a model-agnostic framework, the same evaluation code runs against several architectures, which matters when you are choosing a picker for a new network rather than reusing one you already trust.
The trade-off runs the other way too. EQTransformer's hierarchy and its uncertainty output are specific to this model, and a generic framework has to expose them through a common interface, which tends to flatten model-specific behaviour. If you have already decided on this architecture, the extra abstraction is overhead. The README also lists two community projects aimed at the same gap from a different angle: Blocky Earthquake Transformer, a no-code interface for fine-tuning EqT on regional data, and Siamese Earthquake Transformer. Both exist because the pre-trained global model is a starting point, not a finished regional picker.
Licence, upkeep and what to verify before you commit
The package is MIT-licensed, which is permissive: you can use it commercially, modify it and redistribute it, provided the copyright notice and permission notice travel with it. The pre-trained model weights are distributed through the same package, and the README does not state a separate licence for them, so if you plan to redistribute a fine-tuned derivative, confirm the weight licensing with the author rather than assuming MIT covers the weights. This is not legal advice; it is a gap in the documentation you should close before shipping a product on top of it.
Upgrade cost is dominated by the Python and TensorFlow pin. Every upgrade of EQTransformer pulls against a dependency tree that wants to move forward while the package wants to stay on 3.6 or 3.7. Budget for a frozen environment per project, and treat the conda channel's intermittent install failures as a known cost rather than a transient glitch. If you need newer Python, the only documented route is the source install with a patched setup.py, which you then own.
Before running on production data, verify three things. First, which model you actually loaded, since the original and conservative models use thresholds roughly ten times apart. Second, the TensorFlow version your install path resolved to, because the source tree is documented as targeting 2.5.0 while the PyPI package may differ. Third, your moving-window overlap against a few known large events, using the README's own diagnostic: if large events are missed while small ones are detected, raise the overlap toward 0.9 and re-run before concluding the model is at fault.
Editorial conclusion
Adopt EQTransformer if you are building an earthquake catalog from continuous three-component records and can commit to Python 3.6 or 3.7 with the matching TensorFlow build. Do not adopt it if you need a maintained dependency stack, a large contributor base, or an end-to-end location workflow, because the repository is a single-developer project and the README points elsewhere for phase association beyond a simple implementation. Before running anything on your own data, verify which pre-trained model you loaded, since the original and conservative models use different thresholds, and confirm the TensorFlow version that your install path actually pulled in.
Community notes