docstr: Evaluation in COCO protocol.
  
  Args:
      results (list[list | tuple]): Testing results of the dataset.
      metric (str | list[str]): Metrics to be evaluated. Options are
          'bbox', 'segm', 'proposal', 'proposal_fast'.
      logger (logging.Logger | str | None): Logger used for printing
          related information during evaluation. Default: None.
      jsonfile_prefix (str | None): The prefix of json files. It includes
          the file path and the prefix of filename, e.g., "a/b/prefix".
          If not specified, a temp file will be created. Default: None.
      classwise (bool): Whether to evaluating the AP for each class.
      proposal_nums (Sequence[int]): Proposal number used for evaluating
          recalls, such as recall@100, recall@1000.
          Default: (100, 300, 1000).
      iou_thrs (Sequence[float], optional): IoU threshold used for
          evaluating recalls/mAPs. If set to a list, the average of all
          IoUs will also be computed. If not specified, [0.50, 0.55,
          0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95] will be used.
          Default: None.
      metric_items (list[str] | str, optional): Metric items that will
          be returned. If not specified, ``['AR@100', 'AR@300',
          'AR@1000', 'AR_s@1000', 'AR_m@1000', 'AR_l@1000' ]`` will be
          used when ``metric=='proposal'``, ``['mAP', 'mAP_50', 'mAP_75',
          'mAP_s', 'mAP_m', 'mAP_l']`` will be used when
          ``metric=='bbox' or metric=='segm'``.
  
  Returns:
      dict[str, float]: COCO style evaluation metric.
docstr_tok: ["Evaluation","in","COCO","protocol",".","Args",":","results","(","list","[","list","|","tuple","]",")",":","Testing","results","of","the","dataset",".","metric","(","str","|","list","[","str","]",")",":","Metrics","to","be","evaluated",".","Options","are","'bbox","'",",","'segm","'",",","'proposal","'",",","'proposal_fast","'",".","logger","(","logging.Logger","|","str","|","None",")",":","Logger","used","for","printing","related","information","during","evaluation",".","Default",":","None",".","jsonfile_prefix","(","str","|","None",")",":","The","prefix","of","json","files",".","It","includes","the","file","path","and","the","prefix","of","filename",",","e.g.",",","``","a\/b\/prefix","''",".","If","not","specified",",","a","temp","file","will","be","created",".","Default",":","None",".","classwise","(","bool",")",":","Whether","to","evaluating","the","AP","for","each","class",".","proposal_nums","(","Sequence","[","int","]",")",":","Proposal","number","used","for","evaluating","recalls",",","such","as","recall","@","100",",","recall","@","1000",".","Default",":","(","100",",","300",",","1000",")",".","iou_thrs","(","Sequence","[","float","]",",","optional",")",":","IoU","threshold","used","for","evaluating","recalls\/mAPs",".","If","set","to","a","list",",","the","average","of","all","IoUs","will","also","be","computed",".","If","not","specified",",","[","0.50",",","0.55",",","0.60",",","0.65",",","0.70",",","0.75",",","0.80",",","0.85",",","0.90",",","0.95","]","will","be","used",".","Default",":","None",".","metric_items","(","list","[","str","]","|","str",",","optional",")",":","Metric","items","that","will","be","returned",".","If","not","specified",",","``","[","'AR","@","100","'",",","'AR","@","300","'",",","'AR","@","1000","'",",","'AR_s","@","1000","'",",","'AR_m","@","1000","'",",","'AR_l","@","1000","'","]","``","will","be","used","when","``","metric=='proposal","'","``",",","``","[","'mAP","'",",","'mAP_50","'",",","'mAP_75","'",",","'mAP_s","'",",","'mAP_m","'",",","'mAP_l","'","]","``","will","be","used","when","``","metric=='bbox","'","or","metric=='segm","'","``",".","Returns",":","dict","[","str",",","float","]",":","COCO","style","evaluation","metric","."]
code: def evaluate(
      self,
      results,
      metric="bbox",
      logger=None,
      jsonfile_prefix=None,
      classwise=False,
      proposal_nums=(100, 300, 1000),
      iou_thrs=None,
      metric_items=None,
  ):
      """Evaluation in COCO protocol.
  
      Args:
          results (list[list | tuple]): Testing results of the dataset.
          metric (str | list[str]): Metrics to be evaluated. Options are
              'bbox', 'segm', 'proposal', 'proposal_fast'.
          logger (logging.Logger | str | None): Logger used for printing
              related information during evaluation. Default: None.
          jsonfile_prefix (str | None): The prefix of json files. It includes
              the file path and the prefix of filename, e.g., "a/b/prefix".
              If not specified, a temp file will be created. Default: None.
          classwise (bool): Whether to evaluating the AP for each class.
          proposal_nums (Sequence[int]): Proposal number used for evaluating
              recalls, such as recall@100, recall@1000.
              Default: (100, 300, 1000).
          iou_thrs (Sequence[float], optional): IoU threshold used for
              evaluating recalls/mAPs. If set to a list, the average of all
              IoUs will also be computed. If not specified, [0.50, 0.55,
              0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95] will be used.
              Default: None.
          metric_items (list[str] | str, optional): Metric items that will
              be returned. If not specified, ``['AR@100', 'AR@300',
              'AR@1000', 'AR_s@1000', 'AR_m@1000', 'AR_l@1000' ]`` will be
              used when ``metric=='proposal'``, ``['mAP', 'mAP_50', 'mAP_75',
              'mAP_s', 'mAP_m', 'mAP_l']`` will be used when
              ``metric=='bbox' or metric=='segm'``.
  
      Returns:
          dict[str, float]: COCO style evaluation metric.
      """
  
      metrics = metric if isinstance(metric, list) else [metric]
      allowed_metrics = ["bbox", "segm", "proposal", "proposal_fast"]
      for metric in metrics:
          if metric not in allowed_metrics:
              raise KeyError(f"metric {metric} is not supported")
      if iou_thrs is None:
          iou_thrs = np.linspace(
              0.5,
              0.95,
              int(np.round((0.95 - 0.5) / 0.05)) + 1,
              endpoint=True,
          )
      if metric_items is not None:
          if not isinstance(metric_items, list):
              metric_items = [metric_items]
  
      result_files, tmp_dir = self.format_results(
          results, jsonfile_prefix
      )
  
      eval_results = OrderedDict()
      cocoGt = self.coco
      for metric in metrics:
          msg = f"Evaluating {metric}..."
          if logger is None:
              msg = "\n" + msg
          print_log(msg, logger=logger)
  
          if metric == "proposal_fast":
              ar = self.fast_eval_recall(
                  results, proposal_nums, iou_thrs, logger="silent"
              )
              log_msg = []
              for i, num in enumerate(proposal_nums):
                  eval_results[f"AR@{num}"] = ar[i]
                  log_msg.append(f"\nAR@{num}\t{ar[i]:.4f}")
              log_msg = "".join(log_msg)
              print_log(log_msg, logger=logger)
              continue
  
          if metric not in result_files:
              raise KeyError(f"{metric} is not in results")
          try:
              cocoDt = cocoGt.loadRes(result_files[metric])
          except IndexError:
              print_log(
                  "The testing results of the whole dataset is empty.",
                  logger=logger,
                  level=logging.ERROR,
              )
              break
  
          iou_type = "bbox" if metric == "proposal" else metric
          cocoEval = COCOeval(cocoGt, cocoDt, iou_type)
          cocoEval.params.catIds = self.cat_ids
          cocoEval.params.imgIds = self.img_ids
          cocoEval.params.maxDets = list(proposal_nums)
          cocoEval.params.iouThrs = iou_thrs
          # mapping of cocoEval.stats
          coco_metric_names = {
              "mAP": 0,
              "mAP_50": 1,
              "mAP_75": 2,
              "mAP_s": 3,
              "mAP_m": 4,
              "mAP_l": 5,
              "AR@100": 6,
              "AR@300": 7,
              "AR@1000": 8,
              "AR_s@1000": 9,
              "AR_m@1000": 10,
              "AR_l@1000": 11,
          }
          if metric_items is not None:
              for metric_item in metric_items:
                  if metric_item not in coco_metric_names:
                      raise KeyError(
                          f"metric item {metric_item} is not supported"
                      )
  
          if metric == "proposal":
              cocoEval.params.useCats = 0
              cocoEval.evaluate()
              cocoEval.accumulate()
              cocoEval.summarize()
              if metric_items is None:
                  metric_items = [
                      "AR@100",
                      "AR@300",
                      "AR@1000",
                      "AR_s@1000",
                      "AR_m@1000",
                      "AR_l@1000",
                  ]
  
              for item in metric_items:
                  val = float(
                      f"{cocoEval.stats[coco_metric_names[item]]:.3f}"
                  )
                  eval_results[item] = val
          else:
              cocoEval.evaluate()
              cocoEval.accumulate()
              cocoEval.summarize()
              if classwise:  # Compute per-category AP
                  # Compute per-category AP
                  # from https://github.com/facebookresearch/detectron2/
                  precisions = cocoEval.eval["precision"]
                  # precision: (iou, recall, cls, area range, max dets)
                  assert len(self.cat_ids) == precisions.shape[2]
  
                  results_per_category = []
                  for idx, catId in enumerate(self.cat_ids):
                      # area range index 0: all area ranges
                      # max dets index -1: typically 100 per image
                      nm = self.coco.loadCats(catId)[0]
                      precision = precisions[:, :, idx, 0, -1]
                      precision = precision[precision > -1]
                      if precision.size:
                          ap = np.mean(precision)
                      else:
                          ap = float("nan")
                      results_per_category.append(
                          (f'{nm["name"]}', f"{float(ap):0.3f}")
                      )
  
                  num_columns = min(6, len(results_per_category) * 2)
                  results_flatten = list(
                      itertools.chain(*results_per_category)
                  )
                  headers = ["category", "AP"] * (num_columns // 2)
                  results_2d = itertools.zip_longest(
                      *[
                          results_flatten[i::num_columns]
                          for i in range(num_columns)
                      ]
                  )
                  table_data = [headers]
                  table_data += [result for result in results_2d]
                  table = AsciiTable(table_data)
                  print_log("\n" + table.table, logger=logger)
  
              if metric_items is None:
                  metric_items = [
                      "mAP",
                      "mAP_50",
                      "mAP_75",
                      "mAP_s",
                      "mAP_m",
                      "mAP_l",
                  ]
  
              for metric_item in metric_items:
                  key = f"{metric}_{metric_item}"
                  val = float(
                      f"{cocoEval.stats[coco_metric_names[metric_item]]:.3f}"
                  )
                  eval_results[key] = val
              ap = cocoEval.stats[:6]
              eval_results[f"{metric}_mAP_copypaste"] = (
                  f"{ap[0]:.3f} {ap[1]:.3f} {ap[2]:.3f} {ap[3]:.3f} "
                  f"{ap[4]:.3f} {ap[5]:.3f}"
              )
      if tmp_dir is not None:
          tmp_dir.cleanup()
      return eval_results
  
imports: import itertools
  import logging
  import os.path
  import tempfile
  from collections import OrderedDict
  import mmcv
  import numpy
  from mmcv.utils import print_log
  from pycocotools.coco import COCO
  from pycocotools.cocoeval import COCOeval
  from terminaltables import AsciiTable
  from mmdet.core import eval_recalls
  from .builder import DATASETS
  from .custom import CustomDataset
label_desc: Use image node_id 13 for calling the CocoDataset obj's underlying member method code with example usage: obj.evaluate(results, metric, logger, jsonfile_prefix, classwise, proposal_nums, iou_thrs, metric_items) and returns: eval_results