Closed pletzer closed 2 years ago
iris-esmf-regrid
. We really appreciate it and will get back to you as soon as possible. Awesome job 👍This looks like it's due to a known problem in Iris where you aren't able to construct a "pointless" coordinate (see item 3 in this discussion https://github.com/SciTools/iris/discussions/4438). Due to the way we're interpreting meshes through the existing coordinate infrastructure in iris, we can only handle the case where face coords and edge coords exist (when data is stored on faces or edges). This is due to existing assumptions that all corrdinates ought to have points. We should be able to get this sorted eventually as it is a priority for future Iris/UGRID development, but for the time being you may want to use a work around.
I think it should still be possible to load the mesh in this file with iris.experimental.ugrid.load_mesh
, then it should be possible to add "dummy coordinates" to the mesh, then you can generate MeshCoord
's to describe the mesh using the to_MeshCoord
method, then you can add those coords to a cube loaded from the data without the PARSE_UGRID_ON_LOAD
context. That would look something like:
import numpy as np
import iris
from iris.experimental.ugrid import PARSE_UGRID_ON_LOAD, load_mesh
uav_cube = iris.load_cube("lfric_diag_wind.nc", "upward_air_velocity")
ew_cube = iris.load_cube("lfric_diag_wind.nc", "eastward_wind")
with PARSE_UGRID_ON_LOAD.context():
mesh = load_mesh("lfric_diag_wind.nc")
edge_length = mesh.edge_node_connectivity.indices_by_location().shape[0]
face_length = mesh.face_node_connectivity.indices_by_location().shape[0]
dummy_edge_lat = AuxCoord(np.zeros(edge_length), standard_name="latitude")
dummy_edge_lon = AuxCoord(np.zeros(edge_length), standard_name="longitude")
dummy_face_lat = AuxCoord(np.zeros(face_length), standard_name="latitude")
dummy_face_lon = AuxCoord(np.zeros(face_length), standard_name="longitude")
mesh.add_coords(
edge_x=dummy_edge_lon,
edge_y=dummy_edge_lat,
face_x=dummy_face_lon,
face_y=dummy_face_lat,
)
for coord in mesh.to_MeshCoords("edge"):
ew_cube.add_aux_coord(coord, 2)
for coord in mesh.to_MeshCoords("face"):
uav_cube.add_aux_coord(coord, 2)
This looks like it's due to a known problem in Iris where you aren't able to construct a "pointless" coordinate (see item 3 in this discussion SciTools/iris#4438).
I've been considering fixing that problem, so if now is a good time I'd like to explore that.
The reason we deferred it is that allowing a Coord to have bounds but no points would be rather a big change to the Iris datamodel. However, I feel that we could implement a somewhat "stopgap" solution, whereby a suitable MeshCoord would be created, but will raise an error only if an attempt to access the .points
is made.
Would it help to have a prototype version of Iris which implements that (e.g. a feature branch) ?
@SciTools-incubator/esmf-regrid-devs This issue is stale due to a lack of activity in the last 90 days. Remove stale label or comment, otherwise this issue will close automatically in 7 days time.
@SciTools-incubator/esmf-regrid-devs This stale issue has been automatically closed due to no community activity
🐛 Bug Report
Cannot load a mesh from a ugrid file that contains:
variables: int Mesh2d ; Mesh2d:cf_role = "mesh_topology" ; Mesh2d:edge_node_connectivity = "Mesh2d_edge_nodes" ; Mesh2d:face_edge_connectivity = "Mesh2d_face_edges" ; Mesh2d:face_node_connectivity = "Mesh2d_face_nodes" ; Mesh2d:long_name = "Topology data of 2D unstructured mesh" ; Mesh2d:node_coordinates = "Mesh2d_node_x Mesh2d_node_y" ; Mesh2d:topology_dimension = 2 ; int Mesh2d_face_edges(nMesh2d_face, nMesh2d_vertex) ; ...
How To Reproduce
Steps to reproduce the behaviour:
import iris from iris.experimental.ugrid import PARSE_UGRID_ON_LOAD with PARSE_UGRID_ON_LOAD.context(): mesh = iris.load_cube("lfric_diag_wind.nc")
You'll get
(iris-dev) niwa-35791~/iris-test$ python terror.py Traceback (most recent call last): File "terror.py", line 4, in
mesh = iris.load_cube("lfric_diag_wind.nc")
File "/Users/pletzera/iris/lib/iris/init.py", line 341, in load_cube
cubes = _load_collection(uris, constraints, callback).cubes()
File "/Users/pletzera/iris/lib/iris/init.py", line 276, in _load_collection
result = _CubeFilterCollection.from_cubes(cubes, constraints)
File "/Users/pletzera/iris/lib/iris/cube.py", line 104, in from_cubes
for cube in cubes:
File "/Users/pletzera/iris/lib/iris/init.py", line 261, in _generate_cubes
for cube in iris.io.load_files(part_names, callback, constraints):
File "/Users/pletzera/iris/lib/iris/io/init.py", line 208, in load_files
for cube in handling_format_spec.handler(
File "/Users/pletzera/iris/lib/iris/fileformats/netcdf.py", line 974, in load_cubes
mesh_coords, mesh_dim = _build_mesh_coords(mesh, cf_var)
File "/Users/pletzera/iris/lib/iris/experimental/ugrid/load.py", line 492, in _build_mesh_coords
mesh_coords = mesh.to_MeshCoords(location=cf_var.location)
File "/Users/pletzera/iris/lib/iris/experimental/ugrid/mesh.py", line 1972, in to_MeshCoords
result = [
File "/Users/pletzera/iris/lib/iris/experimental/ugrid/mesh.py", line 1973, in
self.to_MeshCoord(location=location, axis=ax) for ax in self.AXES
File "/Users/pletzera/iris/lib/iris/experimental/ugrid/mesh.py", line 1947, in to_MeshCoord
return MeshCoord(mesh=self, location=location, axis=axis)
File "/Users/pletzera/iris/lib/iris/experimental/ugrid/mesh.py", line 2835, in init
points, bounds = self._construct_access_arrays()
File "/Users/pletzera/iris/lib/iris/experimental/ugrid/mesh.py", line 3046, in _construct_access_arrays
points_coord = self.mesh.coord(include_edges=True, axis=axis)
File "/Users/pletzera/iris/lib/iris/experimental/ugrid/mesh.py", line 1614, in coord
result = self._coord_manager.filter(
File "/Users/pletzera/iris/lib/iris/experimental/ugrid/mesh.py", line 2283, in filter
raise CoordinateNotFoundError(emsg)
iris.exceptions.CoordinateNotFoundError: 'Expected to find exactly 1 coordinate, but found none.'
Expected behaviour
One should be able to load a ugrid file with variables that don't have coordinates. This would be expected for "extensive" variables, which are defined over the entire cell, face or edge. (All nodal variables are expected, however, to have coordinates.)
Screenshots
N/A
Environment
esmf_regrid
version: [e.g., From the command line runpython -c "import esmf_regrid; print(esmf_regrid.__version__)"
]: 0.5.dev0Additional context
Click to expand this section...
``` Add additional verbose information in a collapsible section. ``` See [here](https://gist.github.com/pierrejoubert73/902cc94d79424356a8d20be2b382e1ab) for further details.