diff --git a/cset-workflow/flow.cylc b/cset-workflow/flow.cylc index f8cb076bd..c80a717fb 100644 --- a/cset-workflow/flow.cylc +++ b/cset-workflow/flow.cylc @@ -121,6 +121,9 @@ URL = https://metoffice.github.io/CSET-workflow {% if DETERMINISTIC_PLOT_CAPE_RATIO %} {% include 'includes/deterministic_plot_cape_ratio.cylc' %} {% endif %} +{% if DETERMINISTIC_PLOT_INFLOW_PROPERTIES %} +{% include 'includes/deterministic_plot_inflow_properties.cylc' %} +{% endif %} {% if DETERMINISTIC_PLOT_MODEL_LEVEL_AIR_TEMP %} {% include 'includes/deterministic_plot_model_level_air_temp.cylc' %} {% endif %} diff --git a/cset-workflow/includes/deterministic_plot_inflow_properties.cylc b/cset-workflow/includes/deterministic_plot_inflow_properties.cylc new file mode 100644 index 000000000..b8697da94 --- /dev/null +++ b/cset-workflow/includes/deterministic_plot_inflow_properties.cylc @@ -0,0 +1,45 @@ +[scheduling] + [[graph]] + P1 = """ + recipe_start => deterministic_plot_inflow_layer_properties => recipe_finish + """ + +[runtime] + [[deterministic_plot_inflow_layer_properties]] + script = rose task-run -v --app-key=run_cset_recipe + execution time limit = PT15M + [[[environment]]] + CSET_RECIPE = """ +title: Inflow properties plot +description: | + Extracts data required for, and calculates the Inflow properties diagnostic, plotting on a map. + +steps: + - operator: read.read_cubes + + - operator: convection.inflow_layer_properties + EIB: + operator: filters.filter_cubes + constraint: + operator: constraints.generate_stash_constraint + stash: m01s20i119 + BLheight: + operator: filters.filter_cubes + constraint: + operator: constraints.generate_stash_constraint + stash: m01s00i025 + Orography: + operator: filters.filter_cubes + constraint: + operator: constraints.generate_stash_constraint + stash: m01s00i033 + + - operator: filters.filter_cubes + constraint: + operator: constraints.generate_time_constraint + time_start: 2022-10-28T06:00Z + + - operator: plot.postage_stamp_contour_plot + + - operator: write.write_cube_to_nc +""" diff --git a/cset-workflow/meta/rose-meta.conf b/cset-workflow/meta/rose-meta.conf index f331c7b54..e8672b730 100644 --- a/cset-workflow/meta/rose-meta.conf +++ b/cset-workflow/meta/rose-meta.conf @@ -276,3 +276,12 @@ help=See includes/deterministic_plot_cape_ratio.cylc type=python_boolean compulsory=true sort-key=diag-070 + +[template variables=DETERMINISTIC_PLOT_INFLOW_PROPERTIES] +ns=Diagnostics +description=Extracts data required for, and calculates the inflow properties diagnostic, plotting on a map. + Required STASH m01s20i119, m01s00i025, m01s00i033. +help=See includes/deterministic_plot_inflow_properties.cylc +type=python_boolean +compulsory=true +sort-key=diag-080 diff --git a/src/CSET/operators/convection.py b/src/CSET/operators/convection.py index f3236d0b2..23412171b 100644 --- a/src/CSET/operators/convection.py +++ b/src/CSET/operators/convection.py @@ -20,7 +20,10 @@ """ import copy +import logging +import iris +import iris.cube import numpy as np @@ -136,3 +139,111 @@ def cape_ratio(SBCAPE, MUCAPE, MUCIN, MUCIN_thresh=-75.0): cape_ratio_cube.var_name = "cape_ratio" cape_ratio_cube.attributes.pop("STASH", None) return cape_ratio_cube + + +def inflow_layer_properties(EIB, BLheight, Orography): + r"""Filter one value by another to create a binary mask identifying elevated convection. + + Parameters + ---------- + EIB: Cube + Effective inflow layer base (precalculated or as identified by the model). + If using the UM please use STASH ``m01s20i119``. + BLheight: Cube + Boundary layer height (precalculated or as identified by the model). + If using the UM please use STASH ``m01s00i025``. + Orography: Cube + Model or actual orography, expected to be 2 dimensional. If 3 or 4 dimensional + cube given converts to 2 dimensions assuming static orography field + in ensemble realization and time. + If using the UM please use STASH ``m01s00i033``. + + Returns + ------- + Cube + + Notes + ----- + This diagnostic is based on the concept of an effective inflow layer. + This concept was first introduced by Thompson et al. (2007) [1]_. The + inflow layer defined the region of air that is most likely to be ingested + into the convective event. It is defined by thresholding the CAPE and CIN + values: CAPE > 100 J/kg and |CIN| < 250 J/kg. + + To turn this into a diagnostic for elevated convection the inflow layer + base is filtered against the boundary layer height. The model orography + is added to the boundary layer height to ensure reference height + consistency as the BL height is defined above ground level and the + inflow layer base is defined above sea level in the model output. + + .. math:: EIB > BLheight + Orography + + This is a binary diagnostic. It has a value of 0 to imply the environment + is suitable for surface-based convection. It has a value of 1 to indicate + the environment is suitable to produce elevated convection. + + Further details about this diagnostic for elevated convection + identification can be found in Flack et al. (2023) [2]_. + + Expected applicability ranges: Convective-scale models will be noisier than + parametrized models as they are more responsive to the convection, and thus + it may be more sensible to view as a larger spatial average rather than + at native resolution. + + Interpretation notes: The effective inflow layer base diagnostic from UM STASH + is dependent upon the UM CAPE and CIN diagnostics. These diagnostics are + calculated at the end of the timestep. Therefore this diagnostic is applicable + after precipitation has occurred, not before as is the usual interpretation of + CAPE related diagnostics. + + You might encounter warnings with the following text ``Orography assumed not + to vary with time or ensemble member.`` or ``Orography assumed not to vary with + time and ensemble member. `` these warnings are expected when the orography files + are not 2-dimensional, and do not cause any problems unless ordering is not as + expected. + + References + ---------- + .. [1] Thompson, R. L. Mead, C. M., and Edwards, R., (2007) "Effective + Storm-Relative Helicity and Bulk Shear in Supercell Thunderstorm + Environments." Weather and Forecasting, vol. 22, 102-115, + doi: 10.1175/WAF969.1 + .. [2] Flack, D.L.A., Lehnert, M., Lean, H.W., and Willington, S. (XXXX) + "Characteristics of Diagnostics for Identifying Elevated + Convection over the British Isles in a Convection-Allowing Model." + Weather and Forecasting, vol. 30, 1079-1094, doi: + 10.1175/WAF-D-22-0219.1 + + Examples + -------- + >>> Inflow_properties=convection.inflow_layer_properties(EIB,BLheight,Orography) + >>> iplt.pcolormesh(Inflow_properties[0,:,:],cmap=mpl.cm.Purples) + >>> plt.gca().coastlines('10m') + >>> plt.colorbar() + >>> plt.clim(0,1) + >>> plt.show() + + """ + # Setup new array for output of the diagnostic. + EC_Flagd = np.zeros(EIB.shape) + # Check dimensions for Orography cube and replace with 2D array if not 2D. + if Orography.ndim == 3: + try: + Orography = Orography.slices_over("realization").next() + except iris.exceptions.CoordinateNotFoundError: + Orography = Orography.slices_over("time").next() + logging.warning("Orography assumed not to vary with time or ensemble member") + elif Orography.ndim == 4: + Orography = Orography.slices_over(("time", "realization")).next() + logging.warning("Orography assumed not to vary with time or ensemble member. ") + # Change points where Effective inflow layer base is larger than boundary + # layer height to 1 implying elevated convection. + EC_Flagd[EIB.data > (BLheight.data + Orography.data)] = 1.0 + # Take the coordinates from an existing cube and replace the data. + inflow_properties_cube = EIB.copy() + inflow_properties_cube.data = EC_Flagd + # Rename and remove STASH code. + inflow_properties_cube.var_name = "inflow_layer_properties" + inflow_properties_cube.attributes.pop("STASH", None) + # Return the cube. + return EC_Flagd diff --git a/src/CSET/recipes/Inflow_layer_properties_plot.yaml b/src/CSET/recipes/Inflow_layer_properties_plot.yaml new file mode 100644 index 000000000..398053867 --- /dev/null +++ b/src/CSET/recipes/Inflow_layer_properties_plot.yaml @@ -0,0 +1,32 @@ +title: Inflow layer properties plot +description: | + Extracts data required for, and calculates the Inflow properties diagnostic, plotting on a map. + +steps: + - operator: read.read_cubes + + - operator: convection.inflow_layer_properties + EIB: + operator: filters.filter_cubes + constraint: + operator: constraints.generate_stash_constraint + stash: m01s20i119 + BLheight: + operator: filters.filter_cubes + constraint: + operator: constraints.generate_stash_constraint + stash: m01s00i025 + Orography: + operator: filters.filter_cubes + constraint: + operator: constraints.generate_stash_constraint + stash: m01s00i033 + + - operator: filters.filter_cubes + constraint: + operator: constraints.generate_time_constraint + time_start: 2022-10-28T06:00Z + + - operator: plot.postage_stamp_contour_plot + + - operator: write.write_cube_to_nc diff --git a/tests/operators/test_convection.py b/tests/operators/test_convection.py index 57774000e..5b1e2f05a 100644 --- a/tests/operators/test_convection.py +++ b/tests/operators/test_convection.py @@ -22,3 +22,15 @@ def test_cape_ratio(): convection.cape_ratio(SBCAPE, MUCAPE, MUCIN, MUCIN_thresh=-1.5).data.all() == precalculated_2.data.all() ) + + +def test_inflow_layer_properties(): + """Compare with precalculated properties.""" + precalculated = iris.load_cube("tests/test_data/convection/ECFlagD.nc") + EIB = iris.load_cube("tests/test_data/convection/EIB.nc") + BLheight = iris.load_cube("tests/test_data/convection/BLheight.nc") + Orography = iris.load_cube("tests/test_data/convection/Orography.nc") + assert ( + convection.inflow_layer_properties(EIB, BLheight, Orography).all() + == precalculated.data.all() + ) diff --git a/tests/test_data/convection/BLheight.nc b/tests/test_data/convection/BLheight.nc new file mode 100644 index 000000000..09a9fcb70 Binary files /dev/null and b/tests/test_data/convection/BLheight.nc differ diff --git a/tests/test_data/convection/ECFlagD.nc b/tests/test_data/convection/ECFlagD.nc new file mode 100644 index 000000000..f1dcd4a53 Binary files /dev/null and b/tests/test_data/convection/ECFlagD.nc differ diff --git a/tests/test_data/convection/EIB.nc b/tests/test_data/convection/EIB.nc new file mode 100644 index 000000000..92196370c Binary files /dev/null and b/tests/test_data/convection/EIB.nc differ diff --git a/tests/test_data/convection/Orography.nc b/tests/test_data/convection/Orography.nc new file mode 100644 index 000000000..36b94db37 Binary files /dev/null and b/tests/test_data/convection/Orography.nc differ