Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
session: "tests"

env:
IRIS_TEST_DATA_VERSION: "2.22"
IRIS_TEST_DATA_VERSION: "2.25"
ENV_NAME: "ci-tests"

steps:
Expand Down
8 changes: 2 additions & 6 deletions lib/iris/experimental/geovista.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,10 @@ def cube_to_polydata(cube, **kwargs):
.. testsetup::

from iris import load_cube, sample_data_path
from iris.experimental.ugrid import PARSE_UGRID_ON_LOAD

cube = load_cube(sample_data_path("air_temp.pp"))
cube_w_time = load_cube(sample_data_path("A1B_north_america.nc"))
with PARSE_UGRID_ON_LOAD.context():
cube_mesh = load_cube(sample_data_path("mesh_C4_synthetic_float.nc"))
cube_mesh = load_cube(sample_data_path("mesh_C4_synthetic_float.nc"))

>>> from iris.experimental.geovista import cube_to_polydata

Expand Down Expand Up @@ -212,11 +210,9 @@ def extract_unstructured_region(cube, polydata, region, **kwargs):
from iris import load_cube, sample_data_path
from iris.coords import AuxCoord
from iris.cube import CubeList
from iris.experimental.ugrid import PARSE_UGRID_ON_LOAD

file_path = sample_data_path("mesh_C4_synthetic_float.nc")
with PARSE_UGRID_ON_LOAD.context():
cube_w_mesh = load_cube(file_path)
cube_w_mesh = load_cube(file_path)

level_cubes = CubeList()
for height_level in range(72):
Expand Down
6 changes: 6 additions & 0 deletions lib/iris/experimental/ugrid/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@

"""Infra-structure for unstructured mesh support.

.. deprecated:: 1.10

:data:`PARSE_UGRID_ON_LOAD` is due to be removed at next major release.
Please remove all uses of this, which are no longer needed :
UGRID loading is now **always** active for files containing a UGRID mesh.

Based on CF UGRID Conventions (v1.0), https://ugrid-conventions.github.io/ugrid-conventions/.

.. note::
Expand Down
62 changes: 41 additions & 21 deletions lib/iris/experimental/ugrid/load.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@

Eventual destination: :mod:`iris.fileformats.netcdf`.

.. seealso::

The UGRID Conventions,
https://ugrid-conventions.github.io/ugrid-conventions/

"""

from contextlib import contextmanager
Expand All @@ -18,6 +23,7 @@
import threading
import warnings

from ..._deprecation import warn_deprecated
from ...config import get_logger
from ...coords import AuxCoord
from ...fileformats._nc_load_rules.helpers import get_attr_units, get_names
Expand Down Expand Up @@ -60,20 +66,20 @@ def __init__(self):
:const:`~iris.experimental.ugrid.load.PARSE_UGRID_ON_LOAD`.
Use :meth:`context` to temporarily activate.

.. seealso::

The UGRID Conventions,
https://ugrid-conventions.github.io/ugrid-conventions/
Notes
-----
.. deprecated:: 1.10
Do not use -- due to be removed at next major release :
UGRID loading is now **always** active for files containing a UGRID mesh.

"""
self._state = False

def __bool__(self):
return self._state
return True

@contextmanager
def context(self):
"""Temporarily activate experimental UGRID-aware NetCDF loading.
"""Activate UGRID-aware NetCDF loading.

Use the standard Iris loading API while within the context manager. If
the loaded file(s) include any UGRID content, this will be parsed and
Expand All @@ -89,12 +95,35 @@ def context(self):
constraint=my_constraint,
callback=my_callback)

Notes
-----
.. deprecated:: 1.10
Do not use -- due to be removed at next major release :
UGRID loading is now **always** active for files containing a UGRID mesh.

Examples
--------
Replace usage, for example:

.. code-block:: python

with iris.experimental.ugrid.PARSE_UGRID_ON_LOAD.context():
mesh_cubes = iris.load(path)

with:

.. code-block:: python

mesh_cubes = iris.load(path)

"""
try:
self._state = True
yield
finally:
self._state = False
wmsg = (
"iris.experimental.ugrid.load.PARSE_UGRID_ON_LOAD has been deprecated "
"and will be removed. Please remove all uses : these are no longer needed, "
"as UGRID loading is now applied to any file containing a mesh."
)
warn_deprecated(wmsg)
yield


#: Run-time switch for experimental UGRID-aware NetCDF loading. See :class:`~iris.experimental.ugrid.load.ParseUGridOnLoad`.
Expand Down Expand Up @@ -174,15 +203,6 @@ def load_meshes(uris, var_name=None):

from ...fileformats import FORMAT_AGENT

if not PARSE_UGRID_ON_LOAD:
# Explicit behaviour, consistent with netcdf.load_cubes(), rather than
# an invisible assumption.
message = (
f"PARSE_UGRID_ON_LOAD is {bool(PARSE_UGRID_ON_LOAD)}. Must be "
f"True to enable mesh loading."
)
raise ValueError(message)

if isinstance(uris, str):
uris = [uris]

Expand Down
4 changes: 1 addition & 3 deletions lib/iris/experimental/ugrid/mesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -786,14 +786,12 @@ def from_coords(cls, *coords):

from iris import load_cube, sample_data_path
from iris.experimental.ugrid import (
PARSE_UGRID_ON_LOAD,
MeshXY,
MeshCoord,
)

file_path = sample_data_path("mesh_C4_synthetic_float.nc")
with PARSE_UGRID_ON_LOAD.context():
cube_w_mesh = load_cube(file_path)
cube_w_mesh = load_cube(file_path)

Examples
--------
Expand Down
15 changes: 3 additions & 12 deletions lib/iris/fileformats/netcdf/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,6 @@ def load_cubes(file_sources, callback=None, constraints=None):
# Deferred import to avoid circular imports.
from iris.experimental.ugrid.cf import CFUGridReader
from iris.experimental.ugrid.load import (
PARSE_UGRID_ON_LOAD,
_build_mesh_coords,
_meshes_from_cf,
)
Expand All @@ -600,15 +599,8 @@ def load_cubes(file_sources, callback=None, constraints=None):

for file_source in file_sources:
# Ingest the file. At present may be a filepath or an open netCDF4.Dataset.
meshes = {}
if PARSE_UGRID_ON_LOAD:
cf_reader_class = CFUGridReader
else:
cf_reader_class = iris.fileformats.cf.CFReader

with cf_reader_class(file_source) as cf:
if PARSE_UGRID_ON_LOAD:
meshes = _meshes_from_cf(cf)
with CFUGridReader(file_source) as cf:
meshes = _meshes_from_cf(cf)

# Process each CF data variable.
data_variables = list(cf.cf_group.data_variables.values()) + list(
Expand All @@ -626,8 +618,7 @@ def load_cubes(file_sources, callback=None, constraints=None):
mesh_name = None
mesh = None
mesh_coords, mesh_dim = [], None
if PARSE_UGRID_ON_LOAD:
mesh_name = getattr(cf_var, "mesh", None)
mesh_name = getattr(cf_var, "mesh", None)
if mesh_name is not None:
try:
mesh = meshes[mesh_name]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

from iris import load_cube
from iris.experimental.geovista import cube_to_polydata
from iris.experimental.ugrid import PARSE_UGRID_ON_LOAD
from iris.tests import get_data_path


Expand Down Expand Up @@ -57,8 +56,7 @@ def test_integration_mesh():
]
)

with PARSE_UGRID_ON_LOAD.context():
cube = load_cube(file_path, "conv_rain")
cube = load_cube(file_path, "conv_rain")

polydata = cube_to_polydata(cube[0, :])
# This is a known good output, we have plotted the result and checked it.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

from iris import load_cube
from iris.experimental.geovista import cube_to_polydata, extract_unstructured_region
from iris.experimental.ugrid import PARSE_UGRID_ON_LOAD
from iris.tests import get_data_path


Expand All @@ -21,8 +20,7 @@ def test_face_region_extraction():
]
)

with PARSE_UGRID_ON_LOAD.context():
global_cube = load_cube(file_path, "conv_rain")
global_cube = load_cube(file_path, "conv_rain")
polydata = cube_to_polydata(global_cube[0, :])
region = BBox(lons=[0, 70, 70, 0], lats=[-25, -25, 45, 45])

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
class TestProjectedUnstructured(tests.IrisTest):
def setUp(self):
path = tests.get_data_path(
("NetCDF", "unstructured_grid", "theta_nodal_xios.nc")
("NetCDF", "unstructured_grid", "theta_nodal_not_ugrid.nc")
)
self.src = iris.load_cube(path, "Potential Temperature")

Expand Down
30 changes: 13 additions & 17 deletions lib/iris/tests/integration/experimental/test_ugrid_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import pytest

from iris import Constraint, load
from iris.experimental.ugrid.load import PARSE_UGRID_ON_LOAD, load_mesh, load_meshes
from iris.experimental.ugrid.load import load_mesh, load_meshes
from iris.experimental.ugrid.mesh import MeshXY
from iris.tests.stock.netcdf import (
_file_from_cdl_template as create_file_from_cdl_template,
Expand Down Expand Up @@ -47,8 +47,7 @@ def ugrid_load(uris, constraints=None, callback=None):
constraints = [constraints]
constraints.append(filter_orphan_connectivities)

with PARSE_UGRID_ON_LOAD.context():
return load(uris, constraints, callback)
return load(uris, constraints, callback)


@tests.skip_data
Expand Down Expand Up @@ -110,12 +109,11 @@ def test_3D_veg_pseudo_levels(self):
)

def test_no_mesh(self):
with PARSE_UGRID_ON_LOAD.context():
cube_list = load(
tests.get_data_path(
["NetCDF", "unstructured_grid", "theta_nodal_not_ugrid.nc"]
)
cube_list = load(
tests.get_data_path(
["NetCDF", "unstructured_grid", "theta_nodal_not_ugrid.nc"]
)
)
self.assertTrue(all([cube.mesh is None for cube in cube_list]))


Expand Down Expand Up @@ -207,10 +205,9 @@ def test_mesh_no_cf_role(self):
@tests.skip_data
class Test_load_mesh(tests.IrisTest):
def common_test(self, file_name, mesh_var_name):
with PARSE_UGRID_ON_LOAD.context():
mesh = load_mesh(
tests.get_data_path(["NetCDF", "unstructured_grid", file_name])
)
mesh = load_mesh(
tests.get_data_path(["NetCDF", "unstructured_grid", file_name])
)
# NOTE: cannot use CML tests as this isn't supported for non-Cubes.
self.assertIsInstance(mesh, MeshXY)
self.assertEqual(mesh.var_name, mesh_var_name)
Expand All @@ -225,12 +222,11 @@ def test_mesh_file(self):
self.common_test("mesh_C12.nc", "dynamics")

def test_no_mesh(self):
with PARSE_UGRID_ON_LOAD.context():
meshes = load_meshes(
tests.get_data_path(
["NetCDF", "unstructured_grid", "theta_nodal_not_ugrid.nc"]
)
meshes = load_meshes(
tests.get_data_path(
["NetCDF", "unstructured_grid", "theta_nodal_not_ugrid.nc"]
)
)
self.assertDictEqual({}, meshes)


Expand Down
10 changes: 3 additions & 7 deletions lib/iris/tests/integration/experimental/test_ugrid_save.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import tempfile

import iris
from iris.experimental.ugrid.load import PARSE_UGRID_ON_LOAD
import iris.fileformats.netcdf
from iris.tests.stock.netcdf import _add_standard_data, ncgen_from_cdl

Expand Down Expand Up @@ -48,8 +47,7 @@ def test_example_result_cdls(self):
# Fill in blank data-variables.
_add_standard_data(target_ncfile_path)
# Load as Iris data
with PARSE_UGRID_ON_LOAD.context():
cubes = iris.load(target_ncfile_path)
cubes = iris.load(target_ncfile_path)
# Re-save, to check the save behaviour.
resave_ncfile_path = str(self.temp_dir / f"{ex_name}_resaved.nc")
iris.save(cubes, resave_ncfile_path)
Expand All @@ -69,8 +67,7 @@ def test_example_roundtrips(self):
# Fill in blank data-variables.
_add_standard_data(target_ncfile_path)
# Load the original as Iris data
with PARSE_UGRID_ON_LOAD.context():
orig_cubes = iris.load(target_ncfile_path)
orig_cubes = iris.load(target_ncfile_path)

if "ex4" in ex_name:
# Discard the extra formula terms component cubes
Expand All @@ -80,8 +77,7 @@ def test_example_roundtrips(self):
# Save-and-load-back to compare the Iris saved result.
resave_ncfile_path = str(self.temp_dir / f"{ex_name}_resaved.nc")
iris.save(orig_cubes, resave_ncfile_path)
with PARSE_UGRID_ON_LOAD.context():
savedloaded_cubes = iris.load(resave_ncfile_path)
savedloaded_cubes = iris.load(resave_ncfile_path)

# This should match the original exactly
# ..EXCEPT for our inability to compare meshes.
Expand Down
2 changes: 1 addition & 1 deletion lib/iris/tests/integration/test_regridding.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def test_nearest(self):
class TestUnstructured(tests.IrisTest):
def setUp(self):
path = tests.get_data_path(
("NetCDF", "unstructured_grid", "theta_nodal_xios.nc")
("NetCDF", "unstructured_grid", "theta_nodal_not_ugrid.nc")
)
self.src = iris.load_cube(path, "Potential Temperature")
self.grid = simple_3d()[0, :, :]
Expand Down
Loading