def detect_poison(self, **kwargs) -> tuple[dict, list[int]]:
        """
        Returns poison detected and a report.

        :return: (report, is_clean_lst):
                where a report is a dictionary containing the index as keys the outlier score of suspected poisons as
                values where is_clean is a list, where is_clean_lst[i]=1 means that x_train[i] there is clean and
                is_clean_lst[i]=0, means that x_train[i] was classified as poison.
        """
        self.set_params(**kwargs)

        if self.classifier.layer_names is not None:
            nb_layers = len(self.classifier.layer_names)
        else:
            raise ValueError("No layer names identified.")
        features_x_poisoned = self.classifier.get_activations(
            self.x_train, layer=nb_layers - 1, batch_size=self.batch_size
        )
        if not isinstance(features_x_poisoned, np.ndarray):
            raise ValueError("Wrong type detected.")

        if features_x_poisoned is not None:
            # flatten activations across batch
            features_x_poisoned = np.reshape(features_x_poisoned, (features_x_poisoned.shape[0], -1))
            features_split = segment_by_class(features_x_poisoned, self.y_train, self.classifier.nb_classes)
        else:
            raise ValueError("Activation are `None`.")
        score_by_class = []
        keep_by_class = []

        for idx, feature in enumerate(features_split):
            # Check for empty list
            if len(feature):
                score = SpectralSignatureDefense.spectral_signature_scores(np.vstack(feature))  # type: ignore
                score_cutoff = np.quantile(score, max(1 - self.eps_multiplier * self.expected_pp_poison, 0.0))
                score_by_class.append(score)
                keep_by_class.append(score < score_cutoff)
            else:
                score_by_class.append([0])  # type: ignore
                keep_by_class.append([True])

        base_indices_by_class = segment_by_class(
            np.arange(self.y_train.shape[0]),
            self.y_train,
            self.classifier.nb_classes,
        )
        is_clean_lst = [0] * self.y_train.shape[0]
        report = {}

        for keep_booleans, all_scores, indices in zip(keep_by_class, score_by_class, base_indices_by_class):
            for keep_boolean, all_score, idx in zip(keep_booleans, all_scores, indices):
                if keep_boolean:
                    is_clean_lst[idx] = 1
                else:
                    report[idx] = all_score[0]

        return report, is_clean_lst

        Returns poison detected and a report.

        :return: (report, is_clean_lst):
                where a report is a dictionary containing the index as keys the outlier score of suspected poisons as
                values where is_clean is a list, where is_clean_lst[i]=1 means that x_train[i] there is clean and
                is_clean_lst[i]=0, means that x_train[i] was classified as poison.
        
art/defences/detector/poison/spectral_signature_defense.py