Skip to content

About

No description, website, or topics provided.

Resources

Stars

8 stars

Watchers

2 watching

Forks

Latest commit

 

History

54 Commits

Folders and files

Repository files navigation

HyPyRameter

Spectral parameters (band depths, band areas, slopes, ratios, peaks and indices) for hyperspectral reflectance data: the CRISM parameter set of Viviano-Beck et al. (2014) plus additions for terrestrial and laboratory spectra. Works on image cubes, tables of spectra or a single spectrum.

DOI

Installation

pip install hypyrameter            # or:  uv add hypyrameter
pip install "hypyrameter[browse]"  # + PNG browse products (imageio)
pip install "hypyrameter[denoise]" # + the IOVF denoiser

Requires Python 3.10 or newer. The only hard dependencies are numpy, scipy, pandas and spectral (for ENVI files).

Usage

Core API

import numpy as np
from hypyrameter import compute, valid_parameters, PARAMETERS
from hypyrameter.io import read_envi, write_envi

cube, wavelengths, metadata = read_envi("scene.hdr")   # (rows, cols, bands), nm

names = valid_parameters(wavelengths)      # every parameter the range supports
params = compute(cube, wavelengths, names, progress=lambda f, n: print(f"{f:4.0%} {n}"))
write_envi("scene_params.hdr", params, names, base_metadata=metadata)

# or just a few, on any array with the wavelength axis last:
bd = compute(cube, wavelengths, ["BD2290", "BD1900_2", "RPEAK1"])
one = compute(cube[10, 20], wavelengths, ["BD2290"])   # a single spectrum
  • wavelengths may be in nm or µm (values below 10 are taken as µm).
  • Missing data is NaN in and NaN out. Fill bad bands first with hypyrameter.fill_nans_along_spectrum if you want a parameter whose window straddles them.
  • PARAMETERS maps each name to its wavelength range, description and group; valid_parameters(wavelengths, tolerance=5) filters by range.
  • Parameters that depend on another (BDI1000VIS needs RPEAK1) compute what they need automatically.

Browse products

from hypyrameter.browse import BROWSE_PRODUCTS, browse_image, write_browse_products

layers = {name: params[..., i] for i, name in enumerate(names)}
rgb = browse_image(layers, "PHY")                   # (rows, cols, 3) uint8
write_browse_products(layers, "browse/")            # a PNG per valid product

BROWSE_PRODUCTS holds the 18 CRISM MTRDR browse products with the channels the PDS products' labels name (CRISM Data Product SIS, §3.12.3; Viviano-Beck et al. 2014): TRU, VNA, FEM, FM2, FAL, IRA, MAF, HYD, PHY, PFM, PAL, HYS, ICE, IC2, CHL, CAR, CR2 and TAN; and HyPyRameter's own BIO, FM3, HEM, HYD2, HYD3, PLG, SED and SUL. browse_image stretches each channel by the scene's statistics (stretch), not by the PDS products' fixed ranges.

The 0.2.x classes

cubeParamCalculator and pointParamCalculator still exist as thin wrappers over the core and behave as before, minus the interactive prompts when you give them their inputs:

from hypyrameter.paramCalculator import cubeParamCalculator, pointParamCalculator

pc = cubeParamCalculator(in_file="scene.hdr", outdir="out/")   # dialogs if omitted
pc.run()                       # writes out/scene_params.hdr and browse PNGs

ppc = pointParamCalculator(data_path="spectra.csv")   # or df=..., or a .sed glob
table = ppc.run()              # DataFrame: parameters (rows) x spectra (columns)

Both accept parameters=[...] to compute a subset. See the notebooks in hypyrameter/ for worked examples.

Parameters

Parameter Range (nm) Description
R440 440–440 Reflectance at 440 nm (5-band median)
R463 463–463 Reflectance at 463 nm (5-band median)
R530 530–530 Reflectance at 530 nm (5-band median)
R550 550–550 Reflectance at 550 nm (5-band median)
R600 600–600 Reflectance at 600 nm (5-band median)
R637 637–637 Reflectance at 637 nm (5-band median)
R770 770–770 Reflectance at 770 nm (5-band median)
R1080 1080–1080 Reflectance at 1080 nm (5-band median)
R1330 1330–1330 Reflectance at 1330 nm (11-band median)
R1506 1506–1506 Reflectance at 1506 nm (5-band median)
R2529 2529–2529 Reflectance at 2529 nm (5-band median)
R3920 3920–3920 Reflectance at 3920 nm (5-band median)
HCPINDEX2 1690–2530 High-calcium pyroxene index: weighted continuum-relative depths between 2120 and 2460 nm (continuum 1690-2530 nm)
LCPINDEX2 1560–2450 Low-calcium pyroxene index: weighted continuum-relative depths between 1690 and 1870 nm (continuum 1560-2450 nm)
OLINDEX3 1210–1862 Olivine index: weighted continuum-relative depths between 1210 and 1330 nm (continuum 1750-1862 nm)
ESINDEX 420–950 Elemental sulfur index: steep 420-500 nm slope minus
SINDEX2 2120–2400 Sulfate index: inverted band depth at 2290 nm (2120-2400 nm)
GINDEX 1440–1570 Gypsum index: minimum of the 1447, 1491 and 1540 nm band depths
CPLINDEX 600–710 Chlorophyll index: minimum of the 626 and 678 nm band depths
CHLORINDEX 1800–2450 Chlorite index: weighted 2347, 2254, 2000 and 1921 nm depths and 2105 nm shoulder, minus BD2210_2
BD530_2 440–614 530 nm band depth (ferric oxides)
BD670 620–745 670 nm band depth (custom; hematite/chlorophyll)
BD875 747–980 875 nm band depth (custom; ferric minerals)
BD905 750–1300 905 nm band depth
BD920_2 807–984 920 nm band depth (ferric minerals)
BD1200 1115–1260 1200 nm band depth
BD1300 1080–1750 1300 nm band depth (plagioclase)
BD1400 1330–1467 1400 nm band depth (hydration)
BD1450 1340–1535 1450 nm band depth (hydration)
BD1750 1688–1820 1750 nm band depth (gypsum)
BD1900_2 1850–2067 1930 nm band depth (H2O)
BD2100_2 1930–2250 2130 nm band depth (monohydrated sulfates)
BD2100_3 2016–2220 2100 nm band depth
BD2165 2120–2230 2165 nm band depth (kaolinite group)
BD2190 2120–2250 2190 nm band depth (beidellite, allophane)
BD2210_2 2165–2290 2210 nm band depth (Al-OH phyllosilicates)
BD2250 2120–2340 2250 nm band depth
BD2265 2120–2340 2265 nm band depth (jarosite)
BD2290 2250–2350 2290 nm band depth (Fe/Mg phyllosilicates)
BD2443 2320–2480 2443 nm band depth (nitrate)
BD2355 2300–2450 2355 nm band depth (Fe/Mg phyllosilicates)
BD2600 2530–2630 2600 nm band depth (H2O)
BD1435 1370–1470 1435 nm band depth (CO2 ice, some hydrated minerals)
BD1500_2 1367–1808 1525 nm band depth (H2O ice)
BD2500_2 2364–2570 2480 nm band depth (Mg-carbonate overtone)
BD1900r2 1815–2132 1900 nm band depth, ratio form: mean continuum-relative reflectance at 1908-1941 nm over that at 1862-1875 and 2112-2126 nm (continuum 1815-2132 nm)
BDCARB 2230–2600 Carbonate band depth: geometric mean of the 2330 and 2530 nm band depths
BA1200 1115–1260 1200 nm band area
BA1450 1340–1535 1450 nm band area
BA1900 1850–2067 1900 nm band area
SH600_2 533–716 600 nm shoulder height: 1 - continuum (533-716 nm) / R600 (select ferric minerals)
SH460 420–520 460 nm shoulder height (inverted band depth)
D460 420–520 Alias of SH460 (point-spectra name)
D700 630–830 700 nm drop-off (chlorophyll red edge): continuum-relative 690-720 nm over 740-770 nm (continuum 630-830 nm)
D2200 1815–2430 2200 nm drop-off: continuum-relative 2210 and 2230 nm over 2165 nm (continuum 1815-2430 nm)
D2300 1815–2530 2300 nm drop-off: continuum-relative 2290-2330 nm over 2120-2210 nm (continuum 1815-2530 nm)
MIN2295_2480 2165–2570 Minimum of the 2295 and 2480 nm band depths (Mg carbonate)
MIN2250 2165–2350 Minimum of the 2210 and 2265 nm band depths (opal)
MIN2345_2537 2250–2602 Minimum of the 2345 and 2537 nm band depths (Ca/Fe carbonate)
BH1500 1250–1750 1500 nm band height (inverted band depth)
RPEAK1 442–989 Wavelength (µm) of the reflectance peak of a 5th-order polynomial through 13 anchors between 442 and 989 nm
RPEAK1_2 500–1150 Wavelength (µm) of the reflectance peak between 500 and 1150 nm after Savitzky-Golay smoothing
BDI1000VIS 833–1023 Integrated 1000 nm band depth (VIS): the integral (µm) over 833-1023 nm of 1 - R/RPEAK1, the reflectance normalised by the RPEAK1 peak, through a 4th-order polynomial fit
SLOPE420_500 420–500 Spectral slope 420-500 nm (reflectance per µm); >5 suggests elemental sulfur
SLOPE1815_2530 1815–2530 Spectral slope 1815-2530 nm (reflectance per µm)
ISLOPE 1815–2530 Inverse spectral slope 1815-2530 nm: -SLOPE1815_2530 (point-spectra name)
ISLOPE1 1815–2530 Spectral slope 1: (R1815 - R2530) / (W2530 - W1815), wavelengths in µm (ferric coating on dark rock); the CRISM name of ISLOPE
BD3000 2210–3000 3 µm H2O band depth: 1 - R3000 / (R2530 x R2530 / R2210), allowing for the spectral slope (bound H2O)
CINDEX2 3450–3875 Carbonate index: 1 - continuum (3450-3875 nm) / R3610, the convexity at 3.6 µm between the 3.4 and 3.9 µm carbonate bands
BR800 800–997 Band ratio R800 / R997
BR2530 2210–2530 Band ratio R2530 / R2210
IRR2 2210–2530 Alias of BR2530 (point-spectra name)
BR3500 3390–3500 Band ratio R3500 / R3390
NDVI 665–833 Normalised difference vegetation index (833, 665 nm)
NDWI 560–833 Normalised difference water index (560, 833 nm)
NDMI 833–1670 Normalised difference moisture index (833, 1670 nm)

Denoising

hypyrameter.iovf_generic.iovf is the iterative outlier voting filter of Phillips et al. (2023); it is slow and optional (pip install "hypyrameter[denoise]"). ngMeet_denoiser.m is a MATLAB script for the NGMeet algorithm.

Development

git clone git@github.com:Michael-S-Phillips/HyPyRameter.git
cd HyPyRameter
uv sync --group dev
uv run pytest
uv run ruff check . && uv run ruff format .

Releases: bump version in pyproject.toml, add a CHANGELOG entry, tag vX.Y.Z and push the tag; CI tests, builds and publishes to PyPI.

License

CC BY 4.0. Please cite the associated Planetary Science Journal publication (Phillips et al.).

About

No description, website, or topics provided.

Resources

Stars

8 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages