Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,12 @@ Thumbs.db
# pixi environments
.pixi
*.egg-info

# Local research scratch files (keep out of the package)
/*.zip
/midas.py
/hectorp_wrapper.py
scripts/*.parquet

# Generated GitHub Pages staging copy (see scripts/deploy-pages.sh)
scripts/web/
50 changes: 45 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,55 @@ print(df_many.head())
```

## Example: Comparing GPS and InSAR Data
The basic InSAR/GNSS comparison workflow is offered by the `geepers` command line tool.

The InSAR/GNSS comparison workflow is offered by the `geepers` command line tool:

```bash
geepers --los F33039_los_enu.tif --timeseries-files displacement_20160711_*tif --temporal-coherence-files temporal_coherence_*.tif --similarity-files phase_similarity*.tif
geepers \
--los F33039_los_enu.tif \
--timeseries-files displacement_20160711_*tif \
--temporal-coherence-files temporal_coherence_*.tif \
--similarity-files phase_similarity*.tif \
--insar-buffer-meters 100 \
--requirement-mm 3 0.5 \
--wavelength 0.2384 # NISAR L-band; omit for Sentinel-1
```

The results are saved in the current directory in the `GPS` folder by default.

(TODO: Example data prep for this)
Results are saved in the `GPS` folder by default: per-station time-series
and rate comparisons, plus the structure function (pairwise relative RMSE
vs station separation, checked against the requirement curve) and the
per-epoch network misfit. See
[How-To Guides](https://geepers.readthedocs.io/en/latest/how-to-guides/)
and the runnable
[validation notebook](docs/notebooks/gnss_insar_validation.ipynb).

## Analysis toolbox

Beyond data access and the comparison workflow, geepers ships analysis
modules for GNSS velocity fields (see
[Analysis modules](docs/analysis-modules.md) for usage and the
[tour notebook](docs/notebooks/geepers_tour.ipynb) for a runnable demo):

| Module | Purpose |
|---|---|
| `geepers.midas` | Robust MIDAS velocities (Blewitt et al., 2016) |
| `geepers.trend` | Velocities with realistic uncertainties under power-law + white noise (validated against HectorP); fast Whittle method and parallel `estimate_trend_many` for networks |
| `geepers.variability` | Temporal & spatial velocity-stability metrics, spatial structure function |
| `geepers.quality` | Gap percentage, station quality, reference selection |
| `geepers.steps` | Detection of uncatalogued jumps (AIC sliding window) |
| `geepers.cme` | Common-mode error estimation/removal (PCA/ICA) |
| `geepers.gps_imaging` | Robust weighted-median interpolation (Hammond et al., 2016 GPS Imaging port) |
| `geepers.collocation` | Least-squares collocation, ordinary kriging, plate-boundary separation |
| `geepers.euler` | Euler pole estimation and plate-motion prediction |
| `geepers.strain` | Strain-rate/rotation fields from gridded velocities |
| `geepers.validation` | GNSS-vs-InSAR validation: velocity scatter (MAD/RMSE/R²), structure function, semivariogram, per-epoch misfit |
| `geepers.synthetic` | Schema-valid synthetic networks and series for testing |

An interactive MapLibre viewer for UNR gridded time series is hosted at
**[opera-adt.github.io/geepers](https://opera-adt.github.io/geepers/)**
(globe view, velocity/vector overlays, plate boundaries, per-point time
series). See the [viewer docs](scripts/README.md) to run it locally or
build your own dataset.

### Working with Multiple Sources

Expand Down
121 changes: 114 additions & 7 deletions scripts/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,120 @@
# UNR Grid Web Browser
# OPERA UNR Grid Web Browser

Setup:
Interactive MapLibre GL viewer for UNR gridded GPS time series.
The gridded data are produced by the Nevada Geodetic Laboratory (UNR),
funded by the JPL-led [OPERA](https://www.jpl.nasa.gov/go/opera) project;
the viewer is developed at JPL.

> **Disclaimer**: the viewer and the underlying gridded GPS products are
> research tools provided "as is", without warranty of any kind.
> Displacements, uncertainties, and derived velocities are experimental
> and may contain errors or artifacts. Use of this tool does not imply
> endorsement by JPL/Caltech, NASA, or the University of Nevada, Reno.
Loads a single Parquet file directly in the browser (via
[hyparquet](https://github.com/hyparam/hyparquet)) and scrubs through dates
with GPU-driven color updates — no per-date files, no re-fetching.

## Live site

Hosted on GitHub Pages: **https://opera-adt.github.io/geepers/**

The default dataset is the **global UNR grid, all 28,358 points at monthly
sampling** (2014→2026, ~95 MB), served same-origin from the `gh-pages`
branch. See `deploy-pages.sh` for how the site is (re)built and pushed.

### Viewing the full daily-resolution grid

The full daily grid is too large for browser hosting — GitHub has no
surface that serves it cross-origin (Pages caps files at 100 MB; Release
assets and LFS send no CORS headers). It ships instead as a **local
artifact** for offline viewing:

```bash
cd scripts/
# EXAMPLE BBOX:
python create-geojson.py --bbox -110 28 -101 36 --start-date 2016-01-01
# Creates geojson_sources/
echo "Visit the URL in your browser:"
echo "http://localhost:8123/browse_unr_grid.html"
# OPERA_UNR_GNSS_grid_full.parquet: all 28,358 points, daily, 2014→2026
# (~850 MB; viewer-minimal columns date_idx/point_idx/E/N/U, no sigmas)
python -m http.server 8123
# Open http://localhost:8123/browse_unr_grid.html and use "Open .parquet…"
# in the Data panel to pick OPERA_UNR_GNSS_grid_full.parquet, or:
# browse_unr_grid.html?data=OPERA_UNR_GNSS_grid_full.parquet
```

At full daily resolution the viewer needs ~1.5 GB of browser memory (it
will ask to confirm); use the **Date stride** selector (or `?stride=N`) to
subsample and lighten it. The `_full` file omits the sigma columns, so the
±σ chart band is unavailable there — use a smaller/regional export (with
sigmas) if you need uncertainties.

## Setup

```bash
cd scripts/
# 1. Download data and build the viewer-ready Parquet file (example bbox):
python create-geoparquet.py --bbox -110 28 -101 36 --start-date 2016-01-01
# Creates unr_grid.parquet

# 2. Serve and open:
python -m http.server 8123
# Visit http://localhost:8123/browse_unr_grid.html
```

Useful options:

- `--source grid|stations` — UNR gridded (interpolated) product, or real
UNR GPS station positions (.tenv3). Default `grid`.
- `--gridded-type constant|variable` — time-constant vs time-variable UNR
product (version 0.3 only; grid source only; default `variable`).
- `--output-file my_area.parquet` then open
`browse_unr_grid.html?data=my_area.parquet`.
- `--clear-cache` — wipe the geepers download cache first (forces fresh
downloads).
- `--zero-by mean|start|none` — zero each point's series by its mean, its
first epochs, or `none` to keep values exactly as published (default
`mean`).
- If no file is found, the page offers a local file picker (drag any
compatible `.parquet` in — nothing is uploaded, parsing is in-browser).

The viewer is a single self-contained HTML file — MapLibre GL v5, uPlot and
hyparquet are inlined, so only the basemap/terrain tiles need the network.

## Viewer features

- Date slider + playback (2–30 fps), keyboard: `←`/`→` step, `space` play.
- Click a grid point → East/North/Up time series chart (uPlot) with an
optional ±1σ shaded band; **Shift+click** a second point for a comparison
chart. Charts are resizable (drag the corner), zoomable (drag box, mouse
wheel, double-click resets), and clicking a sample jumps the map to that
date.
- Component selector, colormaps (RdBu, BrBG, Viridis, Turbo, Magma),
invert, symmetric/robust (p2–p98) or manual range in mm; `live` re-runs
the auto range on every date change while scrubbing/playing.
- Velocity mode: color points by per-point linear trend (least-squares,
mm/yr) instead of per-date displacement.
- Vector overlay: horizontal (E+N) and/or vertical (Up, red up / blue
down) quiver arrows over the points, with an arrow-scale slider and a
scale legend above the colorbar. Arrow scaling is automatic (p90 of the
data, follows the date like the color `live` mode) or fixed via typed
reference magnitudes (e.g. H 3, V 1 mm/yr). Arrows show the same field
as the colors (per-date displacement, or velocity in velocity mode).
The globe view gets a dark space backdrop.
- Each chart has a `csv` button (dates + E/N/U ± σ of that point, in mm,
with the current referencing applied).
- Find ID box zooms to a grid point / station by identifier.
- Large files: a memory estimate is checked before loading, and a "Date
stride" selector (`?stride=N`) loads only every Nth date to bound
memory (e.g. the ~1 GB time-variable CA file fits comfortably with
stride 5).
- Reference modes: none (values exactly as stored in the file), per-point
temporal mean, first date, or any chosen date (displacement relative to
that date).
- Basemaps: Carto light/dark, OSM, Esri satellite; globe (default) or
Mercator projection; optional 3D terrain (AWS terrain tiles) with
adjustable exaggeration — right-drag / Ctrl+drag to tilt and rotate.
- Tectonic plate boundaries overlay (Bird 2003, via
[fraxen/tectonicplates](https://github.com/fraxen/tectonicplates));
loads `PB2002_boundaries.json` next to the HTML if present, else from
GitHub raw.
- Data panel: load another `.parquet` (local file or URL) without reloading
the page, and a "Clear cache & reload" button. Fetches are keyed to the
file's `Last-Modified`/`ETag`, so regenerating a parquet under the same
name can never serve stale cached byte ranges.
4,716 changes: 1,723 additions & 2,993 deletions scripts/browse_unr_grid.html

Large diffs are not rendered by default.

Loading
Loading