def test_explainer_single_univariate_multivariate_series(self, test_case):
        """Test TFTExplainer with single univariate and multivariate series and a combination of
        encoders, covariates, and addition of relative index."""
        series_option, cov_option, add_relative_idx, use_encoders = test_case
        series, pc, fc = self.helper_get_input(series_option)
        cov_test_case = dict()
        use_pc, use_fc = False, False
        if "past_covariates" in cov_option:
            cov_test_case["past_covariates"] = pc
            use_pc = True
        if "future_covariates" in cov_option:
            cov_test_case["future_covariates"] = fc
            use_fc = True

        # expected number of features for past covs, future covs, and static covs, and encoder/decoder
        n_target_expected = series.n_components
        n_pc_expected = 1 if "past_covariates" in cov_test_case else 0
        n_fc_expected = 1 if "future_covariates" in cov_test_case else 0
        n_sc_expected = 2
        # encoder is number of past and future covs plus 4 optional encodings (future and past)
        # plus 1 univariate target plus 1 optional relative index
        n_enc_expected = (
            n_pc_expected
            + n_fc_expected
            + n_target_expected
            + (4 if use_encoders else 0)
            + (1 if add_relative_idx else 0)
        )
        # encoder is number of future covs plus 2 optional encodings (future)
        # plus 1 optional relative index
        n_dec_expected = (
            n_fc_expected + (2 if use_encoders else 0) + (1 if add_relative_idx else 0)
        )
        model = self.helper_create_model(
            use_encoders=use_encoders, add_relative_idx=add_relative_idx
        )
        # TFTModel requires future covariates
        if (
            not add_relative_idx
            and "future_covariates" not in cov_test_case
            and not use_encoders
        ):
            with pytest.raises(ValueError):
                model.fit(series=series, **cov_test_case)
            return

        model.fit(series=series, **cov_test_case)
        explainer = TFTExplainer(model)
        explainer2 = TFTExplainer(
            model,
            background_series=series,
            background_past_covariates=pc if use_pc else None,
            background_future_covariates=fc if use_fc else None,
        )
        assert explainer.background_series == explainer2.background_series
        assert (
            explainer.background_past_covariates
            == explainer2.background_past_covariates
        )
        assert (
            explainer.background_future_covariates
            == explainer2.background_future_covariates
        )

        assert hasattr(explainer, "model")
        assert explainer.background_series[0] == series
        if use_pc:
            assert explainer.background_past_covariates[0] == pc
            assert explainer.background_past_covariates[0].n_components == n_pc_expected
        else:
            assert explainer.background_past_covariates is None
        if use_fc:
            assert explainer.background_future_covariates[0] == fc
            assert (
                explainer.background_future_covariates[0].n_components == n_fc_expected
            )
        else:
            assert explainer.background_future_covariates is None
        result = explainer.explain()
        assert isinstance(result, TFTExplainabilityResult)

        enc_imp = result.get_encoder_importance()
        dec_imp = result.get_decoder_importance()
        stc_imp = result.get_static_covariates_importance()
        imps = [enc_imp, dec_imp, stc_imp]
        assert all([isinstance(imp, pd.DataFrame) for imp in imps])
        # importances must sum up to 100 percent
        assert all([
            imp.squeeze().sum() == pytest.approx(100.0, rel=0.2) for imp in imps
        ])
        # importances must have the expected number of columns
        assert all([
            len(imp.columns) == n
            for imp, n in zip(imps, [n_enc_expected, n_dec_expected, n_sc_expected])
        ])

        attention = result.get_attention()
        assert isinstance(attention, TimeSeries)
        # input chunk length + output chunk length = 5 + 2 = 7
        icl, ocl = 5, 2
        freq = series.freq
        assert len(attention) == icl + ocl
        assert attention.start_time() == series.end_time() - (icl - 1) * freq
        assert attention.end_time() == series.end_time() + ocl * freq
        assert attention.n_components == ocl
Test TFTExplainer with single univariate and multivariate series and a combination of
        encoders, covariates, and addition of relative index.
darts/tests/explainability/test_tft_explainer.py