Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
459c1f1
reorged, working
pgbrodrick Feb 14, 2026
afdf796
move quicklooks to sub-cli
pgbrodrick Feb 14, 2026
d8d18a0
add very basic gh-action, update project.toml
pgbrodrick Feb 14, 2026
736a22b
readme and main mods
pgbrodrick Feb 14, 2026
f3d902e
Merge pull request #29 from pgbrodrick/package_help
pgbrodrick Feb 14, 2026
3e239a0
add dev to gh actions
pgbrodrick Feb 14, 2026
7ae04e5
update workflow tests with gdal install
pgbrodrick Feb 14, 2026
86839ee
remove windows install for now
pgbrodrick Feb 14, 2026
8d46df0
swap in pixi as the installer of choice
pgbrodrick Feb 14, 2026
50332dc
be explicit about manifest path
pgbrodrick Feb 14, 2026
52a14bc
make sure osx is in the pyproject
pgbrodrick Feb 14, 2026
7f885d5
update solve groups
pgbrodrick Feb 14, 2026
b0dc378
update pyproject and pixi
pgbrodrick Feb 14, 2026
1466894
add super basic test
pgbrodrick Feb 14, 2026
a4902af
update readme
pgbrodrick Feb 14, 2026
39a83a5
Merge pull request #30 from pgbrodrick/package_help
pgbrodrick Feb 14, 2026
209044a
basic fid download utility
pgbrodrick Feb 15, 2026
d66f065
typo fix
pgbrodrick Feb 15, 2026
91f8256
add some basic plotting routines, fix an io piece or two
pgbrodrick Feb 16, 2026
39e14c4
small plotting tweaks
pgbrodrick Feb 16, 2026
c0fbc00
Merge pull request #31 from pgbrodrick/ea
pgbrodrick Feb 16, 2026
faa3918
Merge pull request #32 from pgbrodrick/plot
pgbrodrick Feb 16, 2026
b35fbc2
readme update
pgbrodrick Feb 16, 2026
f6874fd
add envi reformat, fix some ortho read issues
pgbrodrick Feb 21, 2026
1d664c4
add new reformat utility
pgbrodrick Feb 21, 2026
97fbebf
Merge pull request #33 from pgbrodrick/reformat
pgbrodrick Feb 21, 2026
10b943d
readme update
pgbrodrick Feb 21, 2026
80c3d9d
add pca plots
pgbrodrick Feb 26, 2026
0bd7240
Merge branch 'dev' into pca
pgbrodrick Feb 26, 2026
386feb4
remove lingering extract from separate pr
pgbrodrick Feb 26, 2026
3eec2e1
Merge pull request #34 from pgbrodrick/pca
pgbrodrick Feb 26, 2026
e44bb8d
add mnf
pgbrodrick Mar 28, 2026
9247b6c
Merge pull request #35 from pgbrodrick/mnf
pgbrodrick Mar 28, 2026
e680a17
docs rewrite
pgbrodrick Mar 28, 2026
fce6f20
Merge pull request #36 from pgbrodrick/docs_update
pgbrodrick Mar 28, 2026
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
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# SCM syntax highlighting & preventing 3-way merges
pixi.lock merge=binary linguist-language=YAML linguist-generated=true -diff
39 changes: 39 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Test SpectralUtil CLI

on:
push:
branches: [ main, dev ]
pull_request:
branches: [ main, dev ]

jobs:
test:
name: ${{ matrix.environment }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
# Map these to the environment names we defined in pyproject.toml
environment: [py39, py310, py311, py312]

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Pixi
uses: prefix-dev/setup-pixi@v0.8.1
with:
manifest-path: pyproject.toml
# This installs the specific environment and handles caching automatically
environments: ${{ matrix.environment }}
cache: true

- name: Verify CLI installation
run: |
# Use 'pixi run -e <env>' to execute within the context
pixi run -e ${{ matrix.environment }} spectral_util --help

- name: Run tests
run: |
pixi run -e ${{ matrix.environment }} pytest -v
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,6 @@ cython_debug/

# PyPI configuration file
.pypirc
# pixi environments
.pixi/*
!.pixi/config.toml
216 changes: 200 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,217 @@
# SpectralUtil

SpectralUtil provides command-line and Python tools for common imaging spectroscopy workflows, including quicklooks, plotting, mosaicking, Earthdata download helpers, and format conversion.

# SpectralUtils

This is a package for basic manipulation of imaging spectroscopy data. It is designed to accomodate data from a variety of instruments, abstracting out the
specifics of the file delivery. Currently, the package supports data from the following instruments / product levels:

Supported products include:

- [AVIRIS-3 L1B Radiance](https://doi.org/10.3334/ORNLDAAC/2356)
- [AVIRIS-3 L2A Reflectance](https://daac.ornl.gov/cgi-bin/dsviewer.pl?ds_id=2357)
- AVIRIS-NG L2A Reflectance
- [EMIT L1B Radiance](https://lpdaac.usgs.gov/products/emitl1bradv001/)
- Any data in ENVI format
- [EMIT L2A Reflectance](https://lpdaac.usgs.gov/products/emitl2arflv001/)
- ENVI format inputs

## Installation

Recommended with [pixi](https://pixi.sh):

```bash
pixi install
```

Or with pip:

```bash
pip install spectral_util
```

## Running the CLI

If installed into your current environment:

```bash
spectral_util --help
```

If using the local pixi environment:

```bash
pixi run spectral_util --help
```

The top-level command groups are:

- download
- mosaic
- quicklooks
- plot
- reformat

## CLI Examples by Section

### download

#### download get-fid
```bash
# Download files for one specific FID and product short-name
spectral_util download get-fid ./downloads AV3_L1B_RDN_2356 AV320250809t182459_000

# Download only the RDN granule component (used in examples below)
spectral_util download get-fid ./downloads AV3_L1B_RDN_2356 AV320250809t182459_000 --subfile RDN --version 1

# Overwrite previously-downloaded files
spectral_util download get-fid ./downloads AV3_L1B_RDN_2356 AV320250809t182459_000 --subfile RDN --version 1 --overwrite
```

Assume the downloaded file used in subsequent examples is:

```text
./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc
```

### quicklooks

#### quicklooks rgb
```bash
# Basic RGB quicklook
spectral_util quicklooks rgb ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc output_rgb.tif

# RGB with custom wavelengths and percentile stretch
spectral_util quicklooks rgb ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc output_rgb.tif --red_wl 660 --green_wl 560 --blue_wl 460 --stretch 2 98

# RGB with explicit per-channel scaling (disable stretch)
spectral_util quicklooks rgb ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc output_rgb_scaled.tif --stretch -1 -1 --scale 0 0.2 0 0.2 0 0.2

# Orthorectified RGB output when GLT is available
spectral_util quicklooks rgb ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc output_rgb_ortho.tif --ortho
```

#### quicklooks ndvi
```bash
# Default NDVI
spectral_util quicklooks ndvi ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc output_ndvi.tif

# NDVI with custom wavelengths and band widths
spectral_util quicklooks ndvi ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc output_ndvi_custom.tif --red_wl 665 --nir_wl 842 --red_width 20 --nir_width 20

# Orthorectified NDVI
spectral_util quicklooks ndvi ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc output_ndvi_ortho.tif --ortho
```

#### quicklooks nbr
```bash
# Default NBR
spectral_util quicklooks nbr ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc output_nbr.tif

# NBR with custom NIR/SWIR settings
spectral_util quicklooks nbr ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc output_nbr_custom.tif --nir_wl 860 --swir_wl 2200 --nir_width 20 --swir_width 40

# Orthorectified NBR
spectral_util quicklooks nbr ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc output_nbr_ortho.tif --ortho
```

### plot

#### plot plot-basic-overview
```bash
# Show RGB + selected spectra interactively
spectral_util plot plot-basic-overview ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc

# Save basic overview plot and choose random sampling
spectral_util plot plot-basic-overview ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc --output_file spectra_overview.png --n_points 8 --method random

# K-means representative spectra
spectral_util plot plot-basic-overview ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc --output_file spectra_kmeans.png --n_points 10 --method kmeans
```

#### plot plot-pcs
```bash
# Plot first 20 principal components
spectral_util plot plot-pcs ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc --output_file pcs.png

# Plot a custom PC range with controlled sampling
spectral_util plot plot-pcs ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc --output_file pcs_10_29.png --first_pc 10 --last_pc 29 --n_points 20000 --seed 42
```

#### plot plot-mnf
```bash
# Plot first 20 MNF components
spectral_util plot plot-mnf ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc --output_file mnf.png

# Custom MNF count and covariance sampling options
spectral_util plot plot-mnf ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc --output_file mnf_30.png --n_mnf 30 --n_points 20000 --seed 42

# Estimate noise along rows instead of columns
spectral_util plot plot-mnf ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc --output_file mnf_diff_rows.png --diff_dim 0
```

### mosaic

#### mosaic build-obs-nc
```bash
# Build GLT mosaic from a text file of OBS inputs
spectral_util mosaic build-obs-nc mosaic_glt.tif obs_files.txt --x_resolution 30 --y_resolution -30 --output_epsg 4326

## Utilities
A series of utility scripts are provided to help with common tasks, such as:
# Build with explicit extent and criteria selection
spectral_util mosaic build-obs-nc mosaic_glt_utm.tif obs_files.txt \
--x_resolution 60 --y_resolution -60 --output_epsg 32611 \
--target_extent_ul_lr 3800000 420000 3700000 520000 \
--criteria_band 0 --criteria_mode min --n_cores 8

#### Standard RGB, with stretching
# Exclude selected files and set max nearest-neighbor distance
spectral_util mosaic build-obs-nc mosaic_filtered.tif obs_files.txt \
--ignore_file_list ignore_files.txt --x_resolution 30 --y_resolution -30 --max_distance 45
```
python spectral_util.py rgb EMIT_L1B_RAD_001_20240715T195403_2419712_015.nc emit_rgb.tif

#### mosaic apply-glt
```bash
# Apply GLT to a single raw file
spectral_util mosaic apply-glt mosaic_glt.tif ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc output_ortho.tif

# Apply GLT to a list of raw files and subset bands
spectral_util mosaic apply-glt mosaic_glt.tif raw_files.txt output_rgb.tif --bands 34 --bands 22 --bands 10

# Write ENVI output with custom nodata handling
spectral_util mosaic apply-glt mosaic_glt.tif raw_files.txt output_envi --output_format envi --nodata_value -9999 --glt_nodata_value 0
```

#### Standard RGB, custom wavelengths
#### mosaic stack-glts
```bash
# Merge several GLTs and their file lists into one stack
spectral_util mosaic stack-glts glt_files.txt obs_file_lists.txt stacked_glt.tif stacked_file_list.txt
```
python spectral_util.py rgb EMIT_L1B_RAD_001_20240715T195403_2419712_015.nc emit_rgb.tif --red_wl 2360 --green_wl 1800 --blue_wl 1000

### reformat

#### reformat nc-to-envi
```bash
# Convert NetCDF to ENVI
spectral_util reformat nc-to-envi ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc output_envi

# Convert NetCDF to orthorectified ENVI output
spectral_util reformat nc-to-envi ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc output_envi_ortho --ortho

# Overwrite existing output
spectral_util reformat nc-to-envi ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc output_envi --overwrite
```

### Spectral Indices
## Python API

For programmatic use:

```python
from spectral_util.common import quicklooks
from spectral_util.mosaic import mosaic
from spectral_util.ea_assist import earthaccess_helpers_AV3, earthaccess_helpers_EMIT
```
python spectral_util.py nbr EMIT_L1B_RAD_001_20240715T195403_2419712_015.nc emit_nbr.tif
python spectral_util.py ndvi EMIT_L1B_RAD_001_20240715T195403_2419712_015.nc emit_ndvi.tif
```

## Help

Use help at any level:
spectral_util reformat nc-to-envi ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc output_envi
```bash
spectral_util --help
spectral_util reformat nc-to-envi ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc output_envi_ortho --ortho
spectral_util quicklooks rgb --help
spectral_util plot --help
spectral_util reformat nc-to-envi ./downloads/AV320250809t182459_000_L1B_RDN_4842d6a3_RDN.nc output_envi --overwrite
Loading
Loading