def analyze_correctness(
        self, assigned_clean_by_class: np.ndarray | list[int] | list[np.ndarray], is_clean_by_class: list
    ) -> tuple[np.ndarray, str]:
        """
        For each training sample, determine whether the activation clustering method was correct.

        :param assigned_clean_by_class: Result of clustering.
        :param is_clean_by_class: is clean separated by class.
        :return: Two variables are returned:
                 1) all_errors_by_class[i]: an array indicating the correctness of each assignment
                 in the ith class. Such that:
                 all_errors_by_class[i] = 0 if marked poison, is poison
                 all_errors_by_class[i] = 1 if marked clean, is clean
                 all_errors_by_class[i] = 2 if marked poison, is clean
                 all_errors_by_class[i] = 3 marked clean, is poison
                 2) Json object with confusion matrix per-class.
        """
        all_errors_by_class = []
        poison = 0
        clean = 1
        dic_json = {}

        logger.debug("Error rates per class:")
        for class_i, (assigned_clean, is_clean) in enumerate(zip(assigned_clean_by_class, is_clean_by_class)):
            errors = []
            for assignment, bl_var in zip(assigned_clean, is_clean):
                bl_var = int(bl_var)
                # marked poison, is poison = 0
                # true positive
                if assignment == poison and bl_var == poison:
                    errors.append(0)

                # marked clean, is clean = 1
                # true negative
                elif assignment == clean and bl_var == clean:
                    errors.append(1)

                # marked poison, is clean = 2
                # false positive
                elif assignment == poison and bl_var == clean:
                    errors.append(2)

                # marked clean, is poison = 3
                # false negative
                elif assignment == clean and bl_var == poison:
                    errors.append(3)
                else:
                    raise Exception("Analyze_correctness entered wrong class")

            errors_array = np.asarray(errors)
            logger.debug("-------------------%d---------------", class_i)
            key_i = "class_" + str(class_i)
            matrix_i = self.get_confusion_matrix(errors_array)
            dic_json.update({key_i: matrix_i})
            all_errors_by_class.append(errors_array)

        all_errors_by_class_array = np.asarray(all_errors_by_class, dtype=object)
        conf_matrix_json = json.dumps(dic_json)

        return all_errors_by_class_array, conf_matrix_json

        For each training sample, determine whether the activation clustering method was correct.

        :param assigned_clean_by_class: Result of clustering.
        :param is_clean_by_class: is clean separated by class.
        :return: Two variables are returned:
                 1) all_errors_by_class[i]: an array indicating the correctness of each assignment
                 in the ith class. Such that:
                 all_errors_by_class[i] = 0 if marked poison, is poison
                 all_errors_by_class[i] = 1 if marked clean, is clean
                 all_errors_by_class[i] = 2 if marked poison, is clean
                 all_errors_by_class[i] = 3 marked clean, is poison
                 2) Json object with confusion matrix per-class.
        
art/defences/detector/poison/ground_truth_evaluator.py