Remove PR old association #20
49 fail, 148 pass in 3h 8m 12s
197 tests 148 ✅ 3h 8m 12s ⏱️
1 suites 0 💤
1 files 49 ❌
Results for commit 20fc98e.
Annotations
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1239966755-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 45s]
Raw output
AttributeError: 'NoneType' object has no attribute 'variables'
collection_concept_id = 'C1239966755-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1239966755-GES_DISC', 'concept-id': 'G2936121467-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1239966755-GES_DISC'}]}, 'meta': {'association-details': {'collect...scription': 'Extracted from _FillValue metadata attribute', 'Type': 'SCIENCE_FILLVALUE', 'Value': -32767}], ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1239966750')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
group_walk(f.groups, f, '')
assert lat_var_name and lon_var_name
var_ds = None
msk = None
if science_vars := get_science_vars(collection_variables):
for idx, value in enumerate(science_vars):
science_var_name = science_vars[idx]['umm']['Name']
try:
var_ds = subsetted_ds_new[science_var_name]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
try:
# if the variable couldn't be found because the name includes a group, e.g.,
# `geolocation/relative_azimuth_angle`,
# then try to access the variable after removing the group name.
var_ds = subsetted_ds_new[science_var_name.rsplit("/", 1)[-1]]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
var_ds = None
msk = None
if var_ds is None and msk is None:
pytest.fail(f"Unable to find variable from umm-v to use as science variable.")
else:
# Can't find a science var in UMM-V, just pick one
> science_var_name = next(iter([v for v in subsetted_ds_new.variables if
str(v) not in lat_var_name and str(v) not in lon_var_name and 'time' not in str(v)]))
E AttributeError: 'NoneType' object has no attribute 'variables'
verify_collection.py:437: AttributeError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2936121467-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 481' -H 'Content-Type: multipart/form-data; boundary=29cf45e1cec616b247fba620e2169473' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--29cf45e1cec616b247fba620e2169473
Content-Disposition: form-data; name="forceAsync"
true
--29cf45e1cec616b247fba620e2169473
Content-Disposition: form-data; name="subset"
lat(-83.206536:-60.266544)
--29cf45e1cec616b247fba620e2169473
Content-Disposition: form-data; name="subset"
lon(-157.58040975:-24.766220250000003)
--29cf45e1cec616b247fba620e2169473
Content-Disposition: form-data; name="granuleId"
G2936121467-GES_DISC
--29cf45e1cec616b247fba620e2169473--
' https://harmony.earthdata.nasa.gov/C1239966755-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job 38e27554-4996-4b7d-a416-ed05dc277e53
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1239966750/OMI-Aura_L2-OMAERO_2024m0415t2013-o105065_v003-2024m0416t013715_subsetted.nc4
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1627516290-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 2s]
Raw output
Exception: ('Unprocessable Entity', 'Error: the requested combination of operations: spatial subsetting on C1627516290-GES_DISC is unsupported')
collection_concept_id = 'C1627516290-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1627516290-GES_DISC', 'concept-id': 'G2897233694-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1627516290-GES_DISC'}]}, 'meta': {'association-details': {'collect...: 'Extracted from _FillValue metadata attribute', 'Type': 'SCIENCE_FILLVALUE', 'Value': 9.969209968386869e+36}], ...}}]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1627516290')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
> job_id = harmony_client.submit(harmony_request)
verify_collection.py:359:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/harmony/harmony.py:827: in submit
self._handle_error_response(response)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <harmony.harmony.Client object at 0x7f2bf6db06a0>
response = <Response [422]>
def _handle_error_response(self, response: Response):
"""Raises the appropriate exception based on the response
received from Harmony. Trys to pull out an error message
from a Harmony JSON response when possible.
Args:
response: The Response from Harmony
Raises:
Exception with a Harmony error message or a more generic
HTTPError
"""
if 'application/json' in response.headers.get('Content-Type', ''):
exception_message = None
try:
response_json = response.json()
if hasattr(response_json, 'get'):
exception_message = response_json.get('description')
if not exception_message:
exception_message = response_json.get('error')
except JSONDecodeError:
pass
if exception_message:
> raise Exception(response.reason, exception_message)
E Exception: ('Unprocessable Entity', 'Error: the requested combination of operations: spatial subsetting on C1627516290-GES_DISC is unsupported')
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/harmony/harmony.py:775: Exception
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2897233694-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 477' -H 'Content-Type: multipart/form-data; boundary=811644989eb0a24b7b115147203fa1f9' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--811644989eb0a24b7b115147203fa1f9
Content-Disposition: form-data; name="forceAsync"
true
--811644989eb0a24b7b115147203fa1f9
Content-Disposition: form-data; name="subset"
lat(-76.855425:-59.695575)
--811644989eb0a24b7b115147203fa1f9
Content-Disposition: form-data; name="subset"
lon(-76.722325:-1.608674999999998)
--811644989eb0a24b7b115147203fa1f9
Content-Disposition: form-data; name="granuleId"
G2897233694-GES_DISC
--811644989eb0a24b7b115147203fa1f9--
' https://harmony.earthdata.nasa.gov/C1627516290-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1729925686-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 34s]
Raw output
AttributeError: 'NoneType' object has no attribute 'variables'
collection_concept_id = 'C1729925686-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1729925686-GES_DISC', 'concept-id': 'G2935999643-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1729925686-GES_DISC'}]}, 'meta': {'association-details': {'collect...E', 'Value': -999.989990234375}], 'LongName': 'HDFEOS/SWATHS/N2O-APriori/Data Fields/N2O-APrioriPrecision', ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729925680')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
group_walk(f.groups, f, '')
assert lat_var_name and lon_var_name
var_ds = None
msk = None
if science_vars := get_science_vars(collection_variables):
for idx, value in enumerate(science_vars):
science_var_name = science_vars[idx]['umm']['Name']
try:
var_ds = subsetted_ds_new[science_var_name]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
try:
# if the variable couldn't be found because the name includes a group, e.g.,
# `geolocation/relative_azimuth_angle`,
# then try to access the variable after removing the group name.
var_ds = subsetted_ds_new[science_var_name.rsplit("/", 1)[-1]]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
var_ds = None
msk = None
if var_ds is None and msk is None:
pytest.fail(f"Unable to find variable from umm-v to use as science variable.")
else:
# Can't find a science var in UMM-V, just pick one
> science_var_name = next(iter([v for v in subsetted_ds_new.variables if
str(v) not in lat_var_name and str(v) not in lon_var_name and 'time' not in str(v)]))
E AttributeError: 'NoneType' object has no attribute 'variables'
verify_collection.py:437: AttributeError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2935999643-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 449' -H 'Content-Type: multipart/form-data; boundary=d7ce5d9701e3b80995ccc379769bfc19' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--d7ce5d9701e3b80995ccc379769bfc19
Content-Disposition: form-data; name="forceAsync"
true
--d7ce5d9701e3b80995ccc379769bfc19
Content-Disposition: form-data; name="subset"
lat(-85.5:85.5)
--d7ce5d9701e3b80995ccc379769bfc19
Content-Disposition: form-data; name="subset"
lon(-171.0:171.0)
--d7ce5d9701e3b80995ccc379769bfc19
Content-Disposition: form-data; name="granuleId"
G2935999643-GES_DISC
--d7ce5d9701e3b80995ccc379769bfc19--
' https://harmony.earthdata.nasa.gov/C1729925686-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job 67f17307-6c8a-4bce-a386-0a1654130d69
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729925680/MLS-Aura_L2GP-N2O_v05-02-c01_2024d105_subsetted.nc4
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C2152045877-POCLOUD] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 22s]
Raw output
Exception: ('Unprocessable Entity', 'Error: the requested combination of operations: spatial subsetting on C2152045877-POCLOUD is unsupported')
collection_concept_id = 'C2152045877-POCLOUD', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C2152045877-POCLOUD', 'concept-id': 'G2163249480-POCLOUD', 'concept-type': 'granul...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C2152045877-POCLOUD'}]}, 'meta': {'association-details': {'collecti...'num_pixels', 'Size': 71, 'Type': 'OTHER'}], 'FillValues': [{'Type': 'SCIENCE_FILLVALUE', 'Value': 32767}], ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C2152045870')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
> job_id = harmony_client.submit(harmony_request)
verify_collection.py:359:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/harmony/harmony.py:827: in submit
self._handle_error_response(response)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <harmony.harmony.Client object at 0x7f2bf5a82770>
response = <Response [422]>
def _handle_error_response(self, response: Response):
"""Raises the appropriate exception based on the response
received from Harmony. Trys to pull out an error message
from a Harmony JSON response when possible.
Args:
response: The Response from Harmony
Raises:
Exception with a Harmony error message or a more generic
HTTPError
"""
if 'application/json' in response.headers.get('Content-Type', ''):
exception_message = None
try:
response_json = response.json()
if hasattr(response_json, 'get'):
exception_message = response_json.get('description')
if not exception_message:
exception_message = response_json.get('error')
except JSONDecodeError:
pass
if exception_message:
> raise Exception(response.reason, exception_message)
E Exception: ('Unprocessable Entity', 'Error: the requested combination of operations: spatial subsetting on C2152045877-POCLOUD is unsupported')
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/harmony/harmony.py:775: Exception
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2163249480-POCLOUD for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 494' -H 'Content-Type: multipart/form-data; boundary=d10f0dfab86c976b3f74101a2f20c2be' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--d10f0dfab86c976b3f74101a2f20c2be
Content-Disposition: form-data; name="forceAsync"
true
--d10f0dfab86c976b3f74101a2f20c2be
Content-Disposition: form-data; name="subset"
lat(-74.37763325:74.37742324999999)
--d10f0dfab86c976b3f74101a2f20c2be
Content-Disposition: form-data; name="subset"
lon(-47.728960749999985:110.88111074999999)
--d10f0dfab86c976b3f74101a2f20c2be
Content-Disposition: form-data; name="granuleId"
G2163249480-POCLOUD
--d10f0dfab86c976b3f74101a2f20c2be--
' https://harmony.earthdata.nasa.gov/C2152045877-POCLOUD/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1729925099-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 42s]
Raw output
AttributeError: 'NoneType' object has no attribute 'variables'
collection_concept_id = 'C1729925099-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1729925099-GES_DISC', 'concept-id': 'G2935833807-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1729925099-GES_DISC'}]}, 'meta': {'association-details': {'collect..._FILLVALUE', 'Value': -999.989990234375}], 'LongName': 'HDFEOS/SWATHS/CH3Cl-APriori/Data Fields/L2gpValue', ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729925090')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
group_walk(f.groups, f, '')
assert lat_var_name and lon_var_name
var_ds = None
msk = None
if science_vars := get_science_vars(collection_variables):
for idx, value in enumerate(science_vars):
science_var_name = science_vars[idx]['umm']['Name']
try:
var_ds = subsetted_ds_new[science_var_name]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
try:
# if the variable couldn't be found because the name includes a group, e.g.,
# `geolocation/relative_azimuth_angle`,
# then try to access the variable after removing the group name.
var_ds = subsetted_ds_new[science_var_name.rsplit("/", 1)[-1]]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
var_ds = None
msk = None
if var_ds is None and msk is None:
pytest.fail(f"Unable to find variable from umm-v to use as science variable.")
else:
# Can't find a science var in UMM-V, just pick one
> science_var_name = next(iter([v for v in subsetted_ds_new.variables if
str(v) not in lat_var_name and str(v) not in lon_var_name and 'time' not in str(v)]))
E AttributeError: 'NoneType' object has no attribute 'variables'
verify_collection.py:437: AttributeError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2935833807-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 449' -H 'Content-Type: multipart/form-data; boundary=c1a6038b4d4e75e04761e8e62260d5e0' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--c1a6038b4d4e75e04761e8e62260d5e0
Content-Disposition: form-data; name="forceAsync"
true
--c1a6038b4d4e75e04761e8e62260d5e0
Content-Disposition: form-data; name="subset"
lat(-85.5:85.5)
--c1a6038b4d4e75e04761e8e62260d5e0
Content-Disposition: form-data; name="subset"
lon(-171.0:171.0)
--c1a6038b4d4e75e04761e8e62260d5e0
Content-Disposition: form-data; name="granuleId"
G2935833807-GES_DISC
--c1a6038b4d4e75e04761e8e62260d5e0--
' https://harmony.earthdata.nasa.gov/C1729925099-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job bf8791c1-4d94-4f7c-8019-0c3ec79cf666
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729925090/MLS-Aura_L2GP-CH3Cl_v05-02-c01_2024d105_subsetted.nc4
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1239966791-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 30s]
Raw output
AttributeError: 'NoneType' object has no attribute 'variables'
collection_concept_id = 'C1239966791-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1239966791-GES_DISC', 'concept-id': 'G2935796422-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1239966791-GES_DISC'}]}, 'meta': {'association-details': {'collect...escription': 'Extracted from _FillValue metadata attribute', 'Type': 'SCIENCE_FILLVALUE', 'Value': -9999}], ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1239966790')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
group_walk(f.groups, f, '')
assert lat_var_name and lon_var_name
var_ds = None
msk = None
if science_vars := get_science_vars(collection_variables):
for idx, value in enumerate(science_vars):
science_var_name = science_vars[idx]['umm']['Name']
try:
var_ds = subsetted_ds_new[science_var_name]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
try:
# if the variable couldn't be found because the name includes a group, e.g.,
# `geolocation/relative_azimuth_angle`,
# then try to access the variable after removing the group name.
var_ds = subsetted_ds_new[science_var_name.rsplit("/", 1)[-1]]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
var_ds = None
msk = None
if var_ds is None and msk is None:
pytest.fail(f"Unable to find variable from umm-v to use as science variable.")
else:
# Can't find a science var in UMM-V, just pick one
> science_var_name = next(iter([v for v in subsetted_ds_new.variables if
str(v) not in lat_var_name and str(v) not in lon_var_name and 'time' not in str(v)]))
E AttributeError: 'NoneType' object has no attribute 'variables'
verify_collection.py:437: AttributeError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2935796422-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 487' -H 'Content-Type: multipart/form-data; boundary=6e2fba205ede435080a87922ec7c979e' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--6e2fba205ede435080a87922ec7c979e
Content-Disposition: form-data; name="forceAsync"
true
--6e2fba205ede435080a87922ec7c979e
Content-Disposition: form-data; name="subset"
lat(-83.31191225:-60.439417750000004)
--6e2fba205ede435080a87922ec7c979e
Content-Disposition: form-data; name="subset"
lon(-57.97077200000001:73.897132)
--6e2fba205ede435080a87922ec7c979e
Content-Disposition: form-data; name="granuleId"
G2935796422-GES_DISC
--6e2fba205ede435080a87922ec7c979e--
' https://harmony.earthdata.nasa.gov/C1239966791-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job 7596d5c8-1ac3-4e12-9d8e-ca36e0950847
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1239966790/OMI-Aura_L2-OMCLDRR_2024m0415t1337-o105061_v003-2024m0415t190103_subsetted.nc4
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1239966810-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 36s]
Raw output
AttributeError: 'NoneType' object has no attribute 'variables'
collection_concept_id = 'C1239966810-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1239966810-GES_DISC', 'concept-id': 'G2936131233-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1239966810-GES_DISC'}]}, 'meta': {'association-details': {'collect...acted from _FillValue metadata attribute', 'Type': 'SCIENCE_FILLVALUE', 'Value': -1.0000000150474662e+30}], ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1239966810')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
group_walk(f.groups, f, '')
assert lat_var_name and lon_var_name
var_ds = None
msk = None
if science_vars := get_science_vars(collection_variables):
for idx, value in enumerate(science_vars):
science_var_name = science_vars[idx]['umm']['Name']
try:
var_ds = subsetted_ds_new[science_var_name]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
try:
# if the variable couldn't be found because the name includes a group, e.g.,
# `geolocation/relative_azimuth_angle`,
# then try to access the variable after removing the group name.
var_ds = subsetted_ds_new[science_var_name.rsplit("/", 1)[-1]]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
var_ds = None
msk = None
if var_ds is None and msk is None:
pytest.fail(f"Unable to find variable from umm-v to use as science variable.")
else:
# Can't find a science var in UMM-V, just pick one
> science_var_name = next(iter([v for v in subsetted_ds_new.variables if
str(v) not in lat_var_name and str(v) not in lon_var_name and 'time' not in str(v)]))
E AttributeError: 'NoneType' object has no attribute 'variables'
verify_collection.py:437: AttributeError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2936131233-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 482' -H 'Content-Type: multipart/form-data; boundary=2909e25fc023a78d31c06876e2dbf2d5' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--2909e25fc023a78d31c06876e2dbf2d5
Content-Disposition: form-data; name="forceAsync"
true
--2909e25fc023a78d31c06876e2dbf2d5
Content-Disposition: form-data; name="subset"
lat(-83.1737345:-60.2181055)
--2909e25fc023a78d31c06876e2dbf2d5
Content-Disposition: form-data; name="subset"
lon(-135.09964225:166.79849224999998)
--2909e25fc023a78d31c06876e2dbf2d5
Content-Disposition: form-data; name="granuleId"
G2936131233-GES_DISC
--2909e25fc023a78d31c06876e2dbf2d5--
' https://harmony.earthdata.nasa.gov/C1239966810-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job 26f2af6a-9efe-42a1-afe2-98f71868d298
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1239966810/OMI-Aura_L2-OMPIXCOR_2024m0415t2151-o105066_v003-2024m0416t030643_subsetted.nc4
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1239966829-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 26s]
Raw output
AttributeError: 'NoneType' object has no attribute 'variables'
collection_concept_id = 'C1239966829-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1239966829-GES_DISC', 'concept-id': 'G2936170965-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1239966829-GES_DISC'}]}, 'meta': {'association-details': {'collect...scription': 'Extracted from _FillValue metadata attribute', 'Type': 'SCIENCE_FILLVALUE', 'Value': -1e+30}], ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1239966820')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
group_walk(f.groups, f, '')
assert lat_var_name and lon_var_name
var_ds = None
msk = None
if science_vars := get_science_vars(collection_variables):
for idx, value in enumerate(science_vars):
science_var_name = science_vars[idx]['umm']['Name']
try:
var_ds = subsetted_ds_new[science_var_name]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
try:
# if the variable couldn't be found because the name includes a group, e.g.,
# `geolocation/relative_azimuth_angle`,
# then try to access the variable after removing the group name.
var_ds = subsetted_ds_new[science_var_name.rsplit("/", 1)[-1]]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
var_ds = None
msk = None
if var_ds is None and msk is None:
pytest.fail(f"Unable to find variable from umm-v to use as science variable.")
else:
# Can't find a science var in UMM-V, just pick one
> science_var_name = next(iter([v for v in subsetted_ds_new.variables if
str(v) not in lat_var_name and str(v) not in lon_var_name and 'time' not in str(v)]))
E AttributeError: 'NoneType' object has no attribute 'variables'
verify_collection.py:437: AttributeError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2936170965-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 484' -H 'Content-Type: multipart/form-data; boundary=60ac1b73f2ebcb01f87f2f5efe276669' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--60ac1b73f2ebcb01f87f2f5efe276669
Content-Disposition: form-data; name="forceAsync"
true
--60ac1b73f2ebcb01f87f2f5efe276669
Content-Disposition: form-data; name="subset"
lat(-83.13877525:-60.16607475)
--60ac1b73f2ebcb01f87f2f5efe276669
Content-Disposition: form-data; name="subset"
lon(-159.74061274999997:142.65986275)
--60ac1b73f2ebcb01f87f2f5efe276669
Content-Disposition: form-data; name="granuleId"
G2936170965-GES_DISC
--60ac1b73f2ebcb01f87f2f5efe276669--
' https://harmony.earthdata.nasa.gov/C1239966829-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job 0624f6ce-af7f-4227-b265-be876f05703b
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1239966820/OMI-Aura_L2-OMOCLO_2024m0415t2330-o105067_v003-2024m0416t054050_subsetted.nc4
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1729925130-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 31s]
Raw output
AttributeError: 'NoneType' object has no attribute 'variables'
collection_concept_id = 'C1729925130-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1729925130-GES_DISC', 'concept-id': 'G2935999694-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1729925130-GES_DISC'}]}, 'meta': {'association-details': {'collect...IENCE_FILLVALUE', 'Value': -999.989990234375}], 'LongName': 'HDFEOS/SWATHS/CO-APriori/Data Fields/Quality', ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729925130')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
group_walk(f.groups, f, '')
assert lat_var_name and lon_var_name
var_ds = None
msk = None
if science_vars := get_science_vars(collection_variables):
for idx, value in enumerate(science_vars):
science_var_name = science_vars[idx]['umm']['Name']
try:
var_ds = subsetted_ds_new[science_var_name]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
try:
# if the variable couldn't be found because the name includes a group, e.g.,
# `geolocation/relative_azimuth_angle`,
# then try to access the variable after removing the group name.
var_ds = subsetted_ds_new[science_var_name.rsplit("/", 1)[-1]]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
var_ds = None
msk = None
if var_ds is None and msk is None:
pytest.fail(f"Unable to find variable from umm-v to use as science variable.")
else:
# Can't find a science var in UMM-V, just pick one
> science_var_name = next(iter([v for v in subsetted_ds_new.variables if
str(v) not in lat_var_name and str(v) not in lon_var_name and 'time' not in str(v)]))
E AttributeError: 'NoneType' object has no attribute 'variables'
verify_collection.py:437: AttributeError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2935999694-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 449' -H 'Content-Type: multipart/form-data; boundary=4686f09aae209b2c1cf45bd2c2d708e8' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--4686f09aae209b2c1cf45bd2c2d708e8
Content-Disposition: form-data; name="forceAsync"
true
--4686f09aae209b2c1cf45bd2c2d708e8
Content-Disposition: form-data; name="subset"
lat(-85.5:85.5)
--4686f09aae209b2c1cf45bd2c2d708e8
Content-Disposition: form-data; name="subset"
lon(-171.0:171.0)
--4686f09aae209b2c1cf45bd2c2d708e8
Content-Disposition: form-data; name="granuleId"
G2935999694-GES_DISC
--4686f09aae209b2c1cf45bd2c2d708e8--
' https://harmony.earthdata.nasa.gov/C1729925130-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job c2d7d2e0-f37a-4b19-b7d4-b86ec41f891f
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729925130/MLS-Aura_L2GP-CO_v05-02-c01_2024d105_subsetted.nc4
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1239966779-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 33s]
Raw output
AttributeError: 'NoneType' object has no attribute 'variables'
collection_concept_id = 'C1239966779-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1239966779-GES_DISC', 'concept-id': 'G2936153901-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1239966779-GES_DISC'}]}, 'meta': {'association-details': {'collect...acted from _FillValue metadata attribute', 'Type': 'SCIENCE_FILLVALUE', 'Value': -1.0000000150474662e+30}], ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1239966770')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
group_walk(f.groups, f, '')
assert lat_var_name and lon_var_name
var_ds = None
msk = None
if science_vars := get_science_vars(collection_variables):
for idx, value in enumerate(science_vars):
science_var_name = science_vars[idx]['umm']['Name']
try:
var_ds = subsetted_ds_new[science_var_name]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
try:
# if the variable couldn't be found because the name includes a group, e.g.,
# `geolocation/relative_azimuth_angle`,
# then try to access the variable after removing the group name.
var_ds = subsetted_ds_new[science_var_name.rsplit("/", 1)[-1]]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
var_ds = None
msk = None
if var_ds is None and msk is None:
pytest.fail(f"Unable to find variable from umm-v to use as science variable.")
else:
# Can't find a science var in UMM-V, just pick one
> science_var_name = next(iter([v for v in subsetted_ds_new.variables if
str(v) not in lat_var_name and str(v) not in lon_var_name and 'time' not in str(v)]))
E AttributeError: 'NoneType' object has no attribute 'variables'
verify_collection.py:437: AttributeError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2936153901-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 483' -H 'Content-Type: multipart/form-data; boundary=62a07d215585f5459da985d4598ce347' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--62a07d215585f5459da985d4598ce347
Content-Disposition: form-data; name="forceAsync"
true
--62a07d215585f5459da985d4598ce347
Content-Disposition: form-data; name="subset"
lat(-83.29040475:-60.41268525)
--62a07d215585f5459da985d4598ce347
Content-Disposition: form-data; name="subset"
lon(-107.10759475:24.40756474999999)
--62a07d215585f5459da985d4598ce347
Content-Disposition: form-data; name="granuleId"
G2936153901-GES_DISC
--62a07d215585f5459da985d4598ce347--
' https://harmony.earthdata.nasa.gov/C1239966779-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job f8706071-11ee-4865-a86f-d37b31eae44e
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1239966770/OMI-Aura_L2-OMHCHO_2024m0415t1655-o105063_v003-2024m0416t015014_subsetted.nc4
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C2832221740-POCLOUD] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 1m 23s]
Raw output
harmony.harmony.ProcessingFailedException: WorkItem failed: podaac/l2ss-py:2.9.0: Service request failed with an unknown error
collection_concept_id = 'C2832221740-POCLOUD', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C2832221740-POCLOUD', 'concept-id': 'G2935183805-POCLOUD', 'concept-type': 'granul...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C2832221740-POCLOUD'}]}, 'meta': {'association-details': {'collecti...rization_2', 'Size': 2, 'Type': 'OTHER'}], 'FillValues': [{'Type': 'SCIENCE_FILLVALUE', 'Value': -9999.0}], ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C2832221740')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
> harmony_client.wait_for_processing(job_id, show_progress=True)
verify_collection.py:361:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <harmony.harmony.Client object at 0x7f2bf59d07f0>
job_id = '099ab755-1d93-45db-bbd7-d1933b2596f6', show_progress = True
def wait_for_processing(self, job_id: str, show_progress: bool = False) -> None:
"""Retrieve a submitted job's completion status in percent.
Args:
job_id: UUID string for the job you wish to interrogate.
Returns:
The job's processing progress as a percentage.
:raises
Exception: This can happen if an invalid job_id is provided or Harmony services
can't be reached.
"""
# How often to refresh the screen for progress updates and animating spinners.
ui_update_interval = 0.33 # in seconds
running_w_errors_logged = False
intervals = round(self.check_interval / ui_update_interval)
if show_progress:
with progressbar.ProgressBar(max_value=100, widgets=progressbar_widgets) as bar:
progress = 0
while progress < 100:
progress, status, message = self.progress(job_id)
if status == 'failed':
> raise ProcessingFailedException(job_id, message)
E harmony.harmony.ProcessingFailedException: WorkItem failed: podaac/l2ss-py:2.9.0: Service request failed with an unknown error
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/harmony/harmony.py:962: ProcessingFailedException
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2935183805-POCLOUD for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 468' -H 'Content-Type: multipart/form-data; boundary=76f4c718b6d2c7590d346c2e6256f45e' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--76f4c718b6d2c7590d346c2e6256f45e
Content-Disposition: form-data; name="forceAsync"
true
--76f4c718b6d2c7590d346c2e6256f45e
Content-Disposition: form-data; name="subset"
lat(-82.28583474999999:82.07766475)
--76f4c718b6d2c7590d346c2e6256f45e
Content-Disposition: form-data; name="subset"
lon(-171.0:171.0)
--76f4c718b6d2c7590d346c2e6256f45e
Content-Disposition: form-data; name="granuleId"
G2935183805-POCLOUD
--76f4c718b6d2c7590d346c2e6256f45e--
' https://harmony.earthdata.nasa.gov/C2832221740-POCLOUD/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job 099ab755-1d93-45db-bbd7-d1933b2596f6
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1729925806-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 32s]
Raw output
AttributeError: 'NoneType' object has no attribute 'variables'
collection_concept_id = 'C1729925806-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1729925806-GES_DISC', 'concept-id': 'G2936182267-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1729925806-GES_DISC'}]}, 'meta': {'association-details': {'collect...': [{'Type': 'SCIENCE_FILLVALUE', 'Value': 513}], 'LongName': 'HDFEOS/SWATHS/O3 column/Data Fields/Status', ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729925800')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
group_walk(f.groups, f, '')
assert lat_var_name and lon_var_name
var_ds = None
msk = None
if science_vars := get_science_vars(collection_variables):
for idx, value in enumerate(science_vars):
science_var_name = science_vars[idx]['umm']['Name']
try:
var_ds = subsetted_ds_new[science_var_name]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
try:
# if the variable couldn't be found because the name includes a group, e.g.,
# `geolocation/relative_azimuth_angle`,
# then try to access the variable after removing the group name.
var_ds = subsetted_ds_new[science_var_name.rsplit("/", 1)[-1]]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
var_ds = None
msk = None
if var_ds is None and msk is None:
pytest.fail(f"Unable to find variable from umm-v to use as science variable.")
else:
# Can't find a science var in UMM-V, just pick one
> science_var_name = next(iter([v for v in subsetted_ds_new.variables if
str(v) not in lat_var_name and str(v) not in lon_var_name and 'time' not in str(v)]))
E AttributeError: 'NoneType' object has no attribute 'variables'
verify_collection.py:437: AttributeError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2936182267-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 449' -H 'Content-Type: multipart/form-data; boundary=c67fcafc12fcfa74a3377fcb4f76b467' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--c67fcafc12fcfa74a3377fcb4f76b467
Content-Disposition: form-data; name="forceAsync"
true
--c67fcafc12fcfa74a3377fcb4f76b467
Content-Disposition: form-data; name="subset"
lat(-85.5:85.5)
--c67fcafc12fcfa74a3377fcb4f76b467
Content-Disposition: form-data; name="subset"
lon(-171.0:171.0)
--c67fcafc12fcfa74a3377fcb4f76b467
Content-Disposition: form-data; name="granuleId"
G2936182267-GES_DISC
--c67fcafc12fcfa74a3377fcb4f76b467--
' https://harmony.earthdata.nasa.gov/C1729925806-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job ac79bbc9-5a52-46c2-aebf-5890f6fac4a6
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729925800/MLS-Aura_L2GP-O3_v05-02-c01_2024d105_subsetted.nc4
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C2147947806-POCLOUD] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 18s]
Raw output
Exception: ('Unprocessable Entity', 'Error: the requested combination of operations: spatial subsetting on C2147947806-POCLOUD is unsupported')
collection_concept_id = 'C2147947806-POCLOUD', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C2147947806-POCLOUD', 'concept-id': 'G2162980118-POCLOUD', 'concept-type': 'granul...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C2147947806-POCLOUD'}]}, 'meta': {'association-details': {'collecti...'num_pixels', 'Size': 71, 'Type': 'OTHER'}], 'FillValues': [{'Type': 'SCIENCE_FILLVALUE', 'Value': 65535}], ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C2147947800')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
> job_id = harmony_client.submit(harmony_request)
verify_collection.py:359:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/harmony/harmony.py:827: in submit
self._handle_error_response(response)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <harmony.harmony.Client object at 0x7f2bfca0b0a0>
response = <Response [422]>
def _handle_error_response(self, response: Response):
"""Raises the appropriate exception based on the response
received from Harmony. Trys to pull out an error message
from a Harmony JSON response when possible.
Args:
response: The Response from Harmony
Raises:
Exception with a Harmony error message or a more generic
HTTPError
"""
if 'application/json' in response.headers.get('Content-Type', ''):
exception_message = None
try:
response_json = response.json()
if hasattr(response_json, 'get'):
exception_message = response_json.get('description')
if not exception_message:
exception_message = response_json.get('error')
except JSONDecodeError:
pass
if exception_message:
> raise Exception(response.reason, exception_message)
E Exception: ('Unprocessable Entity', 'Error: the requested combination of operations: spatial subsetting on C2147947806-POCLOUD is unsupported')
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/harmony/harmony.py:775: Exception
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2162980118-POCLOUD for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 473' -H 'Content-Type: multipart/form-data; boundary=157c7d55ff21197f27b937d05c266454' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--157c7d55ff21197f27b937d05c266454
Content-Disposition: form-data; name="forceAsync"
true
--157c7d55ff21197f27b937d05c266454
Content-Disposition: form-data; name="subset"
lat(-73.917924:74.389464)
--157c7d55ff21197f27b937d05c266454
Content-Disposition: form-data; name="subset"
lon(32.86118999999999:176.22721)
--157c7d55ff21197f27b937d05c266454
Content-Disposition: form-data; name="granuleId"
G2162980118-POCLOUD
--157c7d55ff21197f27b937d05c266454--
' https://harmony.earthdata.nasa.gov/C2147947806-POCLOUD/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1729925368-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 32s]
Raw output
AttributeError: 'NoneType' object has no attribute 'variables'
collection_concept_id = 'C1729925368-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1729925368-GES_DISC', 'concept-id': 'G2934310103-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1729925368-GES_DISC'}]}, 'meta': {'association-details': {'collect...CE_FILLVALUE', 'Value': -999.989990234375}], 'LongName': 'HDFEOS/SWATHS/HO2-APriori/Data Fields/L2gpValue', ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729925360')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
group_walk(f.groups, f, '')
assert lat_var_name and lon_var_name
var_ds = None
msk = None
if science_vars := get_science_vars(collection_variables):
for idx, value in enumerate(science_vars):
science_var_name = science_vars[idx]['umm']['Name']
try:
var_ds = subsetted_ds_new[science_var_name]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
try:
# if the variable couldn't be found because the name includes a group, e.g.,
# `geolocation/relative_azimuth_angle`,
# then try to access the variable after removing the group name.
var_ds = subsetted_ds_new[science_var_name.rsplit("/", 1)[-1]]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
var_ds = None
msk = None
if var_ds is None and msk is None:
pytest.fail(f"Unable to find variable from umm-v to use as science variable.")
else:
# Can't find a science var in UMM-V, just pick one
> science_var_name = next(iter([v for v in subsetted_ds_new.variables if
str(v) not in lat_var_name and str(v) not in lon_var_name and 'time' not in str(v)]))
E AttributeError: 'NoneType' object has no attribute 'variables'
verify_collection.py:437: AttributeError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2934310103-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 449' -H 'Content-Type: multipart/form-data; boundary=705996106e20585d5884523aa871950c' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--705996106e20585d5884523aa871950c
Content-Disposition: form-data; name="forceAsync"
true
--705996106e20585d5884523aa871950c
Content-Disposition: form-data; name="subset"
lat(-85.5:85.5)
--705996106e20585d5884523aa871950c
Content-Disposition: form-data; name="subset"
lon(-171.0:171.0)
--705996106e20585d5884523aa871950c
Content-Disposition: form-data; name="granuleId"
G2934310103-GES_DISC
--705996106e20585d5884523aa871950c--
' https://harmony.earthdata.nasa.gov/C1729925368-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job 3e82f61b-3d04-4451-b1fe-645a1f838ab8
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729925360/MLS-Aura_L2GP-HO2_v05-02-c01_2024d104_subsetted.nc4
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C2205620319-POCLOUD] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 10m 0s]
Raw output
Failed: Timeout >600.0s
collection_concept_id = 'C2205620319-POCLOUD', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C2205620319-POCLOUD', 'concept-id': 'G2398096098-POCLOUD', 'concept-type': 'granul...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C2205620319-POCLOUD'}]}, 'meta': {'association-details': {'collecti... {'Name': 'ddm', 'Size': 5, 'Type': 'OTHER'}], 'FillValues': [{'Type': 'SCIENCE_FILLVALUE', 'Value': -99}], ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C2205620310')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
> harmony_client.wait_for_processing(job_id, show_progress=True)
verify_collection.py:361:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/harmony/harmony.py:960: in wait_for_processing
progress, status, message = self.progress(job_id)
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/harmony/harmony.py:931: in progress
response = session.get(self._status_url(job_id))
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/requests/sessions.py:602: in get
return self.request("GET", url, **kwargs)
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/requests/sessions.py:589: in request
resp = self.send(prep, **send_kwargs)
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/requests/sessions.py:703: in send
r = adapter.send(request, **kwargs)
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/requests/adapters.py:486: in send
resp = conn.urlopen(
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/urllib3/connectionpool.py:793: in urlopen
response = self._make_request(
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/urllib3/connectionpool.py:537: in _make_request
response = conn.getresponse()
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/urllib3/connection.py:466: in getresponse
httplib_response = super().getresponse()
/opt/hostedtoolcache/Python/3.10.14/x64/lib/python3.10/http/client.py:1375: in getresponse
response.begin()
/opt/hostedtoolcache/Python/3.10.14/x64/lib/python3.10/http/client.py:318: in begin
version, status, reason = self._read_status()
/opt/hostedtoolcache/Python/3.10.14/x64/lib/python3.10/http/client.py:279: in _read_status
line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
/opt/hostedtoolcache/Python/3.10.14/x64/lib/python3.10/socket.py:705: in readinto
return self._sock.recv_into(b)
/opt/hostedtoolcache/Python/3.10.14/x64/lib/python3.10/ssl.py:1307: in recv_into
return self.read(nbytes, buffer)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <ssl.SSLSocket [closed] fd=-1, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=6>
len = 8192, buffer = <memory at 0x7f2bf8f2b640>
def read(self, len=1024, buffer=None):
"""Read up to LEN bytes and return them.
Return zero-length string on EOF."""
self._checkClosed()
if self._sslobj is None:
raise ValueError("Read on closed or unwrapped SSL socket.")
try:
if buffer is not None:
> return self._sslobj.read(len, buffer)
E Failed: Timeout >600.0s
/opt/hostedtoolcache/Python/3.10.14/x64/lib/python3.10/ssl.py:1163: Failed
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2398096098-POCLOUD for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 448' -H 'Content-Type: multipart/form-data; boundary=bdfc03df7c98933fe9ddcc3e11e02eff' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--bdfc03df7c98933fe9ddcc3e11e02eff
Content-Disposition: form-data; name="forceAsync"
true
--bdfc03df7c98933fe9ddcc3e11e02eff
Content-Disposition: form-data; name="subset"
lat(-38.0:38.0)
--bdfc03df7c98933fe9ddcc3e11e02eff
Content-Disposition: form-data; name="subset"
lon(-171.0:171.0)
--bdfc03df7c98933fe9ddcc3e11e02eff
Content-Disposition: form-data; name="granuleId"
G2398096098-POCLOUD
--bdfc03df7c98933fe9ddcc3e11e02eff--
' https://harmony.earthdata.nasa.gov/C2205620319-POCLOUD/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job d6530a66-1e94-4970-9aa0-5e650bdeab75
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1239966842-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 34s]
Raw output
AttributeError: 'NoneType' object has no attribute 'variables'
collection_concept_id = 'C1239966842-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1239966842-GES_DISC', 'concept-id': 'G2936165275-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1239966842-GES_DISC'}]}, 'meta': {'association-details': {'collect...mm/variable/v1.9.0', 'Version': '1.9.0'}, 'Name': 'HDFEOS/SWATHS/ColumnAmountNO2/Data Fields/AmfTropClear', ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1239966840')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
group_walk(f.groups, f, '')
assert lat_var_name and lon_var_name
var_ds = None
msk = None
if science_vars := get_science_vars(collection_variables):
for idx, value in enumerate(science_vars):
science_var_name = science_vars[idx]['umm']['Name']
try:
var_ds = subsetted_ds_new[science_var_name]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
try:
# if the variable couldn't be found because the name includes a group, e.g.,
# `geolocation/relative_azimuth_angle`,
# then try to access the variable after removing the group name.
var_ds = subsetted_ds_new[science_var_name.rsplit("/", 1)[-1]]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
var_ds = None
msk = None
if var_ds is None and msk is None:
pytest.fail(f"Unable to find variable from umm-v to use as science variable.")
else:
# Can't find a science var in UMM-V, just pick one
> science_var_name = next(iter([v for v in subsetted_ds_new.variables if
str(v) not in lat_var_name and str(v) not in lon_var_name and 'time' not in str(v)]))
E AttributeError: 'NoneType' object has no attribute 'variables'
verify_collection.py:437: AttributeError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2936165275-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 490' -H 'Content-Type: multipart/form-data; boundary=09ea8a2d7062a39439ba355429f37413' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--09ea8a2d7062a39439ba355429f37413
Content-Disposition: form-data; name="forceAsync"
true
--09ea8a2d7062a39439ba355429f37413
Content-Disposition: form-data; name="subset"
lat(-83.37977074999999:-61.46671925)
--09ea8a2d7062a39439ba355429f37413
Content-Disposition: form-data; name="subset"
lon(-135.87459124999998:144.98830125)
--09ea8a2d7062a39439ba355429f37413
Content-Disposition: form-data; name="granuleId"
G2936165275-GES_DISC
--09ea8a2d7062a39439ba355429f37413--
' https://harmony.earthdata.nasa.gov/C1239966842-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job ed3bf8e7-cc77-4914-80a7-4fd38555bfa9
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1239966840/OMI-Aura_L2-OMNO2_2024m0415t0206-o105054_v003-2024m0416t060423_subsetted.nc4
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C2205618975-POCLOUD] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 10m 0s]
Raw output
Failed: Timeout >600.0s
collection_concept_id = 'C2205618975-POCLOUD', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C2205618975-POCLOUD', 'concept-id': 'G2243119784-POCLOUD', 'concept-type': 'granul...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C2205618975-POCLOUD'}]}, 'meta': {'association-details': {'collecti...ample', 'Size': 669788, 'Type': 'OTHER'}], 'FillValues': [{'Type': 'SCIENCE_FILLVALUE', 'Value': -9999.0}], ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C2205618970')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
> harmony_client.wait_for_processing(job_id, show_progress=True)
verify_collection.py:361:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <harmony.harmony.Client object at 0x7f2bfb53f8b0>
job_id = '650a4563-dc4a-470f-8de9-38512fe2ece8', show_progress = True
def wait_for_processing(self, job_id: str, show_progress: bool = False) -> None:
"""Retrieve a submitted job's completion status in percent.
Args:
job_id: UUID string for the job you wish to interrogate.
Returns:
The job's processing progress as a percentage.
:raises
Exception: This can happen if an invalid job_id is provided or Harmony services
can't be reached.
"""
# How often to refresh the screen for progress updates and animating spinners.
ui_update_interval = 0.33 # in seconds
running_w_errors_logged = False
intervals = round(self.check_interval / ui_update_interval)
if show_progress:
with progressbar.ProgressBar(max_value=100, widgets=progressbar_widgets) as bar:
progress = 0
while progress < 100:
progress, status, message = self.progress(job_id)
if status == 'failed':
raise ProcessingFailedException(job_id, message)
if status == 'canceled':
print('Job has been canceled.')
break
if status == 'paused':
print('\nJob has been paused. Call `resume()` to resume.', file=sys.stderr)
break
if (not running_w_errors_logged and status == 'running_with_errors'):
print('\nJob is running with errors.', file=sys.stderr)
running_w_errors_logged = True
# This gets around an issue with progressbar. If we update() with 0, the
# output shows up as "N/A". If we update with, e.g. 0.1, it rounds down or
# truncates to 0 but, importantly, actually displays that.
if progress == 0:
progress = 0.1
for _ in range(intervals):
bar.update(progress) # causes spinner to rotate even when no data change
sys.stdout.flush() # ensures correct behavior in Jupyter notebooks
if progress >= 100:
break
else:
> time.sleep(ui_update_interval)
E Failed: Timeout >600.0s
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/harmony/harmony.py:985: Failed
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2243119784-POCLOUD for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 474' -H 'Content-Type: multipart/form-data; boundary=f17924f60b4996606ebabb8c980077f5' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--f17924f60b4996606ebabb8c980077f5
Content-Disposition: form-data; name="forceAsync"
true
--f17924f60b4996606ebabb8c980077f5
Content-Disposition: form-data; name="subset"
lat(-37.729625:36.194625)
--f17924f60b4996606ebabb8c980077f5
Content-Disposition: form-data; name="subset"
lon(4.500975000000011:175.500025)
--f17924f60b4996606ebabb8c980077f5
Content-Disposition: form-data; name="granuleId"
G2243119784-POCLOUD
--f17924f60b4996606ebabb8c980077f5--
' https://harmony.earthdata.nasa.gov/C2205618975-POCLOUD/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job 650a4563-dc4a-470f-8de9-38512fe2ece8
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1729926467-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 36s]
Raw output
AttributeError: 'NoneType' object has no attribute 'variables'
collection_concept_id = 'C1729926467-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1729926467-GES_DISC', 'concept-id': 'G2934309970-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1729926467-GES_DISC'}]}, 'meta': {'association-details': {'collect... [{'Type': 'SCIENCE_FILLVALUE', 'Value': 513}], 'LongName': 'HDFEOS/SWATHS/RHI-APriori/Data Fields/Status', ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729926460')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
group_walk(f.groups, f, '')
assert lat_var_name and lon_var_name
var_ds = None
msk = None
if science_vars := get_science_vars(collection_variables):
for idx, value in enumerate(science_vars):
science_var_name = science_vars[idx]['umm']['Name']
try:
var_ds = subsetted_ds_new[science_var_name]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
try:
# if the variable couldn't be found because the name includes a group, e.g.,
# `geolocation/relative_azimuth_angle`,
# then try to access the variable after removing the group name.
var_ds = subsetted_ds_new[science_var_name.rsplit("/", 1)[-1]]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
var_ds = None
msk = None
if var_ds is None and msk is None:
pytest.fail(f"Unable to find variable from umm-v to use as science variable.")
else:
# Can't find a science var in UMM-V, just pick one
> science_var_name = next(iter([v for v in subsetted_ds_new.variables if
str(v) not in lat_var_name and str(v) not in lon_var_name and 'time' not in str(v)]))
E AttributeError: 'NoneType' object has no attribute 'variables'
verify_collection.py:437: AttributeError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2934309970-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 449' -H 'Content-Type: multipart/form-data; boundary=a993400d36114f9538b13484ff1b3ff1' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--a993400d36114f9538b13484ff1b3ff1
Content-Disposition: form-data; name="forceAsync"
true
--a993400d36114f9538b13484ff1b3ff1
Content-Disposition: form-data; name="subset"
lat(-85.5:85.5)
--a993400d36114f9538b13484ff1b3ff1
Content-Disposition: form-data; name="subset"
lon(-171.0:171.0)
--a993400d36114f9538b13484ff1b3ff1
Content-Disposition: form-data; name="granuleId"
G2934309970-GES_DISC
--a993400d36114f9538b13484ff1b3ff1--
' https://harmony.earthdata.nasa.gov/C1729926467-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job 689453ac-4d64-48ff-9b38-41af75c4e779
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729926460/MLS-Aura_L2GP-RHI_v05-02-c01_2024d104_subsetted.nc4
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1729925175-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 27s]
Raw output
AttributeError: 'NoneType' object has no attribute 'variables'
collection_concept_id = 'C1729925175-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1729925175-GES_DISC', 'concept-id': 'G2934310238-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1729925175-GES_DISC'}]}, 'meta': {'association-details': {'collect...CE_FILLVALUE', 'Value': -999.989990234375}], 'LongName': 'HDFEOS/SWATHS/HCl-APriori/Data Fields/L2gpValue', ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729925170')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
group_walk(f.groups, f, '')
assert lat_var_name and lon_var_name
var_ds = None
msk = None
if science_vars := get_science_vars(collection_variables):
for idx, value in enumerate(science_vars):
science_var_name = science_vars[idx]['umm']['Name']
try:
var_ds = subsetted_ds_new[science_var_name]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
try:
# if the variable couldn't be found because the name includes a group, e.g.,
# `geolocation/relative_azimuth_angle`,
# then try to access the variable after removing the group name.
var_ds = subsetted_ds_new[science_var_name.rsplit("/", 1)[-1]]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
var_ds = None
msk = None
if var_ds is None and msk is None:
pytest.fail(f"Unable to find variable from umm-v to use as science variable.")
else:
# Can't find a science var in UMM-V, just pick one
> science_var_name = next(iter([v for v in subsetted_ds_new.variables if
str(v) not in lat_var_name and str(v) not in lon_var_name and 'time' not in str(v)]))
E AttributeError: 'NoneType' object has no attribute 'variables'
verify_collection.py:437: AttributeError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2934310238-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 449' -H 'Content-Type: multipart/form-data; boundary=0b5d1fc62a2541305de4b733493cbfb6' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--0b5d1fc62a2541305de4b733493cbfb6
Content-Disposition: form-data; name="forceAsync"
true
--0b5d1fc62a2541305de4b733493cbfb6
Content-Disposition: form-data; name="subset"
lat(-85.5:85.5)
--0b5d1fc62a2541305de4b733493cbfb6
Content-Disposition: form-data; name="subset"
lon(-171.0:171.0)
--0b5d1fc62a2541305de4b733493cbfb6
Content-Disposition: form-data; name="granuleId"
G2934310238-GES_DISC
--0b5d1fc62a2541305de4b733493cbfb6--
' https://harmony.earthdata.nasa.gov/C1729925175-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job 26604a6e-55f9-4dba-a4fc-b63beb8a53ff
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729925170/MLS-Aura_L2GP-HCl_v05-02-c01_2024d104_subsetted.nc4
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1239966794-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 30s]
Raw output
AttributeError: 'NoneType' object has no attribute 'variables'
collection_concept_id = 'C1239966794-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1239966794-GES_DISC', 'concept-id': 'G2936120561-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1239966794-GES_DISC'}]}, 'meta': {'association-details': {'collect...scription': 'Extracted from _FillValue metadata attribute', 'Type': 'SCIENCE_FILLVALUE', 'Value': -32767}], ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1239966791')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
group_walk(f.groups, f, '')
assert lat_var_name and lon_var_name
var_ds = None
msk = None
if science_vars := get_science_vars(collection_variables):
for idx, value in enumerate(science_vars):
science_var_name = science_vars[idx]['umm']['Name']
try:
var_ds = subsetted_ds_new[science_var_name]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
try:
# if the variable couldn't be found because the name includes a group, e.g.,
# `geolocation/relative_azimuth_angle`,
# then try to access the variable after removing the group name.
var_ds = subsetted_ds_new[science_var_name.rsplit("/", 1)[-1]]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
var_ds = None
msk = None
if var_ds is None and msk is None:
pytest.fail(f"Unable to find variable from umm-v to use as science variable.")
else:
# Can't find a science var in UMM-V, just pick one
> science_var_name = next(iter([v for v in subsetted_ds_new.variables if
str(v) not in lat_var_name and str(v) not in lon_var_name and 'time' not in str(v)]))
E AttributeError: 'NoneType' object has no attribute 'variables'
verify_collection.py:437: AttributeError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2936120561-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 470' -H 'Content-Type: multipart/form-data; boundary=8657e513f93d79effa2fa84906e51106' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--8657e513f93d79effa2fa84906e51106
Content-Disposition: form-data; name="forceAsync"
true
--8657e513f93d79effa2fa84906e51106
Content-Disposition: form-data; name="subset"
lat(-83.207645:-60.298395)
--8657e513f93d79effa2fa84906e51106
Content-Disposition: form-data; name="subset"
lon(-159.358803:143.877283)
--8657e513f93d79effa2fa84906e51106
Content-Disposition: form-data; name="granuleId"
G2936120561-GES_DISC
--8657e513f93d79effa2fa84906e51106--
' https://harmony.earthdata.nasa.gov/C1239966794-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job f7edf579-7296-4b86-bf2f-f21ece21ecb5
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1239966791/OMI-Aura_L2-OMDOAO3_2024m0415t2330-o105067_v003-2024m0416t052302_subsetted.nc4
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C2158348170-POCLOUD] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 14s]
Raw output
Exception: ('Unprocessable Entity', 'Error: the requested combination of operations: spatial subsetting on C2158348170-POCLOUD is unsupported')
collection_concept_id = 'C2158348170-POCLOUD', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C2158348170-POCLOUD', 'concept-id': 'G2163332258-POCLOUD', 'concept-type': 'granul...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C2158348170-POCLOUD'}]}, 'meta': {'association-details': {'collecti...', 'Size': 3036, 'Type': 'TIME_DIMENSION'}], 'FillValues': [{'Type': 'SCIENCE_FILLVALUE', 'Value': 32767}], ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C2158348170')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
> job_id = harmony_client.submit(harmony_request)
verify_collection.py:359:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/harmony/harmony.py:827: in submit
self._handle_error_response(response)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <harmony.harmony.Client object at 0x7f2bfcb0f910>
response = <Response [422]>
def _handle_error_response(self, response: Response):
"""Raises the appropriate exception based on the response
received from Harmony. Trys to pull out an error message
from a Harmony JSON response when possible.
Args:
response: The Response from Harmony
Raises:
Exception with a Harmony error message or a more generic
HTTPError
"""
if 'application/json' in response.headers.get('Content-Type', ''):
exception_message = None
try:
response_json = response.json()
if hasattr(response_json, 'get'):
exception_message = response_json.get('description')
if not exception_message:
exception_message = response_json.get('error')
except JSONDecodeError:
pass
if exception_message:
> raise Exception(response.reason, exception_message)
E Exception: ('Unprocessable Entity', 'Error: the requested combination of operations: spatial subsetting on C2158348170-POCLOUD is unsupported')
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/harmony/harmony.py:775: Exception
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2163332258-POCLOUD for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 491' -H 'Content-Type: multipart/form-data; boundary=0c8087635ffad5f015e4c00991450d53' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--0c8087635ffad5f015e4c00991450d53
Content-Disposition: form-data; name="forceAsync"
true
--0c8087635ffad5f015e4c00991450d53
Content-Disposition: form-data; name="subset"
lat(-73.77936749999999:73.7796675)
--0c8087635ffad5f015e4c00991450d53
Content-Disposition: form-data; name="subset"
lon(7.974872500000004:166.47942749999999)
--0c8087635ffad5f015e4c00991450d53
Content-Disposition: form-data; name="granuleId"
G2163332258-POCLOUD
--0c8087635ffad5f015e4c00991450d53--
' https://harmony.earthdata.nasa.gov/C2158348170-POCLOUD/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1729925152-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 28s]
Raw output
AttributeError: 'NoneType' object has no attribute 'variables'
collection_concept_id = 'C1729925152-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1729925152-GES_DISC', 'concept-id': 'G2935897370-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1729925152-GES_DISC'}]}, 'meta': {'association-details': {'collect...ENCE_FILLVALUE', 'Value': -999.989990234375}], 'LongName': 'HDFEOS/SWATHS/GPH-APriori/Data Fields/Quality', ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729925150')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
group_walk(f.groups, f, '')
assert lat_var_name and lon_var_name
var_ds = None
msk = None
if science_vars := get_science_vars(collection_variables):
for idx, value in enumerate(science_vars):
science_var_name = science_vars[idx]['umm']['Name']
try:
var_ds = subsetted_ds_new[science_var_name]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
try:
# if the variable couldn't be found because the name includes a group, e.g.,
# `geolocation/relative_azimuth_angle`,
# then try to access the variable after removing the group name.
var_ds = subsetted_ds_new[science_var_name.rsplit("/", 1)[-1]]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
var_ds = None
msk = None
if var_ds is None and msk is None:
pytest.fail(f"Unable to find variable from umm-v to use as science variable.")
else:
# Can't find a science var in UMM-V, just pick one
> science_var_name = next(iter([v for v in subsetted_ds_new.variables if
str(v) not in lat_var_name and str(v) not in lon_var_name and 'time' not in str(v)]))
E AttributeError: 'NoneType' object has no attribute 'variables'
verify_collection.py:437: AttributeError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2935897370-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 449' -H 'Content-Type: multipart/form-data; boundary=796c2d0b7318e4f50d831be087aaee04' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--796c2d0b7318e4f50d831be087aaee04
Content-Disposition: form-data; name="forceAsync"
true
--796c2d0b7318e4f50d831be087aaee04
Content-Disposition: form-data; name="subset"
lat(-85.5:85.5)
--796c2d0b7318e4f50d831be087aaee04
Content-Disposition: form-data; name="subset"
lon(-171.0:171.0)
--796c2d0b7318e4f50d831be087aaee04
Content-Disposition: form-data; name="granuleId"
G2935897370-GES_DISC
--796c2d0b7318e4f50d831be087aaee04--
' https://harmony.earthdata.nasa.gov/C1729925152-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job 7d8c13ad-ca70-404e-ad96-b80a31742477
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729925150/MLS-Aura_L2GP-GPH_v05-02-c01_2024d105_subsetted.nc4
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1729925178-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 53s]
Raw output
AttributeError: 'NoneType' object has no attribute 'variables'
collection_concept_id = 'C1729925178-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1729925178-GES_DISC', 'concept-id': 'G2936187362-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1729925178-GES_DISC'}]}, 'meta': {'association-details': {'collect...CE_FILLVALUE', 'Value': -999.989990234375}], 'LongName': 'HDFEOS/SWATHS/HCN-APriori/Data Fields/L2gpValue', ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729925171')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
group_walk(f.groups, f, '')
assert lat_var_name and lon_var_name
var_ds = None
msk = None
if science_vars := get_science_vars(collection_variables):
for idx, value in enumerate(science_vars):
science_var_name = science_vars[idx]['umm']['Name']
try:
var_ds = subsetted_ds_new[science_var_name]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
try:
# if the variable couldn't be found because the name includes a group, e.g.,
# `geolocation/relative_azimuth_angle`,
# then try to access the variable after removing the group name.
var_ds = subsetted_ds_new[science_var_name.rsplit("/", 1)[-1]]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
var_ds = None
msk = None
if var_ds is None and msk is None:
pytest.fail(f"Unable to find variable from umm-v to use as science variable.")
else:
# Can't find a science var in UMM-V, just pick one
> science_var_name = next(iter([v for v in subsetted_ds_new.variables if
str(v) not in lat_var_name and str(v) not in lon_var_name and 'time' not in str(v)]))
E AttributeError: 'NoneType' object has no attribute 'variables'
verify_collection.py:437: AttributeError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2936187362-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 449' -H 'Content-Type: multipart/form-data; boundary=d2b4f59be8272f5cda24af9c3b0ddc02' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--d2b4f59be8272f5cda24af9c3b0ddc02
Content-Disposition: form-data; name="forceAsync"
true
--d2b4f59be8272f5cda24af9c3b0ddc02
Content-Disposition: form-data; name="subset"
lat(-85.5:85.5)
--d2b4f59be8272f5cda24af9c3b0ddc02
Content-Disposition: form-data; name="subset"
lon(-171.0:171.0)
--d2b4f59be8272f5cda24af9c3b0ddc02
Content-Disposition: form-data; name="granuleId"
G2936187362-GES_DISC
--d2b4f59be8272f5cda24af9c3b0ddc02--
' https://harmony.earthdata.nasa.gov/C1729925178-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job beab54aa-cb28-439e-9261-8e774e848329
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729925171/MLS-Aura_L2GP-HCN_v05-02-c01_2024d105_subsetted.nc4
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1729926922-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 30s]
Raw output
AttributeError: 'NoneType' object has no attribute 'variables'
collection_concept_id = 'C1729926922-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1729926922-GES_DISC', 'concept-id': 'G2936116537-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1729926922-GES_DISC'}]}, 'meta': {'association-details': {'collect...9.989990234375}], 'LongName': 'HDFEOS/SWATHS/Temperature-APriori/Data Fields/Temperature-APrioriPrecision', ...}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729926920')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
group_walk(f.groups, f, '')
assert lat_var_name and lon_var_name
var_ds = None
msk = None
if science_vars := get_science_vars(collection_variables):
for idx, value in enumerate(science_vars):
science_var_name = science_vars[idx]['umm']['Name']
try:
var_ds = subsetted_ds_new[science_var_name]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
try:
# if the variable couldn't be found because the name includes a group, e.g.,
# `geolocation/relative_azimuth_angle`,
# then try to access the variable after removing the group name.
var_ds = subsetted_ds_new[science_var_name.rsplit("/", 1)[-1]]
msk = np.logical_not(np.isnan(var_ds.data.squeeze()))
break
except Exception:
var_ds = None
msk = None
if var_ds is None and msk is None:
pytest.fail(f"Unable to find variable from umm-v to use as science variable.")
else:
# Can't find a science var in UMM-V, just pick one
> science_var_name = next(iter([v for v in subsetted_ds_new.variables if
str(v) not in lat_var_name and str(v) not in lon_var_name and 'time' not in str(v)]))
E AttributeError: 'NoneType' object has no attribute 'variables'
verify_collection.py:437: AttributeError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G2936116537-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 449' -H 'Content-Type: multipart/form-data; boundary=1d7c95ad6dfa2979ffe5af45743f5155' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--1d7c95ad6dfa2979ffe5af45743f5155
Content-Disposition: form-data; name="forceAsync"
true
--1d7c95ad6dfa2979ffe5af45743f5155
Content-Disposition: form-data; name="subset"
lat(-85.5:85.5)
--1d7c95ad6dfa2979ffe5af45743f5155
Content-Disposition: form-data; name="subset"
lon(-171.0:171.0)
--1d7c95ad6dfa2979ffe5af45743f5155
Content-Disposition: form-data; name="granuleId"
G2936116537-GES_DISC
--1d7c95ad6dfa2979ffe5af45743f5155--
' https://harmony.earthdata.nasa.gov/C1729926922-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job 28dae5f6-af59-49c8-bcfb-bacdf0c502ef
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1729926920/MLS-Aura_L2GP-Temperature_v05-02-c01_2024d105_subsetted.nc4
Check warning on line 0 in tests.verify_collection
github-actions / Regression test results for ops
test_spatial_subset[C1442068490-GES_DISC] (tests.verify_collection) failed
test-results/ops_test_report.xml [took 37s]
Raw output
OSError: [Errno group not found: PRODUCT] 'PRODUCT'
ds = <[AttributeError('NetCDF: Not a valid ID') raised in repr()] Group object at 0x7f2bf7eb3e40>
group = '/METADATA/PRODUCT', mode = 'r'
create_group = <function _netcdf4_create_group at 0x7f2bfe61e440>
def _nc4_require_group(ds, group, mode, create_group=_netcdf4_create_group):
if group in {None, "", "/"}:
# use the root group
return ds
else:
# make sure it's a string
if not isinstance(group, str):
raise ValueError("group must be a string or None")
# support path-like syntax
path = group.strip("/").split("/")
for key in path:
try:
> ds = ds.groups[key]
E KeyError: 'PRODUCT'
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/xarray/backends/netCDF4_.py:187: KeyError
During handling of the above exception, another exception occurred:
collection_concept_id = 'C1442068490-GES_DISC', env = 'ops'
granule_json = {'meta': {'collection-concept-id': 'C1442068490-GES_DISC', 'concept-id': 'G1628672811-GES_DISC', 'concept-type': 'gran...pecification': {'Name': 'UMM-G', 'URL': 'https://cdn.earthdata.nasa.gov/umm/granule/v1.6.5', 'Version': '1.6.5'}, ...}}
collection_variables = [{'associations': {'collections': [{'concept-id': 'C1442068490-GES_DISC'}]}, 'meta': {'association-details': {'collect...ov/umm/variable/v1.9.0', 'Version': '1.9.0'}, 'Name': 'METADATA/QA_STATISTICS/aerosol_index_354_388_pdf_bounds'}}, ...]
harmony_env = <Environment.PROD: 4>
tmp_path = PosixPath('/tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1442068490')
bearer_token = 'eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIj...r1CaNb5vX8boE10HCpjEg-I-l4oZ2r1iDE8CDrpzSJTr-gYRv5dvahM-5VuqaEm-BFxtUMVVts5d1hHyiicrOKToQCj-8yBkcjxUVUXIfe2iZqlsKvtI1Q'
@pytest.mark.timeout(600)
def test_spatial_subset(collection_concept_id, env, granule_json, collection_variables,
harmony_env, tmp_path: pathlib.Path, bearer_token):
test_spatial_subset.__doc__ = f"Verify spatial subset for {collection_concept_id} in {env}"
logging.info("Using granule %s for test", granule_json['meta']['concept-id'])
# Compute a box that is smaller than the granule extent bounding box
north, south, east, west = get_bounding_box(granule_json)
east, west, north, south = create_smaller_bounding_box(east, west, north, south, .95)
# Build harmony request
harmony_client = harmony.Client(env=harmony_env, token=bearer_token)
request_bbox = harmony.BBox(w=west, s=south, e=east, n=north)
request_collection = harmony.Collection(id=collection_concept_id)
harmony_request = harmony.Request(collection=request_collection, spatial=request_bbox,
granule_id=[granule_json['meta']['concept-id']])
logging.info("Sending harmony request %s", harmony_client.request_as_curl(harmony_request))
# Submit harmony request and download result
job_id = harmony_client.submit(harmony_request)
logging.info("Submitted harmony job %s", job_id)
harmony_client.wait_for_processing(job_id, show_progress=True)
subsetted_filepath = None
for filename in [file_future.result()
for file_future
in harmony_client.download_all(job_id, directory=f'{tmp_path}', overwrite=True)]:
logging.info(f'Downloaded: %s', filename)
subsetted_filepath = pathlib.Path(filename)
# Verify spatial subset worked
subsetted_ds = xarray.open_dataset(subsetted_filepath, decode_times=False)
group = None
# Try to read group in file
lat_var_name, lon_var_name = get_lat_lon_var_names(subsetted_ds, subsetted_filepath, collection_variables)
with netCDF4.Dataset(subsetted_filepath) as f:
group_list = []
def group_walk(groups, nc_d, current_group):
global subsetted_ds_new
subsetted_ds_new = None
# check if the top group has lat or lon variable
if lat_var_name in list(nc_d.variables.keys()):
subsetted_ds_new = subsetted_ds
else:
# if not then we'll need to keep track of the group layers
group_list.append(current_group)
# loop through the groups in the current layer
for g in groups:
# end the loop if we've already found latitude
if subsetted_ds_new:
break
# check if the groups have latitude, define the dataset and end the loop if found
if lat_var_name in list(nc_d.groups[g].variables.keys()):
group_list.append(g)
g = '/'.join(group_list)
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
break
# recall the function on a group that has groups in it and didn't find latitude
# this is going 'deeper' into the groups
if len(list(nc_d.groups[g].groups.keys())) > 0:
group_walk(nc_d.groups[g].groups, nc_d.groups[g], g)
else:
continue
> group_walk(f.groups, f, '')
verify_collection.py:405:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
verify_collection.py:396: in group_walk
subsetted_ds_new = xarray.open_dataset(subsetted_filepath, group=g, decode_times=False)
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/xarray/backends/api.py:572: in open_dataset
backend_ds = backend.open_dataset(
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/xarray/backends/netCDF4_.py:593: in open_dataset
store = NetCDF4DataStore.open(
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/xarray/backends/netCDF4_.py:400: in open
return cls(manager, group=group, mode=mode, lock=lock, autoclose=autoclose)
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/xarray/backends/netCDF4_.py:347: in __init__
self.format = self.ds.data_model
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/xarray/backends/netCDF4_.py:409: in ds
return self._acquire()
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/xarray/backends/netCDF4_.py:404: in _acquire
ds = _nc4_require_group(root, self._group, self._mode)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
ds = <[AttributeError('NetCDF: Not a valid ID') raised in repr()] Group object at 0x7f2bf7eb3e40>
group = '/METADATA/PRODUCT', mode = 'r'
create_group = <function _netcdf4_create_group at 0x7f2bfe61e440>
def _nc4_require_group(ds, group, mode, create_group=_netcdf4_create_group):
if group in {None, "", "/"}:
# use the root group
return ds
else:
# make sure it's a string
if not isinstance(group, str):
raise ValueError("group must be a string or None")
# support path-like syntax
path = group.strip("/").split("/")
for key in path:
try:
ds = ds.groups[key]
except KeyError as e:
if mode != "r":
ds = create_group(ds, key)
else:
# wrap error to provide slightly more helpful message
> raise OSError(f"group not found: {key}", e)
E OSError: [Errno group not found: PRODUCT] 'PRODUCT'
../../../../.cache/pypoetry/virtualenvs/l2ss-py-autotest-iYz8Sff2-py3.10/lib/python3.10/site-packages/xarray/backends/netCDF4_.py:193: OSError
--------------------------------- Captured Log ---------------------------------
INFO root:verify_collection.py:344 Using granule G1628672811-GES_DISC for test
INFO root:verify_collection.py:356 Sending harmony request curl -X POST -H 'Accept: */*' -H 'Accept-Encoding: gzip, deflate' -H 'Authorization: *****' -H 'Connection: keep-alive' -H 'Content-Length: 487' -H 'Content-Type: multipart/form-data; boundary=8d347a93a1c1cc8f3deb5be2956e67e0' -H 'User-Agent: Linux/6.5.0-1017-azure harmony-py/0.4.12 CPython/3.10.14 python-requests/2.31.0' -d '--8d347a93a1c1cc8f3deb5be2956e67e0
Content-Disposition: form-data; name="forceAsync"
true
--8d347a93a1c1cc8f3deb5be2956e67e0
Content-Disposition: form-data; name="subset"
lat(-82.265975:-63.873025000000005)
--8d347a93a1c1cc8f3deb5be2956e67e0
Content-Disposition: form-data; name="subset"
lon(-112.057275:162.74827499999998)
--8d347a93a1c1cc8f3deb5be2956e67e0
Content-Disposition: form-data; name="granuleId"
G1628672811-GES_DISC
--8d347a93a1c1cc8f3deb5be2956e67e0--
' https://harmony.earthdata.nasa.gov/C1442068490-GES_DISC/ogc-api-coverages/1.0.0/collections/all/coverage/rangeset
INFO root:verify_collection.py:360 Submitted harmony job cbaadbbd-1483-4dd7-86ea-c2d8f31cb1d0
INFO root:verify_collection.py:366 Downloaded: /tmp/pytest-of-runner/pytest-0/test_spatial_subset_C1442068490/S5P_OFFL_L2_AER_AI_20190806T003836_20190806T022006_09387_01_010302_20190812T000004_subsetted.nc4