From 6d3ce6a55b95b7d5060b9f71b55d4590a54b28f5 Mon Sep 17 00:00:00 2001 From: Sylviabohnenstengel Date: Mon, 20 Nov 2023 19:01:46 +0000 Subject: [PATCH 01/18] extendign constraints operator with constraining by model level and adding recipe for mean model level air temperature. --- src/CSET/operators/constraints.py | 20 +++++++++++ .../extract_instant_model_level_air_temp.yaml | 36 +++++++++++++++++++ tests/operators/test_constraints.py | 9 +++++ 3 files changed, 65 insertions(+) create mode 100644 src/CSET/recipes/extract_instant_model_level_air_temp.yaml diff --git a/src/CSET/operators/constraints.py b/src/CSET/operators/constraints.py index 29b69e1b5..0fbca6daf 100644 --- a/src/CSET/operators/constraints.py +++ b/src/CSET/operators/constraints.py @@ -62,6 +62,26 @@ def generate_var_constraint(varname: str, **kwargs) -> iris.Constraint: return varname_constraint +def generate_model_level_constraint(model_level_name: str, **kwargs) -> iris.Constraint: + """Generate constraint from variable name. + + Operator that takes a CF compliant model_level_number string, and uses iris to + generate a constraint to be passed into the read operator to minimize the + CubeList the read operator loads and speed up loading. + + Arguments + --------- + model_level_name: str + CF compliant model level name of variable. Needed later for LFRic. + + Returns + ------- + model_level_number_constraint: iris.Constraint + """ + model_level_number_constraint = iris.Constraint(model_level_number=model_level_name) + return model_level_number_constraint + + def generate_cell_methods_constraint(cell_methods: list, **kwargs) -> iris.Constraint: """Generate constraint from cell methods. diff --git a/src/CSET/recipes/extract_instant_model_level_air_temp.yaml b/src/CSET/recipes/extract_instant_model_level_air_temp.yaml new file mode 100644 index 000000000..4c136f8d7 --- /dev/null +++ b/src/CSET/recipes/extract_instant_model_level_air_temp.yaml @@ -0,0 +1,36 @@ +title: Extract Meaned Model level Air Temperature +description: | + Extracts out the instantaneous model level air temperature from a file and writes it + to a new one. +section: Grid Stat +major_cat: Major Category 1 +minor_cat: Minor Category 1 + +steps: + - operator: read.read_cubes + constraint: + operator: constraints.generate_var_constraint + varname: air_temperature + + - operator: filters.filter_cubes + constraint: + operator: constraints.combine_constraints + varname_constraint: + operator: constraints.generate_var_constraint + varname: air_temperature + model_level_number_constraint: + operator: constraints.generate_model_level_constraint + model_level_name: 2 + cell_methods_constraint: + operator: constraints.generate_cell_methods_constraint + cell_methods: [] + + - operator: collapse.collapse + coordinate: time + method: MEAN + + - operator: plot.spatial_contour_plot + file_path: CSET_OUTPUT_PATH + + - operator: write.write_cube_to_nc + file_path: CSET_OUTPUT_PATH diff --git a/tests/operators/test_constraints.py b/tests/operators/test_constraints.py index dcd6f8187..b24656c92 100644 --- a/tests/operators/test_constraints.py +++ b/tests/operators/test_constraints.py @@ -33,6 +33,15 @@ def test_generate_var_constraint(): assert repr(var_constraint) == expected_var_constraint +def test_generate_model_level_constraint(): + """Generate iris cube constraint for str variable name.""" + var_constraint = constraints.generate_model_level_constraint("2") + expected_model_level_constraint = ( + "Constraint(coord_values={'model_level_number': 2})" + ) + assert repr(var_constraint) == expected_model_level_constraint + + def test_generate_cell_methods_constraint(): """Generate iris cube constraint for cell methods.""" cell_methods_constraint = constraints.generate_cell_methods_constraint([]) From 822d2b6557b9ee9205c3e4e8d15121dffd2c3540 Mon Sep 17 00:00:00 2001 From: Sylvia Bohnenstengel <62748926+Sylviabohnenstengel@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:58:58 +0000 Subject: [PATCH 02/18] Update src/CSET/operators/constraints.py Co-authored-by: James Frost --- src/CSET/operators/constraints.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/CSET/operators/constraints.py b/src/CSET/operators/constraints.py index 0fbca6daf..47f8d1cca 100644 --- a/src/CSET/operators/constraints.py +++ b/src/CSET/operators/constraints.py @@ -66,8 +66,7 @@ def generate_model_level_constraint(model_level_name: str, **kwargs) -> iris.Con """Generate constraint from variable name. Operator that takes a CF compliant model_level_number string, and uses iris to - generate a constraint to be passed into the read operator to minimize the - CubeList the read operator loads and speed up loading. + generate a constraint to constraint a cube to just that model level. Arguments --------- From 4611ebe3918d65735083aa18a0fdbdc376c9b079 Mon Sep 17 00:00:00 2001 From: Sylvia Bohnenstengel <62748926+Sylviabohnenstengel@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:59:12 +0000 Subject: [PATCH 03/18] Update src/CSET/operators/constraints.py Co-authored-by: James Frost --- src/CSET/operators/constraints.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CSET/operators/constraints.py b/src/CSET/operators/constraints.py index 47f8d1cca..28d2bf2d4 100644 --- a/src/CSET/operators/constraints.py +++ b/src/CSET/operators/constraints.py @@ -63,7 +63,7 @@ def generate_var_constraint(varname: str, **kwargs) -> iris.Constraint: def generate_model_level_constraint(model_level_name: str, **kwargs) -> iris.Constraint: - """Generate constraint from variable name. + """Generate constraint for a particular model level. Operator that takes a CF compliant model_level_number string, and uses iris to generate a constraint to constraint a cube to just that model level. From ccbb6febb86ff2c95731415a3ad2b7ec8ceab432 Mon Sep 17 00:00:00 2001 From: Sylvia Bohnenstengel <62748926+Sylviabohnenstengel@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:59:31 +0000 Subject: [PATCH 04/18] Update src/CSET/operators/constraints.py Co-authored-by: James Frost --- src/CSET/operators/constraints.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CSET/operators/constraints.py b/src/CSET/operators/constraints.py index 28d2bf2d4..b4f74d2a0 100644 --- a/src/CSET/operators/constraints.py +++ b/src/CSET/operators/constraints.py @@ -70,7 +70,7 @@ def generate_model_level_constraint(model_level_name: str, **kwargs) -> iris.Con Arguments --------- - model_level_name: str + model_level_number: str CF compliant model level name of variable. Needed later for LFRic. Returns From 7b160e2cdeaa623b08c58f943a12dae4df7a60b3 Mon Sep 17 00:00:00 2001 From: Sylvia Bohnenstengel <62748926+Sylviabohnenstengel@users.noreply.github.com> Date: Tue, 21 Nov 2023 12:59:42 +0000 Subject: [PATCH 05/18] Update src/CSET/operators/constraints.py Co-authored-by: James Frost --- src/CSET/operators/constraints.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CSET/operators/constraints.py b/src/CSET/operators/constraints.py index b4f74d2a0..ee5d5d811 100644 --- a/src/CSET/operators/constraints.py +++ b/src/CSET/operators/constraints.py @@ -71,7 +71,7 @@ def generate_model_level_constraint(model_level_name: str, **kwargs) -> iris.Con Arguments --------- model_level_number: str - CF compliant model level name of variable. Needed later for LFRic. + CF compliant model level number. Returns ------- From 4322c40e5a770816a8a6e611faf66080bf6271c0 Mon Sep 17 00:00:00 2001 From: Sylvia Bohnenstengel <62748926+Sylviabohnenstengel@users.noreply.github.com> Date: Tue, 21 Nov 2023 13:00:04 +0000 Subject: [PATCH 06/18] Update src/CSET/operators/constraints.py Co-authored-by: James Frost --- src/CSET/operators/constraints.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/CSET/operators/constraints.py b/src/CSET/operators/constraints.py index ee5d5d811..26639b8c7 100644 --- a/src/CSET/operators/constraints.py +++ b/src/CSET/operators/constraints.py @@ -77,6 +77,8 @@ def generate_model_level_constraint(model_level_name: str, **kwargs) -> iris.Con ------- model_level_number_constraint: iris.Constraint """ + # Cast to string in case an integer is given. + model_level_number = str(model_level_number) model_level_number_constraint = iris.Constraint(model_level_number=model_level_name) return model_level_number_constraint From 83cf52f5d18faf19a362ce9cc81d9fa26875d9c1 Mon Sep 17 00:00:00 2001 From: Sylviabohnenstengel Date: Tue, 21 Nov 2023 16:03:38 +0000 Subject: [PATCH 07/18] addressing review suggestions. --- src/CSET/operators/constraints.py | 10 +++++++--- .../recipes/extract_instant_model_level_air_temp.yaml | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/CSET/operators/constraints.py b/src/CSET/operators/constraints.py index 0fbca6daf..6355c4a1f 100644 --- a/src/CSET/operators/constraints.py +++ b/src/CSET/operators/constraints.py @@ -62,7 +62,9 @@ def generate_var_constraint(varname: str, **kwargs) -> iris.Constraint: return varname_constraint -def generate_model_level_constraint(model_level_name: str, **kwargs) -> iris.Constraint: +def generate_model_level_constraint( + model_level_number: str, **kwargs +) -> iris.Constraint: """Generate constraint from variable name. Operator that takes a CF compliant model_level_number string, and uses iris to @@ -71,14 +73,16 @@ def generate_model_level_constraint(model_level_name: str, **kwargs) -> iris.Con Arguments --------- - model_level_name: str + model_level_number: str CF compliant model level name of variable. Needed later for LFRic. Returns ------- model_level_number_constraint: iris.Constraint """ - model_level_number_constraint = iris.Constraint(model_level_number=model_level_name) + model_level_number_constraint = iris.Constraint( + model_level_number=model_level_number + ) return model_level_number_constraint diff --git a/src/CSET/recipes/extract_instant_model_level_air_temp.yaml b/src/CSET/recipes/extract_instant_model_level_air_temp.yaml index 4c136f8d7..06bd3108d 100644 --- a/src/CSET/recipes/extract_instant_model_level_air_temp.yaml +++ b/src/CSET/recipes/extract_instant_model_level_air_temp.yaml @@ -20,7 +20,7 @@ steps: varname: air_temperature model_level_number_constraint: operator: constraints.generate_model_level_constraint - model_level_name: 2 + model_level_number: 2 cell_methods_constraint: operator: constraints.generate_cell_methods_constraint cell_methods: [] From 6cfc64e05162bd698e636c4b453265c725cf60c7 Mon Sep 17 00:00:00 2001 From: Sylvia Bohnenstengel <62748926+Sylviabohnenstengel@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:29:58 +0000 Subject: [PATCH 08/18] Update tests/operators/test_constraints.py Co-authored-by: James Frost --- tests/operators/test_constraints.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/operators/test_constraints.py b/tests/operators/test_constraints.py index b24656c92..910e96b57 100644 --- a/tests/operators/test_constraints.py +++ b/tests/operators/test_constraints.py @@ -34,7 +34,7 @@ def test_generate_var_constraint(): def test_generate_model_level_constraint(): - """Generate iris cube constraint for str variable name.""" + """Generate iris cube constraint for model level number.""" var_constraint = constraints.generate_model_level_constraint("2") expected_model_level_constraint = ( "Constraint(coord_values={'model_level_number': 2})" From d640abe4891fc6334f981592aaa91810ca8136ad Mon Sep 17 00:00:00 2001 From: Sylvia Bohnenstengel <62748926+Sylviabohnenstengel@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:30:16 +0000 Subject: [PATCH 09/18] Update src/CSET/recipes/extract_instant_model_level_air_temp.yaml Co-authored-by: James Frost --- src/CSET/recipes/extract_instant_model_level_air_temp.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CSET/recipes/extract_instant_model_level_air_temp.yaml b/src/CSET/recipes/extract_instant_model_level_air_temp.yaml index 06bd3108d..80b5998c9 100644 --- a/src/CSET/recipes/extract_instant_model_level_air_temp.yaml +++ b/src/CSET/recipes/extract_instant_model_level_air_temp.yaml @@ -1,4 +1,4 @@ -title: Extract Meaned Model level Air Temperature +title: Meaned Model Level Air Temperature Spatial Plot description: | Extracts out the instantaneous model level air temperature from a file and writes it to a new one. From ec4b7de1f4204be74209eb77b78c41236eef4761 Mon Sep 17 00:00:00 2001 From: Sylvia Bohnenstengel <62748926+Sylviabohnenstengel@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:30:37 +0000 Subject: [PATCH 10/18] Update tests/operators/test_constraints.py Co-authored-by: James Frost --- tests/operators/test_constraints.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/operators/test_constraints.py b/tests/operators/test_constraints.py index 910e96b57..e5ac82cca 100644 --- a/tests/operators/test_constraints.py +++ b/tests/operators/test_constraints.py @@ -37,7 +37,7 @@ def test_generate_model_level_constraint(): """Generate iris cube constraint for model level number.""" var_constraint = constraints.generate_model_level_constraint("2") expected_model_level_constraint = ( - "Constraint(coord_values={'model_level_number': 2})" + "Constraint(coord_values={'model_level_number': '2'})" ) assert repr(var_constraint) == expected_model_level_constraint From 3e791f27945eb62de8e33bcf345a2187793a5d1c Mon Sep 17 00:00:00 2001 From: Sylvia Bohnenstengel <62748926+Sylviabohnenstengel@users.noreply.github.com> Date: Tue, 21 Nov 2023 16:31:20 +0000 Subject: [PATCH 11/18] Update src/CSET/recipes/extract_instant_model_level_air_temp.yaml Co-authored-by: James Frost --- src/CSET/recipes/extract_instant_model_level_air_temp.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/CSET/recipes/extract_instant_model_level_air_temp.yaml b/src/CSET/recipes/extract_instant_model_level_air_temp.yaml index 80b5998c9..60cddf845 100644 --- a/src/CSET/recipes/extract_instant_model_level_air_temp.yaml +++ b/src/CSET/recipes/extract_instant_model_level_air_temp.yaml @@ -2,9 +2,6 @@ title: Meaned Model Level Air Temperature Spatial Plot description: | Extracts out the instantaneous model level air temperature from a file and writes it to a new one. -section: Grid Stat -major_cat: Major Category 1 -minor_cat: Minor Category 1 steps: - operator: read.read_cubes From c2470075d0cb21ae2c24979212d18922c774255f Mon Sep 17 00:00:00 2001 From: Sylviabohnenstengel Date: Tue, 21 Nov 2023 16:31:40 +0000 Subject: [PATCH 12/18] adding review changes. --- ...el_level_air_temperature_spatial_plot.yaml | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/CSET/recipes/meaned_model_level_air_temperature_spatial_plot.yaml diff --git a/src/CSET/recipes/meaned_model_level_air_temperature_spatial_plot.yaml b/src/CSET/recipes/meaned_model_level_air_temperature_spatial_plot.yaml new file mode 100644 index 000000000..06bd3108d --- /dev/null +++ b/src/CSET/recipes/meaned_model_level_air_temperature_spatial_plot.yaml @@ -0,0 +1,36 @@ +title: Extract Meaned Model level Air Temperature +description: | + Extracts out the instantaneous model level air temperature from a file and writes it + to a new one. +section: Grid Stat +major_cat: Major Category 1 +minor_cat: Minor Category 1 + +steps: + - operator: read.read_cubes + constraint: + operator: constraints.generate_var_constraint + varname: air_temperature + + - operator: filters.filter_cubes + constraint: + operator: constraints.combine_constraints + varname_constraint: + operator: constraints.generate_var_constraint + varname: air_temperature + model_level_number_constraint: + operator: constraints.generate_model_level_constraint + model_level_number: 2 + cell_methods_constraint: + operator: constraints.generate_cell_methods_constraint + cell_methods: [] + + - operator: collapse.collapse + coordinate: time + method: MEAN + + - operator: plot.spatial_contour_plot + file_path: CSET_OUTPUT_PATH + + - operator: write.write_cube_to_nc + file_path: CSET_OUTPUT_PATH From 863a507f0a1a6c149d3b3cd577a0a7eca1e87123 Mon Sep 17 00:00:00 2001 From: Sylviabohnenstengel Date: Tue, 21 Nov 2023 16:34:03 +0000 Subject: [PATCH 13/18] renaming recipe file --- .../meaned_model_level_air_temperature_spatial_plot.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/CSET/recipes/meaned_model_level_air_temperature_spatial_plot.yaml b/src/CSET/recipes/meaned_model_level_air_temperature_spatial_plot.yaml index 06bd3108d..c8cd8db5f 100644 --- a/src/CSET/recipes/meaned_model_level_air_temperature_spatial_plot.yaml +++ b/src/CSET/recipes/meaned_model_level_air_temperature_spatial_plot.yaml @@ -2,9 +2,6 @@ title: Extract Meaned Model level Air Temperature description: | Extracts out the instantaneous model level air temperature from a file and writes it to a new one. -section: Grid Stat -major_cat: Major Category 1 -minor_cat: Minor Category 1 steps: - operator: read.read_cubes From b935f48accbbe8a2e9a36025da84115ea2b94f05 Mon Sep 17 00:00:00 2001 From: Sylviabohnenstengel Date: Tue, 21 Nov 2023 18:16:25 +0000 Subject: [PATCH 14/18] deleting redundant yaml file --- .../extract_instant_model_level_air_temp.yaml | 33 ------------------- ...el_level_air_temperature_spatial_plot.yaml | 2 +- 2 files changed, 1 insertion(+), 34 deletions(-) delete mode 100644 src/CSET/recipes/extract_instant_model_level_air_temp.yaml diff --git a/src/CSET/recipes/extract_instant_model_level_air_temp.yaml b/src/CSET/recipes/extract_instant_model_level_air_temp.yaml deleted file mode 100644 index 60cddf845..000000000 --- a/src/CSET/recipes/extract_instant_model_level_air_temp.yaml +++ /dev/null @@ -1,33 +0,0 @@ -title: Meaned Model Level Air Temperature Spatial Plot -description: | - Extracts out the instantaneous model level air temperature from a file and writes it - to a new one. - -steps: - - operator: read.read_cubes - constraint: - operator: constraints.generate_var_constraint - varname: air_temperature - - - operator: filters.filter_cubes - constraint: - operator: constraints.combine_constraints - varname_constraint: - operator: constraints.generate_var_constraint - varname: air_temperature - model_level_number_constraint: - operator: constraints.generate_model_level_constraint - model_level_number: 2 - cell_methods_constraint: - operator: constraints.generate_cell_methods_constraint - cell_methods: [] - - - operator: collapse.collapse - coordinate: time - method: MEAN - - - operator: plot.spatial_contour_plot - file_path: CSET_OUTPUT_PATH - - - operator: write.write_cube_to_nc - file_path: CSET_OUTPUT_PATH diff --git a/src/CSET/recipes/meaned_model_level_air_temperature_spatial_plot.yaml b/src/CSET/recipes/meaned_model_level_air_temperature_spatial_plot.yaml index c8cd8db5f..60cddf845 100644 --- a/src/CSET/recipes/meaned_model_level_air_temperature_spatial_plot.yaml +++ b/src/CSET/recipes/meaned_model_level_air_temperature_spatial_plot.yaml @@ -1,4 +1,4 @@ -title: Extract Meaned Model level Air Temperature +title: Meaned Model Level Air Temperature Spatial Plot description: | Extracts out the instantaneous model level air temperature from a file and writes it to a new one. From a89c3139a3faac2639463bb42e1aca289cb06023 Mon Sep 17 00:00:00 2001 From: Sylviabohnenstengel Date: Tue, 21 Nov 2023 18:30:44 +0000 Subject: [PATCH 15/18] correcting bug in recipe. --- src/CSET/operators/constraints.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CSET/operators/constraints.py b/src/CSET/operators/constraints.py index 98d78d1d1..ba32b0d51 100644 --- a/src/CSET/operators/constraints.py +++ b/src/CSET/operators/constraints.py @@ -80,8 +80,8 @@ def generate_model_level_constraint( ------- model_level_number_constraint: iris.Constraint """ - # Cast to string in case an integer is given. - model_level_number = str(model_level_number) + # Cast to int in case a string is given. + model_level_number = int(model_level_number) model_level_number_constraint = iris.Constraint( model_level_number=model_level_number ) From e6f803f25d832043e60189d39031804436b21d65 Mon Sep 17 00:00:00 2001 From: Sylvia Bohnenstengel <62748926+Sylviabohnenstengel@users.noreply.github.com> Date: Tue, 21 Nov 2023 18:42:45 +0000 Subject: [PATCH 16/18] Update tests/operators/test_constraints.py Co-authored-by: James Frost --- tests/operators/test_constraints.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/operators/test_constraints.py b/tests/operators/test_constraints.py index e5ac82cca..910e96b57 100644 --- a/tests/operators/test_constraints.py +++ b/tests/operators/test_constraints.py @@ -37,7 +37,7 @@ def test_generate_model_level_constraint(): """Generate iris cube constraint for model level number.""" var_constraint = constraints.generate_model_level_constraint("2") expected_model_level_constraint = ( - "Constraint(coord_values={'model_level_number': '2'})" + "Constraint(coord_values={'model_level_number': 2})" ) assert repr(var_constraint) == expected_model_level_constraint From 3969426b460aed38e9ece8af9841309c684574fe Mon Sep 17 00:00:00 2001 From: James Frost Date: Thu, 23 Nov 2023 09:02:15 +0000 Subject: [PATCH 17/18] Update src/CSET/operators/constraints.py --- src/CSET/operators/constraints.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CSET/operators/constraints.py b/src/CSET/operators/constraints.py index ba32b0d51..051f9c7bd 100644 --- a/src/CSET/operators/constraints.py +++ b/src/CSET/operators/constraints.py @@ -63,7 +63,7 @@ def generate_var_constraint(varname: str, **kwargs) -> iris.Constraint: def generate_model_level_constraint( - model_level_number: str, **kwargs + model_level_number: int | str, **kwargs ) -> iris.Constraint: """Generate constraint for a particular model level number. From 24dba3b2737ffa925702ef0c30bf2948047939a5 Mon Sep 17 00:00:00 2001 From: James Frost Date: Thu, 23 Nov 2023 09:28:49 +0000 Subject: [PATCH 18/18] Use old union syntax --- src/CSET/operators/constraints.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/CSET/operators/constraints.py b/src/CSET/operators/constraints.py index 051f9c7bd..012c2c629 100644 --- a/src/CSET/operators/constraints.py +++ b/src/CSET/operators/constraints.py @@ -15,6 +15,7 @@ """Operators to generate constraints to filter with.""" from datetime import datetime +from typing import Union import iris import iris.cube @@ -63,7 +64,7 @@ def generate_var_constraint(varname: str, **kwargs) -> iris.Constraint: def generate_model_level_constraint( - model_level_number: int | str, **kwargs + model_level_number: Union[int, str], **kwargs ) -> iris.Constraint: """Generate constraint for a particular model level number.