From fc4c6f96c9899f52f9fc9906f4be180e74bc2057 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Tue, 25 Feb 2025 09:26:05 -0800 Subject: [PATCH 1/4] update checking empty granules with is 360 check --- .../gov/nasa/podaac/forge/Footprinter.java | 49 ++++++++++++++----- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/src/main/java/gov/nasa/podaac/forge/Footprinter.java b/src/main/java/gov/nasa/podaac/forge/Footprinter.java index 2d7e6bb..4df6809 100644 --- a/src/main/java/gov/nasa/podaac/forge/Footprinter.java +++ b/src/main/java/gov/nasa/podaac/forge/Footprinter.java @@ -16,6 +16,7 @@ import ucar.nc2.Attribute; import ucar.nc2.NetcdfFile; import ucar.nc2.Variable; +import ucar.ma2.IndexIterator; import java.io.*; import java.util.ArrayList; @@ -100,6 +101,16 @@ public List buildRanges(String pattern, int[] shapes) throws InvalidRange return ranges; } + // Helper method to determine if longitude values are in 360-degree format + private boolean isLongitude360(double[] lonValues) { + for (double lon : lonValues) { + if (!Double.isNaN(lon) && lon > 180.0) { + return true; + } + } + return false; + } + /** * Checks whether the given latitude and longitude variables contain at least one valid coordinate pair. * @@ -116,27 +127,39 @@ public List buildRanges(String pattern, int[] shapes) throws InvalidRange * @throws IOException If reading from the variables fails. */ public boolean hasValidCoordinatePair(Variable latVariable, Variable lonVariable, - Map latAttMap, Map lonAttMap, - boolean is360) throws IOException { + Map latAttMap, Map lonAttMap) throws IOException { Array latValues = latVariable.read(); Array lonValues = lonVariable.read(); + final String SCALE = "scale"; + final String OFFSET = "offset"; + + int size = (int) Math.min(latValues.getSize(), lonValues.getSize()); + + // Create arrays to store transformed values + double[] transformedLats = new double[size]; + double[] transformedLons = new double[size]; + + // First pass: Apply scale and offset to all values + for (int i = 0; i < size; i++) { + transformedLats[i] = latValues.getDouble(i) * latAttMap.get(SCALE) + latAttMap.get(OFFSET); + transformedLons[i] = lonValues.getDouble(i) * lonAttMap.get(SCALE) + lonAttMap.get(OFFSET); + } + + // Determine if longitude is 360 based on transformed values + boolean is360 = isLongitude360(transformedLons); + // Constants for validation final double MIN_LAT = -90.0; final double MAX_LAT = 90.0; final double MIN_LON = is360 ? 0.0 : -180.0; final double MAX_LON = is360 ? 360.0 : 180.0; - final String SCALE = "scale"; - final String OFFSET = "offset"; - - int size = (int) Math.min(latValues.getSize(), lonValues.getSize()); + // Second pass: Check for valid pairs using transformed values for (int i = 0; i < size; i++) { - // Apply scale and offset to raw values - double lat = latValues.getDouble(i) * latAttMap.get(SCALE) + latAttMap.get(OFFSET); - double lon = lonValues.getDouble(i) * lonAttMap.get(SCALE) + lonAttMap.get(OFFSET); - - // Check if both values are within valid ranges and not NaN + double lat = transformedLats[i]; + double lon = transformedLons[i]; + if (!Double.isNaN(lat) && !Double.isNaN(lon) && lat >= MIN_LAT && lat <= MAX_LAT && lon >= MIN_LON && lon <= MAX_LON) { @@ -201,7 +224,7 @@ public Map footprint() throws FootprintException, InvalidRangeEx Map lonAttMap = getAttributes(lonVariable); int[] shapes = latVariable.getShape(); - boolean isValidLonLat = hasValidCoordinatePair(latVariable, lonVariable, latAttMap, latAttMap, is360); + boolean isValidLonLat = hasValidCoordinatePair(latVariable, lonVariable, latAttMap, latAttMap); if(!isValidLonLat){ throw new FootprintException("The granule trying to footprint doesn't have any valid longitude and latitude data."); @@ -289,7 +312,7 @@ public List constructCoordsFromNetcdf(List rangeList, Variabl boolean is360 = datasetConfig.isIs360(); boolean removeOrigin = datasetConfig.getFootprint().isRemoveOrigin(); - + List lonLats = new ArrayList<>(); for (int i = 0; i < latData.getSize(); i++) { if (latData.getDouble(i) == latAttMap.get(FILL) || lonData.getDouble(i) == lonAttMap.get(FILL)) { From ce3f36acee0ef1ed43de80a7bb0d7b219829a511 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Tue, 25 Feb 2025 09:26:44 -0800 Subject: [PATCH 2/4] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dab20ef..fb4db8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - **update check input lon and lat data** - Update check lon lat data function with now scale and offset of lats and lons. + = Add checking if data is 360 when testing empty granule files ### Deprecated ### Removed ### Fixed From 33f30b121f67e77db6d82d4d12c5bc1ca6dd21e2 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Tue, 25 Feb 2025 09:27:44 -0800 Subject: [PATCH 3/4] remove index iterator import --- src/main/java/gov/nasa/podaac/forge/Footprinter.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/gov/nasa/podaac/forge/Footprinter.java b/src/main/java/gov/nasa/podaac/forge/Footprinter.java index 4df6809..e06d62b 100644 --- a/src/main/java/gov/nasa/podaac/forge/Footprinter.java +++ b/src/main/java/gov/nasa/podaac/forge/Footprinter.java @@ -16,7 +16,6 @@ import ucar.nc2.Attribute; import ucar.nc2.NetcdfFile; import ucar.nc2.Variable; -import ucar.ma2.IndexIterator; import java.io.*; import java.util.ArrayList; From 66657433791b7ba5a06c3ba86e947c5a575107e2 Mon Sep 17 00:00:00 2001 From: Simon Liu Date: Tue, 25 Feb 2025 10:35:56 -0800 Subject: [PATCH 4/4] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb4db8c..04d7e2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - **update check input lon and lat data** - Update check lon lat data function with now scale and offset of lats and lons. - = Add checking if data is 360 when testing empty granule files + - Add checking if data is 360 when testing empty granule files ### Deprecated ### Removed ### Fixed