Skip to main content
st-insar

⚠️ Important Note

This project is actively under development. While the core functionality is production-ready and thoroughly tested, some advanced features are still being refined.

License: MIT Python Tests Coverage Code style: black


Traditional InSAR processing tells you where the ground has subsided. st-insar tells you where it's going to — by fusing high-resolution Sentinel-1 displacement time-series with coarse hydrological reanalysis and optical foundation-model embeddings on a single hierarchical graph, and forecasting forward with a physics-informed Spatio-Temporal Graph Neural Network that is constrained, by construction, to respect Terzaghi's principle of effective stress.

It exists because groundwater-driven land subsidence — in the Central Valley, in Mexico City, in Jakarta — is one of the few climate-adjacent hazards that is genuinely predictable months in advance, if the model is given the right physics and the right multi-modal signal. Most InSAR tooling stops at the interferogram. st-insar starts there.

Why this exists

Land subsidence from groundwater over-extraction is slow, cumulative, and expensive to reverse — by the time a well field, a rail line, or a coastal levee shows visible damage, the compaction that caused it may already be irreversible. InSAR gives geodesists a precise retrospective record of that compaction, at millimeter precision, every 6–12 days. What it doesn't give them, on its own, is a forecast a water manager can act on before the damage happens.

st-insar closes that gap with three design decisions that most subsidence-modeling pipelines skip:

  • No naive resampling. Displacement (PS points, ~5 m) and hydrology (GRACE/ERA5, ~30 km+) live at wildly different resolutions. Instead of upsampling the coarse grid to fake spatial detail it doesn't have, st-insar builds a two-tier hierarchical graph — hydrology cells as super-nodes, PS points as leaf-nodes — and lets graph attention learn the coupling between scales.
  • Physics as a loss term, not a post-hoc filter. A TerzaghiPhysicsLoss penalizes the model, during training, for predicting uplift while groundwater storage is measurably depleting — the one direction effective-stress theory actually constrains. It does not penalize continued subsidence during recharge, since a large fraction of compaction in clay/silt aquitards is inelastic and permanent.
  • Uncertainty you can act on. Every forecast ships with both aleatoric uncertainty (from a Mixture Density Network head, which can represent genuinely multi-modal futures — "extraction continues" vs. "a moratorium kicks in") and epistemic uncertainty (from Monte Carlo Dropout), reported separately, not collapsed into one number.

How it works

                    InSAR (ps-gnn / pyunwrap)     Optical (Clay / Prithvi)     Hydrology (GRACE / ERA5 / SMAP / CHIRPS)
                    6–12 days · ~5 m              ~5 days · ~10 m              monthly · 30 km+
                            │                             │                             │
                            └──────────────┬──────────────┴──────────────┬──────────────┘
                                           ▼                             ▼
                              hierarchical graph harmonizer   (leaf-nodes ↔ parent super-nodes)
                                           │
                                           ▼
                    ┌──────────────────────────────────────────────────────────────┐
                    │                      ST-GNN core                             │
                    │  TCN / LSTM / frozen-MLP encoders → GATv2 spatial coupling    │
                    │  → explicit temporal attention → Mixture Density Network head │
                    └──────────────────────────────────────────────────────────────┘
                                           │
                          trained under TerzaghiPhysicsLoss, spatial-block +
                          temporal-roll-forward CV, two-phase curriculum
                                           │
                                           ▼
                    scenario "what-if" forecasting  →  explainability + calibration
                    (ONNX or native PyTorch, MC Dropout CIs)   (temporal SHAP, coupling maps, Moran's I)
                                           │
                                           ▼
                                 automated HTML report

Each stage is its own module, independently usable:

Module Responsibility
st_insar.data.harmonizer Multi-modal alignment onto a dynamic hierarchical graph; missing-data interpolation
st_insar.models TCN / LSTM / frozen-MLP encoders, GATv2 + temporal attention core, MDN forecast head, TerzaghiPhysicsLoss
st_insar.training Spatial-block + temporal-roll-forward CV, two-phase curriculum, AdamW/cosine training loop, CLI
st_insar.inference Scenario "what-if" forecasting, Monte Carlo Dropout uncertainty, ONNX export/serving
st_insar.analytics Temporal SHAP, spatial-attention coupling maps, spatio-temporal Moran's I, seasonal bias, calibration, HTML reporting
st_insar.visualization Animated subsidence maps, 3D space-time cubes, forecast/SHAP/loss charts

Validation sites

Three sites ship pre-configured, each with an independent ground-truth source the forecasts are checked against — not just internal cross-validation:

Site Ground truth What makes it hard
Mexico City UNAM continuous GNSS network Some of the fastest subsidence rates on Earth (>300 mm/yr in places), highly non-linear urban extraction
Central Valley, California USGS groundwater monitoring wells Decades of intermittent, drought-driven pumping cycles; strong seasonal signal to separate from trend
Jakarta Coastal tide gauge network Subsidence compounding with sea-level rise; land and sea both moving

Installation

git clone https://github.com/st-insar/st-insar.git
cd st-insar
pip install -e ".[dev]"

GPU-accelerated scatter/sparse ops (recommended for graphs beyond a few thousand nodes):

pip install -e ".[gpu]"

Quickstart

from st_insar.data.harmonizer import MultiModalHarmonizer, VALIDATION_SITES

site = VALIDATION_SITES["central_valley"]
harmonizer = MultiModalHarmonizer(site=site)

harmonizer.register_insar(ps_points_path="data/central_valley_ps.geojson")
harmonizer.register_hydrology(era5_path="data/era5_tws.nc", grace_path="data/grace_tws.nc")
harmonizer.register_optical_embeddings(embeddings_path="data/clay_embeddings.nc")
harmonizer.register_static(topo_path="data/dem.tif", geology_path="data/soil_type.tif")

graphs = harmonizer.build_dynamic_graph_sequence(start="2016-01-01", end="2020-12-31", freq="MS")
from st_insar.inference.forecaster import ScenarioForecaster

forecaster = ScenarioForecaster(schema=harmonizer.schema, checkpoint_path="checkpoints/best.pt")
result = forecaster.forecast(x_seq, edge_index, mc_samples=50)   # mean, 95% CI, aleatoric + epistemic variance

# "What if extraction increases 20% over the next 6 months?"
scenario = ScenarioForecaster.scale_hydro_channel(x_seq, harmonizer.schema, factor=1.2, steps=6)
what_if = forecaster.forecast(scenario, edge_index)

Training from raw files, with the full spatial-block CV × curriculum pipeline, runs from the CLI:

st-insar-train \
  --site central_valley \
  --ps-points data/central_valley_ps.geojson \
  --grace data/grace_tws.nc --era5 data/era5.nc \
  --history-len 24 --horizon 12 \
  --phase1-epochs 20 --phase2-epochs 40

Project layout

st_insar/
├── data/            harmonization: multi-modal alignment onto a dynamic hierarchical graph
├── models/          encoders, ST-GNN core (GAT + temporal attention + MDN), TerzaghiPhysicsLoss
├── training/        spatial-block + temporal-roll-forward CV, curriculum, trainer, CLI
├── inference/       scenario forecasting, MC Dropout uncertainty, ONNX export/serving
├── analytics/       temporal SHAP, coupling maps, Moran's I, calibration, HTML report generator
├── visualization/   animated maps, 3D space-time cubes, forecast/SHAP/loss charts
└── utils/           shared helpers
tests/               unit, model, leakage, ONNX, and end-to-end integration tests
assets/              logo source files

Testing

pytest tests/ -m "not slow"     # unit, model, and leakage tests — a few seconds
pytest tests/                    # add the full harmonize → train → forecast → report integration test

48 tests, 76% line coverage, zero mypy errors. The suite is unusually paranoid about two things on purpose: the leakage tests construct a mock dataset where the future has a deliberately different distribution than the past and assert, by inspecting actual tensor values, that no training window ever touched it; the physics tests assert the Terzaghi loss's asymmetry directly (penalized: uplift during depletion; not penalized: continued subsidence during recharge).

Roadmap

  • Package scaffold, pyproject.toml, multi-modal harmonizer
  • Modality encoders, GATv2 spatial coupling, temporal attention, MDN forecast head
  • TerzaghiPhysicsLoss, scenario "what-if" forecasting API, ONNX export
  • Spatial-block + temporal-roll-forward CV, two-phase curriculum, training CLI
  • Temporal SHAP, spatial-attention coupling maps, spatio-temporal Moran's I, calibration
  • Animated maps, 3D space-time cubes, automated HTML reporting
  • Unit, model, leakage, ONNX, and integration test suite; CI
  • Pretrained checkpoints for all three validation sites
  • Direct pygeofetch ingestion (currently: bring your own harmonized files)
  • Multi-GPU / distributed training for continental-scale graphs

Related projects

st-insar is designed to sit downstream of two companion packages and, eventually, feed into a third:

  • ps-gnn — Persistent Scatterer identification
  • pyunwrap — AI-based InSAR phase unwrapping
  • pygeofetch — multi-source Earth observation ingestion (planned integration)

Citation

If st-insar is useful in your research, please cite it:

@software{stinsar2026,
  title  = {st-insar: Physics-Informed Spatio-Temporal Deformation Forecasting},
  author = {{st-insar contributors}},
  year   = {2026},
  url    = {https://github.com/st-insar/st-insar}
}

Contributing

Issues and pull requests are welcome. Before opening a PR: pytest tests/ -m "not slow", ruff check st_insar tests, and black st_insar tests should all be clean — CI runs the same checks, plus the full slow suite, on every push.

License

MIT — see LICENSE.

Metadata

Release files for st-insar 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for st-insar 0.1.1
File Size Uploaded Provenance
st_insar-0.1.1.tar.gz 78.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for st-insar 0.1.1
File Interpreter ABI Platform
st_insar-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 148.1 kB

Release files / st_insar-0.1.1.tar.gz

Download URL st_insar-0.1.1.tar.gz
Size 78.2 kB
Tags Source
SHA-256 checksum
How to use checksums
3e02ef58b391cbb3172148c4405de211d81ef91ae795fa0c2a253b64865d0dfa
BLAKE2b-256 checksum
How to use checksums
d593fa9ec0c894a5385dfaffa5e1f470328015bc958b50735a88ac56938d91bb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / st_insar-0.1.1-py3-none-any.whl

Download URL st_insar-0.1.1-py3-none-any.whl
Size 69.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0ec85a74ad8dc518e4ed36095ff90f4ea3264d50cb15045c40f1b4ce67d97300
BLAKE2b-256 checksum
How to use checksums
3b86551473e3fd3d829de444c5fecd83ff44cde60f58b6780c67ace2b22b17bb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Security for st-insar 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page