Skip to content

Commit de036a8

Browse files
committed
Technical review corrections
1 parent e85b47e commit de036a8

File tree

4 files changed

+57
-22
lines changed

4 files changed

+57
-22
lines changed

src/CSET/operators/plot.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2028,17 +2028,31 @@ def _calculate_CFAD(
20282028
bin_edges: list[float]
20292029
The bin edges for the histogram. The bins need to be specified to
20302030
ensure consistency across the CFAD, otherwise it cannot be interpreted.
2031+
2032+
Notes
2033+
-----
2034+
Contour Frequency by Altitude Diagrams (CFADs) were first designed by
2035+
Yuter and Houze (1995)[YuterandHouze95]. They are calculated by binning the
2036+
data by altitude and then by variable bins (e.g. temperature). The variable
2037+
bins are then normalised by each altitude. This essenitally creates a
2038+
normalised frequency distribution for each altitude. These are then stacked
2039+
and combined in a single plot.
2040+
2041+
References
2042+
----------
2043+
.. [YuterandHouze95] Yuter S.E., and Houze, R.A. (1995) "Three-Dimensional
2044+
Kinematic and Microphysical Evolution of Florida Cumulonimbus. Part II:
2045+
Frequency Distributions of Vertical Velocity, Reflectivity, and
2046+
Differential Reflectivity" Monthly Weather Review, vol. 123, 1941-1963,
2047+
doi: 10.1175/1520-0493(1995)123<1941:TDKAME>2.0.CO;2
20312048
"""
20322049
# Setup empty array for containing the CFAD data.
20332050
CFAD_values = np.zeros(
20342051
(len(cube.coord(vertical_coordinate).points), len(bin_edges) - 1)
20352052
)
20362053

2037-
# Set iterator for CFAD values.
2038-
i = 0
2039-
20402054
# Calculate the CFAD as a histogram summing to one for each level.
2041-
for level_cube in cube.slices_over(vertical_coordinate):
2055+
for i, level_cube in enumerate(cube.slices_over(vertical_coordinate)):
20422056
# Note setting density to True does not produce the correct
20432057
# normalization for a CFAD, where each row must sum to one.
20442058
CFAD_values[i, :] = (
@@ -2047,8 +2061,7 @@ def _calculate_CFAD(
20472061
]
20482062
/ level_cube.data.size
20492063
)
2050-
i += 1
2051-
# calculate central points for bins
2064+
# Calculate central points for bins.
20522065
bins = (np.array(bin_edges[:-1]) + np.array(bin_edges[1:])) / 2.0
20532066
bin_bounds = np.array((bin_edges[:-1], bin_edges[1:])).T
20542067
# Now construct the coordinates for the cube.
@@ -2060,10 +2073,11 @@ def _calculate_CFAD(
20602073
CFAD = iris.cube.Cube(
20612074
CFAD_values,
20622075
dim_coords_and_dims=[(vert_coord, 0), (bin_coord, 1)],
2076+
long_name=f"{cube.name()}_cfad",
20632077
standard_name=cube.standard_name,
20642078
units="1",
20652079
)
2066-
CFAD.attributes["type"] = "Contour Frequency by Altitude Diagram (CFAD)"
2080+
CFAD.rename(f"{cube.name()}_cfad")
20672081
return CFAD
20682082

20692083

tests/conftest.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,3 +323,15 @@ def orography_4D_cube_read_only():
323323
def orography_4D_cube(orography_4D_cube_read_only):
324324
"""Get 4D orography cube to run tests on. It is safe to modify."""
325325
return orography_4D_cube_read_only.copy()
326+
327+
328+
@pytest.fixture()
329+
def xwind_read_only():
330+
"""Get regridded xwind to run tests on. It is NOT safe to modify."""
331+
return read.read_cube("tests/test_data/ageofair/aoa_in_rgd.nc", "x_wind")
332+
333+
334+
@pytest.fixture()
335+
def xwind(xwind_read_only):
336+
"""Get regridded xwind to run tests on. It is safe to modify."""
337+
return xwind_read_only.copy()

tests/operators/test_ageofair.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,6 @@
2222
from CSET.operators import ageofair, read
2323

2424

25-
@pytest.fixture()
26-
def xwind() -> iris.cube.Cube:
27-
"""Get regridded xwind to run tests on."""
28-
return read.read_cube("tests/test_data/ageofair/aoa_in_rgd.nc", "x_wind")
29-
30-
3125
@pytest.fixture()
3226
def ywind() -> iris.cube.Cube:
3327
"""Get regridded ywind to run tests on."""

tests/operators/test_plot.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import logging
1919
from pathlib import Path
2020

21+
import cf_units
2122
import iris.coords
2223
import iris.cube
2324
import matplotlib as mpl
@@ -28,12 +29,6 @@
2829
from CSET.operators import collapse, misc, plot, read
2930

3031

31-
@pytest.fixture()
32-
def xwind() -> iris.cube.Cube:
33-
"""Get regridded xwind to run tests on."""
34-
return iris.load_cube("tests/test_data/ageofair/aoa_in_rgd.nc", "x_wind")
35-
36-
3732
def test_check_single_cube():
3833
"""Conversion to a single cube, and rejection where not possible."""
3934
cube = iris.cube.Cube([0.0])
@@ -1265,13 +1260,11 @@ def test_calculate_CFAD(xwind):
12651260
"""Test calculating a CFAD."""
12661261
bins = np.array([-50, -40, -30, -20, -10, 0, 10, 20, 30, 40, 50])
12671262
calculated_CFAD = np.zeros((len(xwind.coord("pressure").points), len(bins) - 1))
1268-
j = 0
1269-
for level_cube in xwind.slices_over("pressure"):
1263+
for j, level_cube in enumerate(xwind.slices_over("pressure")):
12701264
calculated_CFAD[j, :] = (
12711265
np.histogram(level_cube.data.reshape(level_cube.data.size), bins=bins)[0]
12721266
/ level_cube.data.size
12731267
)
1274-
j += 1
12751268
assert np.allclose(
12761269
plot._calculate_CFAD(
12771270
xwind, "pressure", [-50, -40, -30, -20, -10, 0, 10, 20, 30, 40, 50]
@@ -1280,3 +1273,25 @@ def test_calculate_CFAD(xwind):
12801273
rtol=1e-06,
12811274
atol=1e-02,
12821275
)
1276+
1277+
1278+
def test_name_CFAD(xwind):
1279+
"""Test naming of CFAD cube."""
1280+
expected_name = f"{xwind.name()}_cfad"
1281+
assert (
1282+
plot._calculate_CFAD(
1283+
xwind, "pressure", [-50, -40, -30, -20, -10, 0, 10, 20, 30, 40, 50]
1284+
).name()
1285+
== expected_name
1286+
)
1287+
1288+
1289+
def test_units_CFAD(xwind):
1290+
"""Test units of CFAD cube."""
1291+
expected_units = cf_units.Unit("1")
1292+
assert (
1293+
plot._calculate_CFAD(
1294+
xwind, "pressure", [-50, -40, -30, -20, -10, 0, 10, 20, 30, 40, 50]
1295+
).units
1296+
== expected_units
1297+
)

0 commit comments

Comments
 (0)