
# pygndc

**Geographic Neural Data Cube** - A Python SDK for reading and analyzing `.gndc` compressed geospatial time-series data.

<img width="286" height="320" alt="GeoNDC" src="https://github.com/user-attachments/assets/6c526878-93bc-4b70-bc99-cbb99193931a" />

## What is GeoNDC?

GeoNDC is a neural network-based compression format for multi-dimensional geospatial raster data. A single `.gndc` file stores 4D spatiotemporal data (Time x Height x Width x Bands) with up to **300:1 compression ratios**.

Key capabilities:

- **Arbitrary time reconstruction** - reconstruct data at any time point, not just original observation times
- **Fast random access** - query any pixel at any timestamp instantly
- **Analytic gradients** - compute spatial/temporal derivatives directly from the neural network
- **Multi-sensor support** - Sentinel-2, Landsat, MODIS, HiGLASS, and more

## Online Viewer & Data

- **Web Viewer**: Browse `.gndc` files directly in the browser via WebGPU at [geondc.org/viewer](https://www.geondc.org/viewer/) — no installation required, GPU-accelerated, runs entirely client-side.
- **Sample Data**: Download `.gndc` datasets from [Hugging Face](https://huggingface.co/datasets/geondc/geondc-data).

## Installation

```bash
pip install pygndc
```

Or from source:

```bash
git clone https://github.com/jianboqi/pygndc.git
cd pygndc
pip install .
```

### GPU support (recommended)

`pip install pygndc` installs CPU-only PyTorch by default. For GPU acceleration, install CUDA-enabled PyTorch **first**:

```bash
# Example for CUDA 12.1 (check https://pytorch.org for your CUDA version)
pip install torch --index-url https://download.pytorch.org/whl/cu121

# Then install pygndc
pip install pygndc
```

### tiny-cuda-nn (fastest)

For best performance, install [tiny-cuda-nn](https://github.com/NVlabs/tiny-cuda-nn). This provides the optimized TCNN backend with significantly faster inference and lower memory usage.

```bash
pip install git+https://github.com/NVlabs/tiny-cuda-nn/#subdirectory=bindings/torch
```

> **Note**: tiny-cuda-nn requires an NVIDIA GPU with CUDA support and a C++ compiler. If you cannot install it, pygndc will automatically fall back to pure PyTorch (`torch_gpu` or `torch_cpu`).

### Optional dependencies

```bash
pip install pygndc[all]       # xarray + geopandas + scipy
pip install pygndc[xarray]    # xarray support
pip install pygndc[geo]       # geopandas + shapely
```

### Inference modes

pygndc uses a single `mode` parameter to control both the backend and device:

| Mode | Backend | Device | Description |
|------|---------|--------|-------------|
| `auto` | auto-detect | auto-detect | **Default.** Best available mode |
| `tcnn_cuda` | tiny-cuda-nn | GPU | Fastest. Requires tinycudann + CUDA |
| `torch_gpu` | PyTorch | GPU | No extra dependencies, requires CUDA |
| `torch_cpu` | PyTorch | CPU | Works everywhere, slowest |

## Quick Start

```python
import pygndc

# Open a .gndc file (auto-detects best mode)
with pygndc.open("samples/S2_sample_2022_to_2025.gndc") as ds:
    print(ds)                                          # Shows mode, shape, CRS, etc.

    # Read a frame
    frame = ds.read(t=0)                               # (H, W, C) by index
    frame = ds.read(t="2024-06-15")                    # by date string
    frame = ds.read_at_time("2024-06-15 12:00:00")     # continuous interpolation

    # Point query (coordinates within the sample's bounds)
    series = ds.sample(lon=116.825, lat=40.486)        # (T, C) full time series
    values = ds.sample(lon=116.825, lat=40.486, t=0)   # (C,) single time

    # Pixel time series
    series = ds.pixel_series(row=140, col=140)         # (T, C)

    # Analysis
    ndvi = ds.ndvi(t=0, red_band=2, nir_band=3)       # (H, W)
    dx, dy = ds.gradient(t=0, mode="spatial")          # analytic gradients

    # Export
    arr = ds.to_numpy(t=0)                             # (H, W, C) numpy array
    ds.to_tif("frame_0.tif", t=0)                     # single frame to GeoTIFF
    ds.to_tifs("output_dir/")                          # all frames
    xds = ds.to_xarray()                               # xarray Dataset

# Specify mode explicitly
with pygndc.open("samples/S2_sample_2022_to_2025.gndc", mode="torch_cpu") as ds:
    frame = ds.read(t=0)
```

## CLI Commands

```bash
# Show model info
pygndc info model.gndc
pygndc info model.gndc --json

# Decompress to GeoTIFF files
pygndc decompress -i model.gndc -o ./output
pygndc decompress -i model.gndc -o ./output --timestamp 2024-06-15
pygndc decompress -i model.gndc -o ./output --start 2024-01-01 --end 2024-12-31 --interval 5

# Compute NDVI
pygndc ndvi -i model.gndc -o ndvi.tif --red-band 0 --nir-band 1

# Compute spatial gradient
pygndc derivative -i model.gndc -o gradient.tif --grad-mode mag

# Point query
pygndc sample -i model.gndc --lon 116.5 --lat 39.9

# Export pixel time series to CSV
pygndc timeseries -i model.gndc --row 100 --col 200 -o series.csv

# Launch interactive viewer
pygndc viewer -i model.gndc

# All commands support --mode (auto, tcnn_cuda, torch_gpu, torch_cpu)
pygndc decompress -i model.gndc -o ./output --mode torch_cpu
```

## Interactive Viewer

A GUI tool for visualizing `.gndc` files with multiple display modes, time navigation, and pixel inspection.

```python
from pygndc import start_viewer
start_viewer()
```

Features:
- RGB, NDVI, temporal gradient, and spatial gradient display modes
- Time slider with date navigation
- Click-to-inspect pixel time series
- Region selection and zoom
- Export current frame or entire time series

## File Format

A `.gndc` file is a zstandard-compressed archive containing:

| Component | Description |
|-----------|-------------|
| Header | JSON metadata (dimensions, timestamps, CRS, band info) |
| Model Weights | Compressed neural network parameters |
| Mask Data | Optional validity mask (static or dynamic) |
| Residuals | Optional correction data for higher accuracy |

## API Reference

See [API_Reference.md](API_Reference.md) for the full API documentation.

## License

MIT License

## Citation

```bibtex
@software{pygndc,
  author = {Jianbo Qi},
  title = {pygndc: Geographic Neural Data Cube},
  year = {2024},
  url = {https://github.com/jianboqi/pygndc},
  license = {MIT}
}
```

## Contact

- Author: Jianbo Qi
- Email: jianboqi@126.com
- Issues: [GitHub Issues](https://github.com/jianboqi/pygndc/issues)
