From e4e23109819971be4fe42320e397ac17c4cd042e Mon Sep 17 00:00:00 2001 From: Patrick Peglar Date: Wed, 24 Jul 2024 15:13:56 +0100 Subject: [PATCH] Move all iris.mesh.save into iris.fileformats.netcdf.save Fix experimental.ugrid import of save_mesh --- lib/iris/experimental/ugrid.py | 2 +- lib/iris/fileformats/netcdf/saver.py | 39 ++++++++++++++ lib/iris/mesh/__init__.py | 3 +- lib/iris/mesh/save.py | 53 ------------------- .../netcdf/saver/test_Saver__ugrid.py | 3 +- 5 files changed, 43 insertions(+), 57 deletions(-) delete mode 100644 lib/iris/mesh/save.py diff --git a/lib/iris/experimental/ugrid.py b/lib/iris/experimental/ugrid.py index a1c46ec3c0..23b3df7d0e 100644 --- a/lib/iris/experimental/ugrid.py +++ b/lib/iris/experimental/ugrid.py @@ -30,11 +30,11 @@ import threading from .._deprecation import warn_deprecated +from ..mesh import save_mesh from ..mesh.load import load_mesh, load_meshes from ..mesh.mesh import Connectivity as _Connectivity from ..mesh.mesh import Mesh as _Mesh from ..mesh.mesh import MeshCoord as _MeshCoord -from ..mesh.save import save_mesh from ..mesh.utils import recombine_submeshes diff --git a/lib/iris/fileformats/netcdf/saver.py b/lib/iris/fileformats/netcdf/saver.py index 5749d558b3..c4245594a4 100644 --- a/lib/iris/fileformats/netcdf/saver.py +++ b/lib/iris/fileformats/netcdf/saver.py @@ -2796,3 +2796,42 @@ def is_valid_packspec(p): result = sman.delayed_completion() return result + + +def save_mesh(mesh, filename, netcdf_format="NETCDF4"): + """Save mesh(es) to a netCDF file. + + Parameters + ---------- + mesh : :class:`iris.mesh.MeshXY` or iterable + Mesh(es) to save. + filename : str + Name of the netCDF file to create. + netcdf_format : str, default="NETCDF4" + Underlying netCDF file format, one of 'NETCDF4', 'NETCDF4_CLASSIC', + 'NETCDF3_CLASSIC' or 'NETCDF3_64BIT'. Default is 'NETCDF4' format. + + """ + # TODO: integrate with standard saving API when no longer 'experimental'. + + if isinstance(mesh, typing.Iterable): + meshes = mesh + else: + meshes = [mesh] + + # Initialise Manager for saving + with Saver(filename, netcdf_format) as sman: + # Iterate through the list. + for mesh in meshes: + # Get suitable dimension names. + mesh_dimensions, _ = sman._get_dim_names(mesh) + + # Create dimensions. + sman._create_cf_dimensions(cube=None, dimension_names=mesh_dimensions) + + # Create the mesh components. + sman._add_mesh(mesh) + + # Add a conventions attribute. + # TODO: add 'UGRID' to conventions, when this is agreed with CF ? + sman.update_global_attributes(Conventions=CF_CONVENTIONS_VERSION) diff --git a/lib/iris/mesh/__init__.py b/lib/iris/mesh/__init__.py index ac4f2324f8..96d75c34dd 100644 --- a/lib/iris/mesh/__init__.py +++ b/lib/iris/mesh/__init__.py @@ -8,10 +8,11 @@ Based on CF UGRID Conventions (v1.0), https://ugrid-conventions.github.io/ugrid-conventions/. """ +from iris.fileformats.netcdf.saver import save_mesh + from ..config import get_logger from .load import load_mesh, load_meshes from .mesh import Connectivity, MeshCoord, MeshXY -from .save import save_mesh from .utils import recombine_submeshes __all__ = [ diff --git a/lib/iris/mesh/save.py b/lib/iris/mesh/save.py deleted file mode 100644 index 992fcc83de..0000000000 --- a/lib/iris/mesh/save.py +++ /dev/null @@ -1,53 +0,0 @@ -# Copyright Iris contributors -# -# This file is part of Iris and is released under the BSD license. -# See LICENSE in the root of the repository for full licensing details. - -"""Extension to Iris' NetCDF saving to allow :class:`~iris.mesh.mesh.MeshXY` saving in UGRID format. - -Eventual destination: :mod:`iris.fileformats.netcdf`. - -""" - -from collections.abc import Iterable - -from ..fileformats import netcdf - - -def save_mesh(mesh, filename, netcdf_format="NETCDF4"): - """Save mesh(es) to a netCDF file. - - Parameters - ---------- - mesh : :class:`iris.mesh.MeshXY` or iterable - Mesh(es) to save. - filename : str - Name of the netCDF file to create. - netcdf_format : str, default="NETCDF4" - Underlying netCDF file format, one of 'NETCDF4', 'NETCDF4_CLASSIC', - 'NETCDF3_CLASSIC' or 'NETCDF3_64BIT'. Default is 'NETCDF4' format. - - """ - # TODO: integrate with standard saving API when no longer 'experimental'. - - if isinstance(mesh, Iterable): - meshes = mesh - else: - meshes = [mesh] - - # Initialise Manager for saving - with netcdf.Saver(filename, netcdf_format) as sman: - # Iterate through the list. - for mesh in meshes: - # Get suitable dimension names. - mesh_dimensions, _ = sman._get_dim_names(mesh) - - # Create dimensions. - sman._create_cf_dimensions(cube=None, dimension_names=mesh_dimensions) - - # Create the mesh components. - sman._add_mesh(mesh) - - # Add a conventions attribute. - # TODO: add 'UGRID' to conventions, when this is agreed with CF ? - sman.update_global_attributes(Conventions=netcdf.CF_CONVENTIONS_VERSION) diff --git a/lib/iris/tests/unit/fileformats/netcdf/saver/test_Saver__ugrid.py b/lib/iris/tests/unit/fileformats/netcdf/saver/test_Saver__ugrid.py index b8328c3d3e..757e9d1fbd 100644 --- a/lib/iris/tests/unit/fileformats/netcdf/saver/test_Saver__ugrid.py +++ b/lib/iris/tests/unit/fileformats/netcdf/saver/test_Saver__ugrid.py @@ -23,8 +23,7 @@ from iris.coords import AuxCoord from iris.cube import Cube, CubeList from iris.fileformats.netcdf import _thread_safe_nc -from iris.mesh.mesh import Connectivity, MeshXY -from iris.mesh.save import save_mesh +from iris.mesh import Connectivity, MeshXY, save_mesh from iris.tests.stock import realistic_4d XY_LOCS = ("x", "y")