MCPcopy Index your code
hub / github.com/awesome-spectral-indices/spyndex

github.com/awesome-spectral-indices/spyndex @0.11.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release 0.11.0 ↗ · + Follow
56 symbols 133 edges 9 files 52 documented · 93%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

spyndex

<em><a href="https://github.com/davemlz/awesome-ee-spectral-indices" target="_blank">
Awesome Spectral Indices</a> in Python:</em>






<b><a href="https://github.com/numpy/numpy" target="_blank">
Numpy</a> | <a href="https://github.com/pandas-dev/pandas" target="_blank">
Pandas</a> | <a href="https://github.com/geopandas/geopandas" target="_blank">
GeoPandas</a> | <a href="https://github.com/pydata/xarray" target="_blank">
Xarray</a> | <a href="https://github.com/google/earthengine-api" target="_blank">
Earth Engine</a> | <a href="https://github.com/microsoft/planetary-computer-sdk-for-python" target="_blank">
Planetary Computer</a> | <a href="https://docs.dask.org/en/latest/" target="_blank">
Dask</a> | <a href="https://cupy.dev/" target="_blank">
Cupy</a> | <a href="https://github.com/xarray-contrib/cupy-xarray" target="_blank">
Cupy-Xarray</a> </b>

PyPI conda-forge Documentation Status Tests Awesome Spectral Indices License GitHub Sponsors Buy me a coffee Ko-fi Twitter Black isort


GitHub: https://github.com/davemlz/spyndex

Documentation: https://spyndex.readthedocs.io/

Paper: https://doi.org/10.1038/s41597-023-02096-0

PyPI: https://pypi.org/project/spyndex/

Conda-forge: https://anaconda.org/conda-forge/spyndex

Tutorials: https://spyndex.readthedocs.io/en/latest/tutorials.html


Citation

If you use this work, please consider citing the following paper:

@article{montero2023standardized,
  title={A standardized catalogue of spectral indices to advance the use of remote sensing in Earth system research},
  author={Montero, David and Aybar, C{\'e}sar and Mahecha, Miguel D and Martinuzzi, Francesco and S{\"o}chting, Maximilian and Wieneke, Sebastian},
  journal={Scientific Data},
  volume={10},
  number={1},
  pages={197},
  year={2023},
  publisher={Nature Publishing Group UK London}
}

Overview

The Awesome Spectral Indices is a standardized ready-to-use curated list of spectral indices that can be used as expressions for computing spectral indices in remote sensing applications. The list was born initially to supply spectral indices for Google Earth Engine through eemont and spectral, but given the necessity to compute spectral indices for other object classes outside the Earth Engine ecosystem, a new package was required.

Spyndex is a python package that uses the spectral indices from the Awesome Spectral Indices list and creates an expression evaluation method that is compatible with python object classes that support overloaded operators (e.g. numpy.ndarray, pandas.Series, xarray.DataArray).

Some of the spyndex features are listed here:

  • Access to Spectral Indices from the Awesome Spectral Indices list.
  • Multiple Spectral Indices computation.
  • Kernel Indices computation.
  • Parallel processing.
  • Compatibility with a lot of python objects!

Check the simple usage of spyndex here:

import spyndex
import numpy as np
import xarray as xr

N = np.random.normal(0.6,0.10,10000)
R = np.random.normal(0.1,0.05,10000)

da = xr.DataArray(
    np.array([N,R]).reshape(2,100,100),
    dims = ("band","x","y"),
    coords = {"band": ["NIR","Red"]}
)

idx = spyndex.computeIndex(
    index = ["NDVI","SAVI"],
    params = {
        "N": da.sel(band = "NIR"),
        "R": da.sel(band = "Red"),
        "L": 0.5
    }
)

Bands can also be passed as keywords arguments:

idx = spyndex.computeIndex(
    index = ["NDVI","SAVI"],
    N = da.sel(band = "NIR"),
    R = da.sel(band = "Red"),
    L = 0.5
)

And indices can be computed from their class:

idx = spyndex.indices.NDVI.compute(
    N = da.sel(band = "NIR"),
    R = da.sel(band = "Red"),
)

How does it work?

Any python object class that supports overloaded operators can be used with spyndex methods.


"Hey... what do you mean by 'overloaded operators'?"


That's the million dollars' question! An object class that supports overloaded operators is the one that allows you to compute mathematical operations using common operators (+, -, /, *, **) like a + b, a + b * c or (a - b) / (a + b). You know the last one, right? That's the formula of the famous NDVI.

So, if you can use the overloaded operators with an object class, you can use that class with spyndex!

BE CAREFUL! Not all overloaded operators work as mathematical operators. In a list object class, the addition operator (+) concatenates two objects instead of performing an addition operation! So you must convert the list into a numpy.ndarray before using spyndex!

Here is a little list of object classes that support mathematical overloaded operators:

And wait, there is more! If objects that support overloaded operatores can be used in spyndex, that means that you can work in parallel with dask!

Here is the list of the dask objects that you can use with spyndex:

  • dask.Array (with dask)
  • dask.Series (with dask)

BUT WAIT! THERE IS EVEN MORE! If you want GPU-accelerated computing, you can use cupy!

This means that you can actually use spyndex in a lot of processes! For example, you can download a Sentinel-2 image with sentinelsat, open and read it with rasterio and then compute the desired spectral indices with spyndex. Or you can search through the Landsat-8 STAC in the Planetary Computer ecosystem using pystac-client, convert it to an xarray.DataArray with stackstac and then compute spectral indices using spyndex in parallel with dask or with GPU acceleration using cupy! Amazing, right!?

Installation

Install the latest version from PyPI:

pip install spyndex

Upgrade spyndex by running:

pip install -U spyndex

Install the latest version from conda-forge:

conda install -c conda-forge spyndex

Install the latest dev version from GitHub by running:

pip install git+https://github.com/davemlz/spyndex

Features

Exploring Spectral Indices

Spectral Indices from the Awesome Spectral Indices list can be accessed through spyndex.indices. This is a Box object where each one of the indices in the list can be accessed as well as their attributes:

import spyndex

# All indices
spyndex.indices

# NDVI index
spyndex.indices["NDVI"]

# Or with dot notation
spyndex.indices.NDVI

# Formula of the NDVI
spyndex.indices["NDVI"]["formula"]

# Or with dot notation
spyndex.indices.NDVI.formula

# Reference of the NDVI
spyndex.indices["NDVI"]["reference"]

# Or with dot notation
spyndex.indices.NDVI.reference

Default Values

Some Spectral Indices require constant values in order to be computed. Default values can be accessed through spyndex.constants. This is a Box object where each one of the constants can be accessed:

import spyndex

# All constants
spyndex.constants

# Canopy Background Adjustment
spyndex.constants["L"]

# Or with dot notation
spyndex.constants.L

# Default value
spyndex.constants["L"]["default"]

# Or with dot notation
spyndex.constants.L.default

Band Parameters

The standard band parameters description can be accessed through spyndex.bands. This is a Box object where each one of the bands can be accessed:

import spyndex

# All bands
spyndex.bands

# Blue band
spyndex.bands["B"]

# Or with dot notation
spyndex.bands.B

One (or more) Spectral Indices Computation

Use the computeIndex() method to compute as many spectral indices as you want! The index parameter receives the spectral index or a list of spectral indices to compute, while the params parameter receives a dictionary with the required parameters for the spectral indices computation.

import spyndex
import xarray as xr
import matplotlib.pyplot as plt
from rasterio import plot

# Open a dataset (in this case a xarray.DataArray)
snt = spyndex.datasets.open("sentinel")

# Scale the data (remember that the valid domain for reflectance is [0,1])
snt = snt / 10000

# Compute the desired spectral indices
idx = spyndex.computeIndex(
    index = ["NDVI","GNDVI","SAVI"],
    params = {
        "N": snt.sel(band = "B08"),
        "R": snt.sel(band = "B04"),
        "G": snt.sel(band = "B03"),
        "L": 0.5
    }
)

# Plot the indices (and the RGB image for comparison)
fig, ax = plt.subplots(2,2,figsize = (10,10))
plot.show(snt.sel(band = ["B04","B03","B02"]).data / 0.3,ax = ax[0,0],title = "RGB")
plot.show(idx.sel(index = "NDVI").data,ax = ax[0,1],title = "NDVI")
plot.show(idx.sel(index = "GNDVI").data,ax = ax[1,0],title = "GNDVI")
plot.show(idx.sel(index = "SAVI").data,ax = ax[1,1],title = "SAVI")

sentinel spectral indices

Kernel Indices Computation

Use the computeKernel() method to compute the required kernel for kernel indices like the kNDVI! The kernel parameter receives the kernel to compute, while the params parameter receives a dictionary with the required parameters for the kernel computation (e.g., a, b and sigma for the RBF kernel).

```python import spyndex import xarray as xr import matplotlib.pyplot as plt from rasterio import plot

Open a dataset (in this case a xarray.DataArray)

snt = spyndex.datasets.open("sentinel")

Scale the data (remember that the valid domain for reflectance is [0,1])

snt = snt / 10000

Compute the kNDVI

Core symbols most depended-on inside this repo

_load_JSON
called by 4
spyndex/utils.py
_get_indices
called by 3
spyndex/utils.py
_check_params
called by 2
spyndex/utils.py
_has_ee_image
called by 2
spyndex/utils.py
_has_ee_number
called by 2
spyndex/utils.py
_maybe_import_earthengine
called by 2
spyndex/utils.py
compute
called by 2
spyndex/axioms.py
_create_indices
called by 1
spyndex/axioms.py

Shape

Method 35
Function 13
Class 8

Languages

Python100%

Modules by API surface

spyndex/axioms.py29 symbols
tests/test_spyndex.py17 symbols
spyndex/utils.py6 symbols
spyndex/spyndex.py2 symbols
spyndex/plot.py1 symbols
spyndex/datasets.py1 symbols

For agents

$ claude mcp add spyndex \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page