Skip to content

Fix isel() bugs: missing indexers' coords; UxDataset.isel() silently skips slicing / fails if grid dim coords exist - #1759

Open
Sevans711 wants to merge 3 commits into
mainfrom
sevans/isel-bugfixes-uxdataset-and-coords
Open

Sevans711 wants to merge 3 commits into
mainfrom
sevans/isel-bugfixes-uxdataset-and-coords

Conversation

@Sevans711

Copy link
Copy Markdown
Collaborator

Closes #1712;
Closes #1713 / Closes #1714

Overview

Mapping code changes to original issues:

In all cases, also updated test_indexing.py accordingly. For 1713 and 1714, it was sufficient to just uncomment some existing lines which now serve as regression tests for these issues. For 1712, it also included building new tests inside test_indexing_by_dataarray(), which led to discovering #1758.

Expansion of scope: updated UxDataset._slice_dataset_from_grid in a few different ways to increase consistency with UxDataArray indexing methods:

  1. Renamed to UxDataset._slice_from_grid (to match naming conventions of UxDataArray._slice_from_grid)
  2. Deleted the "Prefer authoritative coords from the sliced grid if available" code. I don't think it would ever be desirable to overwrite dataset coords for a grid dimension based on the underlying grid's coords, during isel(). The PR which originally added those lines also contains no description of their purpose (see Add UxDataset.isel()  #1352), and they were not being covered by any example within the test suite (removing them does not cause any existing tests to fail).
  3. Deleted the logical branch for handling data arrays in self.data_vars when grid_dim in da.dims and not hasattr(da, "_slice_from_grid"). This branch would never be reached. (Right now, all data_vars are UxDataArrays. Eventually, maybe only data_vars with a grid dimension will be UxDataArrays. Either way, there should never be a data_var which both has a grid dim and is an xr.DataArray.)
  4. No longer accepts grid_dim or grid_indexer args; these were only being used in the now-removed parts of the code from points (2) and (3) above.
  5. Now returns a UxDataset instead of an xr.Dataset. (UxDataArray._slice_from_grid returns a UxDataArray, not an xr.DataArray.)

Tiny expansions of scope:

  1. Updated UxDataArray._slice_from_grid() to return an object of type(self), instead of UxDataArray. This has no extra cost, and makes uxarray slightly more object-oriented friendly. Before this change, on subclasses like class MyCoolArray(UxDataArray), isel() would return a UxDataArray instance if indexing by exactly 1 grid dim (e.g. isel(n_face=7)), but an instance of the subclass (MyCoolArray) if indexing by 0 grid dims (e.g. isel(time=0)) or if additionally indexing by something other than a grid dim (e.g. isel(time=0, n_face=7)). After this change it will always return an instance of the subclass (MyCoolArray) regardless of which dimensions get indexed.
  2. Minor syntax change in the UxDataArray.isel() code (i.e. calling the result result instead of da or xarr, and updating the value of result inside the if indexers:... block instead of returning from directly inside that block) to emphasize that the implementation is nearly identical to UxDataset.isel(). Maybe some day the full implementation, or at least a majority of it, could be moved to a shared parent class (something like UxDataContainer?), as a way to help avoid any more unexpected behavior differences between UxDataArray.isel() and UxDataset.isel().

Tiny expansions of scope unrelated to original issue:

  1. Small code cleanup with no functionality changes: noticed and removed import uxarray from top of dataset.py and dataarray.py files. Pretty sure it doesn't belong there; importing a full package from within itself is not standard practice. Removing this made it necessary to make a few other tiny updates:
  • (8a) updated UxDataset.get_dual() to use type(self) instead of uxarray.UxDataset, and to use UxDataArray instead of uxarray.UxDataArray.
  • (8b) Similarly, UxDataArray.get_dual() now uses type(self) instead of uxarray.UxDataArray.
  • (8c) Also updated UxDataArray.to_dataset() to explicitly include from uxarray.core.dataset import UxDataset instead of using uxarray.core.dataset.UxDataset.

PR Checklist

General

  • An issue is created and linked
  • Added appropriate labels (if your uxarray repo permissions allow it)
  • Filled out Overview and Expected Usage (if applicable) sections

Testing & Benchmarking

  • There is adequate test coverage of changes from this PR (add new tests if needed)
  • [N/A] If this PR could affect performance, ran ASV benchmarks and confirmed they show expected behavior (add a new benchmark if necessary)

Documentation and Examples

  • Docstrings updated with any function changes, and included in all new functions
  • User (public) functions added to docs/api.rst; internal (private) function names start with an underscore (_)
  • [N/A] If touched any notebook files, cleared the output of all cells before committing
  • [N/A] If added new notebook files, put into appropriate directories and referenced in appropriate files

AI Disclosure

AI Usage: GitHub Copilot's inline code suggestions, plus a small discussion with Claude for debugging/understanding syntax of super().

  • I have tested and take responsibility for all AI-generated content in my PR.

#1713: UxDataset.isel() silently fails to slice when providing grid dim not in the dataset

#1714: In UxDataset.isel() if "n_face" coords assigned: ValueError: dimension 'n_face' already exists as a scalar variable
@Sevans711 Sevans711 self-assigned this Sep 14, 2026
@Sevans711 Sevans711 added the bug Something isn't working label Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

1 participant