Source code for improver.cli.normalise_to_reference

#!/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.
"""CLI to enforce the sum total of a set of forecasts to be equal to a reference."""

from improver import cli


[docs] @cli.clizefy @cli.with_output def process( *cubes: cli.inputcubelist, reference_name: str, return_name: str, ignore_zero_total: bool = False, ): """Module to enforce that the sum of data in a list of cubes is equal to the corresponding data in a reference cube. Only one of the updated cubes is returned. The data are updated as follows, if there are 2 cubes to be normalised containing data points a and b respectively with corresponding reference r, then: a_new = r * (a / (a + b)) b_new = r * (b / (a + b)) which ensures that r = a_new + b_new. Args: cubes (List of iris.cube.Cube): A list of cubes containing both the cubes to be updated and the reference cube. The reference cube will be identified by matching the cube name to reference_name. reference_name (str): The name of the reference cube, this must match exactly one cube in cubes. return_name (str): The name of the cube to be returned. this must match exactly one cube in cubes. ignore_zero_total (bool): Determines whether an error will be raised in the instance where the total of non-reference cubes is zero but the corresponding value in reference is non-zero. If True this error will not be raised - instead the data in the updated cubes will remain as zero values, if False an error will be raised. Returns: iris.cube.Cube: The cube in cubes with name matching return_name. The data in the cube will have been updated, but the metadata will be identical. """ from improver.utilities.flatten import flatten from improver.utilities.forecast_reference_enforcement import ( normalise_to_reference, split_cubes_by_name, ) cubes = flatten(cubes) reference_cube, input_cubes = split_cubes_by_name(cubes, reference_name) if len(reference_cube) == 1: reference_cube = reference_cube[0] else: msg = ( f"Exactly one cube with a name matching reference_name is required, but " f"{len(reference_cube)} were found." ) raise ValueError(msg) output = normalise_to_reference(input_cubes, reference_cube, ignore_zero_total) output = output.extract_cube(return_name) return output