uxarray 2026.2.0__tar.gz → 2026.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. {uxarray-2026.2.0 → uxarray-2026.4.0}/CONTRIBUTING.md +2 -2
  2. {uxarray-2026.2.0 → uxarray-2026.4.0}/INSTALLATION.md +2 -2
  3. {uxarray-2026.2.0 → uxarray-2026.4.0}/PKG-INFO +2 -2
  4. {uxarray-2026.2.0 → uxarray-2026.4.0}/pyproject.toml +1 -1
  5. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/core/accessors.py +2 -2
  6. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/core/dataarray.py +29 -4
  7. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/core/dataset.py +21 -3
  8. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/grid/coordinates.py +0 -8
  9. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/io/utils.py +84 -21
  10. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/remap/bilinear.py +1 -1
  11. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray.egg-info/PKG-INFO +2 -2
  12. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray.egg-info/requires.txt +1 -1
  13. {uxarray-2026.2.0 → uxarray-2026.4.0}/.codecov.yml +0 -0
  14. {uxarray-2026.2.0 → uxarray-2026.4.0}/.git_archival.txt +0 -0
  15. {uxarray-2026.2.0 → uxarray-2026.4.0}/.gitattributes +0 -0
  16. {uxarray-2026.2.0 → uxarray-2026.4.0}/CITATION.cff +0 -0
  17. {uxarray-2026.2.0 → uxarray-2026.4.0}/CODE_OF_CONDUCT.md +0 -0
  18. {uxarray-2026.2.0 → uxarray-2026.4.0}/LICENSE +0 -0
  19. {uxarray-2026.2.0 → uxarray-2026.4.0}/MANIFEST.in +0 -0
  20. {uxarray-2026.2.0 → uxarray-2026.4.0}/README.md +0 -0
  21. {uxarray-2026.2.0 → uxarray-2026.4.0}/build.sh +0 -0
  22. {uxarray-2026.2.0 → uxarray-2026.4.0}/setup.cfg +0 -0
  23. {uxarray-2026.2.0 → uxarray-2026.4.0}/setup.py +0 -0
  24. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/__init__.py +0 -0
  25. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/constants.py +0 -0
  26. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/conventions/__init__.py +0 -0
  27. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/conventions/descriptors.py +0 -0
  28. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/conventions/ugrid.py +0 -0
  29. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/core/__init__.py +0 -0
  30. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/core/aggregation.py +0 -0
  31. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/core/api.py +0 -0
  32. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/core/gradient.py +0 -0
  33. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/core/utils.py +0 -0
  34. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/core/zonal.py +0 -0
  35. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/cross_sections/__init__.py +0 -0
  36. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/cross_sections/dataarray_accessor.py +0 -0
  37. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/cross_sections/grid_accessor.py +0 -0
  38. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/cross_sections/sample.py +0 -0
  39. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/formatting_html.py +0 -0
  40. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/grid/__init__.py +0 -0
  41. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/grid/arcs.py +0 -0
  42. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/grid/area.py +0 -0
  43. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/grid/bounds.py +0 -0
  44. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/grid/connectivity.py +0 -0
  45. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/grid/dual.py +0 -0
  46. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/grid/geometry.py +0 -0
  47. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/grid/grid.py +0 -0
  48. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/grid/integrate.py +0 -0
  49. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/grid/intersections.py +0 -0
  50. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/grid/neighbors.py +0 -0
  51. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/grid/point_in_face.py +0 -0
  52. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/grid/slice.py +0 -0
  53. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/grid/utils.py +0 -0
  54. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/grid/validation.py +0 -0
  55. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/io/__init__.py +0 -0
  56. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/io/_delaunay.py +0 -0
  57. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/io/_esmf.py +0 -0
  58. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/io/_exodus.py +0 -0
  59. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/io/_fesom2.py +0 -0
  60. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/io/_geopandas.py +0 -0
  61. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/io/_geos.py +0 -0
  62. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/io/_healpix.py +0 -0
  63. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/io/_icon.py +0 -0
  64. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/io/_mpas.py +0 -0
  65. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/io/_scrip.py +0 -0
  66. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/io/_structured.py +0 -0
  67. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/io/_topology.py +0 -0
  68. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/io/_ugrid.py +0 -0
  69. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/io/_vertices.py +0 -0
  70. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/io/_voronoi.py +0 -0
  71. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/plot/__init__.py +0 -0
  72. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/plot/accessor.py +0 -0
  73. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/plot/constants.py +0 -0
  74. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/plot/matplotlib.py +0 -0
  75. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/plot/utils.py +0 -0
  76. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/remap/__init__.py +0 -0
  77. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/remap/accessor.py +0 -0
  78. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/remap/inverse_distance_weighted.py +0 -0
  79. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/remap/nearest_neighbor.py +0 -0
  80. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/remap/spatial_coords_remap.py +0 -0
  81. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/remap/utils.py +0 -0
  82. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/subset/__init__.py +0 -0
  83. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/subset/dataarray_accessor.py +0 -0
  84. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/subset/grid_accessor.py +0 -0
  85. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/utils/__init__.py +0 -0
  86. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray/utils/computing.py +0 -0
  87. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray.egg-info/SOURCES.txt +0 -0
  88. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray.egg-info/dependency_links.txt +0 -0
  89. {uxarray-2026.2.0 → uxarray-2026.4.0}/uxarray.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
- # Contributing to Uxarray
1
+ # Contributing to UXarray
2
2
 
3
- Anyone can contribute to and participate in the Uxarray project
3
+ Anyone can contribute to and participate in the UXarray project
4
4
  at any levels of project development! We conduct all of our work
5
5
  in the open, and all of our work is Open Source Licensed.
6
6
 
@@ -1,5 +1,5 @@
1
- # How to install Uxarray
1
+ # How to install UXarray
2
2
 
3
3
  Please see our
4
- [Uxarray Installation](https://uxarray.readthedocs.io/en/latest/getting-started/installation.html)
4
+ [UXarray Installation](https://uxarray.readthedocs.io/en/latest/getting-started/installation.html)
5
5
  instructions for detailed information!
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: uxarray
3
- Version: 2026.2.0
3
+ Version: 2026.4.0
4
4
  Summary: Xarray extension for unstructured climate and global weather data analysis and visualization.
5
5
  License: Apache License
6
6
  Version 2.0, January 2004
@@ -230,7 +230,7 @@ Requires-Dist: matplotlib
230
230
  Requires-Dist: matplotlib-inline
231
231
  Requires-Dist: netcdf4
232
232
  Requires-Dist: numba
233
- Requires-Dist: numpy<2.4
233
+ Requires-Dist: numpy
234
234
  Requires-Dist: pandas
235
235
  Requires-Dist: pyarrow
236
236
  Requires-Dist: requests
@@ -31,7 +31,7 @@ dependencies = [
31
31
  "matplotlib-inline",
32
32
  "netcdf4",
33
33
  "numba",
34
- "numpy<2.4",
34
+ "numpy",
35
35
  "pandas",
36
36
  "pyarrow",
37
37
  "requests",
@@ -1,5 +1,5 @@
1
1
  """
2
- Delegation-based accessor classes for UxArray groupby operations.
2
+ Delegation-based accessor classes for UXarray groupby operations.
3
3
 
4
4
  These classes wrap xarray's groupby/resample/etc objects and ensure that
5
5
  operations return UxDataArray/UxDataset objects with preserved uxgrid.
@@ -34,7 +34,7 @@ DATAARRAY_ACCESSOR_METHODS = {
34
34
 
35
35
 
36
36
  class BaseAccessor:
37
- """Base class for all UxArray accessor classes."""
37
+ """Base class for all UXarray accessor classes."""
38
38
 
39
39
  # Default methods known to return DataArrays/Datasets - optimized for performance
40
40
  _DEFAULT_PRESERVE_METHODS = {
@@ -573,7 +573,7 @@ class UxDataArray(xr.DataArray):
573
573
 
574
574
  Examples
575
575
  --------
576
- Open a Uxarray dataset and compute the integral
576
+ Open a UXarray dataset and compute the integral
577
577
 
578
578
  >>> import uxarray as ux
579
579
  >>> uxds = ux.open_dataset("grid.ug", "centroid_pressure_data_ug")
@@ -691,10 +691,19 @@ class UxDataArray(xr.DataArray):
691
691
  dims = list(self.dims)
692
692
  dims[face_axis] = "latitudes"
693
693
 
694
+ # Assign coords from `self` to the result except one that corresponds to `dims[face_axis]`
695
+ new_coords = {
696
+ k: v
697
+ for k, v in self.coords.items()
698
+ if self.dims[face_axis] not in v.dims
699
+ }
700
+ # Add latitudes to the resulting coords
701
+ new_coords["latitudes"] = latitudes
702
+
694
703
  return xr.DataArray(
695
704
  res,
696
705
  dims=dims,
697
- coords={"latitudes": latitudes},
706
+ coords=new_coords,
698
707
  name=self.name + "_zonal_mean"
699
708
  if self.name is not None
700
709
  else "zonal_mean",
@@ -736,10 +745,19 @@ class UxDataArray(xr.DataArray):
736
745
  dims = list(self.dims)
737
746
  dims[face_axis] = "latitudes"
738
747
 
748
+ # Assign coords from `self` to the result except one that corresponds to `dims[face_axis]`
749
+ new_coords = {
750
+ k: v
751
+ for k, v in self.coords.items()
752
+ if self.dims[face_axis] not in v.dims
753
+ }
754
+ # Add latitudes to the resulting coords
755
+ new_coords["latitudes"] = centers
756
+
739
757
  return xr.DataArray(
740
758
  res,
741
759
  dims=dims,
742
- coords={"latitudes": centers},
760
+ coords=new_coords,
743
761
  name=self.name + "_zonal_mean"
744
762
  if self.name is not None
745
763
  else "zonal_mean",
@@ -853,10 +871,17 @@ class UxDataArray(xr.DataArray):
853
871
  data=hit_count, dims="radius", coords={"radius": radii_deg}
854
872
  )
855
873
 
874
+ # Assign coords from `self` to the result except one that corresponds to `dims[face_axis]`
875
+ new_coords = {
876
+ k: v for k, v in self.coords.items() if self.dims[face_axis] not in v.dims
877
+ }
878
+ # Add radii_deg to the resulting coords
879
+ new_coords["radius"] = radii_deg
880
+
856
881
  uxda = xr.DataArray(
857
882
  means,
858
883
  dims=dims,
859
- coords={"radius": radii_deg},
884
+ coords=new_coords,
860
885
  name=self.name + "_azimuthal_mean"
861
886
  if self.name is not None
862
887
  else "azimuthal_mean",
@@ -90,6 +90,24 @@ class UxDataset(xr.Dataset):
90
90
  else:
91
91
  self._uxgrid = uxgrid
92
92
 
93
+ # As of xarray's 2026.4.0, `xr.Dataset(xr.Dataset)` is prohibited;
94
+ # hence this check, i.e. if we get `xr.Dataset` as input, use its `data_vars`
95
+ # as `dict` and handle `coords` and `attrs` properly as well
96
+ if args and isinstance(args[0], xr.Dataset):
97
+ ds = args[0]
98
+ # Replacee only args[0], `ds`, with `ds.data_vars` as `dict`
99
+ args = (dict(ds.data_vars),) + args[1:]
100
+ # coords not passed positionally
101
+ if len(args) < 2:
102
+ kwargs.setdefault(
103
+ "coords", dict(ds.coords)
104
+ ) # Set it as kwarg only if not explicitly provided
105
+ # attrs not passed positionally
106
+ if len(args) < 3:
107
+ kwargs.setdefault(
108
+ "attrs", ds.attrs
109
+ ) # Set it as kwarg only if not explicitly provided
110
+
93
111
  super().__init__(*args, **kwargs)
94
112
 
95
113
  # declare plotting accessor
@@ -567,7 +585,7 @@ class UxDataset(xr.Dataset):
567
585
 
568
586
  Examples
569
587
  --------
570
- Open a Uxarray dataset
588
+ Open a UXarray dataset
571
589
 
572
590
  >>> import uxarray as ux
573
591
  >>> uxds = ux.open_dataset("grid.ug", "centroid_pressure_data_ug")
@@ -627,9 +645,9 @@ class UxDataset(xr.Dataset):
627
645
  """
628
646
  if grid_format == "HEALPix":
629
647
  ds = self.rename_dims({"n_face": "cell"})
630
- return xr.Dataset(ds)
648
+ return xr.Dataset(ds.data_vars, coords=ds.coords, attrs=ds.attrs)
631
649
 
632
- return xr.Dataset(self)
650
+ return xr.Dataset(self.data_vars, coords=self.coords, attrs=self.attrs)
633
651
 
634
652
  def get_dual(self):
635
653
  """Compute the dual mesh for a dataset, returns a new dataset object.
@@ -68,10 +68,6 @@ def _xyz_to_lonlat_rad_no_norm(
68
68
  def _xyz_to_lonlat_rad_scalar(x, y, z, normalize=True):
69
69
  if normalize:
70
70
  x, y, z = _normalize_xyz_scalar(x, y, z)
71
- denom = abs(x * x + y * y + z * z)
72
- x /= denom
73
- y /= denom
74
- z /= denom
75
71
 
76
72
  lon = np.arctan2(y, x)
77
73
  lat = np.asin(z)
@@ -121,10 +117,6 @@ def _xyz_to_lonlat_rad(
121
117
 
122
118
  if normalize:
123
119
  x, y, z = _normalize_xyz(x, y, z)
124
- denom = np.abs(x * x + y * y + z * z)
125
- x /= denom
126
- y /= denom
127
- z /= denom
128
120
 
129
121
  lon = np.arctan2(y, x)
130
122
  lat = np.arcsin(z)
@@ -7,51 +7,114 @@ from uxarray.io._mpas import _mpas_to_ugrid_dims
7
7
  from uxarray.io._ugrid import _is_ugrid, _read_ugrid
8
8
 
9
9
 
10
+ def _is_exodus(dataset: xr.Dataset) -> bool:
11
+ """Check whether a dataset looks like an Exodus mesh."""
12
+ has_packed_coords = "coord" in dataset
13
+ has_split_coords = {"coordx", "coordy"}.issubset(dataset.variables)
14
+ has_connectivity = any(
15
+ name.startswith("connect") for name in dataset.variables
16
+ ) or any("num_nod_per_el" in dim for dim in dataset.dims)
17
+
18
+ return has_connectivity and (has_packed_coords or has_split_coords)
19
+
20
+
21
+ def _is_scrip(dataset: xr.Dataset) -> bool:
22
+ """Check whether a dataset looks like an unstructured SCRIP grid."""
23
+ required_vars = {
24
+ "grid_center_lon",
25
+ "grid_center_lat",
26
+ "grid_corner_lon",
27
+ "grid_corner_lat",
28
+ }
29
+ unstructured_markers = {"grid_imask", "grid_rank", "grid_area"}
30
+
31
+ return required_vars.issubset(dataset.variables) and any(
32
+ marker in dataset for marker in unstructured_markers
33
+ )
34
+
35
+
36
+ def _is_mpas(dataset: xr.Dataset) -> bool:
37
+ """Check whether a dataset looks like an MPAS grid."""
38
+ if "verticesOnCell" not in dataset:
39
+ return False
40
+
41
+ companion_groups = (
42
+ {"nEdgesOnCell"},
43
+ {"latCell", "lonCell"},
44
+ {"latVertex", "lonVertex"},
45
+ {"xCell", "yCell", "zCell"},
46
+ {"xVertex", "yVertex", "zVertex"},
47
+ )
48
+
49
+ return any(group.issubset(dataset.variables) for group in companion_groups)
50
+
51
+
52
+ def _is_esmf(dataset: xr.Dataset) -> bool:
53
+ """Check whether a dataset looks like an ESMF mesh."""
54
+ return "maxNodePElement" in dataset.dims and "elementConn" in dataset
55
+
56
+
57
+ def _is_geos_cs(dataset: xr.Dataset) -> bool:
58
+ """Check whether a dataset looks like a GEOS cube-sphere grid."""
59
+ required_dims = {"nf", "YCdim", "XCdim"}
60
+ required_vars = {"corner_lons", "corner_lats"}
61
+
62
+ return required_dims.issubset(dataset.sizes) and required_vars.issubset(
63
+ dataset.variables
64
+ )
65
+
66
+
67
+ def _is_icon(dataset: xr.Dataset) -> bool:
68
+ """Check whether a dataset looks like an ICON grid."""
69
+ required_vars = {"vertex_of_cell", "clon", "clat", "vlon", "vlat"}
70
+ return required_vars.issubset(dataset.variables)
71
+
72
+
73
+ def _is_fesom2(dataset: xr.Dataset) -> bool:
74
+ """Check whether a dataset looks like a FESOM2 grid."""
75
+ return "triag_nodes" in dataset
76
+
77
+
10
78
  def _parse_grid_type(dataset):
11
- """Checks input and contents to determine grid type. Supports detection of
12
- UGrid, SCRIP, Exodus, ESMF, and shape file.
79
+ """Determine the grid type represented by an input dataset.
13
80
 
14
81
  Parameters
15
82
  ----------
16
83
  dataset : Xarray dataset
17
- Xarray dataset of the grid
84
+ Xarray dataset containing grid topology information.
18
85
 
19
86
  Returns
20
87
  -------
21
- mesh_type : str
22
- File type of the file, ug, exo, scrip or shp
88
+ tuple[str, str | None, str | None]
89
+ A 3-tuple of ``(mesh_type, lon_name, lat_name)``. ``mesh_type`` is one
90
+ of ``"Exodus"``, ``"Scrip"``, ``"UGRID"``, ``"MPAS"``, ``"ESMF"``,
91
+ ``"GEOS-CS"``, ``"ICON"``, ``"FESOM2"``, or ``"Structured"``. The
92
+ longitude and latitude coordinate names are only returned for structured
93
+ grids and are otherwise ``None``.
23
94
 
24
95
  Raises
25
96
  ------
26
97
  RuntimeError
27
- If invalid file type
28
- ValueError
29
- If file is not in UGRID format
98
+ If the dataset format cannot be recognized.
30
99
  """
31
100
 
32
101
  _structured, lon_name, lat_name = _is_structured(dataset)
33
102
 
34
- if "coord" in dataset:
35
- # exodus with coord or coordx
36
- mesh_type = "Exodus"
37
- elif "coordx" in dataset:
103
+ if _is_exodus(dataset):
38
104
  mesh_type = "Exodus"
39
- elif "grid_center_lon" in dataset:
40
- # scrip with grid_center_lon
105
+ elif _is_scrip(dataset):
41
106
  mesh_type = "Scrip"
42
107
  elif _is_ugrid(dataset):
43
- # ugrid topology is present
44
108
  mesh_type = "UGRID"
45
- elif "verticesOnCell" in dataset:
109
+ elif _is_mpas(dataset):
46
110
  mesh_type = "MPAS"
47
- elif "maxNodePElement" in dataset.dims:
111
+ elif _is_esmf(dataset):
48
112
  mesh_type = "ESMF"
49
- elif all(key in dataset.sizes for key in ["nf", "YCdim", "XCdim"]):
50
- # expected dimensions for a GEOS cube sphere grid
113
+ elif _is_geos_cs(dataset):
51
114
  mesh_type = "GEOS-CS"
52
- elif "vertex_of_cell" in dataset:
115
+ elif _is_icon(dataset):
53
116
  mesh_type = "ICON"
54
- elif "triag_nodes" in dataset:
117
+ elif _is_fesom2(dataset):
55
118
  mesh_type = "FESOM2"
56
119
  elif _structured:
57
120
  mesh_type = "Structured"
@@ -128,7 +128,7 @@ def _barycentric_weights(point_xyz, dual, data_size, source_grid):
128
128
  # there were rare cases where counts > 0, hence the newer condition at the end
129
129
  elif counts == 1:
130
130
  all_weights[i, 0] = 1.0
131
- all_indices[i, 0] = int(cur_inds[0])
131
+ all_indices[i, 0] = int(cur_inds[0].squeeze())
132
132
  # 2/2/2026: For some `remap_to="nodes"` cases, `counts` happen to be bigger than 1. Not sure
133
133
  # if the best way to add weights from multiple faces is to take only the first face's though
134
134
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: uxarray
3
- Version: 2026.2.0
3
+ Version: 2026.4.0
4
4
  Summary: Xarray extension for unstructured climate and global weather data analysis and visualization.
5
5
  License: Apache License
6
6
  Version 2.0, January 2004
@@ -230,7 +230,7 @@ Requires-Dist: matplotlib
230
230
  Requires-Dist: matplotlib-inline
231
231
  Requires-Dist: netcdf4
232
232
  Requires-Dist: numba
233
- Requires-Dist: numpy<2.4
233
+ Requires-Dist: numpy
234
234
  Requires-Dist: pandas
235
235
  Requires-Dist: pyarrow
236
236
  Requires-Dist: requests
@@ -8,7 +8,7 @@ matplotlib
8
8
  matplotlib-inline
9
9
  netcdf4
10
10
  numba
11
- numpy<2.4
11
+ numpy
12
12
  pandas
13
13
  pyarrow
14
14
  requests
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes