Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
324798a
add functionality to calculate and plot spectra
cehalliwell Oct 15, 2025
12ecba1
correct line in operators.rst
cehalliwell Oct 15, 2025
c81877a
unit tests for power spectrum code
cehalliwell Oct 20, 2025
8cbf4fd
move power spectra operator into plot operator
cehalliwell Oct 20, 2025
0db1864
Tidy up spurious comments
cehalliwell Oct 20, 2025
9a8de34
remove any occurrence of power_spectrum operator (now removed)
cehalliwell Oct 20, 2025
93ab85c
Update unit tests for power spectra code and tidy up
cehalliwell Oct 22, 2025
e53f5d4
Remove occurrences of deleted power_spectrum operator
cehalliwell Oct 22, 2025
c31fd48
Remove redundant comments
cehalliwell Oct 22, 2025
ab55d05
Tidy up comments
cehalliwell Oct 23, 2025
8cc454c
Correct x-axis label for power spectra
cehalliwell Oct 23, 2025
b862484
Changes addressing review comments
cehalliwell Nov 11, 2025
055150b
Merge branch 'main' into 215_regional_power_spectra_DCT
jfrost-mo Nov 11, 2025
5549102
Update src/CSET/cset_workflow/meta/diagnostics/rose-meta.conf
cehalliwell Nov 12, 2025
11a81ed
Update src/CSET/cset_workflow/meta/diagnostics/rose-meta.conf
cehalliwell Nov 12, 2025
bbe16b3
Update src/CSET/operators/plot.py
cehalliwell Nov 12, 2025
5dffde9
Update src/CSET/operators/plot.py
cehalliwell Nov 12, 2025
5d78282
Update src/CSET/cset_workflow/meta/diagnostics/rose-meta.conf
cehalliwell Nov 12, 2025
0e27884
change name of function _DCT_ps in tests.
cehalliwell Nov 12, 2025
9f67c94
change name of function _create_alpha_matrix in tests.
cehalliwell Nov 12, 2025
81baa6d
Fix comment in docstring
jfrost-mo Nov 12, 2025
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
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ dependencies = [
"markdown-it-py >= 3.0",
"nc-time-axis",
"iris-grib",
"scipy",
"scikit-image",
]

Expand Down
1 change: 1 addition & 0 deletions requirements/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ dependencies:
- markdown-it-py >= 3.0
- nc-time-axis
- iris-grib
- scipy
- importlib_resources # For python < 3.12
- scikit-image # For image processing techniques.

Expand Down
62 changes: 58 additions & 4 deletions src/CSET/cset_workflow/meta/diagnostics/rose-meta.conf
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,24 @@ type=python_boolean
compulsory=true
sort-key=0surface7b

[template variables=SPECTRUM_SURFACE_FIELD]
ns=Diagnostics/Fields
description=Create power spectra plots of specified surface fields.
Use SPECTRUM_SURFACE_FIELD_SEQUENCE to set plotting mode.
type=python_boolean
compulsory=true
sort-key=0surface8

[template variables=SPECTRUM_SURFACE_FIELD_SEQUENCE]
ns=Diagnostics/Fields
description=Select analysis method for output surface field spectra.
Set to True for spectrum at each model output time.
Set to False for a spectrum of each ensemble member.
type=python_boolean
compulsory=true
sort-key=0surface8a


#######################################################################
# Pressure level fields.
[Diagnostics/Pressure]
Expand Down Expand Up @@ -393,6 +411,23 @@ type=real,real
compulsory=true
sort-key=1pressure8b

[template variables=SPECTRUM_PLEVEL_FIELD]
ns=Diagnostics/Pressure
description=Create spectrum of specified pressure level fields.
Use SPECTRUM_PLEVEL_FIELD_SEQUENCE to set plotting mode.
type=python_boolean
compulsory=true
sort-key=1pressure9

[template variables=SPECTRUM_PLEVEL_FIELD_SEQUENCE]
ns=Diagnostics/Pressure
description=Select analysis method for output pressure level spectra.
Set to True for spectrum at each model output time.
Set to False for a spectrum of each ensemble member.
type=python_boolean
compulsory=true
sort-key=1pressure9a

[template variables=SPATIAL_STRUCTURAL_SIMILARITY_PLEVEL_FIELD]
ns=Diagnostics/Pressure
description=Create spatially mapped structural similarity plots for
Expand All @@ -402,7 +437,7 @@ description=Create spatially mapped structural similarity plots for
help=Requires a field with a time coordinate of "time" or "hour".
type=python_boolean
compulsory=true
sort-key=1pressure9
sort-key=1pressure9e

[template variables=MEAN_STRUCTURAL_SIMILARITY_PLEVEL_FIELD]
ns=Diagnostics/Pressure
Expand All @@ -412,7 +447,8 @@ description=Create time series plots of the mean structural similarity
help=Requires a field with a time coordinate of "time" or "hour".
type=python_boolean
compulsory=true
sort-key=1pressure9b
sort-key=1pressure9f


########################################################################
# Model-level fields.
Expand Down Expand Up @@ -595,6 +631,23 @@ type=real,real
compulsory=true
sort-key=2modellevel8c

[template variables=SPECTRUM_MLEVEL_FIELD]
ns=Diagnostics/ModelLevel
description=Create spectrum of specified model level fields.
Use SPECTRUM_MLEVEL_FIELD_SEQUENCE to set plotting mode.
type=python_boolean
compulsory=true
sort-key=2modellevel9

[template variables=SPECTRUM_MLEVEL_FIELD_SEQUENCE]
ns=Diagnostics/ModelLevel
description=Select analysis method for output model level spectrum.
Set to True for spectrum at each model output time.
Set to False for a spectrum of each ensemble member.
type=python_boolean
compulsory=true
sort-key=2modellevel9a

[template variables=SPATIAL_STRUCTURAL_SIMILARITY_MLEVEL]
ns=Diagnostics/ModelLevel
description=Create spatially mapped structural similarity plots for
Expand All @@ -603,7 +656,7 @@ description=Create spatially mapped structural similarity plots for
help=Requires a field with a time coordinate of "time" or "hour".
type=python_boolean
compulsory=true
sort-key=2modellevel9
sort-key=2modellevel9e

[template variables=MEAN_STRUCTURAL_SIMILARITY_MLEVEL]
ns=Diagnostics/ModelLevel
Expand All @@ -613,7 +666,8 @@ description=Create time series plots of the mean structural similarity
help=Requires a field with a time coordinate of "time" or "hour".
type=python_boolean
compulsory=true
sort-key=2modellevel9b
sort-key=2modellevel9f


#######################################################
# Verification
Expand Down
2 changes: 2 additions & 0 deletions src/CSET/loaders/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from CSET.loaders import (
aoa,
histograms,
power_spectrum,
profiles,
spatial_difference_field,
spatial_field,
Expand All @@ -33,6 +34,7 @@
__all__ = [
"aoa",
"histograms",
"power_spectrum",
"profiles",
"spatial_difference_field",
"spatial_field",
Expand Down
95 changes: 95 additions & 0 deletions src/CSET/loaders/power_spectrum.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# © Crown copyright, Met Office (2022-2025) and CSET contributors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Load power spectrum recipes."""

import itertools

from CSET.recipes import Config, RawRecipe, get_models


def load(conf: Config):
"""Yield recipes from the given workflow configuration."""
# Load a list of model detail dictionaries.
models = get_models(conf.asdict())

# Surface (2D) fields.
if conf.SPECTRUM_SURFACE_FIELD:
for field in conf.SURFACE_FIELDS:
yield RawRecipe(
recipe="generic_surface_power_spectrum_series.yaml",
variables={
"VARNAME": field,
"MODEL_NAME": [model["name"] for model in models],
"SEQUENCE": "time"
if conf.SPECTRUM_SURFACE_FIELD_SEQUENCE
else "realization",
"SUBAREA_TYPE": conf.SUBAREA_TYPE if conf.SELECT_SUBAREA else None,
"SUBAREA_EXTENT": conf.SUBAREA_EXTENT
if conf.SELECT_SUBAREA
else None,
},
model_ids=[model["id"] for model in models],
aggregation=False,
)

# Pressure level fields.
if conf.SPECTRUM_PLEVEL_FIELD:
for field, plevel in itertools.product(
conf.PRESSURE_LEVEL_FIELDS,
conf.PRESSURE_LEVELS,
):
yield RawRecipe(
recipe="generic_level_power_spectrum_series.yaml",
variables={
"VARNAME": field,
"LEVELTYPE": "pressure",
"LEVEL": plevel,
"MODEL_NAME": [model["name"] for model in models],
"SEQUENCE": "time"
if conf.SPECTRUM_PLEVEL_FIELD_SEQUENCE
else "realization",
"SUBAREA_TYPE": conf.SUBAREA_TYPE if conf.SELECT_SUBAREA else None,
"SUBAREA_EXTENT": conf.SUBAREA_EXTENT
if conf.SELECT_SUBAREA
else None,
},
model_ids=[model["id"] for model in models],
aggregation=False,
)

# Model level fields
if conf.SPECTRUM_MLEVEL_FIELD:
for field, mlevel in itertools.product(
conf.MODEL_LEVEL_FIELDS,
conf.MODEL_LEVELS,
):
yield RawRecipe(
recipe="generic_level_power_spectrum_series.yaml",
variables={
"VARNAME": field,
"LEVELTYPE": "model_level_number",
"LEVEL": mlevel,
"MODEL_NAME": [model["name"] for model in models],
"SEQUENCE": "time"
if conf.SPECTRUM_MLEVEL_FIELD_SEQUENCE
else "realization",
"SUBAREA_TYPE": conf.SUBAREA_TYPE if conf.SELECT_SUBAREA else None,
"SUBAREA_EXTENT": conf.SUBAREA_EXTENT
if conf.SELECT_SUBAREA
else None,
},
model_ids=[model["id"] for model in models],
aggregation=False,
)
Loading