def process_input(
    model: ForecastingModel,
    input_type: str,
    series: Optional[Union[TimeSeries, Sequence[TimeSeries]]] = None,
    past_covariates: Optional[Union[TimeSeries, Sequence[TimeSeries]]] = None,
    future_covariates: Optional[Union[TimeSeries, Sequence[TimeSeries]]] = None,
    fallback_series: Optional[Union[TimeSeries, Sequence[TimeSeries]]] = None,
    fallback_past_covariates: Optional[Union[TimeSeries, Sequence[TimeSeries]]] = None,
    fallback_future_covariates: Optional[
        Union[TimeSeries, Sequence[TimeSeries]]
    ] = None,
    check_component_names: bool = False,
    requires_input: bool = True,
    requires_covariates_encoding: bool = False,
    test_stationarity: bool = False,
):
    """Helper function to process and check either of the background or foreground series input to
    `_ForecastingModelExplainer`.

    If no input was provided (`series`, `past/future_covariates`), the fallback will be used for downstream tasks.
    Will raise an error if both input and fallback are not available.

    The fallback is dependent on the input type ("background" or "foreground"):
    - for background `input_type`: fallback are the series saved in fitted forecasting model
    - for foreground `input_type`: fallback are the background series from `_ForecastingModelExplainer`

    Parameters
    ----------
    model
        any `ForecastingModel`.
    input_type
        the type of input series. Either "background" or "foreground"
    series
         Optionally, one or a sequence of target `TimeSeries`.
    past_covariates
         Optionally, one or a sequence of past covariates `TimeSeries`.
    future_covariates
         Optionally, one or a sequence of future covariates `TimeSeries`.
    fallback_series
        Optionally, one or a sequence of target `TimeSeries` to fall back to in case `series` was not provided.
    fallback_past_covariates
        Optionally, one or a sequence of past covariates `TimeSeries` to fall back to in case `past_covariates` was
        not provided.
    fallback_future_covariates
        Optionally, one or a sequence of future covariates `TimeSeries` to fall back to in case `future_covariates` was
        not provided.
    check_component_names
        Whether to enforce that, in the case of multiple time series, all series of the same type (target or
        *_covariates) must have the same component names.
    requires_input
        Whether the input is required. If `True`, raises an error if no input was provided.
    requires_covariates_encoding
        Whether to apply the model's encoders to the input covariates. This should only be `True` if the
        Explainer will not call model methods `fit()` or `predict()` directly.
    test_stationarity
        Whether to raise a warning if not all components from the target `series` are stationary.
    """
    if input_type not in ["background", "foreground"]:
        raise_log(
            ValueError(
                f"Unknown `input_type='{input_type}'`. Must be one of ['background', 'foreground']."
            ),
            logger,
        )

    # if any input is given, treat it as if the input was required
    if (
        series is not None
        or past_covariates is not None
        or future_covariates is not None
    ):
        requires_input = True

    # if `series` was not passed, use the fallback input
    # - for background input type: fallback are the series saved in fitted forecasting model
    # - for foreground input type: fallback are the background series from `_ForecastingModelExplainer`
    if series is None:
        raise_if(
            (past_covariates is not None) or (future_covariates is not None),
            f"Supplied {input_type} past or future covariates but no {input_type} series. Please also provide "
            f"`{input_type}_series`.",
            logger,
        )
        if requires_input and fallback_series is None:
            error_msg = (
                "`model` was fit on multiple time series."
                if input_type == "background"
                else "no `background_series` was provided at `Explainer` creation"
            )
            raise_log(
                ValueError(f"`{input_type}_series` must be provided {error_msg}"),
                logger,
            )
        series = fallback_series
        past_covariates = fallback_past_covariates
        future_covariates = fallback_future_covariates
    # otherwise use the passed input, and generate the covariate encodings (they will be removed again later on
    # if `requires_covariates_encoding=False`)
    else:
        if model.encoders.encoding_available:
            past_covariates, future_covariates = model.generate_fit_encodings(
                series=series,
                past_covariates=past_covariates,
                future_covariates=future_covariates,
            )

    series = series2seq(series)
    past_covariates = series2seq(past_covariates)
    future_covariates = series2seq(future_covariates)

    (
        target_components,
        static_covariates_components,
        past_covariates_components,
        future_covariates_components,
    ) = get_component_names(
        series=series,
        past_covariates=past_covariates,
        future_covariates=future_covariates,
    )

    _check_valid_input(
        model,
        input_type,
        series,
        past_covariates,
        future_covariates,
        target_components,
        past_covariates_components,
        future_covariates_components,
        check_component_names=check_component_names,
        requires_input=requires_input,
        test_stationarity=test_stationarity,
    )

    # make sure to remove any encodings from covariates if downstream tasks require covariates without encodings
    if not requires_covariates_encoding and model.encoders.encoding_available:
        if past_covariates is not None and model.encoders.past_encoders:
            cov = past_covariates[0]
            encoded = model.encoders.past_components
            drop_cols = cov.components[cov.components.isin(encoded)]
            if not drop_cols.empty and len(drop_cols) == cov.n_components:
                past_covariates = None
            elif not drop_cols.empty:
                past_covariates = [
                    cov[cov.components.drop(drop_cols).tolist()]
                    for cov in past_covariates
                ]
        if future_covariates is not None and model.encoders.future_encoders:
            cov = future_covariates[0]
            encoded = model.encoders.future_components
            drop_cols = cov.components[cov.components.isin(encoded)]
            if not drop_cols.empty and len(drop_cols) == cov.n_components:
                future_covariates = None
            elif not drop_cols.empty:
                future_covariates = [
                    cov[cov.components.drop(drop_cols).tolist()]
                    for cov in future_covariates
                ]
    return (
        series,
        past_covariates,
        future_covariates,
        target_components,
        static_covariates_components,
        past_covariates_components,
        future_covariates_components,
    )
Helper function to process and check either of the background or foreground series input to
    `_ForecastingModelExplainer`.

    If no input was provided (`series`, `past/future_covariates`), the fallback will be used for downstream tasks.
    Will raise an error if both input and fallback are not available.

    The fallback is dependent on the input type ("background" or "foreground"):
    - for background `input_type`: fallback are the series saved in fitted forecasting model
    - for foreground `input_type`: fallback are the background series from `_ForecastingModelExplainer`

    Parameters
    ----------
    model
        any `ForecastingModel`.
    input_type
        the type of input series. Either "background" or "foreground"
    series
         Optionally, one or a sequence of target `TimeSeries`.
    past_covariates
         Optionally, one or a sequence of past covariates `TimeSeries`.
    future_covariates
         Optionally, one or a sequence of future covariates `TimeSeries`.
    fallback_series
        Optionally, one or a sequence of target `TimeSeries` to fall back to in case `series` was not provided.
    fallback_past_covariates
        Optionally, one or a sequence of past covariates `TimeSeries` to fall back to in case `past_covariates` was
        not provided.
    fallback_future_covariates
        Optionally, one or a sequence of future covariates `TimeSeries` to fall back to in case `future_covariates` was
        not provided.
    check_component_names
        Whether to enforce that, in the case of multiple time series, all series of the same type (target or
        *_covariates) must have the same component names.
    requires_input
        Whether the input is required. If `True`, raises an error if no input was provided.
    requires_covariates_encoding
        Whether to apply the model's encoders to the input covariates. This should only be `True` if the
        Explainer will not call model methods `fit()` or `predict()` directly.
    test_stationarity
        Whether to raise a warning if not all components from the target `series` are stationary.
    
darts/explainability/utils.py