diff --git a/CHANGELOG.md b/CHANGELOG.md index 698ff57..c757856 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## v1.1.6 +### 2025-02-24 + +This version of HOSS adds support for multiple coordinate variables that +are in the same group for cases where coordinates are used in place of +dimensions. This also supports exclusive requests of coordinate +datasets that do not have coordinate attributes or dimensions. + ## v1.1.5 ### 2025-02-14 diff --git a/docker/service_version.txt b/docker/service_version.txt index e25d8d9..0664a8f 100644 --- a/docker/service_version.txt +++ b/docker/service_version.txt @@ -1 +1 @@ -1.1.5 +1.1.6 diff --git a/hoss/coordinate_utilities.py b/hoss/coordinate_utilities.py index 3da1527..d5e2843 100644 --- a/hoss/coordinate_utilities.py +++ b/hoss/coordinate_utilities.py @@ -106,19 +106,11 @@ def get_dimension_array_names( latitude_coordinates, longitude_coordinates = get_coordinate_variables( varinfo, [variable_name] ) - # Given variable has coordinates: use latitude coordinate + # Given variable has coordinates: use latitude and longitude coordinate # to define variable spatial dimensions. if len(latitude_coordinates) == 1 and len(longitude_coordinates) == 1: dimension_names = create_spatial_dimension_names_from_coordinates( - varinfo, latitude_coordinates[0] - ) - - # Given variable variable has no coordinate attribute itself, - # but is itself a coordinate (latitude or longitude): - # use as a coordinate to define spatial dimensions - elif variable.is_latitude() or variable.is_longitude(): - dimension_names = create_spatial_dimension_names_from_coordinates( - varinfo, variable_name + varinfo, latitude_coordinates[0], longitude_coordinates[0] ) else: dimension_names = {} @@ -126,22 +118,25 @@ def get_dimension_array_names( def create_spatial_dimension_names_from_coordinates( - varinfo: VarInfoFromDmr, variable_name: str + varinfo: VarInfoFromDmr, lat_coord_name: str, lon_coord_name: str ) -> dict[str:str]: - """returns the x-y variable names that would - match the group of the input variable. The 'dim_y' dimension - and 'dim_x' names are returned with the group pathname + """returns the x-y dimension names concatenated with full path names + of the latitude and longitude coordinate variable names. The names are + returned as a dictionary with y_coordinate, x_coordinate order. """ - variable = varinfo.get_variable(variable_name) + lat_coord_variable = varinfo.get_variable(lat_coord_name) + lon_coord_variable = varinfo.get_variable(lon_coord_name) - if variable is not None: + if lat_coord_variable is not None and lon_coord_variable is not None: dimension_names = { - 'projection_y_coordinate': f'{variable.group_path}/y_dim', - 'projection_x_coordinate': f'{variable.group_path}/x_dim', + 'projection_y_coordinate': f'{lat_coord_variable.full_name_path}_' + f'{lon_coord_variable.full_name_path}/y_dim', + 'projection_x_coordinate': f'{lat_coord_variable.full_name_path}_' + f'{lon_coord_variable.full_name_path}/x_dim', } else: - raise MissingVariable(variable_name) + raise MissingVariable(f'{lat_coord_name},{lon_coord_name}') return dimension_names @@ -159,7 +154,6 @@ def create_dimension_arrays_from_coordinates( 3) Generate the x-y dimscale array and return to the calling method """ - # dimension_names = get_dimension_array_names(varinfo, variable_name) if len(dimension_names) < 2: raise InvalidDimensionNames(dimension_names) @@ -263,10 +257,17 @@ def get_valid_sample_pts( # get maximally spread points within rows max_x_spread_pts = get_max_spread_pts(~valid_lat_lon_mask) + if valid_lat_lon_mask.ndim == 2: + transpose_mask = np.transpose(~valid_lat_lon_mask) + elif valid_lat_lon_mask.ndim == 3: + # this is for nominal order (z,y,x) + transpose_mask = np.transpose(~valid_lat_lon_mask, (0, 2, 1)) + else: + raise NotImplementedError # Doing the same for the columns is done by transposing the valid_mask # and then fixing the results from [x, y] to [y, x]. - max_y_spread_trsp = get_max_spread_pts(np.transpose(~valid_lat_lon_mask)) + max_y_spread_trsp = get_max_spread_pts(transpose_mask) max_y_spread_pts = [ list(np.flip(max_y_spread_trsp[0])), list(np.flip(max_y_spread_trsp[1])), diff --git a/hoss/hoss_config.json b/hoss/hoss_config.json index c50abe9..d2499c4 100644 --- a/hoss/hoss_config.json +++ b/hoss/hoss_config.json @@ -1,6 +1,6 @@ { "Identification": "hoss_config", - "Version": 22, + "Version": 23, "CollectionShortNamePath": [ "/HDF5_GLOBAL/short_name", "/NC_GLOBAL/short_name", @@ -400,6 +400,132 @@ ], "_Description": "Ensure variables in /Soil_Moisture_Retrieval_Data_Polar_PM group point to correct coordinate variables." }, + { + "Applicability": { + "Mission": "SMAP", + "ShortNamePath": "SPL3SMP", + "VariablePattern": "/Soil_Moisture_Retrieval_Data_AM/(lat|long)itude" + }, + "Attributes": [ + { + "Name": "coordinates", + "Value": "/Soil_Moisture_Retrieval_Data_AM/latitude, /Soil_Moisture_Retrieval_Data_AM/longitude" + } + ], + "_Description": "Ensure coordinate variables in /Soil_Moisture_Retrieval_Data_AM group have coordinate attributes." + }, + { + "Applicability": { + "Mission": "SMAP", + "ShortNamePath": "SPL3SMP_E", + "VariablePattern": "/Soil_Moisture_Retrieval_Data_AM/(lat|long)itude" + }, + "Attributes": [ + { + "Name": "coordinates", + "Value": "/Soil_Moisture_Retrieval_Data_AM/latitude, /Soil_Moisture_Retrieval_Data_AM/longitude" + } + ], + "_Description": "Ensure coordinate variables in /Soil_Moisture_Retrieval_Data_AM group have coordinate attributes." + }, + { + "Applicability": { + "Mission": "SMAP", + "ShortNamePath": "SPL3SMP_E", + "VariablePattern": "/Soil_Moisture_Retrieval_Data_Polar_AM/(lat|long)itude" + }, + "Attributes": [ + { + "Name": "coordinates", + "Value": "/Soil_Moisture_Retrieval_Data_Polar_AM/latitude, /Soil_Moisture_Retrieval_Data_Polar_AM/longitude" + } + ], + "_Description": "Ensure coordinate variables in /Soil_Moisture_Retrieval_Data_Polar_AM group have coordinate attributes." + }, + { + "Applicability": { + "Mission": "SMAP", + "ShortNamePath": "SPL3SM(A|AP)", + "VariablePattern": "/Soil_Moisture_Retrieval_Data/(lat|long)itude" + }, + "Attributes": [ + { + "Name": "coordinates", + "Value": "/Soil_Moisture_Retrieval_Data/latitude, /Soil_Moisture_Retrieval_Data/longitude" + } + ], + "_Description": "Ensure coordinate variables in /Soil_Moisture_Retrieval_Data group have coordinate attributes." + }, + { + "Applicability": { + "Mission": "SMAP", + "ShortNamePath": "SPL2SMAP_S", + "VariablePattern": "/Soil_Moisture_Retrieval_Data_1km/(lat|long)itude_1km" + }, + "Attributes": [ + { + "Name": "coordinates", + "Value": "/Soil_Moisture_Retrieval_Data_1km/latitude_1km, /Soil_Moisture_Retrieval_Data_1km/longitude_1km" + } + ], + "_Description": "Ensure coordinate variables in /Soil_Moisture_Retrieval_Data_1km group have coordinate attributes." + }, + { + "Applicability": { + "Mission": "SMAP", + "ShortNamePath": "SPL2SMAP_S", + "VariablePattern": "/Soil_Moisture_Retrieval_Data_3km/(lat|long)itude_3km" + }, + "Attributes": [ + { + "Name": "coordinates", + "Value": "/Soil_Moisture_Retrieval_Data_3km/latitude_3km, /Soil_Moisture_Retrieval_Data_3km/longitude_3km" + } + ], + "_Description": "Ensure coordinate variables in /Soil_Moisture_Retrieval_Data_3km group have coordinate attributes." + }, + { + "Applicability": { + "Mission": "SMAP", + "ShortNamePath": "SPL3FTA", + "VariablePattern": "/Freeze_Thaw_Retrieval_Data/(lat|long)itude" + }, + "Attributes": [ + { + "Name": "coordinates", + "Value": "/Freeze_Thaw_Retrieval_Data/latitude, /Freeze_Thaw_Retrieval_Data/longitude" + } + ], + "_Description": "Ensure coordinate variables in /Freeze_Thaw_Retrieval_Data group have coordinate attributes." + }, + { + "Applicability": { + "Mission": "SMAP", + "ShortNamePath": "SPL3FT(P|P_E)", + "VariablePattern": "/Freeze_Thaw_Retrieval_Data_Global/(lat|long)itude" + }, + "Attributes": [ + { + "Name": "coordinates", + "Value": "/Freeze_Thaw_Retrieval_Data_Global/latitude, /Freeze_Thaw_Retrieval_Data_Global/longitude" + } + ], + "_Description": "Ensure coordinate variables in /Freeze_Thaw_Retrieval_Data_Global group have coordinate attributes." + }, + { + "Applicability": { + "Mission": "SMAP", + "ShortNamePath": "SPL3FT(P|P_E)", + "VariablePattern": "/Freeze_Thaw_Retrieval_Data_Polar/(latitude|longitude)" + }, + "Attributes": [ + { + "Name": "coordinates", + "Value": "/Freeze_Thaw_Retrieval_Data_Polar/latitude, /Freeze_Thaw_Retrieval_Data_Polar/longitude" + } + ], + "_Description": "Ensure coordinate variables in /Freeze_Thaw_Retrieval_Data_Polar group have coordinate attributes." + }, { "Applicability": { "Mission": "SMAP", @@ -445,7 +571,7 @@ { "Applicability": { "Mission": "SMAP", - "ShortNamePath": "SPL3SMP", + "ShortNamePath": "SPL3SMP|SPL3FT(A|P|P_E)", "VariablePattern": ".*/x_dim" }, "Attributes": [ @@ -467,7 +593,7 @@ { "Applicability": { "Mission": "SMAP", - "ShortNamePath": "SPL3SMP", + "ShortNamePath": "SPL3SMP|SPL3FT(A|P|P_E)", "VariablePattern": ".*/y_dim" }, "Attributes": [ @@ -489,7 +615,7 @@ { "Applicability": { "Mission": "SMAP", - "ShortNamePath": "SPL3SMP", + "ShortNamePath": "SPL3FT(A|P|P_E)", "VariablePattern": ".*/am_pm" }, "Attributes": [ @@ -504,6 +630,24 @@ ], "_Description": "The pseudo-dimension variable is here supplemented with variable attributes (as if it was a dimension variables) to clarify the dimension name" }, + { + "Applicability": { + "Mission": "SMAP", + "ShortNamePath": "SPL3SMP", + "VariablePattern": ".*/lc_type" + }, + "Attributes": [ + { + "Name": "dimensions", + "Value": "lc_type" + }, + { + "Name": "long_name", + "Value": "land cover type" + } + ], + "_Description": "The pseudo-dimension variable is here supplemented with variable attributes (as if it was a dimension variable) to clarify the dimension name" + }, { "Applicability": { "Mission": "ICESat2", diff --git a/hoss/projection_utilities.py b/hoss/projection_utilities.py index c3c6cf5..06fc701 100644 --- a/hoss/projection_utilities.py +++ b/hoss/projection_utilities.py @@ -78,8 +78,7 @@ def get_grid_mapping_attributes(variable: str, varinfo: VarInfoFromDmr) -> Dict: if cf_attributes: return cf_attributes - else: - raise MissingGridMappingVariable(grid_mapping, variable) + raise MissingGridMappingVariable(grid_mapping, variable) except AttributeError as exception: raise MissingGridMappingVariable(grid_mapping, variable) from exception diff --git a/tests/data/SC_SPL3SMP_008_fake.dmr b/tests/data/SC_SPL3SMP_008_fake.dmr index 009e070..7bf9dfe 100644 --- a/tests/data/SC_SPL3SMP_008_fake.dmr +++ b/tests/data/SC_SPL3SMP_008_fake.dmr @@ -111,6 +111,90 @@ Y + + + + + Longitude of the center of the Earth based grid cell. + + + degrees_east + + + + + + + Latitude of the center of the Earth based grid cell. + + + degrees_north + + + + + + + Longitude of the center of the Earth based grid cell. + + + degrees_east + + + + + + + Latitude of the center of the Earth based grid cell. + + + degrees_north + + + + + + + Representative SCA-V soil moisture measurement for the Earth based grid cell. + + + cm**3/cm**3 + + + /Soil_Moisture_Retrieval_Data_AM/same_folder_latitude1 /Soil_Moisture_Retrieval_Data_AM/same_folder_longitude1 + + + 0.01999999955 + + + 0.5 + + + -9999. + + + + + + + Representative SCA-V soil moisture measurement for the Earth based grid cell. + + + cm**3/cm**3 + + + /Soil_Moisture_Retrieval_Data_AM/same_folder_latitude2 /Soil_Moisture_Retrieval_Data_AM/same_folder_longitude2 + + + 0.01999999955 + + + 0.5 + + + -9999. + + diff --git a/tests/unit/test_coordinate_utilities.py b/tests/unit/test_coordinate_utilities.py index 3e5d2c2..7ba7663 100644 --- a/tests/unit/test_coordinate_utilities.py +++ b/tests/unit/test_coordinate_utilities.py @@ -529,8 +529,8 @@ def test_create_spatial_dimension_names_from_coordinates(self): """ expected_dimension_names = { - 'projection_y_coordinate': '/Soil_Moisture_Retrieval_Data_AM/y_dim', - 'projection_x_coordinate': '/Soil_Moisture_Retrieval_Data_AM/x_dim', + 'projection_y_coordinate': '/Soil_Moisture_Retrieval_Data_AM/latitude_/Soil_Moisture_Retrieval_Data_AM/longitude/y_dim', + 'projection_x_coordinate': '/Soil_Moisture_Retrieval_Data_AM/latitude_/Soil_Moisture_Retrieval_Data_AM/longitude/x_dim', } with self.subTest( @@ -538,17 +538,7 @@ def test_create_spatial_dimension_names_from_coordinates(self): ): self.assertDictEqual( create_spatial_dimension_names_from_coordinates( - self.varinfo, self.latitude - ), - expected_dimension_names, - ) - - with self.subTest( - 'Retrieves expected dimension names for the longitude variable' - ): - self.assertDictEqual( - create_spatial_dimension_names_from_coordinates( - self.varinfo, self.longitude + self.varinfo, self.latitude, self.longitude ), expected_dimension_names, ) @@ -556,11 +546,13 @@ def test_create_spatial_dimension_names_from_coordinates(self): with self.subTest('Raises exception for missing coordinate variable'): with self.assertRaises(MissingVariable) as context: create_spatial_dimension_names_from_coordinates( - self.varinfo, '/Soil_Moisture_Retrieval_Data_AM/random_variable' + self.varinfo, + '/Soil_Moisture_Retrieval_Data_AM/random_variable', + '/Soil_Moisture_Retrieval_Data_AM/random_variable', ) self.assertEqual( context.exception.message, - '"/Soil_Moisture_Retrieval_Data_AM/random_variable" is ' + '"/Soil_Moisture_Retrieval_Data_AM/random_variable,/Soil_Moisture_Retrieval_Data_AM/random_variable" is ' 'not present in source granule file.', ) @@ -569,13 +561,13 @@ def test_get_dimension_array_names(self): are returned for the requested variables """ - expected_override_dimensions_AM = { - 'projection_y_coordinate': '/Soil_Moisture_Retrieval_Data_AM/y_dim', - 'projection_x_coordinate': '/Soil_Moisture_Retrieval_Data_AM/x_dim', + expected_override_dimensions_am = { + 'projection_y_coordinate': '/Soil_Moisture_Retrieval_Data_AM/latitude_/Soil_Moisture_Retrieval_Data_AM/longitude/y_dim', + 'projection_x_coordinate': '/Soil_Moisture_Retrieval_Data_AM/latitude_/Soil_Moisture_Retrieval_Data_AM/longitude/x_dim', } - expected_override_dimensions_PM = { - 'projection_y_coordinate': '/Soil_Moisture_Retrieval_Data_PM/y_dim', - 'projection_x_coordinate': '/Soil_Moisture_Retrieval_Data_PM/x_dim', + expected_override_dimensions_pm = { + 'projection_y_coordinate': '/Soil_Moisture_Retrieval_Data_PM/latitude_pm_/Soil_Moisture_Retrieval_Data_PM/longitude_pm/y_dim', + 'projection_x_coordinate': '/Soil_Moisture_Retrieval_Data_PM/latitude_pm_/Soil_Moisture_Retrieval_Data_PM/longitude_pm/x_dim', } with self.subTest( @@ -585,7 +577,7 @@ def test_get_dimension_array_names(self): get_dimension_array_names( self.varinfo, '/Soil_Moisture_Retrieval_Data_AM/surface_flag' ), - expected_override_dimensions_AM, + expected_override_dimensions_am, ) with self.subTest( @@ -593,7 +585,7 @@ def test_get_dimension_array_names(self): ): self.assertDictEqual( get_dimension_array_names(self.varinfo, self.longitude), - expected_override_dimensions_AM, + expected_override_dimensions_am, ) with self.subTest( @@ -601,7 +593,7 @@ def test_get_dimension_array_names(self): ): self.assertDictEqual( get_dimension_array_names(self.varinfo, self.latitude), - expected_override_dimensions_AM, + expected_override_dimensions_am, ) with self.subTest( @@ -611,7 +603,7 @@ def test_get_dimension_array_names(self): get_dimension_array_names( self.varinfo, '/Soil_Moisture_Retrieval_Data_PM/surface_flag_pm' ), - expected_override_dimensions_PM, + expected_override_dimensions_pm, ) with self.subTest( 'Retrieves empty dimensions list when science variable has no coordinates' @@ -638,6 +630,31 @@ def test_get_dimension_array_names(self): 'projection_x_coordinate': '/Freeze_Thaw_Retrieval_Data_Global/x_dim', }, ) + with self.subTest( + 'Retrieves expected dimension names for coordinates in the same folder' + ): + dimension_names1 = get_dimension_array_names( + self.test_varinfo, + '/Soil_Moisture_Retrieval_Data_AM/variable1_with_same_folder_coordinates', + ) + self.assertEqual( + dimension_names1, + { + 'projection_y_coordinate': '/Soil_Moisture_Retrieval_Data_AM/same_folder_latitude1_/Soil_Moisture_Retrieval_Data_AM/same_folder_longitude1/y_dim', + 'projection_x_coordinate': '/Soil_Moisture_Retrieval_Data_AM/same_folder_latitude1_/Soil_Moisture_Retrieval_Data_AM/same_folder_longitude1/x_dim', + }, + ) + dimension_names2 = get_dimension_array_names( + self.test_varinfo, + '/Soil_Moisture_Retrieval_Data_AM/variable2_with_same_folder_coordinates', + ) + self.assertEqual( + dimension_names2, + { + 'projection_y_coordinate': '/Soil_Moisture_Retrieval_Data_AM/same_folder_latitude2_/Soil_Moisture_Retrieval_Data_AM/same_folder_longitude2/y_dim', + 'projection_x_coordinate': '/Soil_Moisture_Retrieval_Data_AM/same_folder_latitude2_/Soil_Moisture_Retrieval_Data_AM/same_folder_longitude2/x_dim', + }, + ) def test_get_configured_dimension_order(self): """Ensure that the expected x-y dimension name @@ -689,13 +706,11 @@ def test_get_configured_dimension_order(self): 'projection_x_coordinate': '/Freeze_Thaw_Retrieval_Data_Global/x_dim', } - assert ( - len( - get_configured_dimension_order( - self.smap_ftp_varinfo, configured_dimension_names_nominal - ) - ) - == 0 + self.assertDictEqual( + get_configured_dimension_order( + self.smap_ftp_varinfo, configured_dimension_names_nominal + ), + expected_dimension_order, ) def test_get_row_col_sizes_from_coordinates(self): @@ -1087,6 +1102,22 @@ def test_get_valid_sample_pts(self): context.exception.message, 'No valid coordinate data', ) + with self.subTest('Get two sets of valid indices from 3d coordinates dataset'): + expected_grid_indices = ( + [[0, 0], [4, 0]], + [[0, 0], [0, 9]], + ) + actual_row_indices, actual_col_indices = get_valid_sample_pts( + self.lat_arr_3d, + self.lon_arr_3d, + self.varinfo.get_variable(self.latitude), + self.varinfo.get_variable(self.longitude), + ) + self.assertListEqual(actual_row_indices, expected_grid_indices[0]) + self.assertListEqual(actual_col_indices, expected_grid_indices[1]) + self.assertTupleEqual( + (actual_row_indices, actual_col_indices), expected_grid_indices + ) def test_get_dimension_order_and_dim_values(self): """Ensure that the correct dimension order index @@ -1376,7 +1407,7 @@ def test_create_dimension_arrays_from_nominal_3d_coordinates( } ) expected_xdim = np.array([-17349514.353068016, 17349514.353068016]) - expected_ydim = np.array([7296524.6913595535, -7296509.222123815]) + expected_ydim = np.array([7296524.6913595535, -7296524.691359556]) with self.subTest('Projected x-y dim arrays from coordinate datasets'): with Dataset(self.smap_ftp_file_path, 'r') as smap_prefetch: diff --git a/tests/unit/test_spatial.py b/tests/unit/test_spatial.py index 19aa7d0..0199bea 100644 --- a/tests/unit/test_spatial.py +++ b/tests/unit/test_spatial.py @@ -80,10 +80,22 @@ def test_get_spatial_index_ranges_projected_from_coordinates(self): '/Soil_Moisture_Retrieval_Data_PM/longitude_pm', } expected_index_ranges = { - '/Soil_Moisture_Retrieval_Data_AM/x_dim': (487, 594), - '/Soil_Moisture_Retrieval_Data_AM/y_dim': (9, 38), - '/Soil_Moisture_Retrieval_Data_PM/x_dim': (487, 594), - '/Soil_Moisture_Retrieval_Data_PM/y_dim': (9, 38), + '/Soil_Moisture_Retrieval_Data_AM/latitude_/Soil_Moisture_Retrieval_Data_AM/longitude/x_dim': ( + 487, + 594, + ), + '/Soil_Moisture_Retrieval_Data_AM/latitude_/Soil_Moisture_Retrieval_Data_AM/longitude/y_dim': ( + 9, + 38, + ), + '/Soil_Moisture_Retrieval_Data_PM/latitude_pm_/Soil_Moisture_Retrieval_Data_PM/longitude_pm/x_dim': ( + 487, + 594, + ), + '/Soil_Moisture_Retrieval_Data_PM/latitude_pm_/Soil_Moisture_Retrieval_Data_PM/longitude_pm/y_dim': ( + 9, + 38, + ), } index_ranges = get_spatial_index_ranges( required_variables, @@ -273,8 +285,14 @@ def test_get_x_y_index_ranges_from_coordinates( ) smap_file_path = 'tests/data/SC_SPL3SMP_008_prefetch.nc4' expected_index_ranges = { - '/Soil_Moisture_Retrieval_Data_AM/x_dim': (487, 595), - '/Soil_Moisture_Retrieval_Data_AM/y_dim': (9, 38), + '/Soil_Moisture_Retrieval_Data_AM/latitude_/Soil_Moisture_Retrieval_Data_AM/longitude/x_dim': ( + 487, + 595, + ), + '/Soil_Moisture_Retrieval_Data_AM/latitude_/Soil_Moisture_Retrieval_Data_AM/longitude/y_dim': ( + 9, + 38, + ), } bbox = BBox(2, 54, 42, 72) diff --git a/tests/unit/test_subset.py b/tests/unit/test_subset.py index ca6c775..3d8c3c9 100644 --- a/tests/unit/test_subset.py +++ b/tests/unit/test_subset.py @@ -1521,10 +1521,22 @@ def test_subset_granule_with_no_dimensions( '/Soil_Moisture_Retrieval_Data_PM/latitude_pm[9:38][487:595]', } expected_index_ranges = { - '/Soil_Moisture_Retrieval_Data_AM/x_dim': (487, 595), - '/Soil_Moisture_Retrieval_Data_AM/y_dim': (9, 38), - '/Soil_Moisture_Retrieval_Data_PM/x_dim': (487, 595), - '/Soil_Moisture_Retrieval_Data_PM/y_dim': (9, 38), + '/Soil_Moisture_Retrieval_Data_AM/latitude_/Soil_Moisture_Retrieval_Data_AM/longitude/x_dim': ( + 487, + 595, + ), + '/Soil_Moisture_Retrieval_Data_AM/latitude_/Soil_Moisture_Retrieval_Data_AM/longitude/y_dim': ( + 9, + 38, + ), + '/Soil_Moisture_Retrieval_Data_PM/latitude_pm_/Soil_Moisture_Retrieval_Data_PM/longitude_pm/x_dim': ( + 487, + 595, + ), + '/Soil_Moisture_Retrieval_Data_PM/latitude_pm_/Soil_Moisture_Retrieval_Data_PM/longitude_pm/y_dim': ( + 9, + 38, + ), } mock_get_varinfo.return_value = smap_varinfo