def METHOD_NAME(
    self,
    performance_df,
    validation_df,
    selection_threshold=None,
    use_labels=True,
    method="soft",
):
    """
    Computes hard or soft voting based on the probabilities in performance_df. Weights are computed based
    on the balanced accuracies of validation_df.
    ref: S. Raschka. Python Machine Learning., 2015
    Args:
        performance_df (pd.DataFrame): Results that need to be assembled.
        validation_df (pd.DataFrame): Results on the validation set used to compute the performance
            of each separate part of the image.
        selection_threshold (float): with soft-voting method, allows to exclude some parts of the image
            if their associated performance is too low.
        use_labels (bool): If True, metrics are computed and the label column values must be different
            from None.
        method (str): method to assemble the results. Current implementation proposes soft or hard-voting.
    Returns:
        df_final (pd.DataFrame) the results on the image level
        results (Dict[str, float]) the metrics on the image level
    """
    def check_prediction(row):
        if row["true_label"] == row["predicted_label"]:
            return 1
        else:
            return 0
    if method == "soft":
        # Compute the sub-level accuracies on the validation set:
        validation_df["accurate_prediction"] = validation_df.apply(
            lambda x: check_prediction(x), axis=1
        )
        sub_level_accuracies = validation_df.groupby(f"{self.mode}_id")[
            "accurate_prediction"
        ].mean()
        if selection_threshold is not None:
            sub_level_accuracies[sub_level_accuracies < selection_threshold] = 0
        weight_series = sub_level_accuracies / sub_level_accuracies.sum()
    elif method == "hard":
        n_modes = validation_df[f"{self.mode}_id"].nunique()
        weight_series = pd.DataFrame(np.ones((n_modes, 1)))
    else:
        raise NotImplementedError(
            f"Ensemble method {method} was not implemented. "
            f"Please choose in ['hard', 'soft']."
        )
    # Sort to allow weighted average computation
    performance_df.sort_values(
        ["participant_id", "session_id", f"{self.mode}_id"], inplace=True
    )
    weight_series.sort_index(inplace=True)
    # Soft majority vote
    df_final = pd.DataFrame(columns=self.columns)
    for (subject, session), subject_df in performance_df.groupby(
        ["participant_id", "session_id"]
    ):
        label = subject_df["true_label"].unique().item()
        proba_list = [
            np.average(subject_df[f"proba{i}"], weights=weight_series)
            for i in range(self.n_classes)
        ]
        prediction = proba_list.index(max(proba_list))
        row = [[subject, session, 0, label, prediction] + proba_list]
        row_df = pd.DataFrame(row, columns=self.columns)
        df_final = pd.concat([df_final, row_df])
    if use_labels:
        results = self.compute_metrics(df_final)
    else:
        results = None
    return df_final, results