code: def evaluate_bounds(
      estimated_bounds: Dict[str, pd.DataFrame],
      bin_predictions: Dict[str, pd.DataFrame],
      uncertainty_pairs: List,
      num_bins: int,
      targets: List[int],
      num_folds: int = 8,
      show_fig: bool = False,
      combine_middle_bins: bool = False,
  ) -> Dict:
      """
      Evaluates error bounds for given uncertainty pairs and estimated bounds.
  
      Args:
          estimated_bounds (Dict[str, pd.DataFrame]): Dictionary of error bounds for each model.
          bin_predictions (Dict[str, pd.DataFrame]): Dictionary of bin predictions for each model.
          uncertainty_pairs (List[List[str]]): List of uncertainty pairs to be evaluated.
          num_bins (int): Number of bins to be used.
          targets (List[str]): List of targets to be evaluated.
          num_folds (int, optional): Number of folds for cross-validation. Defaults to 8.
          show_fig (bool, optional): Flag to show the figure. Defaults to False.
          combine_middle_bins (bool, optional): Flag to combine the middle bins. Defaults to False.
  
      Returns:
          Dict: Dictionary containing evaluation results.
      """
  
      if combine_middle_bins:
          num_bins = 3
  
      # Initialize results dicts
      all_bound_percents = {}
      all_bound_percents_notargetsep = {}
  
      all_concat_errorbound_bins_target_sep_foldwise = [
          {} for x in range(len(targets))
      ]  # type: List[Dict]
      all_concat_errorbound_bins_target_sep_all = [
          {} for x in range(len(targets))
      ]  # type: List[Dict]
  
      # Loop over combinations of models (model) and uncertainty types (uncert_pair)
      for i, (model, data_structs) in enumerate(
          bin_predictions.items()
      ):
          error_bounds = estimated_bounds[model + " Error Bounds"]
  
          for uncert_pair in uncertainty_pairs:
              uncertainty_type = uncert_pair[0]
  
              fold_learned_bounds_mean_targets = []
              fold_learned_bounds_mean_bins = [
                  [] for x in range(num_bins)
              ]  # type: List[List]
              fold_learned_bounds_bins_targetsnotsep = [
                  [] for x in range(num_bins)
              ]  # type: List[List]
              fold_all_bins_concat_targets_sep_foldwise = [
                  [[] for y in range(num_bins)]
                  for x in range(len(targets))
              ]  # type: List[List]
              fold_all_bins_concat_targets_sep_all = [
                  [[] for y in range(num_bins)]
                  for x in range(len(targets))
              ]  # type: List[List]
  
              for fold in range(num_folds):
                  # Get the ids for this fold
                  fold_errors = data_structs[
                      (data_structs["Testing Fold"] == fold)
                  ][["uid", "target_idx", uncertainty_type + " Error"]]
                  fold_bins = data_structs[
                      (data_structs["Testing Fold"] == fold)
                  ][
                      [
                          "uid",
                          "target_idx",
                          uncertainty_type + " Uncertainty bins",
                      ]
                  ]
                  fold_bounds = strip_for_bound(
                      error_bounds[error_bounds["fold"] == fold][
                          uncertainty_type + " Uncertainty bounds"
                      ].values
                  )
  
                  return_dict = bin_wise_bound_eval(
                      fold_bounds,
                      fold_errors,
                      fold_bins,
                      targets,
                      uncertainty_type,
                      num_bins=num_bins,
                      show_fig=show_fig,
                  )
                  fold_learned_bounds_mean_targets.append(
                      return_dict["mean all targets"]
                  )
  
                  for idx_bin in range(
                      len(return_dict["mean all bins"])
                  ):
                      fold_learned_bounds_mean_bins[idx_bin].append(
                          return_dict["mean all bins"][idx_bin]
                      )
                      fold_learned_bounds_bins_targetsnotsep[
                          idx_bin
                      ] = (
                          fold_learned_bounds_bins_targetsnotsep[
                              idx_bin
                          ]
                          + return_dict["mean all"][idx_bin]
                      )
  
                      for target_idx in range(len(targets)):
                          fold_all_bins_concat_targets_sep_foldwise[
                              target_idx
                          ][idx_bin] = (
                              fold_all_bins_concat_targets_sep_foldwise[
                                  target_idx
                              ][idx_bin]
                              + return_dict[
                                  "all bins concatenated targets seperated"
                              ][target_idx][idx_bin]
                          )
                          combined = (
                              fold_all_bins_concat_targets_sep_all[
                                  target_idx
                              ][idx_bin]
                              + return_dict[
                                  "all bins concatenated targets seperated"
                              ][target_idx][idx_bin]
                          )
  
                          fold_all_bins_concat_targets_sep_all[
                              target_idx
                          ][idx_bin] = combined
  
              # Reverses order so they are worst to best i.e. B5 -> B1
              all_bound_percents[
                  model + " " + uncertainty_type
              ] = fold_learned_bounds_mean_bins[::-1]
              all_bound_percents_notargetsep[
                  model + " " + uncertainty_type
              ] = fold_learned_bounds_bins_targetsnotsep[::-1]
  
              for target_idx in range(
                  len(all_concat_errorbound_bins_target_sep_foldwise)
              ):
                  all_concat_errorbound_bins_target_sep_foldwise[
                      target_idx
                  ][
                      model + " " + uncertainty_type
                  ] = fold_all_bins_concat_targets_sep_foldwise[
                      target_idx
                  ]
                  all_concat_errorbound_bins_target_sep_all[target_idx][
                      model + " " + uncertainty_type
                  ] = fold_all_bins_concat_targets_sep_all[target_idx]
  
      return {
          "Error Bounds All": all_bound_percents,
          "all_bound_percents_notargetsep": all_bound_percents_notargetsep,
          "all errorbound concat bins targets sep foldwise": all_concat_errorbound_bins_target_sep_foldwise,
          "all errorbound concat bins targets sep all": all_concat_errorbound_bins_target_sep_all,
      }
  
file_path: pykale/kale/evaluate/uncertainty_metrics.py
imports: from typing import Dict, List
  import numpy
  import pandas
  from kale.evaluate.similarity_metrics import jaccard_similarity
  from kale.prepdata.string_transform import strip_for_bound
label_desc: Use image node_id 1 for calling a global function with example usage: evaluate_bounds(estimated_bounds, bin_predictions, uncertainty_pairs, num_bins, targets, num_folds, show_fig, combine_middle_bins) and returns: dict