From f6874fd02c659895ac47d0322ae7787549bd94bb Mon Sep 17 00:00:00 2001 From: Phil Brodrick Date: Sat, 21 Feb 2026 07:19:01 -0800 Subject: [PATCH 1/2] add envi reformat, fix some ortho read issues --- spectral_util/__main__.py | 2 ++ spectral_util/common/quicklooks.py | 2 ++ spectral_util/ea_assist/download.py | 2 ++ spectral_util/mosaic/mosaic.py | 3 +++ spectral_util/spec_io/spec_io.py | 8 ++++---- 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/spectral_util/__main__.py b/spectral_util/__main__.py index 4325861..29a8725 100644 --- a/spectral_util/__main__.py +++ b/spectral_util/__main__.py @@ -6,6 +6,7 @@ from spectral_util.mosaic import mosaic from spectral_util.ea_assist import earthaccess_helpers_AV3, earthaccess_helpers_EMIT from spectral_util import ea_assist +from spectral_util.spec_io import reformat @click.group() def cli(): @@ -15,6 +16,7 @@ def cli(): cli.add_command(mosaic.cli, name='mosaic') cli.add_command(common.cli_quicklook, name='quicklooks') cli.add_command(common.cli_plot, name='plot') +cli.add_command(reformat.cli, name='reformat') if __name__ == '__main__': cli() \ No newline at end of file diff --git a/spectral_util/common/quicklooks.py b/spectral_util/common/quicklooks.py index e6c8dc6..597c0db 100644 --- a/spectral_util/common/quicklooks.py +++ b/spectral_util/common/quicklooks.py @@ -52,6 +52,7 @@ def ndvi(input_file, output_file, ortho, red_wl, nir_wl, red_width, nir_width): """ Calculate NDVI. + \b Args: input_file (str): Path to the input file. output_file (str): Path to the output file. @@ -77,6 +78,7 @@ def nbr(input_file, output_file, ortho, nir_wl, swir_wl, nir_width, swir_width): """ Calculate NBR. + \b Args: input_file (str): Path to the input file. output_file (str): Path to the output file. diff --git a/spectral_util/ea_assist/download.py b/spectral_util/ea_assist/download.py index 4696ea4..d38e807 100644 --- a/spectral_util/ea_assist/download.py +++ b/spectral_util/ea_assist/download.py @@ -77,6 +77,8 @@ def get_scene(outdir: str, def get_fid(outdir, short_name, fid, subfile, version, overwrite): """ Download Earth Data granules based on search criteria. + + \b Args: outdir (str): Directory to save downloaded files. short_name (str): Short name of the dataset to search for. diff --git a/spectral_util/mosaic/mosaic.py b/spectral_util/mosaic/mosaic.py index 6331b75..83ae636 100644 --- a/spectral_util/mosaic/mosaic.py +++ b/spectral_util/mosaic/mosaic.py @@ -179,6 +179,7 @@ def stack_glts(glt_files, obs_file_lists, output_glt_file, output_file_list): """ Stack the GLTs from the input files. + \b Args: glt_files (list): List of GLT files to stack, in order. obs_file_lists (list): List of observation file lists, matching order to glt_files. @@ -239,6 +240,7 @@ def build_obs_nc(output_file, input_file_list, ignore_file_list, x_resolution, y """ Build a mosaic from the input file. + \b Args: output_file (str): Path to the output file. input_file_list (str): Path to the input file. @@ -384,6 +386,7 @@ def apply_glt(glt_file, raw_files, output_file, nodata_value, bands, output_form """ Apply the GLT to the input files. + \b Args: glt_file (str): Path to the GLT file. raw_files (str): Path to the raw files. diff --git a/spectral_util/spec_io/spec_io.py b/spectral_util/spec_io/spec_io.py index ba9d792..fa4b3e6 100644 --- a/spectral_util/spec_io/spec_io.py +++ b/spectral_util/spec_io/spec_io.py @@ -458,7 +458,7 @@ def open_loc_l1b_rad_nc(input_file, lazy=True, load_glt=False, load_loc=False): loc_plus_elev = np.stack([ds_loc['lat'], ds_loc['lon'], ds_loc['elev']], axis = -1) meta = GenericGeoMetadata([ds_loc['lat'].long_name, ds_loc['lon'].long_name, ds_loc['elev'].long_name], - trans, proj, glt=glt, pre_orthod=True, nodata_value=nodata_value, loc=loc) + trans, proj, glt=glt, pre_orthod=False, nodata_value=nodata_value, loc=loc) return meta, loc_plus_elev @@ -532,7 +532,7 @@ def open_emit_l2a_mask_nc(input_file, mask_type, lazy=True, load_glt=False, load mask = np.array(ds[mask_type][...]) - meta = GenericGeoMetadata(mask_names, trans, proj, glt=glt, pre_orthod=True, nodata_value=nodata_value, loc=loc) + meta = GenericGeoMetadata(mask_names, trans, proj, glt=glt, pre_orthod=False, nodata_value=nodata_value, loc=loc) return meta, mask @@ -568,7 +568,7 @@ def open_emit_obs_nc(input_file, lazy=True, load_glt=False, load_loc=False): logging.warning("Lazy loading not supported for observation data.") obs = ds['obs'][...] - meta = GenericGeoMetadata(obs_names, trans, proj, glt=glt, pre_orthod=True, nodata_value=nodata_value, loc=loc) + meta = GenericGeoMetadata(obs_names, trans, proj, glt=glt, pre_orthod=False, nodata_value=nodata_value, loc=loc) return meta, obs @@ -670,7 +670,7 @@ def open_airborne_obs(input_file, lazy=True, load_glt=False, load_loc=False): logging.warning("Lazy loading not supported for observation data.") obs = np.stack([ds['observation_parameters'][on] for on in obs_names], axis=-1) - meta = GenericGeoMetadata(obs_names, trans, proj, glt=glt, pre_orthod=True, nodata_value=nodata_value, loc=loc) + meta = GenericGeoMetadata(obs_names, trans, proj, glt=glt, pre_orthod=False, nodata_value=nodata_value, loc=loc) return meta, obs From 1d664c400449e9eb1d582222b90be99f9d0b6df7 Mon Sep 17 00:00:00 2001 From: Phil Brodrick Date: Sat, 21 Feb 2026 07:20:07 -0800 Subject: [PATCH 2/2] add new reformat utility --- spectral_util/spec_io/reformat.py | 53 +++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 spectral_util/spec_io/reformat.py diff --git a/spectral_util/spec_io/reformat.py b/spectral_util/spec_io/reformat.py new file mode 100644 index 0000000..0221317 --- /dev/null +++ b/spectral_util/spec_io/reformat.py @@ -0,0 +1,53 @@ +import click +import os +import numpy as np +from scipy.spatial import KDTree +from scipy.signal import convolve2d + +import time +import spectral_util.spec_io as spec_io +from osgeo import osr +import pyproj +import logging +from tqdm import tqdm +from copy import deepcopy +osr.UseExceptions() + +@click.command() +@click.argument('nc_file') +@click.argument('output_file') +@click.option('--ortho', is_flag=True) +@click.option('--overwrite', is_flag=True) +def nc_to_envi(nc_file: str, output_file: str, ortho=False, overwrite=False): + """Convert a NetCDF file to ENVI format. + + \b + Args: + nc_file (str): Path to the input NetCDF file. + output_file (str): Path to the output ENVI file. + ortho (bool, optional): Whether to orthorectify the data. Defaults to False. + """ + meta, dat = spec_io.load_data(nc_file, load_glt=True) + dat = np.array(dat) + + if ortho and meta.orthoable: + dat = spec_io.ortho_data(dat, meta.glt) + + if os.path.isfile(output_file) and not overwrite: + raise FileExistsError(f'Output file {output_file} already exists. Use --overwrite to overwrite it.') + + spec_io.write_envi_file(dat, meta, output_file) + + + + + +@click.group() +def cli(): + pass + + +cli.add_command(nc_to_envi) + +if __name__ == '__main__': + cli()