def scan(
        self,
        clean_x: np.ndarray,
        adv_x: np.ndarray,
        clean_size: int | None = None,
        adv_size: int | None = None,
        run: int = 10,
    ) -> tuple[np.ndarray, np.ndarray, float]:
        """
        Returns scores of highest scoring subsets.

        :param clean_x: Data presumably without anomalies.
        :param adv_x: Data presumably with anomalies (adversarial samples).
        :param clean_size:
        :param adv_size:
        :param run:
        :return: (clean_scores, adv_scores, detection_power).
        """
        clean_pval_ranges = self._calculate_pvalue_ranges(clean_x)
        adv_pval_ranges = self._calculate_pvalue_ranges(adv_x)

        clean_scores = []
        adv_scores = []

        if clean_size is None or adv_size is None:
            # Individual scan
            with tqdm(
                total=len(clean_pval_ranges) + len(adv_pval_ranges), desc="Subset scanning", disable=not self.verbose
            ) as pbar:
                for _, c_p in enumerate(clean_pval_ranges):
                    best_score, _, _, _ = Scanner.fgss_individ_for_nets(c_p, score_function=self.scoring_function)
                    clean_scores.append(best_score)
                    pbar.update(1)
                for _, a_p in enumerate(adv_pval_ranges):
                    best_score, _, _, _ = Scanner.fgss_individ_for_nets(a_p, score_function=self.scoring_function)
                    adv_scores.append(best_score)
                    pbar.update(1)

        else:
            len_adv_x = len(adv_x)
            len_clean_x = len(clean_x)

            for _ in trange(run, desc="Subset scanning", disable=not self.verbose):
                np.random.seed()

                clean_choice = np.random.choice(range(len_clean_x), clean_size, replace=False)
                adv_choice = np.random.choice(range(len_adv_x), adv_size, replace=False)

                combined_pvals = np.concatenate((clean_pval_ranges[clean_choice], adv_pval_ranges[adv_choice]), axis=0)

                best_score, _, _, _ = Scanner.fgss_for_nets(
                    clean_pval_ranges[clean_choice], score_function=self.scoring_function
                )
                clean_scores.append(best_score)
                best_score, _, _, _ = Scanner.fgss_for_nets(combined_pvals, score_function=self.scoring_function)
                adv_scores.append(best_score)

        clean_scores_array = np.asarray(clean_scores)
        adv_scores_array = np.asarray(adv_scores)

        y_true = np.concatenate([np.ones(len(adv_scores)), np.zeros(len(clean_scores))])
        all_scores = np.concatenate([adv_scores, clean_scores])

        fpr, tpr, _ = metrics.roc_curve(y_true, all_scores)
        roc_auc: float = metrics.auc(fpr, tpr)
        detection_power = roc_auc

        return clean_scores_array, adv_scores_array, detection_power

        Returns scores of highest scoring subsets.

        :param clean_x: Data presumably without anomalies.
        :param adv_x: Data presumably with anomalies (adversarial samples).
        :param clean_size:
        :param adv_size:
        :param run:
        :return: (clean_scores, adv_scores, detection_power).
        
art/defences/detector/evasion/subsetscanning/detector.py