Skip to content

Commit

Permalink
Merge pull request #522 from MetOffice/400_support_filtering_to_region
Browse files Browse the repository at this point in the history
Add functionality to filter by region
  • Loading branch information
jfrost-mo authored May 10, 2024
2 parents 8df724d + 54a1b6c commit 244f64d
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,24 @@
inherit = PARALLEL
[[[environment]]]
CSET_RECIPE_NAME = "lfric_generic_surface_domain_mean_time_series.yaml"
CSET_ADDOPTS = "--VARNAME={{model_field}}"
CSET_ADDOPTS = """
--VARNAME={{model_field}}
--SUBAREA_LAT_BOUND_BOTTOM={{SUBAREA_LAT_BOUND_BOTTOM}}
--SUBAREA_LAT_BOUND_TOP={{SUBAREA_LAT_BOUND_TOP}}
--SUBAREA_LON_BOUND_RIGHT={{SUBAREA_LON_BOUND_RIGHT}}
--SUBAREA_LON_BOUND_LEFT={{SUBAREA_LON_BOUND_LEFT}}
"""

[[collate_lfric_domain_mean_surface_time_series_{{model_field}}]]
inherit = COLLATE
[[[environment]]]
CSET_RECIPE_NAME = "lfric_generic_surface_domain_mean_time_series.yaml"
CSET_ADDOPTS = "--VARNAME={{model_field}}"
CSET_ADDOPTS = """
--VARNAME={{model_field}}
--SUBAREA_LAT_BOUND_BOTTOM={{SUBAREA_LAT_BOUND_BOTTOM}}
--SUBAREA_LAT_BOUND_TOP={{SUBAREA_LAT_BOUND_TOP}}
--SUBAREA_LON_BOUND_RIGHT={{SUBAREA_LON_BOUND_RIGHT}}
--SUBAREA_LON_BOUND_LEFT={{SUBAREA_LON_BOUND_LEFT}}
"""
{% endfor %}
{% endif %}
16 changes: 14 additions & 2 deletions cset-workflow/includes/lfric_plot_spatial_surface_model_field.cylc
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,24 @@
inherit = PARALLEL
[[[environment]]]
CSET_RECIPE_NAME = "lfric_generic_surface_spatial_plot_sequence.yaml"
CSET_ADDOPTS = "--VARNAME={{model_field}}"
CSET_ADDOPTS = """
--VARNAME={{model_field}}
--SUBAREA_LAT_BOUND_BOTTOM={{SUBAREA_LAT_BOUND_BOTTOM}}
--SUBAREA_LAT_BOUND_TOP={{SUBAREA_LAT_BOUND_TOP}}
--SUBAREA_LON_BOUND_RIGHT={{SUBAREA_LON_BOUND_RIGHT}}
--SUBAREA_LON_BOUND_LEFT={{SUBAREA_LON_BOUND_LEFT}}
"""

[[lfric_generic_spatial_plot_time_series_collation_{{model_field}}]]
inherit = COLLATE
[[[environment]]]
CSET_RECIPE_NAME = "lfric_generic_surface_spatial_plot_sequence.yaml"
CSET_ADDOPTS = "--VARNAME={{model_field}}"
CSET_ADDOPTS = """
--VARNAME={{model_field}}
--SUBAREA_LAT_BOUND_BOTTOM={{SUBAREA_LAT_BOUND_BOTTOM}}
--SUBAREA_LAT_BOUND_TOP={{SUBAREA_LAT_BOUND_TOP}}
--SUBAREA_LON_BOUND_RIGHT={{SUBAREA_LON_BOUND_RIGHT}}
--SUBAREA_LON_BOUND_LEFT={{SUBAREA_LON_BOUND_LEFT}}
"""
{% endfor %}
{% endif %}
41 changes: 40 additions & 1 deletion cset-workflow/meta/rose-meta.conf
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,6 @@ type=integer
compulsory=true
sort-key=incr_in2


################################################################################
# Diagnostics
################################################################################
Expand Down Expand Up @@ -513,3 +512,43 @@ help=See includes/domain_mean_time_series_stash.cylc
type=python_boolean
compulsory=true
sort-key=stash2

[template variables=SELECT_SUBAREA]
ns=Diagnostics
description=Only analyse a subset of the region defined by the input data.
help=Select this option to run a recipe over a defined latitude-longitude range.
trigger=template variables=SUBAREA_LAT_BOUND_TOP: True;
=template variables=SUBAREA_LAT_BOUND_BOTTOM: True;
=template variables=SUBAREA_LON_BOUND_LEFT: True;
=template variables=SUBAREA_LON_BOUND_RIGHT: True;
type=python_boolean
compulsory=true
sort-key=subsection1

[template variables=SUBAREA_LAT_BOUND_TOP]
ns=Diagnostics
description=Top edge coordinate of the sub-area, real.
help=Recommend looking at the input data to get these values. Uses the grid's native units.
type=real
sort-key=subsection2

[template variables=SUBAREA_LAT_BOUND_BOTTOM]
ns=Diagnostics
description=Bottom edge coordinate of the sub-area, real.
help=Recommend looking at the input data to get these values. Uses the grid's native units.
type=real
sort-key=subsection2

[template variables=SUBAREA_LON_BOUND_LEFT]
ns=Diagnostics
description=Left edge coordinate of the sub-area, real.
help=Recommend looking at the input data to get these values. Uses the grid's native units.
type=real
sort-key=subsection2

[template variables=SUBAREA_LON_BOUND_RIGHT]
ns=Diagnostics
description=Right edge coordinate of the sub-area, real.
help=Recommend looking at the input data to get these values. Uses the grid's native units.
type=real
sort-key=subsection2
3 changes: 3 additions & 0 deletions docs/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ Unreleased
.. Add your changes here, highlighting any user facing changes. E.g:
.. "* `@gh-user`_ did foo to bar in :pr:`9999`. This enables baz."
* `@dasha-shchep`_ added ``generate_area_constraint`` operator and added to
LFRic recipes in :pr:`522`. This was their first contribution 🎉
* `@jfrost-mo`_ dropped python 3.9 support in :pr:`448` The minimum required
python is now 3.10.
* `@jfrost-mo`_ fixed some outdated documentation examples in :pr:`546`
Expand All @@ -38,6 +40,7 @@ Unreleased
* `@jfrost-mo`_ updated the example rose-suite.conf to reflect what a modern
version should look like in :pr:`508`

.. _@dasha-shchep: https://github.com/dasha-shchep
.. _@cjohnson-pi: https://github.com/cjohnson-pi
.. _@Ashfinn: https://github.com/Ashfinn

Expand Down
33 changes: 33 additions & 0 deletions src/CSET/operators/constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,39 @@ def generate_time_constraint(
return time_constraint


def generate_area_constraint(
lat_start: float, lat_end: float, lon_start: float, lon_end: float, **kwargs
) -> iris.Constraint:
"""Generate an area constraint between latitude/longitude limits.
Operator that takes a set of latitude and longitude limits and returns a
constraint that selects grid values only inside that area. Works with the
data's native grid so is defined within the rotated pole CRS.
Arguments
---------
lat_start: float
Latitude value for lower bound
lat_end: float
Latitude value for top bound
lon_start: float
Longitude value for left bound
lon_end: float
Longitude value for right bound
Returns
-------
area_constraint: iris.Constraint
"""
area_constraint = iris.Constraint(
coord_values={
"grid_latitude": lambda cell: lat_start < cell < lat_end,
"grid_longitude": lambda cell: lon_start < cell < lon_end,
}
)
return area_constraint


def combine_constraints(
constraint: iris.Constraint = None, **kwargs
) -> iris.Constraint:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ parallel:
validity_time_constraint:
operator: constraints.generate_time_constraint
time_start: $VALIDITY_TIME
area_constraint:
operator: constraints.generate_area_constraint
lat_start: $SUBAREA_LAT_BOUND_BOTTOM
lat_end: $SUBAREA_LAT_BOUND_TOP
lon_start: $SUBAREA_LON_BOUND_LEFT
lon_end: $SUBAREA_LON_BOUND_RIGHT

# Remove source stash attribute, as it can be encoded in different orders.
# Remove uuid and timeStamp, as these are only relevant to output files, not
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ parallel:
validity_time_constraint:
operator: constraints.generate_time_constraint
time_start: $VALIDITY_TIME
area_constraint:
operator: constraints.generate_area_constraint
lat_start: $SUBAREA_LAT_BOUND_BOTTOM
lat_end: $SUBAREA_LAT_BOUND_TOP
lon_start: $SUBAREA_LON_BOUND_LEFT
lon_end: $SUBAREA_LON_BOUND_RIGHT

# Remove source stash attribute, as it can be encoded in different orders.
# Remove uuid and timeStamp, as these are only relevant to output files, not
Expand Down
7 changes: 7 additions & 0 deletions tests/operators/test_constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ def test_generate_pressure_level_constraint_no_pressure():
assert expected_pressure_constraint in repr(pressure_constraint)


def test_generate_area_constraint():
"""Generate area constraint with lat-lon limits."""
area_constraint = constraints.generate_area_constraint(0.0, 0.0, 0.1, 0.1)
expected_area_constraint = "Constraint(coord_values={'grid_latitude': <function generate_area_constraint.<locals>.<lambda> at"
assert expected_area_constraint in repr(area_constraint)


def test_combine_constraints():
"""Combine constraint."""
stash_constraint = constraints.generate_stash_constraint("m01s03i236")
Expand Down

0 comments on commit 244f64d

Please sign in to comment.