diff --git a/CHANGELOG.md b/CHANGELOG.md index 5442885..aa9222f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,20 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [v1.3.1](https://github.com/emit-sds/emit-sds-l2a/compare/v1.3.0...v1.3.1) + +> 10 January 2023 + +- Bad wavelengths update [`#6`](https://github.com/emit-sds/emit-sds-l2a/pull/6) +- Fix NetCDF metadata issues [`590878b`](https://github.com/emit-sds/emit-sds-l2a/commit/590878b13295794091e704d90e00594911db8882) +- grab bbl if specified, if not add something in [`dfb55c4`](https://github.com/emit-sds/emit-sds-l2a/commit/dfb55c43a44518e37a7db07d19240f598201fe5e) +- add bad wavelengths to uncertainty [`60ebe71`](https://github.com/emit-sds/emit-sds-l2a/commit/60ebe714974074ca0cf0150f39969c140793d2ac) + #### [v1.3.0](https://github.com/emit-sds/emit-sds-l2a/compare/v1.2.0...v1.3.0) -> 3 November 2022 +> 7 November 2022 +- Merge develop into main for v1.3.0 [`#5`](https://github.com/emit-sds/emit-sds-l2a/pull/5) - Analytical atm updates [`#4`](https://github.com/emit-sds/emit-sds-l2a/pull/4) - Rerun updates [`#3`](https://github.com/emit-sds/emit-sds-l2a/pull/3) - updated covariance for oxygen a help [`272d852`](https://github.com/emit-sds/emit-sds-l2a/commit/272d852d89bac2dab5adc597deebf1d16b595d1f) diff --git a/output_conversion.py b/output_conversion.py index 46044fa..9092af6 100644 --- a/output_conversion.py +++ b/output_conversion.py @@ -10,6 +10,7 @@ from emit_utils.file_checks import netcdf_ext, envi_header from spectral.io import envi import logging +import numpy as np def main(): @@ -51,11 +52,12 @@ def main(): logging.debug('Creating global attributes') makeGlobalAttr(nc_ds, args.rfl_file, args.glt_file) - nc_ds.title = "EMIT L2A Surface Reflectance 60 m " + args.version + nc_ds.title = "EMIT L2A Estimated Surface Reflectance 60 m " + args.version nc_ds.summary = nc_ds.summary + \ f"\\n\\nThis file contains L2A estimated surface reflectances \ - and geolocation data. Reflectance estimates are created using an Optimal Estimation technique - see ATBD for \ - details. Reflectance values are reported as fractions (relative to 1). " +and geolocation data. Reflectance estimates are created using an Optimal Estimation technique - see ATBD for \ +details. Reflectance values are reported as fractions (relative to 1). \ +Geolocation data (latitude, longitude, height) and a lookup table to project the data are also included." nc_ds.sync() logging.debug('Creating dimensions') @@ -67,6 +69,18 @@ def main(): add_variable(nc_ds, "sensor_band_parameters/fwhm", "f4", "Full Width at Half Max", "nm", [float(d) for d in rfl_ds.metadata['fwhm']], {"dimensions": ("bands",)}) + # Handle data pre January, where bbl was not set in ENVI header + if 'bbl' not in rfl_ds.metadata or rfl_ds.metadata['bbl'] == '{}': + wl = np.array(nc_ds['sensor_band_parameters']['wavelengths']) + bbl = np.ones(len(wl)) + bbl[np.logical_and(wl > 1325, wl < 1435)] = 0 + bbl[np.logical_and(wl > 1770, wl < 1962)] = 0 + else: + bbl = [bool(d) for d in rfl_ds.metadata['bbl']] + + add_variable(nc_ds, "sensor_band_parameters/good_wavelengths", "u1", "Wavelengths where reflectance is useable: 1 = good data, 0 = bad data", "unitless", + bbl, {"dimensions": ("bands",)}) + logging.debug('Creating and writing location data') add_loc(nc_ds, args.loc_file) @@ -93,11 +107,12 @@ def main(): logging.debug('Creating global attributes') makeGlobalAttr(nc_ds, args.rfl_unc_file, args.glt_file) - nc_ds.title = "EMIT L2A Surface Reflectance Uncertainty 60 m V001" + nc_ds.title = "EMIT L2A Estimated Surface Reflectance Uncertainty 60 m " + args.version nc_ds.summary = nc_ds.summary + \ f"\\n\\nThis file contains L2A estimated surface reflectance uncertainties \ - and geolocation data. Reflectance uncertainty estimates are created using an Optimal Estimation technique - see ATBD for \ - details. Reflectance uncertainty values are reported as fractions (relative to 1). " +and geolocation data. Reflectance uncertainty estimates are created using an Optimal Estimation technique - see ATBD for \ +details. Reflectance uncertainty values are reported as fractions (relative to 1). \ +Geolocation data (latitude, longitude, height) and a lookup table to project the data are also included." nc_ds.sync() logging.debug('Creating dimensions') @@ -108,6 +123,8 @@ def main(): [float(d) for d in rfl_ds.metadata['wavelength']], {"dimensions": ("bands",)}) add_variable(nc_ds, "sensor_band_parameters/fwhm", "f4", "Full Width at Half Max", "nm", [float(d) for d in rfl_ds.metadata['fwhm']], {"dimensions": ("bands",)}) + add_variable(nc_ds, "sensor_band_parameters/good_wavelengths", "u1", "Wavelengths where reflectance is useable: 1 = good data, 0 = bad data", "unitless", + bbl, {"dimensions": ("bands",)}) logging.debug('Creating and writing location data') add_loc(nc_ds, args.loc_file) @@ -134,10 +151,12 @@ def main(): logging.debug('Creating global attributes') makeGlobalAttr(nc_ds, args.mask_file, args.glt_file) - nc_ds.title = "EMIT L2A Masks 60 m V001" + nc_ds.title = "EMIT L2A Masks 60 m " + args.version nc_ds.summary = nc_ds.summary + \ f"\\n\\nThis file contains masks for L2A estimated surface reflectances \ - and geolocation data. Masks account for clouds, cloud shadows (via buffering), spacecraft interference, and poor atmospheric conditions." +and geolocation data. Masks account for clouds, cloud shadows (via buffering), spacecraft interference, and poor \ +atmospheric conditions. \ +Geolocation data (latitude, longitude, height) and a lookup table to project the data are also included." nc_ds.sync() logging.debug('Creating dimensions')