Lightweight, physics-based forward model for generating synthetic InSAR deformation data from earthquake sources
Project description
EQ-INSAR
Earthquake InSAR Synthetic Data Generator
A lightweight, physics-based forward model for generating synthetic InSAR surface deformation data from earthquake sources. Designed for machine learning training, benchmarking, and sensitivity analysis.
Features
-
Davis (1986) Point Source Model
- Fast computation for generating large training datasets
- Accurate for small-to-moderate earthquakes (Mw < 6.5)
- Suitable for far-field observations
-
InSAR-Native Outputs
- Line-of-sight (LOS) displacement
- Wrapped/unwrapped interferometric phase
-
Multiple Satellites
- Sentinel-1, ALOS-2, TerraSAR-X, COSMO-SkyMed, RADARSAT-2, NISAR, SAOCOM, ENVISAT, ICEYE
- Automatic geometry (incidence, heading, wavelength)
-
Simple Noise Models
- Gaussian random noise
- Orbital ramps
-
ML Training Ready
- Time series with pre-event/event/post-event frames
- Binary segmentation labels
- Batch generation with random parameters
-
Export Formats
- GeoTIFF (requires
rasterio) - NetCDF (requires
netCDF4)
- GeoTIFF (requires
-
Minimal Dependencies
- NumPy only for core computation
- No SciPy requirement
Requirements
- Python 3.8 or higher
- NumPy >= 1.20.0
Optional dependencies:
matplotlib>= 3.3.0 (visualization)rasterio>= 1.2.0 (GeoTIFF export)netCDF4>= 1.5.0 (NetCDF export)
Installation
From PyPI
pip install eq-insar #TODO for now please install from source
From Source
git clone https://github.com/kcieslik/eq-insar.git
cd eq-insar
pip install .
Development Installation
For development with editable install:
git clone https://github.com/kcieslik/eq-insar.git
cd eq-insar
pip install -e ".[dev]"
Optional Dependencies
Install optional features using extras:
# Visualization (matplotlib)
pip install eq-insar[viz]
# GeoTIFF export (rasterio)
pip install eq-insar[geotiff]
# NetCDF export (netCDF4)
pip install eq-insar[netcdf]
# All I/O formats (rasterio + netCDF4)
pip install eq-insar[io]
# Everything (all optional dependencies)
pip install eq-insar[all]
# Development (pytest, coverage)
pip install eq-insar[dev]
Or install individual packages manually:
pip install matplotlib # For visualization
pip install rasterio # For GeoTIFF export
pip install netCDF4 # For NetCDF export
Quick Start
Generate a Single Interferogram
from eq_insar import generate_synthetic_insar, plot_displacement_components
# Mw 6.0 thrust earthquake with Sentinel-1 geometry
result = generate_synthetic_insar(
Mw=6.0,
strike_deg=30,
dip_deg=45,
rake_deg=90, # thrust fault
depth_km=10,
satellite='sentinel1',
orbit='ascending'
)
# Access the data
los_displacement = result['los_displacement'] # (height, width) array
wrapped_phase = result['wrapped_phase'] # (height, width) array
unwrapped_phase = result['unwrapped_phase'] # (height, width) array
# Visualize (requires matplotlib)
fig = plot_displacement_components(result)
Generate Time Series for ML Training
from eq_insar import generate_timeseries
result = generate_timeseries(
Mw=6.0,
satellite='sentinel1',
n_pre=5, # pre-event frames (noise only)
n_event=1, # event frames (signal + noise)
n_post=5 # post-event frames (noise only)
)
# Access data
X = result['timeseries'] # (11, height, width)
y = result['labels'] # binary segmentation masks
Batch Generation for ML Pipelines
from eq_insar import generate_training_batch, batch_to_arrays
# Generate batch with randomized parameters
batch = generate_training_batch(
n_samples=100,
Mw_range=(5.0, 7.0),
satellite='sentinel1',
seed=42 # for reproducibility
)
# Convert to stacked arrays for PyTorch/TensorFlow
X, y = batch_to_arrays(batch)
# X: (100, T, H, W) - input time series
# y: (100, T, H, W) - segmentation labels
Custom Earthquake Parameters
from eq_insar import sample_earthquake_parameters, generate_synthetic_insar
# Sample random earthquake parameters
params = sample_earthquake_parameters(
Mw_range=(5.5, 6.5),
depth_range=(5, 20),
seed=42
)
# Generate interferogram with sampled parameters
result = generate_synthetic_insar(**params, satellite='sentinel1')
API Reference
Main Functions
| Function | Description |
|---|---|
generate_synthetic_insar() |
Generate a single interferogram |
generate_timeseries() |
Generate time series with pre/co/post-event frames |
generate_training_batch() |
Generate multiple samples with random parameters |
sample_earthquake_parameters() |
Sample random earthquake parameters |
batch_to_arrays() |
Convert batch to stacked NumPy arrays |
Satellite Functions
| Function | Description |
|---|---|
list_satellites() |
List all available satellite configurations |
get_satellite(name) |
Get configuration for a specific satellite |
SatelliteConfig |
Dataclass for satellite parameters |
Core Physics Functions
| Function | Description |
|---|---|
mw_to_m0() |
Convert moment magnitude to seismic moment |
m0_to_mw() |
Convert seismic moment to moment magnitude |
double_couple_moment_tensor() |
Create moment tensor from strike/dip/rake |
slip_from_moment() |
Calculate slip from seismic moment |
davis_point_source() |
Compute displacement using Davis (1986) model |
InSAR Functions
| Function | Description |
|---|---|
compute_los_vector() |
Compute LOS unit vector from geometry |
compute_los_displacement() |
Project 3D displacement to LOS |
displacement_to_phase() |
Convert displacement to interferometric phase |
wrap_phase() |
Wrap phase to [-pi, pi] |
phase_to_displacement() |
Convert phase back to displacement |
generate_random_noise() |
Generate Gaussian noise |
generate_orbital_ramp() |
Generate orbital ramp artifacts |
I/O Functions
| Function | Description |
|---|---|
save_geotiff() |
Save array as GeoTIFF |
save_displacement_geotiff() |
Save displacement components as GeoTIFFs |
save_phase_geotiff() |
Save phase data as GeoTIFF |
save_netcdf() |
Save single interferogram as NetCDF |
save_timeseries_netcdf() |
Save time series as NetCDF |
load_netcdf() |
Load data from NetCDF |
Visualization Functions
| Function | Description |
|---|---|
plot_displacement_components() |
Plot E/N/U displacement and LOS |
plot_insar_products() |
Plot wrapped/unwrapped phase |
plot_timeseries_frames() |
Plot time series frames |
plot_timeseries_statistics() |
Plot time series statistics |
plot_timeseries_at_points() |
Plot time series at specific locations |
plot_timeseries_displacement_components() |
Plot displacement components over time |
plot_timeseries_profile() |
Plot displacement profiles |
plot_timeseries_difference() |
Plot differences between frames |
Supported Satellites
| Satellite | Band | Wavelength | Default Incidence | Agency |
|---|---|---|---|---|
| Sentinel-1 | C | 5.5 cm | 33° | ESA |
| ALOS-2 | L | 22.9 cm | 35° | JAXA |
| TerraSAR-X | X | 3.1 cm | 35° | DLR |
| COSMO-SkyMed | X | 3.1 cm | 35° | ASI |
| RADARSAT-2 | C | 5.5 cm | 35° | CSA |
| NISAR | L | 23.8 cm | 35° | NASA/ISRO |
| SAOCOM | L | 23.5 cm | 35° | CONAE |
| ENVISAT | C | 5.6 cm | 23° | ESA |
| ICEYE | X | 3.1 cm | 30° | ICEYE |
from eq_insar import list_satellites, get_satellite
# List all satellites
print(list_satellites())
# Get specific satellite configuration
sentinel1 = get_satellite('sentinel1')
print(f"Wavelength: {sentinel1.wavelength_m * 100:.2f} cm")
Fault Geometry Convention
Uses Aki & Richards (2002) convention:
| Parameter | Range | Description |
|---|---|---|
| Strike | 0-360° | Clockwise from North |
| Dip | 0-90° | From horizontal |
| Rake | -180 to 180° | Slip direction |
Rake angle meanings:
- 0°: Left-lateral strike-slip
- 90°: Thrust/reverse
- ±180°: Right-lateral strike-slip
- -90°: Normal fault
Export Data
GeoTIFF (requires rasterio)
from eq_insar import generate_synthetic_insar, save_displacement_geotiff
result = generate_synthetic_insar(Mw=6.0, satellite='sentinel1')
save_displacement_geotiff(result, 'output/', prefix='eq_mw60')
# Creates: eq_mw60_east.tif, eq_mw60_north.tif, eq_mw60_up.tif, eq_mw60_los.tif
NetCDF
from eq_insar import save_netcdf, save_timeseries_netcdf, load_netcdf
# Single interferogram
result = generate_synthetic_insar(Mw=6.0, satellite='sentinel1')
save_netcdf(result, 'output/interferogram.nc')
# Time series
result_ts = generate_timeseries(Mw=6.0, satellite='sentinel1')
save_timeseries_netcdf(result_ts, 'output/timeseries.nc')
# Load back
data = load_netcdf('output/interferogram.nc')
Examples
See the examples/ directory for Jupyter notebooks:
- showcase.ipynb: Comprehensive tutorial covering:
- Single interferogram generation
- Fault type comparison (thrust, normal, strike-slip)
- Magnitude scaling effects
- Satellite comparison (C-band, L-band, X-band)
- Noise effects visualization
- Time series for ML training
- Batch generation
- Publication-quality figures
Package Structure
eq-insar/
├── pyproject.toml # Package configuration
├── README.md # This file
├── LICENSE # MIT License
├── src/
│ └── eq_insar/ # Main package
│ ├── __init__.py # Public API with lazy imports
│ ├── constants.py # Satellite configs, physical constants
│ ├── core/ # Seismic physics
│ │ ├── __init__.py
│ │ ├── davis.py # Davis (1986) point source model
│ │ └── moment_tensor.py# Moment tensor, magnitude conversion
│ ├── generators/ # Synthetic data generation
│ │ ├── __init__.py
│ │ ├── single.py # Single interferogram
│ │ ├── timeseries.py # Time series generation
│ │ └── batch.py # Batch generation for ML
│ ├── insar/ # InSAR processing
│ │ ├── __init__.py
│ │ ├── projection.py # LOS projection, phase conversion
│ │ └── noise.py # Noise models
│ ├── io/ # Data export
│ │ ├── __init__.py
│ │ ├── geotiff.py # GeoTIFF export
│ │ └── netcdf.py # NetCDF export/load
│ └── visualization/ # Plotting functions
│ ├── __init__.py
│ ├── displacement.py # Displacement plots
│ └── timeseries.py # Time series plots
├── tests/ # Test suite
│ ├── __init__.py
│ └── test_generators.py # Unit tests
└── examples/ # Example notebooks
└── showcase.ipynb # Tutorial notebook
Development
Running Tests
# Install with dev dependencies
pip install -e ".[dev]"
# Run all tests
pytest tests/
# Run with coverage
pytest tests/ --cov=eq_insar --cov-report=html
# Run specific test
pytest tests/test_generators.py::TestGenerateSyntheticInsar::test_basic_generation
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/new-feature) - Make your changes
- Run tests (
pytest tests/) - Commit your changes (
git commit -am 'Add new feature') - Push to the branch (
git push origin feature/new-feature) - Create a Pull Request
Physics References
- Davis, P.M. (1986). Surface deformation due to a dipping hydrofracture. Journal of Geophysical Research
- Aki, K. & Richards, P.G. (2002). Quantitative Seismology, 2nd ed. University Science Books
- Hanks, T.C. & Kanamori, H. (1979). A moment magnitude scale. Journal of Geophysical Research
- Wells, D.L. & Coppersmith, K.J. (1994). New empirical relationships among magnitude, rupture length, rupture width, rupture area, and surface displacement. Bulletin of the Seismological Society of America
Citation
If you use EQ-INSAR in your research, please cite:
@software{cieslik2026eqinsar,
author = {Cieslik, Konrad and Milczarek, Wojciech},
title = {EQ-INSAR: A Python Package for Generating Synthetic Earthquake InSAR Deformation Data},
year = {2026},
url = {https://github.com/kcieslik/eq-insar}
}
License
MIT License - see LICENSE file for details.
Acknowledgments
This package was developed at the Wroclaw University of Science and Technology.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file eq_insar-0.1.0.tar.gz.
File metadata
- Download URL: eq_insar-0.1.0.tar.gz
- Upload date:
- Size: 37.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bf722665a9a2aaf38ecf67aa16ee99cf8cb1d2e188dcad4c55e732831fef8ff1
|
|
| MD5 |
f0015c0f408fbb37063a746d553c2152
|
|
| BLAKE2b-256 |
d9e90ed5733bb275af9dd3e56353a469a58683a40fabc36467de2e730aabf305
|
File details
Details for the file eq_insar-0.1.0-py3-none-any.whl.
File metadata
- Download URL: eq_insar-0.1.0-py3-none-any.whl
- Upload date:
- Size: 40.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f18d53dd87ed71d55176b96ea26aaad2dcfe73dc40ffc6441312b0c01f3eef24
|
|
| MD5 |
d71ce172180eb0cf6aa2806bc830feda
|
|
| BLAKE2b-256 |
4b72de1cdbb497dd5ba0d22d141fb01faa48f652657e1f1de2c36035c7c65e2f
|