diff --git a/CHANGELOG.md b/CHANGELOG.md index c757856..771612a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## v1.1.7 +### 2025-05-21 + +This version of HOSS updates the hoss configuration file to include +EASE_column_index and EASE_row_index as ancillary variables for the SPL2SMAP_S +collection. + ## v1.1.6 ### 2025-02-24 diff --git a/docker/service_version.txt b/docker/service_version.txt index 0664a8f..2bf1ca5 100644 --- a/docker/service_version.txt +++ b/docker/service_version.txt @@ -1 +1 @@ -1.1.6 +1.1.7 diff --git a/hoss/hoss_config.json b/hoss/hoss_config.json index d2499c4..6b1cd7e 100644 --- a/hoss/hoss_config.json +++ b/hoss/hoss_config.json @@ -690,6 +690,35 @@ ], "_Description": "Include /delta_time_beg and /delta_time_end as ancillary variables." }, + { + "Applicability": { + "Mission": "SMAP", + "ShortNamePath": "SPL2SMAP_S", + "VariablePattern": "/Soil_Moisture_Retrieval_Data_1km/(.*)_1km$" + + }, + "Attributes": [ + { + "Name": "ancillary_variables", + "Value": "/Soil_Moisture_Retrieval_Data_1km/EASE_column_index_1km,/Soil_Moisture_Retrieval_Data_1km/EASE_row_index_1km" + } + ], + "_Description": "Include EASE_column_index_1km and EASE_row_index_1km as ancillary variables." + }, + { + "Applicability": { + "Mission": "SMAP", + "ShortNamePath": "SPL2SMAP_S", + "VariablePattern": "/Soil_Moisture_Retrieval_Data_3km/(.*)_3km$" + }, + "Attributes": [ + { + "Name": "ancillary_variables", + "Value": "/Soil_Moisture_Retrieval_Data_3km/EASE_column_index_3km,/Soil_Moisture_Retrieval_Data_3km/EASE_row_index_3km" + } + ], + "_Description": "Include EASE_column_index_3km and EASE_row_index_3km as ancillary variables." + }, { "Applicability": { "Mission": "MERRA-2", diff --git a/tests/data/SC_SPL2SMAP_S.dmr b/tests/data/SC_SPL2SMAP_S.dmr new file mode 100644 index 0000000..bcfb405 --- /dev/null +++ b/tests/data/SC_SPL2SMAP_S.dmr @@ -0,0 +1,308 @@ + + + + + + + Latitude of the center of the Earth based grid cell. + + + degrees_north + + + + + + + Longitude of the center of the Earth based grid cell. + + + degrees_east + + + + + + + The row index of the 3 km EASE grid cell that contains the associated data. + + + /Soil_Moisture_Retrieval_Data_3km/latitude_3km /Soil_Moisture_Retrieval_Data_3km/longitude_3km + + + 0 + + + 65535 + + + 65534 + + + + + + + + + cm**3/cm**3 + + + 0. + + + Representative soil moisture measurement for the 3 km Earth based grid cell for option 1. + + + /Soil_Moisture_Retrieval_Data_3km/latitude_3km /Soil_Moisture_Retrieval_Data_3km/longitude_3km + + + 0.75 + + + -9999. + + + + + + + + + Bit flags that record ambient surface conditions for the grid cell + + + /Soil_Moisture_Retrieval_Data_3km/latitude_3km /Soil_Moisture_Retrieval_Data_3km/longitude_3km + + + 65534 + + + 1s, 2s, 4s, 8s, 16s, 32s, 64s, 128s, 256s, 512s, 1024s, 2048s, 4096s + + + 3_km_static_water_body_flag 3_km_radar_water_body_detection_flag 3_km_coastal_proximity_flag 3_km_urban_area_flag 3_km_precipitation_flag 3_km_snow_or_ice_flag 3_km_permanent_snow_or_ice_flag 3_km_radar_frozen_ground_flag 3_km_model_frozen_ground_flag 3_km_mountainous_terrain_flag 3_km_dense_vegetation_flag 3_km_scene_edge_flag 3_km_anomalous_sigma0_flag + + + + + + + + + The column index of the 3 km EASE grid cell that contains the associated data. + + + /Soil_Moisture_Retrieval_Data_3km/latitude_3km /Soil_Moisture_Retrieval_Data_3km/longitude_3km + + + 0 + + + 65535 + + + 65534 + + + + + + + + + Diffuse reflecting power of the Earth's surface within the grid cell. + + + /Soil_Moisture_Retrieval_Data_3km/latitude_3km /Soil_Moisture_Retrieval_Data_3km/longitude_3km + + + 0. + + + 1. + + + -9999. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Longitude of the center of the Earth based grid cell. + + + degrees_east + + + + + + + Latitude of the center of the Earth based grid cell. + + + degrees_north + + + + + + + cm**3/cm**3 + + + 0. + + + Representative soil moisture measurement for the 1 km Earth based grid cell for option 1. + + + /Soil_Moisture_Retrieval_Data_1km/latitude_1km /Soil_Moisture_Retrieval_Data_1km/longitude_1km + + + 0.75 + + + -9999. + + + + + + + + + The column index of the 1 km EASE grid cell that contains the associated data. + + + /Soil_Moisture_Retrieval_Data_1km/latitude_1km /Soil_Moisture_Retrieval_Data_1km/longitude_1km + + + 0 + + + 65535 + + + 65534 + + + + + + + + + Temperature at land surface based on GEOS5 GMAO. + + + Kelvin + + + /Soil_Moisture_Retrieval_Data_1km/latitude_1km /Soil_Moisture_Retrieval_Data_1km/longitude_1km + + + 200. + + + 350. + + + -9999. + + + + + + + + + The row index of the 1 km EASE grid cell that contains the associated data. + + + /Soil_Moisture_Retrieval_Data_1km/latitude_1km /Soil_Moisture_Retrieval_Data_1km/longitude_1km + + + 0 + + + 65535 + + + 65534 + + + + + + + + + Diffuse reflecting power of the Earth's surface within the grid cell. + + + /Soil_Moisture_Retrieval_Data_1km/latitude_1km /Soil_Moisture_Retrieval_Data_1km/longitude_1km + + + 0. + + + 1. + + + -9999. + + + + + + + + + Bit flags that record ambient surface conditions for the grid cell + + + /Soil_Moisture_Retrieval_Data_1km/latitude_1km /Soil_Moisture_Retrieval_Data_1km/longitude_1km + + + 65534 + + + 1s, 2s, 4s, 8s, 16s, 32s, 64s, 128s, 256s, 512s, 1024s, 2048s, 4096s + + + 1_km_static_water_body_flag 1_km_radar_water_body_detection_flag 1_km_coastal_proximity_flag 1_km_urban_area_flag 1_km_precipitation_flag 1_km_snow_or_ice_flag 1_km_permanent_snow_or_ice_flag 1_km_radar_frozen_ground_flag 1_km_model_frozen_ground_flag 1_km_mountainous_terrain_flag 1_km_dense_vegetation_flag 1_km_scene_edge_flag 1_km_anomalous_sigma0_flag + + + + + + diff --git a/tests/unit/test_subset.py b/tests/unit/test_subset.py index 3d8c3c9..3218c3d 100644 --- a/tests/unit/test_subset.py +++ b/tests/unit/test_subset.py @@ -1242,6 +1242,12 @@ def test_get_required_variables(self): subset) - the return value should include all non-dimension variables from the `VarInfoFromDmr` instance. + * Test case 6: variables not in message, but configured as ancillary + variables in the json file. The output should include the + only the ancillary variables associated with the requested variable. + * Test case 7: variables in multiple groups not in message, but configured as ancillary + variables in the json file. The output should include the + ancillary variables associated with all the requested variables. """ all_variables = { @@ -1317,6 +1323,58 @@ def test_get_required_variables(self): all_variables, ) + # Tests for ancillary variables + spl2smap_s_varinfo = VarInfoFromDmr( + 'tests/data/SC_SPL2SMAP_S.dmr', 'SPL2SMAP_S', 'hoss/hoss_config.json' + ) + harmony_variables = [ + HarmonyVariable( + { + 'fullPath': '/Soil_Moisture_Retrieval_Data_1km/albedo_1km', + 'id': 'V1234-PROVIDER', + 'name': 'albedo_1km', + } + ), + HarmonyVariable( + { + 'fullPath': '/Soil_Moisture_Retrieval_Data_3km/soil_moisture_3km', + 'id': 'V1234-PROVIDER', + 'name': 'soil_moisture_3km', + } + ), + ] + with self.subTest('Variables configured as ancillary for a single group'): + self.assertSetEqual( + get_required_variables( + spl2smap_s_varinfo, [harmony_variables[0]], False, self.logger + ), + { + '/Soil_Moisture_Retrieval_Data_1km/albedo_1km', + '/Soil_Moisture_Retrieval_Data_1km/EASE_row_index_1km', + '/Soil_Moisture_Retrieval_Data_1km/EASE_column_index_1km', + '/Soil_Moisture_Retrieval_Data_1km/latitude_1km', + '/Soil_Moisture_Retrieval_Data_1km/longitude_1km', + }, + ) + with self.subTest('Variables configured as ancillary in multiple groups'): + self.assertSetEqual( + get_required_variables( + spl2smap_s_varinfo, harmony_variables, False, self.logger + ), + { + '/Soil_Moisture_Retrieval_Data_1km/albedo_1km', + '/Soil_Moisture_Retrieval_Data_3km/soil_moisture_3km', + '/Soil_Moisture_Retrieval_Data_1km/EASE_row_index_1km', + '/Soil_Moisture_Retrieval_Data_1km/EASE_column_index_1km', + '/Soil_Moisture_Retrieval_Data_3km/EASE_row_index_3km', + '/Soil_Moisture_Retrieval_Data_3km/EASE_column_index_3km', + '/Soil_Moisture_Retrieval_Data_1km/latitude_1km', + '/Soil_Moisture_Retrieval_Data_1km/longitude_1km', + '/Soil_Moisture_Retrieval_Data_3km/latitude_3km', + '/Soil_Moisture_Retrieval_Data_3km/longitude_3km', + }, + ) + def test_fill_variables(self): """Ensure only the expected variables are filled (e.g., those with a longitude crossing the grid edge). Longitude variables should not