Skip to content

Fix handling empty slices of a tensor - #802

Merged
sandorkertesz merged 7 commits into
developfrom
fix/xr-engine-empty-slices
Sep 17, 2025
Merged

Fix handling empty slices of a tensor#802
sandorkertesz merged 7 commits into
developfrom
fix/xr-engine-empty-slices

Conversation

@pawel-wolff

Copy link
Copy Markdown
Contributor

Description

This PR fixes a problem in handling empty slices of Xarray objects whenever the underlying data in managed by a field list through a FieldListTensor object (e.g. when a GRIB file is converted to Xarray via .to_xarray(lazy_load=True, ...) method). Consider the following code:

from earthkit.data import from_source
from earthkit.data.testing import earthkit_remote_test_data_file

ds_ek = from_source("url", earthkit_remote_test_data_file("xr_engine/level/pl.grib"))
ds = ds_ek.to_xarray(lazy_load=True)

ds2 = ds.sel(level=slice(350, 360))  # in ds2, the level-dim has size 0
ds2.load()  # crashes

ds3 = ds.load().sel(level=slice(350, 360))   # this works, because the full ds is loaded into memory 
                                             # before extracting an empty slice

The problem with ds2.load() comes from the fact that the underlying field list is empty (i.e. None, see

).

This PR fixes this issue by properly handling the case of an empty field list, see:

def _to_array(self, method, index=None, **kwargs):

A related code was refactored slightly to remove some code duplication between to_numpy, to_array methods within FieldListTensor and FieldListSparseTensor classes.

A relevant test was added.

Contributor Declaration

By opening this pull request, I affirm the following:

  • All authors agree to the Contributor License Agreement.
  • The code follows the project's coding standards.
  • I have performed self-review and added comments where needed.
  • I have added or updated tests to verify that my changes are effective and functional.
  • I have run all existing tests and confirmed they pass.

@codecov-commenter

codecov-commenter commented Sep 15, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.98%. Comparing base (195942d) to head (caa73ce).

Additional details and impacted files
@@             Coverage Diff             @@
##           develop     #802      +/-   ##
===========================================
+ Coverage    85.96%   85.98%   +0.01%     
===========================================
  Files          173      174       +1     
  Lines        13450    13467      +17     
  Branches       674      676       +2     
===========================================
+ Hits         11562    11579      +17     
  Misses        1698     1698              
  Partials       190      190              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread src/earthkit/data/indexing/tensor.py Outdated
Comment thread src/earthkit/data/indexing/tensor.py Outdated

def _to_array(self, method, index=None, **kwargs):
arr, current_field_shape = self._prepare_tensor_data(method, index=index, **kwargs)
if arr is None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be array format agnostic. The array_namespace is ideally in the kwargs.

Comment thread src/earthkit/data/indexing/tensor.py Outdated
import earthkit.utils.array.namespace.numpy as xp

arr = xp.empty(shape=0, dtype="f8")
return arr.reshape(self.user_shape + current_field_shape)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reshape on the array namespace should be used.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean using the top-level function xp.reshape(arr, new_shape) for an array namespace xp rather than arr.reshape(new_shape) ?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, exactly. We try to use all these methods on the array namespace (when it supports the methods). Both empty and reshape are part of the array api.

Comment thread tests/xr_engine/test_xr_tensor.py Outdated
@sandorkertesz
sandorkertesz merged commit fecc708 into develop Sep 17, 2025
131 checks passed
@pawel-wolff
pawel-wolff deleted the fix/xr-engine-empty-slices branch September 17, 2025 15:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants