Skip to content

Conversation

@rajeeja
Copy link
Contributor

@rajeeja rajeeja commented Nov 11, 2025

Fixes #1401
Add support for OASIS/YAC multi-grid SCRIP files so UXarray can read the same debugging grids YAC produces @nils3er - please review.

Also, added a ux.list_grid_names(...) utility for quick inspection of available grids before loading.

This lets UXarray ingest the exact multi-grid outputs from YAC/OASIS-based workflows, paving the way for future coupler history support.

@rajeeja rajeeja requested a review from erogluorhan November 11, 2025 20:51
@nils3er
Copy link

nils3er commented Nov 13, 2025

Thanks for handling this so quickly!

I tested the code with a grid generated by yac and that works well. But when i tried to open the grids from the OASIS benchmarks i stubled across an IndexError in xarray:

----> 1 grids = ux.open_multigrid("grids.nc", mask_filename="masks_no_atm.nc", gridnames=["t12e"])

File ~/projects/uxarray/uxarray/core/api.py:221, in open_multigrid(grid_filename_or_obj, gridnames, mask_filename, **kwargs)
    219 loaded_grids: Dict[str, Grid] = {}
    220 for grid_name in grids_to_load:
--> 221     scrip_ds = _extract_single_grid(grid_ds, grid_name, grids_dict[grid_name])
    222     grid_ds_ugrid, source_dims_dict = _read_scrip(scrip_ds)
    224     grid = Grid(
    225         grid_ds_ugrid,
    226         source_grid_spec="Scrip",
    227         source_dims_dict=source_dims_dict,
    228     )

File ~/projects/uxarray/uxarray/io/_scrip.py:408, in _extract_single_grid(ds, grid_name, metadata)
    406 else:
    407     if computed_lat_lon is None:
--> 408         computed_lat_lon = grid_center_lat_lon(result)
    409     center_lat_da = xr.DataArray(computed_lat_lon[0], dims=["grid_size"])
    411 if center_lon and center_lon in ds:

File ~/projects/uxarray/uxarray/io/_scrip.py:272, in grid_center_lat_lon(ds)
    269 center_lat = np.rad2deg(np.arctan2(z, np.sqrt(x**2 + y**2)))
    271 # Make negative lons positive
--> 272 center_lon[center_lon < 0] += 360
    274 return center_lat, center_lon

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/core/dataarray.py:887, in DataArray.__getitem__(self, key)
    884     return self._getitem_coord(key)
    885 else:
    886     # xarray-style array indexing
--> 887     return self.isel(indexers=self._item_key_to_dict(key))

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/core/dataarray.py:1573, in DataArray.isel(self, indexers, drop, missing_dims, **indexers_kwargs)
   1570 indexers = either_dict_or_kwargs(indexers, indexers_kwargs, "isel")
   1572 if any(is_fancy_indexer(idx) for idx in indexers.values()):
-> 1573     ds = self._to_temp_dataset()._isel_fancy(
   1574         indexers, drop=drop, missing_dims=missing_dims
   1575     )
   1576     return self._from_temp_dataset(ds)
   1578 # Much faster algorithm for when all indexers are ints, slices, one-dimensional
   1579 # lists, or zero or one-dimensional np.ndarray's

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/core/dataset.py:2885, in Dataset._isel_fancy(self, indexers, drop, missing_dims)
   2881 var_indexers = {
   2882     k: v for k, v in valid_indexers.items() if k in var.dims
   2883 }
   2884 if var_indexers:
-> 2885     new_var = var.isel(indexers=var_indexers)
   2886     # drop scalar coordinates
   2887     # https://github.com/pydata/xarray/issues/6554
   2888     if name in self.coords and drop and new_var.ndim == 0:

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/core/variable.py:1130, in Variable.isel(self, indexers, missing_dims, **indexers_kwargs)
   1127 indexers = drop_dims_from_indexers(indexers, self.dims, missing_dims)
   1129 key = tuple(indexers.get(dim, slice(None)) for dim in self.dims)
-> 1130 return self[key]

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/core/variable.py:817, in Variable.__getitem__(self, key)
    804 def __getitem__(self, key) -> Self:
    805     """Return a new Variable object whose contents are consistent with
    806     getting the provided key from the underlying data.
    807 
   (...)    815     array `x.values` directly.
    816     """
--> 817     dims, indexer, new_order = self._broadcast_indexes(key)
    818     indexable = as_indexable(self._data)
    820     data = indexing.apply_indexer(indexable, indexer)

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/core/variable.py:656, in Variable._broadcast_indexes(self, key)
    650 if all(
    651     (isinstance(k, BASIC_INDEXING_TYPES) and not isinstance(k, bool))
    652     for k in key
    653 ):
    654     return self._broadcast_indexes_basic(key)
--> 656 self._validate_indexers(key)
    657 # Detect it can be mapped as an outer indexer
    658 # If all key is unlabeled, or
    659 # key can be mapped as an OuterIndexer.
    660 if all(not isinstance(k, Variable) for k in key):

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/core/variable.py:705, in Variable._validate_indexers(self, key)
    700     raise IndexError(
    701         f"Boolean array size {len(k):d} is used to index array "
    702         f"with shape {self.shape}."
    703     )
    704 if k.ndim > 1:
--> 705     raise IndexError(
    706         f"{k.ndim}-dimensional boolean indexing is not supported. "
    707     )
    708 if is_duck_dask_array(k.data):
    709     raise KeyError(
    710         "Indexing with a boolean dask array is not allowed. "
    711         "This will result in a dask array of unknown shape. "
    712         "Such arrays are unsupported by Xarray."
    713         "Please compute the indexer first using .compute()"
    714     )

IndexError: 2-dimensional boolean indexing is not supported.

I used uv to setup the venv. uv pip freeze says

Using Python 3.12.3 environment at: /home/nils/projects/uxarray/venv_multigrid
antimeridian==0.4.3
asttokens==3.0.0
bleach==6.3.0
bokeh==3.8.1
cartopy==0.25.0
certifi==2025.11.12
cftime==1.6.5
charset-normalizer==3.4.4
click==8.3.0
cloudpickle==3.1.2
colorcet==3.1.0
contourpy==1.3.3
cycler==0.12.1
dask==2025.11.0
datashader==0.18.2
decorator==5.2.1
executing==2.2.1
fonttools==4.60.1
fsspec==2025.10.0
geopandas==1.1.1
geoviews==1.14.1
healpix==2025.1
holoviews==1.22.0
hvplot==0.12.1
idna==3.11
ipython==9.7.0
ipython-pygments-lexers==1.1.1
jedi==0.19.2
jinja2==3.1.6
joblib==1.5.2
kiwisolver==1.4.9
linkify-it-py==2.0.3
llvmlite==0.45.1
locket==1.0.0
markdown==3.10
markdown-it-py==4.0.0
markupsafe==3.0.3
matplotlib==3.10.7
matplotlib-inline==0.2.1
mdit-py-plugins==0.5.0
mdurl==0.1.2
multipledispatch==1.0.0
narwhals==2.11.0
netcdf4==1.7.3
numba==0.62.1
numpy==2.3.4
packaging==25.0
pandas==2.3.3
panel==1.8.3
param==2.2.1
parso==0.8.5
partd==1.4.2
pexpect==4.9.0
pillow==12.0.0
polars==1.35.2
polars-runtime-32==1.35.2
prompt-toolkit==3.0.52
ptyprocess==0.7.0
pure-eval==0.2.3
pyarrow==22.0.0
pyct==0.6.0
pygments==2.19.2
pyogrio==0.11.1
pyparsing==3.2.5
pyproj==3.7.2
pyshp==3.0.2.post1
python-dateutil==2.9.0.post0
pytz==2025.2
pyviz-comms==3.0.6
pyyaml==6.0.3
requests==2.32.5
retrying==1.4.2
scikit-learn==1.7.2
scipy==1.16.3
shapely==2.1.2
six==1.17.0
spatialpandas==0.5.0
stack-data==0.6.3
threadpoolctl==3.6.0
toolz==1.1.0
tornado==6.5.2
tqdm==4.67.1
traitlets==5.14.3
typing-extensions==4.15.0
tzdata==2025.2
uc-micro-py==1.0.3
urllib3==2.5.0
-e file:///home/nils/projects/uxarray
wcwidth==0.2.14
webencodings==0.5.1
xarray==2025.10.1
xyzservices==2025.10.0

@rajeeja
Copy link
Contributor Author

rajeeja commented Nov 13, 2025

Thanks for handling this so quickly!

I tested the code with a grid generated by yac and that works well. But when i tried to open the grids from the OASIS benchmarks i stubled across an IndexError in xarray:

Thanks for testing this. I used this script to generate the test files. Maybe some assumptions I made was incorrect there. Can you check and also share the OASIS files you used to test this?

@rajeeja
Copy link
Contributor Author

rajeeja commented Nov 14, 2025

Thanks for handling this so quickly!

I tested the code with a grid generated by yac and that works well. But when i tried to open the grids from the OASIS benchmarks i stubled across an IndexError in xarray:

My last commit might have fixed that. I added a safeguard so xarray no longer tries 2‑D boolean indexing when the OASIS grids leave center_lon/center_lat as DataArrays. Please pull the latest and try your ux.open_multigrid call again—let me know if the IndexError still appears.

@nils3er
Copy link

nils3er commented Nov 14, 2025

great! The IndexError is fixed now. But i still have problems.

Now i get a ValueError:

ValueError                                Traceback (most recent call last)
Cell In[2], line 1
----> 1 grids = ux.open_multigrid("/home/nils/Downloads/compare_interpolations/grids_compare/grids.nc", mask_filename="/home/nils/Downloads/compare_interpolations/grids_compare/masks_no_atm.nc")

File ~/projects/uxarray/uxarray/core/api.py:221, in open_multigrid(grid_filename_or_obj, gridnames, mask_filename, **kwargs)
    219 loaded_grids: Dict[str, Grid] = {}
    220 for grid_name in grids_to_load:
--> 221     scrip_ds = _extract_single_grid(grid_ds, grid_name, grids_dict[grid_name])
    222     grid_ds_ugrid, source_dims_dict = _read_scrip(scrip_ds)
    224     grid = Grid(
    225         grid_ds_ugrid,
    226         source_grid_spec="Scrip",
    227         source_dims_dict=source_dims_dict,
    228     )

File ~/projects/uxarray/uxarray/io/_scrip.py:413, in _extract_single_grid(ds, grid_name, metadata)
    411     if computed_lat_lon is None:
    412         computed_lat_lon = grid_center_lat_lon(result)
--> 413     center_lat_da = xr.DataArray(computed_lat_lon[0], dims=["grid_size"])
    415 if center_lon and center_lon in ds:
    416     center_lon_da = ds[center_lon].rename({cell_dim: "grid_size"}).copy()

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/core/dataarray.py:461, in DataArray.__init__(self, data, coords, dims, name, attrs, indexes, fastpath)
    459 data = _check_data_shape(data, coords, dims)
    460 data = as_compatible_data(data)
--> 461 coords, dims = _infer_coords_and_dims(data.shape, coords, dims)
    462 variable = Variable(dims, data, attrs, fastpath=True)
    464 if not isinstance(coords, Coordinates):

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/core/dataarray.py:166, in _infer_coords_and_dims(shape, coords, dims)
    164 dims_tuple = tuple(dims)
    165 if len(dims_tuple) != len(shape):
--> 166     raise ValueError(
    167         "different number of dimensions on data "
    168         f"and dims: {len(shape)} vs {len(dims_tuple)}"
    169     )
    170 for d in dims_tuple:
    171     if not hashable(d):

ValueError: different number of dimensions on data and dims: 2 vs 1

As far as I understood the code, it lacks the detection of multidimensional cell arrays. E.g. here https://github.com/UXARRAY/uxarray/pull/1404/files#diff-9ea4ae11df0f0212a38f7a79686328d0dcf5f0386cd0afcf877981c2fc4d372cR327 only one dimension name for the cells are extracted.

As i understood it you could detect the multiple dimensions (e.g. ("x_bggd", "y_bggd")) and then - instead of renaming the cell_dim to grid_size - you can stack them:

ds.stack(grid_size=("x_bggd", "y_bggd"))

@rajeeja
Copy link
Contributor Author

rajeeja commented Nov 20, 2025

great! The IndexError is fixed now. But i still have problems.

Now i get a ValueError:

ValueError                                Traceback (most recent call last)
Cell In[2], line 1
----> 1 grids = ux.open_multigrid("/home/nils/Downloads/compare_interpolations/grids_compare/grids.nc", mask_filename="/home/nils/Downloads/compare_interpolations/grids_compare/masks_no_atm.nc")

File ~/projects/uxarray/uxarray/core/api.py:221, in open_multigrid(grid_filename_or_obj, gridnames, mask_filename, **kwargs)
    219 loaded_grids: Dict[str, Grid] = {}
    220 for grid_name in grids_to_load:
--> 221     scrip_ds = _extract_single_grid(grid_ds, grid_name, grids_dict[grid_name])
    222     grid_ds_ugrid, source_dims_dict = _read_scrip(scrip_ds)
    224     grid = Grid(
    225         grid_ds_ugrid,
    226         source_grid_spec="Scrip",
    227         source_dims_dict=source_dims_dict,
    228     )

File ~/projects/uxarray/uxarray/io/_scrip.py:413, in _extract_single_grid(ds, grid_name, metadata)
    411     if computed_lat_lon is None:
    412         computed_lat_lon = grid_center_lat_lon(result)
--> 413     center_lat_da = xr.DataArray(computed_lat_lon[0], dims=["grid_size"])
    415 if center_lon and center_lon in ds:
    416     center_lon_da = ds[center_lon].rename({cell_dim: "grid_size"}).copy()

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/core/dataarray.py:461, in DataArray.__init__(self, data, coords, dims, name, attrs, indexes, fastpath)
    459 data = _check_data_shape(data, coords, dims)
    460 data = as_compatible_data(data)
--> 461 coords, dims = _infer_coords_and_dims(data.shape, coords, dims)
    462 variable = Variable(dims, data, attrs, fastpath=True)
    464 if not isinstance(coords, Coordinates):

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/core/dataarray.py:166, in _infer_coords_and_dims(shape, coords, dims)
    164 dims_tuple = tuple(dims)
    165 if len(dims_tuple) != len(shape):
--> 166     raise ValueError(
    167         "different number of dimensions on data "
    168         f"and dims: {len(shape)} vs {len(dims_tuple)}"
    169     )
    170 for d in dims_tuple:
    171     if not hashable(d):

ValueError: different number of dimensions on data and dims: 2 vs 1

As far as I understood the code, it lacks the detection of multidimensional cell arrays. E.g. here https://github.com/UXARRAY/uxarray/pull/1404/files#diff-9ea4ae11df0f0212a38f7a79686328d0dcf5f0386cd0afcf877981c2fc4d372cR327 only one dimension name for the cells are extracted.

As i understood it you could detect the multiple dimensions (e.g. ("x_bggd", "y_bggd")) and then - instead of renaming the cell_dim to grid_size - you can stack them:

ds.stack(grid_size=("x_bggd", "y_bggd"))

Please pull try again; do you have a test file that I can include in our tests?

@nils3er
Copy link

nils3er commented Nov 25, 2025

Loading the grids works now. But if i add the masks i get the following error:

In [2]: grids = ux.open_multigrid("/home/nils/Downloads/compare_interpolations/grids_compare/grids.nc", mask_filename="/home/nils/Downloads/compare_interpolations/grids_compare/masks_no_atm.nc")
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[2], line 1
----> 1 grids = ux.open_multigrid("/home/nils/Downloads/compare_interpolations/grids_compare/grids.nc", mask_filename="/home/nils/Downloads/compare_interpolations/grids_compare/masks_no_atm.nc")

File ~/projects/uxarray/uxarray/core/api.py:245, in open_multigrid(grid_filename_or_obj, gridnames, mask_filename, **kwargs)
    243     mask_values = np.asarray(mask_flat.values)
    244     active_indices = np.flatnonzero(mask_values == 1)
--> 245     grid = grid.isel(n_face=active_indices)
    246 else:
    247     warn(
    248         f"Mask variable '{mask_var}' not found in mask file; "
    249         f"grid '{grid_name}' will be returned without masking."
    250     )

File ~/projects/uxarray/uxarray/grid/grid.py:2452, in Grid.isel(self, inverse_indices, **dim_kwargs)
   2449     return _slice_edge_indices(self, dim_kwargs["n_edge"])
   2451 elif "n_face" in dim_kwargs:
-> 2452     return _slice_face_indices(
   2453         self, dim_kwargs["n_face"], inverse_indices=inverse_indices
   2454     )
   2456 else:
   2457     raise ValueError(
   2458         "Indexing must be along a grid dimension: ('n_node', 'n_edge', 'n_face')"
   2459     )

File ~/projects/uxarray/uxarray/grid/slice.py:207, in _slice_face_indices(grid, indices, inclusive, inverse_indices)
    195                 raise ValueError(
    196                     "Incorrect type of index for `inverse_indices`. Try passing one of the following "
    197                     "instead: 'face', 'edge', 'node'"
    198                 )
    200     return Grid.from_dataset(
    201         ds,
    202         source_grid_spec=grid.source_grid_spec,
    203         is_subset=True,
    204         inverse_indices=inverse_indices_ds,
    205     )
--> 207 return Grid.from_dataset(ds, source_grid_spec=grid.source_grid_spec, is_subset=True)

File ~/projects/uxarray/uxarray/grid/grid.py:306, in Grid.from_dataset(cls, dataset, use_dual, **kwargs)
    303     except TypeError:
    304         raise ValueError("Unsupported Grid Format")
--> 306 return cls(
    307     grid_ds,
    308     source_grid_spec,
    309     source_dims_dict,
    310     is_subset=kwargs.get("is_subset", False),
    311     inverse_indices=kwargs.get("inverse_indices"),
    312 )

File ~/projects/uxarray/uxarray/grid/grid.py:235, in Grid.__init__(self, grid_ds, source_grid_spec, source_dims_dict, is_subset, inverse_indices)
    232 self._normalized = None
    234 # set desired longitude range to [-180, 180]
--> 235 _set_desired_longitude_range(self)

File ~/projects/uxarray/uxarray/grid/coordinates.py:698, in _set_desired_longitude_range(uxgrid)
    696 for lon_name in ["node_lon", "edge_lon", "face_lon"]:
    697     if lon_name in uxgrid._ds:
--> 698         if uxgrid._ds[lon_name].max() > 180:
    699             da = uxgrid._ds[lon_name]
    700             wrapped = (uxgrid._ds[lon_name] + 180) % 360 - 180

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/core/_aggregations.py:2816, in DataArrayAggregations.max(self, dim, skipna, keep_attrs, **kwargs)
   2745 def max(
   2746     self,
   2747     dim: Dims = None,
   (...)   2751     **kwargs: Any,
   2752 ) -> Self:
   2753     """
   2754     Reduce this DataArray's data by applying ``max`` along some dimension(s).
   2755 
   (...)   2814     array(nan)
   2815     """
-> 2816     return self.reduce(
   2817         duck_array_ops.max,
   2818         dim=dim,
   2819         skipna=skipna,
   2820         keep_attrs=keep_attrs,
   2821         **kwargs,
   2822     )

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/core/dataarray.py:3909, in DataArray.reduce(self, func, dim, axis, keep_attrs, keepdims, **kwargs)
   3865 def reduce(
   3866     self,
   3867     func: Callable[..., Any],
   (...)   3873     **kwargs: Any,
   3874 ) -> Self:
   3875     """Reduce this array by applying `func` along some dimension(s).
   3876 
   3877     Parameters
   (...)   3906         summarized data and the indicated dimension(s) removed.
   3907     """
-> 3909     var = self.variable.reduce(func, dim, axis, keep_attrs, keepdims, **kwargs)
   3910     return self._replace_maybe_drop_dims(var)

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/core/variable.py:1766, in Variable.reduce(self, func, dim, axis, keep_attrs, keepdims, **kwargs)
   1759 keep_attrs_ = (
   1760     _get_keep_attrs(default=False) if keep_attrs is None else keep_attrs
   1761 )
   1763 # Note that the call order for Variable.mean is
   1764 #    Variable.mean -> NamedArray.mean -> Variable.reduce
   1765 #    -> NamedArray.reduce
-> 1766 result = super().reduce(
   1767     func=func, dim=dim, axis=axis, keepdims=keepdims, **kwargs
   1768 )
   1770 # return Variable always to support IndexVariable
   1771 return Variable(
   1772     result.dims, result._data, attrs=result._attrs if keep_attrs_ else None
   1773 )

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/namedarray/core.py:919, in NamedArray.reduce(self, func, dim, axis, keepdims, **kwargs)
    917         data = func(self.data, axis=axis, **kwargs)
    918     else:
--> 919         data = func(self.data, **kwargs)
    921 if getattr(data, "shape", ()) == self.shape:
    922     dims = self.dims

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/core/duck_array_ops.py:532, in _create_nan_agg_method.<locals>.f(values, axis, skipna, **kwargs)
    530     with warnings.catch_warnings():
    531         warnings.filterwarnings("ignore", "All-NaN slice encountered")
--> 532         return func(values, axis=axis, **kwargs)
    533 except AttributeError:
    534     if not is_duck_dask_array(values):

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/computation/nanops.py:78, in nanmax(a, axis, out)
     75 if a.dtype.kind == "O":
     76     return _nan_minmax_object("max", dtypes.get_neg_infinity(a.dtype), a, axis)
---> 78 return nputils.nanmax(a, axis=axis)

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/xarray/core/nputils.py:242, in _create_method.<locals>.f(values, axis, **kwargs)
    240         result = np.float64(result)
    241 else:
--> 242     result = getattr(npmodule, name)(values, axis=axis, **kwargs)
    244 return result

File ~/projects/uxarray/venv_multigrid/lib/python3.12/site-packages/numpy/lib/_nanfunctions_impl.py:485, in nanmax(a, axis, out, keepdims, initial, where)
    480     kwargs['where'] = where
    482 if (type(a) is np.ndarray or type(a) is np.memmap) and a.dtype != np.object_:
    483     # Fast, but not safe for subclasses of ndarray, or object arrays,
    484     # which do not implement isnan (gh-9009), or fmax correctly (gh-8975)
--> 485     res = np.fmax.reduce(a, axis=axis, out=out, **kwargs)
    486     if np.isnan(res).any():
    487         warnings.warn("All-NaN slice encountered", RuntimeWarning,
    488                       stacklevel=2)

ValueError: zero-size array to reduction operation fmax which has no identity

For testing i use the grid files that are contained in the OASIS benchmarks: https://zenodo.org/records/5342778 and a yac generated grid:
healpix3.tar.gz

@nils3er
Copy link

nils3er commented Dec 4, 2025

I tested your update! No errors anymore! 🥳

But i stumbled over one thing! It would be great if one could set a valid_mask_value or similar. Because if i load the example grids, the torc grid looks like
torc
while it is actually an ocean grid which should look like
torc_inv

Question would be how the interface look like? One valid_mask_value per grid? Or a general one?

Thanks for all the effort!

@rajeeja
Copy link
Contributor Author

rajeeja commented Dec 4, 2025

Question would be how the interface look like? One valid_mask_value per grid? Or a general one?

Thanks for the test; Ah, the plot you see if because open_multigrid currently assumes 1 means “keep” and 0 means “discard”. When applied to torc, that inverts the intended meaning: land is kept, ocean is dropped.

per grid is better, I think: how about a per-grid dict: mask_active_value={"torc": 0, "atm": 1}?

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.

Support OASIS flavor of SCRIP grid files (open_multigrid)

3 participants