#!/usr/bin/env python
# (C) Crown Copyright, Met Office. All rights reserved.
#
# This file is part of 'IMPROVER' and is released under the BSD 3-Clause license.
# See LICENSE in the root of the repository for full licensing details.
"""Script to apply coefficients for Ensemble Model Output
Statistics (EMOS), otherwise known as Non-homogeneous Gaussian
Regression (NGR)."""
from improver import cli
[docs]
@cli.clizefy
@cli.with_output
def process(
*cubes: cli.inputcubelist,
validity_times: cli.comma_separated_list = None,
realizations_count: int = None,
randomise=False,
random_seed: int = None,
ignore_ecc_bounds_exceedance=False,
tolerate_time_mismatch=False,
predictor="mean",
land_sea_mask_name: str = None,
percentiles: cli.comma_separated_list = None,
):
"""Applying coefficients for Ensemble Model Output Statistics.
Load in arguments for applying coefficients for Ensemble Model Output
Statistics (EMOS), otherwise known as Non-homogeneous Gaussian
Regression (NGR). The coefficients are applied to the forecast
that is supplied, so as to calibrate the forecast. The calibrated
forecast is written to a cube. If no coefficients are provided the input
forecast is returned unchanged.
Args:
input_cubes (iris.cube.CubeList):
A list of cubes containing:
- A Cube containing the forecast to be calibrated. The input format
could be either realizations, probabilities or percentiles.
- A cubelist containing the coefficients used for calibration or None.
If none then the input, or probability template if provided,
is returned unchanged.
- Optionally, cubes representing static additional predictors.
These static additional predictors are expected not to have a
time coordinate.
- Optionally, a cube containing the land-sea mask on the same domain
as the forecast that is to be calibrated. Land points are
specified by ones and sea points are specified by zeros.
The presence of a land-sea mask will enable land-only calibration, in
which sea points are returned without the application of
calibration. If a land-sea mask is provided, the land_sea_mask_name
must also be provided, in order to identify the land-sea mask.
- Optionally, a cube containing a probability forecast that will be
used as a template when generating probability output when the input
format of the forecast cube is not probabilities i.e. realizations
or percentiles. If no coefficients are provided and a probability
template is provided, the probability template forecast will be
returned as the uncalibrated probability forecast.
validity_times (List[str]):
Times at which the forecast must be valid. This must be provided
as a four digit string (HHMM) where the first two digits represent the hour
and the last two digits represent the minutes e.g. 0300 or 0315. If the
forecast provided is at a different validity time then no coefficients
will be applied.
realizations_count (int):
Option to specify the number of ensemble realizations that will be
created from probabilities or percentiles when applying the EMOS
coefficients.
randomise (bool):
Option to reorder the post-processed forecasts randomly. If not
set, the ordering of the raw ensemble is used. This option is
only valid when the input format is realizations.
random_seed (int):
Option to specify a value for the random seed for testing
purposes, otherwise the default random seen behaviour is utilised.
The random seed is used in the generation of the random numbers
used for either the randomise option to order the input
percentiles randomly, rather than use the ordering from the raw
ensemble, or for splitting tied values within the raw ensemble,
so that the values from the input percentiles can be ordered to
match the raw ensemble.
ignore_ecc_bounds_exceedance (bool):
If True, where the percentiles exceed the ECC bounds range,
raises a warning rather than an exception. This occurs when the
current forecasts is in the form of probabilities and is
converted to percentiles, as part of converting the input
probabilities into realizations.
tolerate_time_mismatch (bool):
If True, tolerate a mismatch in validity time and forecast period
for coefficients vs forecasts. Use with caution!
predictor (str):
String to specify the form of the predictor used to calculate
the location parameter when estimating the EMOS coefficients.
Currently the ensemble mean ("mean") and the ensemble
realizations ("realizations") are supported as the predictors.
land_sea_mask_name (str):
Name of the land-sea mask cube. This must be provided if a
land-sea mask is provided within the list of input cubes, in
order to identify the land-sea mask. Providing the land-sea mask
ensures that only land points will be calibrated.
percentiles (List[float]):
The set of percentiles used to create the calibrated forecast.
Returns:
iris.cube.Cube:
The calibrated forecast cube.
"""
from improver.calibration import (
split_forecasts_and_coeffs,
)
from improver.calibration.emos_calibration import ApplyEMOS
from improver.calibration.utilities import prepare_cube_no_calibration
(forecast, coefficients, additional_predictors, land_sea_mask, prob_template) = (
split_forecasts_and_coeffs(cubes, land_sea_mask_name)
)
uncalibrated_forecast = prepare_cube_no_calibration(
forecast,
coefficients,
ignore_ecc_bounds_exceedance=ignore_ecc_bounds_exceedance,
validity_times=validity_times,
percentiles=percentiles,
prob_template=prob_template,
)
if uncalibrated_forecast is not None:
return uncalibrated_forecast
calibration_plugin = ApplyEMOS(percentiles=percentiles)
result = calibration_plugin(
forecast,
coefficients,
additional_fields=additional_predictors,
land_sea_mask=land_sea_mask,
prob_template=prob_template,
realizations_count=realizations_count,
ignore_ecc_bounds=ignore_ecc_bounds_exceedance,
tolerate_time_mismatch=tolerate_time_mismatch,
predictor=predictor,
randomise=randomise,
random_seed=random_seed,
)
return result