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