Skip to main content

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.

Python 3.8+ License: MIT

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)
  • 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

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/new-feature)
  3. Make your changes
  4. Run tests (pytest tests/)
  5. Commit your changes (git commit -am 'Add new feature')
  6. Push to the branch (git push origin feature/new-feature)
  7. 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

eq_insar-0.1.0.tar.gz (37.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

eq_insar-0.1.0-py3-none-any.whl (40.3 kB view details)

Uploaded Python 3

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

Hashes for eq_insar-0.1.0.tar.gz
Algorithm Hash digest
SHA256 bf722665a9a2aaf38ecf67aa16ee99cf8cb1d2e188dcad4c55e732831fef8ff1
MD5 f0015c0f408fbb37063a746d553c2152
BLAKE2b-256 d9e90ed5733bb275af9dd3e56353a469a58683a40fabc36467de2e730aabf305

See more details on using hashes here.

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

Hashes for eq_insar-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f18d53dd87ed71d55176b96ea26aaad2dcfe73dc40ffc6441312b0c01f3eef24
MD5 d71ce172180eb0cf6aa2806bc830feda
BLAKE2b-256 4b72de1cdbb497dd5ba0d22d141fb01faa48f652657e1f1de2c36035c7c65e2f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page