Metadata-Version: 2.4
Name: disp_xr
Version: 0.5.0
Summary: OPERA DISP xarray tools
Maintainer-email: Marin Govorcin <marin.govorcin@jpl.nasa.gov>
License: BSD 3-Clause License
        
        Copyright (c) 2025, Marin Govorcin
        
        Redistribution and use in source and binary forms, with or without
        modification, are permitted provided that the following conditions are met:
        
        1. Redistributions of source code must retain the above copyright notice, this
           list of conditions and the following disclaimer.
        
        2. Redistributions in binary form must reproduce the above copyright notice,
           this list of conditions and the following disclaimer in the documentation
           and/or other materials provided with the distribution.
        
        3. Neither the name of the copyright holder nor the names of its
           contributors may be used to endorse or promote products derived from
           this software without specific prior written permission.
        
        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
        AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
        FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
        CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
        OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        
Project-URL: Homepage, https://github.com/mgovorcin/disp-xr
Project-URL: Bug Tracker, https://github.com/mgovorcin/disp-xr/issues
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: LICENSES/geepers-Apache-2.0.txt
License-File: LICENSES/geepers-NOTICE.txt
License-File: LICENSES/opera-utils-BSD-3-Clause.txt
License-File: THIRD_PARTY_NOTICES.md
Requires-Dist: click>=7.0
Requires-Dist: dask
Requires-Dist: donfig>=0.8
Requires-Dist: zarr>=3.1.6
Requires-Dist: flox
Requires-Dist: fsspec
Requires-Dist: h5netcdf
Requires-Dist: h5py
Requires-Dist: netcdf4
Requires-Dist: numbagg
Requires-Dist: numpy
Requires-Dist: packaging
Requires-Dist: pandas
Requires-Dist: pydantic>=2.4
Requires-Dist: pyproj
Requires-Dist: pyyaml
Requires-Dist: rasterio
Requires-Dist: rioxarray>=0.23
Requires-Dist: scipy
Requires-Dist: threadpoolctl
Requires-Dist: xarray
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: pytest-cov; extra == "test"
Requires-Dist: pytest-xdist; extra == "test"
Requires-Dist: cf_xarray; extra == "test"
Provides-Extra: docs
Requires-Dist: mkdocs; extra == "docs"
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
Requires-Dist: mkdocstrings>=0.29; extra == "docs"
Requires-Dist: mkdocstrings-python>=1.16; extra == "docs"
Requires-Dist: mkdocs-jupyter>=0.25; extra == "docs"
Requires-Dist: ipykernel; extra == "docs"
Requires-Dist: matplotlib; extra == "docs"
Provides-Extra: gnss
Requires-Dist: geepers>=0.4; extra == "gnss"
Provides-Extra: hex
Requires-Dist: h3>=4; extra == "hex"
Requires-Dist: geopandas; extra == "hex"
Provides-Extra: mintpy
Requires-Dist: mintpy; extra == "mintpy"
Provides-Extra: plot
Requires-Dist: matplotlib; extra == "plot"
Provides-Extra: interactive
Requires-Dist: hvplot; extra == "interactive"
Requires-Dist: datashader; extra == "interactive"
Provides-Extra: aws
Requires-Dist: aiohttp; extra == "aws"
Requires-Dist: asf_search; extra == "aws"
Requires-Dist: dem_stitcher; extra == "aws"
Requires-Dist: requests; extra == "aws"
Requires-Dist: s3fs; extra == "aws"
Requires-Dist: shapely; extra == "aws"
Requires-Dist: tile_mate; extra == "aws"
Provides-Extra: cloud
Requires-Dist: virtualizarr[hdf,icechunk]>=2.4; extra == "cloud"
Provides-Extra: eof
Requires-Dist: xeofs; extra == "eof"
Provides-Extra: serve
Requires-Dist: xpublish>=0.5; extra == "serve"
Requires-Dist: xpublish-tiles>=0.9; extra == "serve"
Requires-Dist: fastapi; extra == "serve"
Requires-Dist: uvicorn; extra == "serve"
Requires-Dist: pydantic>=2; extra == "serve"
Provides-Extra: jax
Requires-Dist: jax; extra == "jax"
Dynamic: license-file


# Xarray tools for OPERA DISP

[![test](https://github.com/mgovorcin/disp-xr/actions/workflows/test.yml/badge.svg)](https://github.com/mgovorcin/disp-xr/actions/workflows/test.yml)
[![docs](https://github.com/mgovorcin/disp-xr/actions/workflows/docs.yml/badge.svg)](https://mgovorcin.github.io/disp-xr/)
[![coverage](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/mgovorcin/disp-xr/badges/coverage.json)](https://github.com/mgovorcin/disp-xr/actions/workflows/test.yml)

Documentation: <https://mgovorcin.github.io/disp-xr/>

Analysis tools using [`xarray`](https://xarray.dev) for OPERA Surface Displacement from Sentinel-1 (DISP-S1) and Surface Displacement from NISAR (DISP-NISAR).

## Quick start

```python
import disp_xr as dxr

df = dxr.find_products("path/to/granules/")   # or "s3://bucket/prefix/"
ds = dxr.open_disp(df, corrections=True)       # lazy (time, y, x), CRS attached
ds = dxr.chain(ds)                        # displacement from the first date

ds.displacement.isel(x=4000, y=3000).plot()    # one pixel's time series
```

`open_disp` returns displacement as stored in the granules, relative to each
ministack's reference date; `stack_disp` chains the ministacks. See
`docs/specs.md` for the plan and `CHANGELOG.md` for what has changed.

## Documentation

The documentation (install, getting started, concepts, command line, a
gallery of examples and the API reference) is published at
<https://mgovorcin.github.io/disp-xr/> once the repository is public. It
builds locally with mkdocs:

```bash
pixi run -e docs mkdocs serve    # http://127.0.0.1:8000
```

## Development setup

### Prerequisite installs

1. Download source code:
```bash
git clone https://github.com/mgovorcin/disp-xr.git
```
2. Install with [pixi](https://pixi.sh) (recommended). It reads `pyproject.toml` and installs `disp_xr` in editable mode:
```bash
cd disp-xr
pixi install            # core environment
pixi install -e dev     # plus tests, linters, aws, plot, mintpy and notebook extras
pixi run -e test test   # run the tests
pixi run -e test check  # run the pre-commit hooks
```
Environments: `default`, `test`, `docs` and `dev`.

   Or install the dependencies with conda/mamba, either to a new environment:
```bash
mamba env create --name disp_xr --file disp-xr/environment.yml
conda activate disp_xr
```
or install within your existing env with mamba.

3. With conda/mamba only (pixi already did this), install `disp_xr` via pip in editable mode
```bash
python -m pip install --no-deps -e  disp-xr
```

### Setup for contributing

We use [pre-commit](https://pre-commit.com/) to automatically run linting, formatting, and [mypy type checking](https://www.mypy-lang.org/).
Additionally, we follow [`numpydoc` conventions for docstrings](https://numpydoc.readthedocs.io/en/latest/format.html).
To install pre-commit locally, run:

```bash
pre-commit install
```
This adds a pre-commit hooks so that linting/formatting is done automatically. If code does not pass the checks, you will be prompted to fix it before committing.
Remember to re-add any files you want to commit which have been altered by `pre-commit`. You can do this by re-running `git add` on the files.

Since we use [black](https://black.readthedocs.io/en/stable/) for formatting and [flake8](https://flake8.pycqa.org/en/latest/) for linting, it can be helpful to install these plugins into your editor so that code gets formatted and linted as you save.

### Running the unit tests

Tests run on small synthetic DISP-S1 stacks written at run time (`tests/fixtures/make_disp.py`); no data download is needed. See `tests/data/README.md`.

```bash
pixi run -e test test   # pytest, including doctests in src/disp_xr
pixi run -e test cov    # with a coverage report
```

With conda/mamba, install the test extra and run pytest:

```bash
python -m pip install --no-deps -e .[test]
pytest
```

Tests marked `xfail(strict=True)` assert the correct behavior for known bugs listed in `docs/code_review.md`. When a fix lands, the test starts passing, pytest reports it as a failure (XPASS), and the marker is removed in the same change.
