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
4 changes: 2 additions & 2 deletions docs/iris/src/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ def autolog(message):
if iris.__version__ == "dev":
version = "dev"
else:
# major.feature(.minor)-dev -> major.minor
version = ".".join(iris.__version__.split("-")[0].split(".")[:2])
# major.minor.patch-dev -> major.minor.patch
version = ".".join(iris.__version__.split("-")[0].split(".")[:3])
# The full version, including alpha/beta/rc tags.
release = iris.__version__

Expand Down
520 changes: 520 additions & 0 deletions docs/iris/src/whatsnew/3.0.1.rst

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/iris/src/whatsnew/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Iris versions.
.. toctree::
:maxdepth: 1

3.0.1.rst
3.0.rst
2.4.rst
2.3.rst
Expand Down
2 changes: 1 addition & 1 deletion lib/iris/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def callback(cube, field, filename):


# Iris revision.
__version__ = "3.0.0"
__version__ = "3.0.1"

# Restrict the names imported when using "from iris import *"
__all__ = [
Expand Down
25 changes: 25 additions & 0 deletions lib/iris/aux_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from abc import ABCMeta, abstractmethod
import warnings

import cf_units
import dask.array as da
import numpy as np

Expand Down Expand Up @@ -619,6 +620,10 @@ def _check_dependencies(delta, sigma, surface_air_pressure):
warnings.warn(msg, UserWarning, stacklevel=2)

# Check units.
if sigma is not None and sigma.units.is_unknown():
# Be graceful, and promote unknown to dimensionless units.
sigma.units = cf_units.Unit("1")

if sigma is not None and not sigma.units.is_dimensionless():
raise ValueError("Invalid units: sigma must be dimensionless.")
if (
Expand Down Expand Up @@ -863,6 +868,10 @@ def _check_dependencies(sigma, eta, depth, depth_c, nsigma, zlev):
)
raise ValueError(msg)

if sigma is not None and sigma.units.is_unknown():
# Be graceful, and promote unknown to dimensionless units.
sigma.units = cf_units.Unit("1")

if sigma is not None and not sigma.units.is_dimensionless():
msg = (
"Invalid units: sigma coordinate {!r} "
Expand Down Expand Up @@ -1127,6 +1136,10 @@ def _check_dependencies(sigma, eta, depth):
warnings.warn(msg, UserWarning, stacklevel=2)

# Check units.
if sigma is not None and sigma.units.is_unknown():
# Be graceful, and promote unknown to dimensionless units.
sigma.units = cf_units.Unit("1")

if sigma is not None and not sigma.units.is_dimensionless():
msg = (
"Invalid units: sigma coordinate {!r} "
Expand Down Expand Up @@ -1335,6 +1348,10 @@ def _check_dependencies(s, c, eta, depth, depth_c):
# Check units.
coords = ((s, "s"), (c, "c"))
for coord, term in coords:
if coord is not None and coord.units.is_unknown():
# Be graceful, and promote unknown to dimensionless units.
coord.units = cf_units.Unit("1")

if coord is not None and not coord.units.is_dimensionless():
msg = (
"Invalid units: {} coordinate {!r} "
Expand Down Expand Up @@ -1551,6 +1568,10 @@ def _check_dependencies(s, eta, depth, a, b, depth_c):
raise ValueError(msg)

# Check units.
if s is not None and s.units.is_unknown():
# Be graceful, and promote unknown to dimensionless units.
s.units = cf_units.Unit("1")

if s is not None and not s.units.is_dimensionless():
msg = (
"Invalid units: s coordinate {!r} "
Expand Down Expand Up @@ -1776,6 +1797,10 @@ def _check_dependencies(s, c, eta, depth, depth_c):
# Check units.
coords = ((s, "s"), (c, "c"))
for coord, term in coords:
if coord is not None and coord.units.is_unknown():
# Be graceful, and promote unknown to dimensionless units.
coord.units = cf_units.Unit("1")

if coord is not None and not coord.units.is_dimensionless():
msg = (
"Invalid units: {} coordinate {!r} "
Expand Down
3 changes: 3 additions & 0 deletions lib/iris/fileformats/netcdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,9 @@ def coord_from_term(term):
warnings.warn(msg)
coord_a = coord_from_term("a")
if coord_a is not None:
if coord_a.units.is_unknown():
# Be graceful, and promote unknown to dimensionless units.
coord_a.units = "1"
delta = coord_a * coord_p0.points[0]
delta.units = coord_a.units * coord_p0.units
delta.rename("vertical pressure")
Expand Down
9 changes: 9 additions & 0 deletions lib/iris/tests/unit/aux_factory/test_HybridPressureFactory.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,15 @@ def test_factory_metadata(self):
self.assertIsNone(factory.coord_system)
self.assertEqual(factory.attributes, {})

def test_promote_sigma_units_unknown_to_dimensionless(self):
sigma = mock.Mock(units=cf_units.Unit("unknown"), nbounds=0)
factory = HybridPressureFactory(
delta=self.delta,
sigma=sigma,
surface_air_pressure=self.surface_air_pressure,
)
self.assertEqual("1", factory.dependencies["sigma"].units)


class Test_dependencies(tests.IrisTest):
def setUp(self):
Expand Down
6 changes: 6 additions & 0 deletions lib/iris/tests/unit/aux_factory/test_OceanSFactory.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@ def test_depth_incompatible_units(self):
with self.assertRaises(ValueError):
OceanSFactory(**self.kwargs)

def test_promote_s_units_unknown_to_dimensionless(self):
s = mock.Mock(units=Unit("unknown"), nbounds=0)
self.kwargs["s"] = s
factory = OceanSFactory(**self.kwargs)
self.assertEqual("1", factory.dependencies["s"].units)


class Test_dependencies(tests.IrisTest):
def setUp(self):
Expand Down
9 changes: 9 additions & 0 deletions lib/iris/tests/unit/aux_factory/test_OceanSg1Factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,15 @@ def test_depth_incompatible_units(self):
with self.assertRaises(ValueError):
OceanSg1Factory(**self.kwargs)

def test_promote_c_and_s_units_unknown_to_dimensionless(self):
c = mock.Mock(units=Unit("unknown"), nbounds=0)
s = mock.Mock(units=Unit("unknown"), nbounds=0)
self.kwargs["c"] = c
self.kwargs["s"] = s
factory = OceanSg1Factory(**self.kwargs)
self.assertEqual("1", factory.dependencies["c"].units)
self.assertEqual("1", factory.dependencies["s"].units)


class Test_dependencies(tests.IrisTest):
def setUp(self):
Expand Down
9 changes: 9 additions & 0 deletions lib/iris/tests/unit/aux_factory/test_OceanSg2Factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,15 @@ def test_depth_incompatible_units(self):
with self.assertRaises(ValueError):
OceanSg2Factory(**self.kwargs)

def test_promote_c_and_s_units_unknown_to_dimensionless(self):
c = mock.Mock(units=Unit("unknown"), nbounds=0)
s = mock.Mock(units=Unit("unknown"), nbounds=0)
self.kwargs["c"] = c
self.kwargs["s"] = s
factory = OceanSg2Factory(**self.kwargs)
self.assertEqual("1", factory.dependencies["c"].units)
self.assertEqual("1", factory.dependencies["s"].units)


class Test_dependencies(tests.IrisTest):
def setUp(self):
Expand Down
6 changes: 6 additions & 0 deletions lib/iris/tests/unit/aux_factory/test_OceanSigmaFactory.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ def test_depth_incompatible_units(self):
with self.assertRaises(ValueError):
OceanSigmaFactory(**self.kwargs)

def test_promote_sigma_units_unknown_to_dimensionless(self):
sigma = mock.Mock(units=Unit("unknown"), nbounds=0)
self.kwargs["sigma"] = sigma
factory = OceanSigmaFactory(**self.kwargs)
self.assertEqual("1", factory.dependencies["sigma"].units)


class Test_dependencies(tests.IrisTest):
def setUp(self):
Expand Down
6 changes: 6 additions & 0 deletions lib/iris/tests/unit/aux_factory/test_OceanSigmaZFactory.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ def test_depth_incompatible_units(self):
with self.assertRaises(ValueError):
OceanSigmaZFactory(**self.kwargs)

def test_promote_sigma_units_unknown_to_dimensionless(self):
sigma = mock.Mock(units=Unit("unknown"), nbounds=0)
self.kwargs["sigma"] = sigma
factory = OceanSigmaZFactory(**self.kwargs)
self.assertEqual("1", factory.dependencies["sigma"].units)


class Test_dependencies(tests.IrisTest):
def setUp(self):
Expand Down
41 changes: 39 additions & 2 deletions lib/iris/tests/unit/fileformats/netcdf/test__load_aux_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,44 @@ def test_formula_terms_ap(self):
self.assertEqual(factory.surface_air_pressure, self.ps)

def test_formula_terms_a_p0(self):
coord_a = DimCoord(np.arange(5), units="Pa")
coord_p0 = DimCoord(10, units="1")
coord_a = DimCoord(np.arange(5), units="1")
coord_p0 = DimCoord(10, units="Pa")
coord_expected = DimCoord(
np.arange(5) * 10,
units="Pa",
long_name="vertical pressure",
var_name="ap",
)
self.cube_parts["coordinates"].extend(
[(coord_a, "a"), (coord_p0, "p0")]
)
self.requires["formula_terms"] = dict(a="a", b="b", ps="ps", p0="p0")
_load_aux_factory(self.engine, self.cube)
# Check cube.coord_dims method.
self.assertEqual(self.cube.coord_dims.call_count, 1)
args, _ = self.cube.coord_dims.call_args
self.assertEqual(len(args), 1)
self.assertIs(args[0], coord_a)
# Check cube.add_aux_coord method.
self.assertEqual(self.cube.add_aux_coord.call_count, 1)
args, _ = self.cube.add_aux_coord.call_args
self.assertEqual(len(args), 2)
self.assertEqual(args[0], coord_expected)
self.assertIsInstance(args[1], mock.Mock)
# Check cube.add_aux_factory method.
self.assertEqual(self.cube.add_aux_factory.call_count, 1)
args, _ = self.cube.add_aux_factory.call_args
self.assertEqual(len(args), 1)
factory = args[0]
self.assertEqual(factory.delta, coord_expected)
self.assertEqual(factory.sigma, mock.sentinel.b)
self.assertEqual(factory.surface_air_pressure, self.ps)

def test_formula_terms_a_p0__promote_a_units_unknown_to_dimensionless(
self,
):
coord_a = DimCoord(np.arange(5), units="unknown")
coord_p0 = DimCoord(10, units="Pa")
coord_expected = DimCoord(
np.arange(5) * 10,
units="Pa",
Expand All @@ -71,6 +107,7 @@ def test_formula_terms_a_p0(self):
args, _ = self.cube.coord_dims.call_args
self.assertEqual(len(args), 1)
self.assertIs(args[0], coord_a)
self.assertEqual("1", args[0].units)
# Check cube.add_aux_coord method.
self.assertEqual(self.cube.add_aux_coord.call_count, 1)
args, _ = self.cube.add_aux_coord.call_args
Expand Down