def process(cube: cli.inputcube, advection_velocity: inputadvection, orographic_enhancement: cli.inputcube = None, *, attributes_config: cli.inputjson = None, max_lead_time: int = 360, lead_time_interval: int = 15): """Module to extrapolate input cubes given advection velocity fields. Args: cube (iris.cube.Cube): The data to be advected. advection_velocity (iris.cube.CubeList): Advection cubes of U and V. These must have the names of. precipitation_advection_x_velocity precipitation_advection_y_velocity orographic_enhancement (iris.cube.Cube): Cube containing orographic enhancement forecasts for the lead times at which an extrapolation nowcast is required. attributes_config (dict): Dictionary containing the required changes to the attributes. max_lead_time (int): Maximum lead time required (mins). lead_time_interval (int): Interval between required lead times (mins). Returns: iris.cube.CubeList: New cubes with updated time and extrapolated data. """ from improver.nowcasting.forecasting import CreateExtrapolationForecast from improver.utilities.cube_manipulation import merge_cubes u_cube, v_cube = advection_velocity # extrapolate input data to required lead times forecast_plugin = CreateExtrapolationForecast( cube, u_cube, v_cube, orographic_enhancement, attributes_dict=attributes_config) forecast_cubes = forecast_plugin.process(lead_time_interval, max_lead_time) return merge_cubes(forecast_cubes)
def process(input_cube, u_cube, v_cube, speed_cube, direction_cube, orographic_enhancement_cube=None, attributes_dict=None, max_lead_time=360, lead_time_interval=15, accumulation_fidelity=0, accumulation_period=15, accumulation_units='m'): """Module to extrapolate input cubes given advection velocity fields. Args: input_cube (iris.cube.Cube): The input Cube to be processed. u_cube (iris.cube.Cube): Cube with the velocities in the x direction. Must be used with v_cube. s_cube and d_cube must be None. v_cube (iris.cube.Cube): Cube with the velocities in the y direction. Must be used with u_cube. s_cube and d_cube must be None. speed_cube (iris.cube.Cube): Cube containing advection speeds, usually wind speed. Must be used with d_cube. u_cube and v_cube must be None. direction_cube (iris.cube.Cube): Cube from which advection speeds are coming. The directions should be on the same grid as the input speeds, including the same vertical levels. Must be used with d_cube. u_cube and v_cube must be None. orographic_enhancement_cube (iris.cube.Cube): Cube containing the orographic enhancement fields. May have data for multiple times in the cube. Default is None. attributes_dict (dict): Dictionary containing the required changes to the attributes. Default is None. max_lead_time (int): Maximum lead time required (mins). Default is 360. lead_time_interval (int): Interval between required lead times (mins). Default is 15. accumulation_fidelity (int): If set, this will additionally return accumulations calculated from the advected fields. This fidelity specifies the time interval in minutes between advected fields that is used to calculate these accumulations. This interval must be a factor of the lead_time_interval. Default is 0. accumulation_period (int): The period over which the accumulation is calculated (mins). Only full accumulation periods will be computed. At lead times that are shorter than the accumulation period, no accumulation output will be produced. accumulation_units (str): Desired units in which the accumulations should be expressed. e.g. 'mm' Default is 'm'. Returns: (tuple): tuple containing: **accumulation_cubes** (iris.cube.CubeList): A cubelist containing precipitation accumulation cubes where the accumulation periods are determined by the lead_time_interval. **forecast_to_return** (iris.cube.CubeList): New cubes with updated time and extrapolated data. Raises: ValueError: can either use s_cube and d_cube or u_cube and v_cube. Therefore: (s and d)⊕(u and v) ValueError: If accumulation_fidelity is greater than 0 and max_lead_time is not cleanly divisible by accumulation_fidelity. """ if (speed_cube and direction_cube) and not (u_cube or v_cube): u_cube, v_cube = ResolveWindComponents().process( speed_cube, direction_cube) elif (u_cube or v_cube) and (speed_cube or direction_cube): raise ValueError('Cannot mix advection component velocities with speed' ' and direction') # determine whether accumulations are also to be returned, and modify time # interval if finer intervals are needed for accumulations time_interval = lead_time_interval if accumulation_fidelity > 0: fraction, _ = np.modf(max_lead_time / accumulation_fidelity) if fraction != 0: msg = ("The specified lead_time_interval ({}) is not cleanly " "divisible by the specified accumulation_fidelity ({}). As " "a result the lead_time_interval cannot be constructed from" " accumulation cubes at this fidelity.") raise ValueError( msg.format(lead_time_interval, accumulation_fidelity)) time_interval = accumulation_fidelity # extrapolate input data to required lead times forecast_plugin = CreateExtrapolationForecast( input_cube, u_cube, v_cube, orographic_enhancement_cube=orographic_enhancement_cube, attributes_dict=attributes_dict) forecast_cubes = forecast_plugin.process(time_interval, max_lead_time) # calculate accumulations if required accumulation_cubes = None if accumulation_fidelity > 0: lead_times = (np.arange(lead_time_interval, max_lead_time + 1, lead_time_interval)) plugin = Accumulation(accumulation_units=accumulation_units, accumulation_period=accumulation_period * 60, forecast_periods=lead_times * 60) accumulation_cubes = plugin.process(forecast_cubes) # filter out rate forecasts that are not required lead_time_filter = lead_time_interval // time_interval forecast_to_return = forecast_cubes[::lead_time_filter].copy() return accumulation_cubes, forecast_to_return