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 @@ -46,7 +46,7 @@ jobs:
session: "tests"

env:
IRIS_TEST_DATA_VERSION: "2.16"
IRIS_TEST_DATA_VERSION: "2.17"
ENV_NAME: "ci-tests"

steps:
Expand Down
32 changes: 32 additions & 0 deletions docs/src/whatsnew/3.3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,36 @@ This document explains the changes made to Iris for this release
any issues or feature requests for improving Iris. Enjoy!


v3.3.1 (29 Sep 2022)
====================

.. dropdown:: :opticon:`alert` v3.3.1 Patches
:container: + shadow
:title: text-primary text-center font-weight-bold
:body: bg-light
:animate: fade-in

The patches in this release of Iris include:

#. `@pp-mo`_ fixed the Jupyter notebook display of :class:`~iris.cube.CubeList`.
(:issue:`4973`, :pull:`4976`)

#. `@pp-mo`_ fixed a bug in NAME loaders where data with no associated statistic would
load as a cube with invalid cell-methods, which cannot be printed or saved to netcdf.
(:issue:`3288`, :pull:`4933`)

#. `@pp-mo`_ ensured that :data:`iris.cube.Cube.cell_methods` must always be an iterable
of :class:`iris.coords.CellMethod` objects (:pull:`4933`).

#. `@trexfeathers`_ advanced the Cartopy pin to ``>=0.21``, as Cartopy's
change to default Transverse Mercator projection affects an Iris test.
See `SciTools/cartopy@fcb784d`_ and `SciTools/cartopy@8860a81`_ for more
details. (:pull:`4992`)

#. `@trexfeathers`_ introduced the ``netcdf4!=1.6.1`` pin to avoid a
problem with segfaults. (:pull:`4992`)


📢 Announcements
================

Expand Down Expand Up @@ -339,3 +369,5 @@ This document explains the changes made to Iris for this release
.. _PyData Sphinx Theme: https://pydata-sphinx-theme.readthedocs.io/en/stable/index.html
.. _pytest: https://docs.pytest.org
.. _setuptools-scm: https://github.com/pypa/setuptools_scm
.. _SciTools/cartopy@fcb784d: https://github.com/SciTools/cartopy/commit/fcb784daa65d95ed9a74b02ca292801c02bc4108
.. _SciTools/cartopy@8860a81: https://github.com/SciTools/cartopy/commit/8860a8186d4dc62478e74c83f3b2b3e8f791372e
27 changes: 23 additions & 4 deletions lib/iris/cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ def _assert_is_cube(obj):
)
raise ValueError(msg)

def _repr_html_(self):
from iris.experimental.representation import CubeListRepresentation

representer = CubeListRepresentation(self)
return representer.repr_html()

# TODO #370 Which operators need overloads?

def __add__(self, other):
Expand Down Expand Up @@ -2293,10 +2299,23 @@ def cell_methods(self):
return self._metadata_manager.cell_methods

@cell_methods.setter
def cell_methods(self, cell_methods):
self._metadata_manager.cell_methods = (
tuple(cell_methods) if cell_methods else tuple()
)
def cell_methods(self, cell_methods: Iterable):
if not cell_methods:
# For backwards compatibility: Empty or null value is equivalent to ().
cell_methods = ()
else:
# Can supply any iterable, which is converted (copied) to a tuple.
cell_methods = tuple(cell_methods)
for cell_method in cell_methods:
# All contents should be CellMethods. Requiring class membership is
# somewhat non-Pythonic, but simple, and not a problem for now.
if not isinstance(cell_method, iris.coords.CellMethod):
msg = (
f"Cube.cell_methods assigned value includes {cell_method}, "
"which is not an iris.coords.CellMethod."
)
raise ValueError(msg)
self._metadata_manager.cell_methods = cell_methods

def core_data(self):
"""
Expand Down
6 changes: 4 additions & 2 deletions lib/iris/fileformats/name_loaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,9 @@ def _generate_cubes(
cube.attributes[key] = value

if cell_methods is not None:
cube.add_cell_method(cell_methods[i])
cell_method = cell_methods[i]
if cell_method is not None:
cube.add_cell_method(cell_method)

yield cube

Expand Down Expand Up @@ -610,7 +612,7 @@ def _build_cell_methods(av_or_ints, coord):
cell_method = None
msg = "Unknown {} statistic: {!r}. Unable to create cell method."
warnings.warn(msg.format(coord, av_or_int))
cell_methods.append(cell_method)
cell_methods.append(cell_method) # NOTE: this can be a None
return cell_methods


Expand Down
47 changes: 47 additions & 0 deletions lib/iris/tests/results/name/NAMEII_field__no_time_averaging.cml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0" ?>
<cubes xmlns="urn:x-iris:cubeml-0.2">
<cube dtype="float32" long_name="VOLCANIC_ASH_AIR_CONCENTRATION" units="g/m2">
<attributes>
<attribute name="End of release" value="0000UTC 13/01/2011"/>
<attribute name="Forecast duration" value="6 hours"/>
<attribute name="Met data" value="NWP Flow.ECMWF ERAInt Regional"/>
<attribute name="NAME Version" value="NAME III (version 7.2)"/>
<attribute name="Quantity" value="Air Concentration"/>
<attribute name="Release height" value="Multiple Sources"/>
<attribute name="Release location" value="Multiple Sources"/>
<attribute name="Release rate" value="Multiple Sources"/>
<attribute name="Run time" value="1333UTC 07/12/2018"/>
<attribute name="Species" value="VOLCANIC_ASH"/>
<attribute name="Species Category" value="VOLCANIC"/>
<attribute name="Start of release" value="2200UTC 12/01/2011"/>
<attribute name="Time Av or Int" value="No time averaging"/>
<attribute name="Title" value="VA_Tutorial"/>
</attributes>
<coords>
<coord datadims="[0]">
<dimCoord bounds="[[29.9375, 30.0625],
[30.0625, 30.1875]]" id="77a50eb5" points="[30.0, 30.125]" shape="(2,)" standard_name="latitude" units="Unit('degrees')" value_type="float64">
<geogCS earth_radius="6371229.0"/>
</dimCoord>
</coord>
<coord datadims="[1]">
<dimCoord bounds="[[9.9375, 10.0625],
[10.0625, 10.1875]]" id="f913a8b3" points="[10.0, 10.125]" shape="(2,)" standard_name="longitude" units="Unit('degrees')" value_type="float64">
<geogCS earth_radius="6371229.0"/>
</dimCoord>
</coord>
<coord>
<dimCoord bounds="[[359686.0, 359686.0]]" id="cb784457" points="[359686.0]" shape="(1,)" standard_name="time" units="Unit('hours since 1970-01-01 00:00:00', calendar='standard')" value_type="float64"/>
</coord>
<coord>
<auxCoord id="e92ff7b7" long_name="z" points="[Vertical integral]" shape="(1,)" units="Unit('no_unit')" value_type="string">
<attributes>
<attribute name="positive" value="up"/>
</attributes>
</auxCoord>
</coord>
</coords>
<cellMethods/>
<data dtype="float32" shape="(2, 2)" state="loaded"/>
</cube>
</cubes>
47 changes: 47 additions & 0 deletions lib/iris/tests/results/name/NAMEII_field__no_time_averaging_0.cml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0" ?>
<cubes xmlns="urn:x-iris:cubeml-0.2">
<cube dtype="float32" long_name="VOLCANIC_ASH_AIR_CONCENTRATION" units="g/m2">
<attributes>
<attribute name="End of release" value="0000UTC 13/01/2011"/>
<attribute name="Forecast duration" value="6 hours"/>
<attribute name="Met data" value="NWP Flow.ECMWF ERAInt Regional"/>
<attribute name="NAME Version" value="NAME III (version 7.2)"/>
<attribute name="Quantity" value="Air Concentration"/>
<attribute name="Release height" value="Multiple Sources"/>
<attribute name="Release location" value="Multiple Sources"/>
<attribute name="Release rate" value="Multiple Sources"/>
<attribute name="Run time" value="1333UTC 07/12/2018"/>
<attribute name="Species" value="VOLCANIC_ASH"/>
<attribute name="Species Category" value="VOLCANIC"/>
<attribute name="Start of release" value="2200UTC 12/01/2011"/>
<attribute name="Time Av or Int" value="No time averaging"/>
<attribute name="Title" value="VA_Tutorial"/>
</attributes>
<coords>
<coord datadims="[0]">
<dimCoord bounds="[[29.9375, 30.0625],
[30.0625, 30.1875]]" id="77a50eb5" points="[30.0, 30.125]" shape="(2,)" standard_name="latitude" units="Unit('degrees')" value_type="float64">
<geogCS earth_radius="6371229.0"/>
</dimCoord>
</coord>
<coord datadims="[1]">
<dimCoord bounds="[[9.9375, 10.0625],
[10.0625, 10.1875]]" id="f913a8b3" points="[10.0, 10.125]" shape="(2,)" standard_name="longitude" units="Unit('degrees')" value_type="float64">
<geogCS earth_radius="6371229.0"/>
</dimCoord>
</coord>
<coord>
<dimCoord bounds="[[359686.0, 359686.0]]" id="cb784457" points="[359686.0]" shape="(1,)" standard_name="time" units="Unit('hours since 1970-01-01 00:00:00', calendar='standard')" value_type="float64"/>
</coord>
<coord>
<auxCoord id="e92ff7b7" long_name="z" points="[Vertical integral]" shape="(1,)" units="Unit('no_unit')" value_type="string">
<attributes>
<attribute name="positive" value="up"/>
</attributes>
</auxCoord>
</coord>
</coords>
<cellMethods/>
<data checksum="0xecbb4b55" dtype="float32" shape="(2, 2)"/>
</cube>
</cubes>
31 changes: 30 additions & 1 deletion lib/iris/tests/test_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
# import iris tests first so that some things can be initialised before
# importing anything else
import iris.tests as tests # isort:skip

import tempfile

import iris


Expand Down Expand Up @@ -39,7 +42,7 @@ def test_NAMEIII_version2(self):
)
self.assertCMLApproxData(cubes, ("name", "NAMEIII_version2.cml"))

def test_NAMEII_trajectory(self):
def test_NAMEIII_trajectory(self):
cubes = iris.load(
tests.get_data_path(("NAME", "NAMEIII_trajectory.txt"))
)
Expand All @@ -48,6 +51,32 @@ def test_NAMEII_trajectory(self):
cubes, ("name", "NAMEIII_trajectory.cml"), checksum=False
)

def test_NAMEII__no_time_averaging(self):
cubes = iris.load(
tests.get_data_path(("NAME", "NAMEII_no_time_averaging.txt"))
)

# Also check that it saves without error.
# This was previously failing, see https://github.com/SciTools/iris/issues/3288
with tempfile.TemporaryDirectory() as temp_dirpath:
iris.save(cubes, temp_dirpath + "/tmp.nc")

self.assertCML(
cubes[0],
(
"name",
"NAMEII_field__no_time_averaging_0.cml",
),
)
self.assertCML(
cubes,
(
"name",
"NAMEII_field__no_time_averaging.cml",
),
checksum=False,
)


if __name__ == "__main__":
tests.main()
Loading