From 43c51dee85c23fe0c5edc1acf05e00666744da74 Mon Sep 17 00:00:00 2001 From: Matt Savoie Date: Tue, 10 Sep 2024 21:05:13 -0600 Subject: [PATCH] DAS-1934: Most basic implementation to allow umm-grid definitions (#14) --- CHANGELOG.md | 21 +++++++++++++++++---- README.md | 12 ++++++++---- bin/build-image | 2 +- bin/build-test | 2 +- bin/extract-release-notes.sh | 25 ++++++++++++++++--------- bin/run-test | 2 +- docker/service_version.txt | 2 +- docs/requirements.txt | 8 ++++---- swath_projector/exceptions.py | 9 +++++++++ swath_projector/reproject.py | 11 ++++++----- tests/unit/test_reproject.py | 8 +++++--- 11 files changed, 69 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c27abfe..0586534 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,20 @@ -## v1.0.1 -### 2024-04-05 +# Changelog + +## [v1.1.0] - 2024-08-29 +### Changed + +- [[DAS-1934](https://bugs.earthdata.nasa.gov/browse/DAS-1934)] + Input parameters that include both both resolutions (`xres` and `yres`) and + dimenions (`height` and `width`) no longer always raise an exception. An + exception is raised only when the parameters describe a grid that is not + internally consistent. [#14](https://github.com/nasa/harmony-swath-projector/pull/14) + +## [v1.0.1] - 2024-04-05 This version of the Swath Projector implements black code formatting across the entire repository. There should be no functional changes to the service. -## v1.0.0 -### 2023-11-16 +## [v1.0.0] - 2023-11-16 This version of the Harmony Swath Projector contains all functionality previously released internally to EOSDIS as `sds/swot-reproject:0.0.4`. @@ -23,3 +32,7 @@ Repository structure changes include: For more information on internal releases prior to NASA open-source approval, see legacy-CHANGELOG.md. + +[v1.1.0]:(https://github.com/nasa/harmony-swath-projector/releases/tag/1.0.1) +[v1.0.1]:(https://github.com/nasa/harmony-swath-projector/releases/tag/1.0.1) +[v1.0.0]:(https://github.com/nasa/harmony-swath-projector/releases/tag/1.0.0) diff --git a/README.md b/README.md index d234842..bfaad5f 100644 --- a/README.md +++ b/README.md @@ -105,10 +105,14 @@ The Swath Projector can specify several options for reprojection in the CRS. If the `scaleExtent` is not specified, it is derived from the walking the perimeter of the input grid, reprojected those points to the target CRS, and finding the extreme values in each reprojected dimension. -* `scaleSize`: The resolution of each output pixel in the reprojected CRS. This - should not be specified if the `height` and `width` are also supplied. The - default values are derived from finding the total area of the swath via Gauss' - Area formula, and assuming the pixels are square. +* `scaleSize`: The resolution of each output pixel in the reprojected CRS. The + default values are derived from finding the total area of the swath via + Gauss' Area formula, and assuming the pixels are square. This should not + normally be specified if the `height` and `width` are also supplied, in this + case the grid definition must be internally consistent with itself. Where + consistency is determined by the equation `scaleSize = (scaleExtent.max - + scaleExtent.min) / dimension` + All the attributes in the `format` property are optional, and have defaults as described. diff --git a/bin/build-image b/bin/build-image index dce8416..3915b12 100755 --- a/bin/build-image +++ b/bin/build-image @@ -21,4 +21,4 @@ tag=${1:-latest} # version number from `docker/service_version.txt`. # - "latest", so the test Dockerfile can use the service image as a base image. # -docker build -t ${image}:${tag} -t ${image}:latest -f docker/service.Dockerfile . +docker build --platform linux/amd64 -t ${image}:${tag} -t ${image}:latest -f docker/service.Dockerfile . diff --git a/bin/build-test b/bin/build-test index 05ae115..8ae6d9d 100755 --- a/bin/build-test +++ b/bin/build-test @@ -17,4 +17,4 @@ fi # Build the image # -docker build -t ${image}:${tag} -f docker/tests.Dockerfile . +docker build --platform linux/amd64 -t ${image}:${tag} -f docker/tests.Dockerfile . diff --git a/bin/extract-release-notes.sh b/bin/extract-release-notes.sh index 00cbf40..a7cd3b5 100755 --- a/bin/extract-release-notes.sh +++ b/bin/extract-release-notes.sh @@ -7,17 +7,24 @@ # 2023-06-16: Created. # 2023-10-10: Copied from earthdata-varinfo repository to HOSS. # 2024-01-03: Copied from HOSS repository to the Swath Projector. +# 2024-09-01: Copied and modified from HyBIG repository to handle new format. # ############################################################################### CHANGELOG_FILE="CHANGELOG.md" -VERSION_PATTERN="^## v" -# Count number of versions in version file: -number_of_versions=$(grep -c "${VERSION_PATTERN}" ${CHANGELOG_FILE}) -if [ ${number_of_versions} -gt 1 ] -then - grep -B 9999 -m 2 "${VERSION_PATTERN}" ${CHANGELOG_FILE} | sed '$d' | sed '$d' -else - cat ${CHANGELOG_FILE} -fi +## captures versions +## >## v1.0.0 +## >## [v1.0.0] +VERSION_PATTERN="^## [\[]v" + +## captures url links +#[v1.0.0]:(https://github.com/nasa/harmony-swath-projector/releases/tag/1.0.0) +LINK_PATTERN="^\[.*\].*/tag/.*" + +# Read the file and extract text between the first two occurrences of the +# VERSION_PATTERN +result=$(awk "/$VERSION_PATTERN/{c++; if(c==2) exit;} c==1" "$CHANGELOG_FILE") + +# Print the result +echo "$result" | grep -v "$VERSION_PATTERN" | grep -v "$LINK_PATTERN" diff --git a/bin/run-test b/bin/run-test index a3594dc..0a1731f 100755 --- a/bin/run-test +++ b/bin/run-test @@ -24,7 +24,7 @@ mkdir -p coverage # Run the tests in a Docker container with mounted volumes for XML report # output and test coverage reporting -docker run --rm \ +docker run --platform linux/amd64 --rm \ -v $(pwd)/test-reports:/home/tests/reports \ -v $(pwd)/coverage:/home/tests/coverage \ ghcr.io/nasa/harmony-swath-projector-test "$@" diff --git a/docker/service_version.txt b/docker/service_version.txt index 7dea76e..9084fa2 100644 --- a/docker/service_version.txt +++ b/docker/service_version.txt @@ -1 +1 @@ -1.0.1 +1.1.0 diff --git a/docs/requirements.txt b/docs/requirements.txt index efb479f..2ebeb36 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -10,7 +10,7 @@ # $ jupyter notebook. # 5) Click on the Swath Projector User Guide notebook. # -harmony-py ~= 0.4.9 -matplotlib ~= 3.7.2 -netCDF4 ~= 1.6.4 -notebook ~= 7.0.0 +harmony-py==0.4.15 +matplotlib==3.9.2 +netCDF4==1.7.1.post2 +notebook==7.2.2 diff --git a/swath_projector/exceptions.py b/swath_projector/exceptions.py index 49f7d84..b908569 100644 --- a/swath_projector/exceptions.py +++ b/swath_projector/exceptions.py @@ -43,3 +43,12 @@ def __init__(self, missing_coordinate): 'MissingCoordinatesError', f'Could not find coordinate {missing_coordinate}.', ) + + +class InvalidTargetGrid(CustomError): + """Raised when a request specifies an incomplete or invalid grid.""" + + def __init__(self): + super().__init__( + 'InvalidTargetGrid', 'Insufficient or invalid target grid parameters.' + ) diff --git a/swath_projector/reproject.py b/swath_projector/reproject.py index dab1192..808bf78 100644 --- a/swath_projector/reproject.py +++ b/swath_projector/reproject.py @@ -7,10 +7,12 @@ from typing import Dict from harmony.message import Message +from harmony.message_utility import has_self_consistent_grid from pyproj import Proj from varinfo import VarInfoFromNetCDF4 from swath_projector import nc_merge +from swath_projector.exceptions import InvalidTargetGrid from swath_projector.interpolation import resample_all_variables RADIUS_EARTH_METRES = ( @@ -122,14 +124,13 @@ def get_parameters_from_message( if parameters['interpolation'] in [None, '', 'None']: parameters['interpolation'] = INTERPOLATION_DEFAULT - # ERROR 5: -tr and -ts options cannot be used at the same time. + # when a user requests both a resolution and dimensions, then ensure the + # extents are consistent. if (parameters['xres'] is not None or parameters['yres'] is not None) and ( parameters['height'] is not None or parameters['width'] is not None ): - raise Exception( - '"scaleSize", "width" or/and "height" cannot ' - 'be used at the same time in the message.' - ) + if not has_self_consistent_grid(message): + raise InvalidTargetGrid() if not os.path.isfile(parameters['input_file']): raise Exception('Input file does not exist') diff --git a/tests/unit/test_reproject.py b/tests/unit/test_reproject.py index e3b566f..70a60d7 100644 --- a/tests/unit/test_reproject.py +++ b/tests/unit/test_reproject.py @@ -87,7 +87,7 @@ def test_get_parameters_error_5(self): dimensions, an exception is raised. """ - exception_snippet = 'cannot be used at the same time in the message.' + exception_snippet = 'Insufficient or invalid target grid parameters.' test_args = [ ['height and scaleSize', True, False, True, True], @@ -121,8 +121,10 @@ def test_get_parameters_error_5(self): with self.assertRaises(Exception) as context: get_parameters_from_message(message, self.granule_url, self.granule) - - self.assertTrue(str(context.exception).endswith(exception_snippet)) + self.assertTrue( + str(context.exception).endswith(exception_snippet), + f'Test Failed: {description}', + ) def test_get_parameters_missing_extents_or_dimensions(self): """Ensure that an exception is raised if there is only one of either