Skip to content

climate_ref_esmvaltool.diagnostics.ozone #

O3LatMonthMapplot #

Bases: ESMValToolDiagnostic

Calculate the ozone diagnostics - zonal mean total column ozone vs. annual cycle plot.

Source code in packages/climate-ref-esmvaltool/src/climate_ref_esmvaltool/diagnostics/ozone.py
class O3LatMonthMapplot(ESMValToolDiagnostic):
    """
    Calculate the ozone diagnostics - zonal mean total column ozone vs. annual cycle plot.
    """

    name = "Ozone Diagnostics"
    slug = "ozone-annual-cycle"
    base_recipe = "ref/recipe_ref_ozone.yml"

    data_requirements = toz_data_requirement
    facets = ()
    test_data_spec = toz_test_spec
    files = (
        FileDefinition(
            file_pattern="plots/lat_month_mapplot/plot/*.png",
            dimensions={"variable_id": "toz", "statistic": "zonal mean annual cycle"},
        ),
    )

    @staticmethod
    def update_recipe(
        recipe: Recipe,
        input_files: dict[SourceDatasetType, pandas.DataFrame],
    ) -> None:
        """Update the recipe."""
        recipe_variables = dataframe_to_recipe(input_files[get_cmip_source_type(input_files)])
        dataset = recipe_variables["toz"]["additional_datasets"][0]
        # set model (CMIP6) time range to 2005...2014
        dataset["timerange"] = "2005/2014"
        recipe["datasets"] = [dataset]
        diagnostic = "lat_month_mapplot"
        recipe["diagnostics"] = {diagnostic: recipe["diagnostics"][diagnostic]}
        recipe["diagnostics"][diagnostic]["variables"]["toz"]["timerange"] = "2005/2014"

update_recipe(recipe, input_files) staticmethod #

Update the recipe.

Source code in packages/climate-ref-esmvaltool/src/climate_ref_esmvaltool/diagnostics/ozone.py
@staticmethod
def update_recipe(
    recipe: Recipe,
    input_files: dict[SourceDatasetType, pandas.DataFrame],
) -> None:
    """Update the recipe."""
    recipe_variables = dataframe_to_recipe(input_files[get_cmip_source_type(input_files)])
    dataset = recipe_variables["toz"]["additional_datasets"][0]
    # set model (CMIP6) time range to 2005...2014
    dataset["timerange"] = "2005/2014"
    recipe["datasets"] = [dataset]
    diagnostic = "lat_month_mapplot"
    recipe["diagnostics"] = {diagnostic: recipe["diagnostics"][diagnostic]}
    recipe["diagnostics"][diagnostic]["variables"]["toz"]["timerange"] = "2005/2014"

O3LatTimeMapplot #

Bases: ESMValToolDiagnostic

Calculate the ozone diagnostics - zonal mean total column ozone vs. time.

Source code in packages/climate-ref-esmvaltool/src/climate_ref_esmvaltool/diagnostics/ozone.py
class O3LatTimeMapplot(ESMValToolDiagnostic):
    """
    Calculate the ozone diagnostics - zonal mean total column ozone vs. time.
    """

    name = "Ozone Diagnostics"
    slug = "ozone-lat-time"
    base_recipe = "ref/recipe_ref_ozone.yml"

    data_requirements = toz_data_requirement
    facets = ()
    test_data_spec = toz_test_spec
    files = (
        FileDefinition(
            file_pattern="plots/lat_time_mapplot/plot/*.png",
            dimensions={"variable_id": "toz", "statistic": "zonal mean vs time"},
        ),
    )

    @staticmethod
    def update_recipe(
        recipe: Recipe,
        input_files: dict[SourceDatasetType, pandas.DataFrame],
    ) -> None:
        """Update the recipe."""
        recipe_variables = dataframe_to_recipe(input_files[get_cmip_source_type(input_files)])
        dataset = recipe_variables["toz"]["additional_datasets"][0]
        # set time range of model (CMIP6) dataset (should match observational period)
        dataset["timerange"] = "1996/2014"
        recipe["datasets"] = [dataset]
        diagnostic = "lat_time_mapplot"
        recipe["diagnostics"] = {diagnostic: recipe["diagnostics"][diagnostic]}
        recipe["diagnostics"][diagnostic]["variables"]["toz"]["timerange"] = "1996/2014"

update_recipe(recipe, input_files) staticmethod #

Update the recipe.

Source code in packages/climate-ref-esmvaltool/src/climate_ref_esmvaltool/diagnostics/ozone.py
@staticmethod
def update_recipe(
    recipe: Recipe,
    input_files: dict[SourceDatasetType, pandas.DataFrame],
) -> None:
    """Update the recipe."""
    recipe_variables = dataframe_to_recipe(input_files[get_cmip_source_type(input_files)])
    dataset = recipe_variables["toz"]["additional_datasets"][0]
    # set time range of model (CMIP6) dataset (should match observational period)
    dataset["timerange"] = "1996/2014"
    recipe["datasets"] = [dataset]
    diagnostic = "lat_time_mapplot"
    recipe["diagnostics"] = {diagnostic: recipe["diagnostics"][diagnostic]}
    recipe["diagnostics"][diagnostic]["variables"]["toz"]["timerange"] = "1996/2014"

O3PolarCapTimeseriesNH #

Bases: ESMValToolDiagnostic

Calculate the ozone diagnostics - March NH polar mean (60N-80N) time series.

Source code in packages/climate-ref-esmvaltool/src/climate_ref_esmvaltool/diagnostics/ozone.py
class O3PolarCapTimeseriesNH(ESMValToolDiagnostic):
    """
    Calculate the ozone diagnostics - March NH polar mean (60N-80N) time series.
    """

    name = "Ozone Diagnostics"
    slug = "ozone-nh-mar"
    base_recipe = "ref/recipe_ref_ozone.yml"

    data_requirements = toz_data_requirement
    facets = ()
    test_data_spec = toz_test_spec
    files = (
        FileDefinition(
            file_pattern="plots/polar_cap_time_series_NH/plot/timeseries_toz_NH_MAR.png",
            dimensions={"variable_id": "toz", "statistic": "Northern Hemisphere March polar mean"},
        ),
    )
    # dim0=0 is the model, dim0=1 contains the observational reference data.
    series = (
        SeriesDefinition(
            file_pattern="work/polar_cap_time_series_NH/plot/timeseries_toz_NH_MAR.nc",
            sel={"dim0": 0},
            dimensions={"variable_id": "toz", "statistic": "Northern Hemisphere March polar mean"},
            values_name="toz",
            index_name="time",
            attributes=[],
        ),
    )

    @staticmethod
    def update_recipe(
        recipe: Recipe,
        input_files: dict[SourceDatasetType, pandas.DataFrame],
    ) -> None:
        """Update the recipe."""
        # Make sure only grid cells south of 80N are considered as there are no
        # measurements north of 80N in March. Specifying 85N as northern boundary
        # in the orignal 'recipe_ref_ozone.yml' is a bug!
        recipe["preprocessors"]["create_time_series_NH"]["extract_region"]["end_latitude"] = 80
        recipe_variables = dataframe_to_recipe(input_files[get_cmip_source_type(input_files)])
        dataset = recipe_variables["toz"]["additional_datasets"][0]
        # set model (CMIP6) time range to 1950...2014
        dataset["timerange"] = "1950/2014"
        recipe["datasets"] = [dataset]
        diagnostic = "polar_cap_time_series_NH"
        # adjust plot title to reflect bug fix regarding northern boundary (see above)
        recipe["diagnostics"][diagnostic]["scripts"]["plot"]["plots"]["timeseries"]["pyplot_kwargs"][
            "title"
        ] = "Total Column Ozone, 60-80N, March"
        recipe["diagnostics"] = {diagnostic: recipe["diagnostics"][diagnostic]}

update_recipe(recipe, input_files) staticmethod #

Update the recipe.

Source code in packages/climate-ref-esmvaltool/src/climate_ref_esmvaltool/diagnostics/ozone.py
@staticmethod
def update_recipe(
    recipe: Recipe,
    input_files: dict[SourceDatasetType, pandas.DataFrame],
) -> None:
    """Update the recipe."""
    # Make sure only grid cells south of 80N are considered as there are no
    # measurements north of 80N in March. Specifying 85N as northern boundary
    # in the orignal 'recipe_ref_ozone.yml' is a bug!
    recipe["preprocessors"]["create_time_series_NH"]["extract_region"]["end_latitude"] = 80
    recipe_variables = dataframe_to_recipe(input_files[get_cmip_source_type(input_files)])
    dataset = recipe_variables["toz"]["additional_datasets"][0]
    # set model (CMIP6) time range to 1950...2014
    dataset["timerange"] = "1950/2014"
    recipe["datasets"] = [dataset]
    diagnostic = "polar_cap_time_series_NH"
    # adjust plot title to reflect bug fix regarding northern boundary (see above)
    recipe["diagnostics"][diagnostic]["scripts"]["plot"]["plots"]["timeseries"]["pyplot_kwargs"][
        "title"
    ] = "Total Column Ozone, 60-80N, March"
    recipe["diagnostics"] = {diagnostic: recipe["diagnostics"][diagnostic]}

O3PolarCapTimeseriesSH #

Bases: ESMValToolDiagnostic

Calculate the ozone diagnostics - October SH polar mean (60S-85S) time series.

Source code in packages/climate-ref-esmvaltool/src/climate_ref_esmvaltool/diagnostics/ozone.py
class O3PolarCapTimeseriesSH(ESMValToolDiagnostic):
    """
    Calculate the ozone diagnostics - October SH polar mean (60S-85S) time series.
    """

    name = "Ozone Diagnostics"
    slug = "ozone-sh-oct"
    base_recipe = "ref/recipe_ref_ozone.yml"

    data_requirements = toz_data_requirement
    facets = ()
    test_data_spec = toz_test_spec
    files = (
        FileDefinition(
            file_pattern="plots/polar_cap_time_series_SH/plot/timeseries_toz_SH_Oct.png",
            dimensions={"variable_id": "toz", "statistic": "Southern Hemisphere October polar mean"},
        ),
    )
    # dim0=0 is the model, dim0=1 contains the observational reference data.
    series = (
        SeriesDefinition(
            file_pattern="work/polar_cap_time_series_SH/plot/timeseries_toz_SH_Oct.nc",
            sel={"dim0": 0},
            dimensions={"variable_id": "toz", "statistic": "Southern Hemisphere October polar mean"},
            values_name="toz",
            index_name="time",
            attributes=[],
        ),
    )

    @staticmethod
    def update_recipe(
        recipe: Recipe,
        input_files: dict[SourceDatasetType, pandas.DataFrame],
    ) -> None:
        """Update the recipe."""
        recipe_variables = dataframe_to_recipe(input_files[get_cmip_source_type(input_files)])
        dataset = recipe_variables["toz"]["additional_datasets"][0]
        # set model (CMIP6) time range to 1950...2014
        dataset["timerange"] = "1950/2014"
        recipe["datasets"] = [dataset]
        diagnostic = "polar_cap_time_series_SH"
        recipe["diagnostics"] = {diagnostic: recipe["diagnostics"][diagnostic]}

update_recipe(recipe, input_files) staticmethod #

Update the recipe.

Source code in packages/climate-ref-esmvaltool/src/climate_ref_esmvaltool/diagnostics/ozone.py
@staticmethod
def update_recipe(
    recipe: Recipe,
    input_files: dict[SourceDatasetType, pandas.DataFrame],
) -> None:
    """Update the recipe."""
    recipe_variables = dataframe_to_recipe(input_files[get_cmip_source_type(input_files)])
    dataset = recipe_variables["toz"]["additional_datasets"][0]
    # set model (CMIP6) time range to 1950...2014
    dataset["timerange"] = "1950/2014"
    recipe["datasets"] = [dataset]
    diagnostic = "polar_cap_time_series_SH"
    recipe["diagnostics"] = {diagnostic: recipe["diagnostics"][diagnostic]}

O3ZonalMeanProfiles #

Bases: ESMValToolDiagnostic

Calculate the ozone diagnostics - stratospheric zonal mean profiles.

Source code in packages/climate-ref-esmvaltool/src/climate_ref_esmvaltool/diagnostics/ozone.py
class O3ZonalMeanProfiles(ESMValToolDiagnostic):
    """
    Calculate the ozone diagnostics - stratospheric zonal mean profiles.
    """

    name = "Ozone Diagnostics"
    slug = "ozone-zonal"
    base_recipe = "ref/recipe_ref_ozone.yml"

    data_requirements = (
        DataRequirement(
            source_type=SourceDatasetType.CMIP6,
            filters=(
                FacetFilter(
                    facets={
                        "variable_id": "o3",
                        "experiment_id": "historical",
                        "table_id": "Amon",
                    },
                ),
            ),
            group_by=("source_id", "member_id", "grid_label"),
            constraints=(
                RequireTimerange(
                    group_by=("instance_id",),
                    start=PartialDateTime(2005, 1),
                    end=PartialDateTime(2014, 12),
                ),
                RequireContiguousTimerange(group_by=("instance_id",)),
            ),
        ),
        # TODO: Use ESACCI-OZONE (SAGE-OMPS, variable o3) from obs4MIPs once available.
    )
    facets = ()
    test_data_spec = TestDataSpecification(
        test_cases=(
            TestCase(
                name="cmip6",
                description="Test with CMIP6 data.",
                requests=(
                    CMIP6Request(
                        slug="cmip6",
                        facets={
                            "experiment_id": "historical",
                            "frequency": "mon",
                            "source_id": "GFDL-ESM4",
                            "variable_id": "o3",
                        },
                        remove_ensembles=True,
                        time_span=("1996", "2015"),
                    ),
                ),
            ),
            TestCase(
                name="cmip7",
                description="Test with CMIP7 data.",
                requests=(
                    CMIP7Request(
                        slug="cmip7",
                        facets={
                            "experiment_id": ["historical"],
                            "source_id": "GFDL-ESM4",
                            "variable_id": "o3",
                            "branded_variable": [
                                "o3_tavg-al-hxy-u",
                            ],
                            "variant_label": "r1i1p1f1",
                            "frequency": ["fx", "mon"],
                            "region": "glb",
                        },
                        remove_ensembles=True,
                        time_span=("1980", "2009"),
                    ),
                ),
            ),
        ),
    )

    @staticmethod
    def update_recipe(
        recipe: Recipe,
        input_files: dict[SourceDatasetType, pandas.DataFrame],
    ) -> None:
        """Update the recipe."""
        recipe_variables = dataframe_to_recipe(input_files[get_cmip_source_type(input_files)])
        dataset = recipe_variables["o3"]["additional_datasets"][0]
        # set model (CMIP6) time range to 2005...2014
        dataset["timerange"] = "2005/2014"
        recipe["datasets"] = [dataset]
        diagnostic = "zonal_mean_profiles"
        # adjust plot title to actual time range
        recipe["diagnostics"][diagnostic]["scripts"]["plot"]["plots"]["zonal_mean_profile"]["pyplot_kwargs"][
            "suptitle"
        ] = "{long_name} (2005-2014 mean)"
        recipe["diagnostics"] = {diagnostic: recipe["diagnostics"][diagnostic]}
        recipe["diagnostics"][diagnostic]["variables"]["o3"]["timerange"] = "2005/2014"

update_recipe(recipe, input_files) staticmethod #

Update the recipe.

Source code in packages/climate-ref-esmvaltool/src/climate_ref_esmvaltool/diagnostics/ozone.py
@staticmethod
def update_recipe(
    recipe: Recipe,
    input_files: dict[SourceDatasetType, pandas.DataFrame],
) -> None:
    """Update the recipe."""
    recipe_variables = dataframe_to_recipe(input_files[get_cmip_source_type(input_files)])
    dataset = recipe_variables["o3"]["additional_datasets"][0]
    # set model (CMIP6) time range to 2005...2014
    dataset["timerange"] = "2005/2014"
    recipe["datasets"] = [dataset]
    diagnostic = "zonal_mean_profiles"
    # adjust plot title to actual time range
    recipe["diagnostics"][diagnostic]["scripts"]["plot"]["plots"]["zonal_mean_profile"]["pyplot_kwargs"][
        "suptitle"
    ] = "{long_name} (2005-2014 mean)"
    recipe["diagnostics"] = {diagnostic: recipe["diagnostics"][diagnostic]}
    recipe["diagnostics"][diagnostic]["variables"]["o3"]["timerange"] = "2005/2014"