Skip to content
Open
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
13 changes: 13 additions & 0 deletions src/CSET/operators/collapse.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

from CSET._common import iter_maybe
from CSET.operators.aggregate import add_hour_coordinate
from CSET.operators.misc import guess_bounds


def collapse(
Expand Down Expand Up @@ -112,6 +113,18 @@ def collapse(
cube_max = cube.collapsed(coordinate, iris.analysis.MAX)
cube_min = cube.collapsed(coordinate, iris.analysis.MIN)
collapsed_cubes.append(cube_max - cube_min)
elif method == "AREA_AVG":
# Mask nans
if np.count_nonzero(np.isnan(cube.data)) > 0:
cube.data = np.ma.masked_invalid(cube.data)

# Compute grid cell areas
cube = guess_bounds(cube)
grid_areas = iris.analysis.cartography.area_weights(cube)

collapsed_cubes.append(
cube.collapsed(coordinate, iris.analysis.MEAN, weights=grid_areas)
)
else:
collapsed_cubes.append(
cube.collapsed(coordinate, getattr(iris.analysis, method))
Expand Down
36 changes: 36 additions & 0 deletions src/CSET/operators/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -428,3 +428,39 @@ def convert_units(cubes: iris.cube.Cube | iris.cube.CubeList, units: str):
return new_cubelist[0]
else:
return new_cubelist


def guess_bounds(cube):
"""
Guess bounds for x and y coordinates on a cube.

Arguments
---------
cube: iris.cube.Cube
Input cube whose x and y coordinate bounds will be guessed if missing.

Returns
-------
iris.cube.Cube
The same cube with bounds added to x and y coordinates where absent.

Raises
------
ValueError
If the cube uses a variable resolution grid where bounds cannot be
guessed reliably.
"""
# Loop over spatial coordinates
for axis in ["x", "y"]:
coord = cube.coord(axis=axis)
try:
_ = iris.util.regular_step(coord)
except ValueError as e:
logging.warning(
"Cannot guess bounds for a variable resolution (non-regular) grid: %s",
e,
)
# Guess bounds if there aren't any
if coord.bounds is None:
coord.guess_bounds()
return cube
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
category: Surface Time Series
title: Domain area average $VARNAME time series
description: Plots a time series of the domain area average $VARNAME.

steps:
- operator: read.read_cubes
file_paths: $INPUT_PATHS
model_names: $MODEL_NAME
constraint:
operator: constraints.combine_constraints
varname_constraint:
operator: constraints.generate_var_constraint
varname: $VARNAME
cell_methods_constraint:
operator: constraints.generate_cell_methods_constraint
cell_methods: []
varname: $VARNAME
pressure_level_constraint:
operator: constraints.generate_level_constraint
coordinate: "pressure"
levels: []
subarea_type: $SUBAREA_TYPE
subarea_extent: $SUBAREA_EXTENT

# Area-weighted average
- operator: collapse.collapse
coordinate: [grid_latitude, grid_longitude]
method: AREA_AVG

# Make a single NetCDF with all the data inside it.
- operator: write.write_cube_to_nc
overwrite: True

# Plot the data.
- operator: plot.plot_line_series
Loading