code: def _evaluate_box_proposals(
      dataset_predictions,
      coco_api,
      thresholds=None,
      area="all",
      limit=None,
  ):
      """
      Evaluate detection proposal recall metrics. This function is a much
      faster alternative to the official COCO API recall evaluation code. However,
      it produces slightly different results.
      """
      # Record max overlap value for each gt box
      # Return vector of overlap values
      areas = {
          "all": 0,
          "small": 1,
          "medium": 2,
          "large": 3,
          "96-128": 4,
          "128-256": 5,
          "256-512": 6,
          "512-inf": 7,
      }
      area_ranges = [
          [0**2, 1e5**2],  # all
          [0**2, 32**2],  # small
          [32**2, 96**2],  # medium
          [96**2, 1e5**2],  # large
          [96**2, 128**2],  # 96-128
          [128**2, 256**2],  # 128-256
          [256**2, 512**2],  # 256-512
          [512**2, 1e5**2],
      ]  # 512-inf
      assert area in areas, "Unknown area range: {}".format(area)
      area_range = area_ranges[areas[area]]
      gt_overlaps = []
      num_pos = 0
  
      for prediction_dict in dataset_predictions:
          predictions = prediction_dict["proposals"]
  
          # sort predictions in descending order
          # TODO maybe remove this and make it explicit in the documentation
          inds = predictions.objectness_logits.sort(descending=True)[1]
          predictions = predictions[inds]
  
          ann_ids = coco_api.getAnnIds(
              imgIds=prediction_dict["image_id"]
          )
          anno = coco_api.loadAnns(ann_ids)
          gt_boxes = [
              BoxMode.convert(
                  obj["bbox"], BoxMode.XYWH_ABS, BoxMode.XYXY_ABS
              )
              for obj in anno
              if obj["iscrowd"] == 0
          ]
          gt_boxes = torch.as_tensor(gt_boxes).reshape(
              -1, 4
          )  # guard against no boxes
          gt_boxes = Boxes(gt_boxes)
          gt_areas = torch.as_tensor(
              [obj["area"] for obj in anno if obj["iscrowd"] == 0]
          )
  
          if len(gt_boxes) == 0 or len(predictions) == 0:
              continue
  
          valid_gt_inds = (gt_areas >= area_range[0]) & (
              gt_areas <= area_range[1]
          )
          gt_boxes = gt_boxes[valid_gt_inds]
  
          num_pos += len(gt_boxes)
  
          if len(gt_boxes) == 0:
              continue
  
          if limit is not None and len(predictions) > limit:
              predictions = predictions[:limit]
  
          overlaps = pairwise_iou(predictions.proposal_boxes, gt_boxes)
  
          _gt_overlaps = torch.zeros(len(gt_boxes))
          for j in range(min(len(predictions), len(gt_boxes))):
              # find which proposal box maximally covers each gt box
              # and get the iou amount of coverage for each gt box
              max_overlaps, argmax_overlaps = overlaps.max(dim=0)
  
              # find which gt box is 'best' covered (i.e. 'best' = most iou)
              gt_ovr, gt_ind = max_overlaps.max(dim=0)
              assert gt_ovr >= 0
              # find the proposal box that covers the best covered gt box
              box_ind = argmax_overlaps[gt_ind]
              # record the iou coverage of this gt box
              _gt_overlaps[j] = overlaps[box_ind, gt_ind]
              assert _gt_overlaps[j] == gt_ovr
              # mark the proposal box and the gt box as used
              overlaps[box_ind, :] = -1
              overlaps[:, gt_ind] = -1
  
          # append recorded iou coverage level
          gt_overlaps.append(_gt_overlaps)
      gt_overlaps = (
          torch.cat(gt_overlaps, dim=0)
          if len(gt_overlaps)
          else torch.zeros(0, dtype=torch.float32)
      )
      gt_overlaps, _ = torch.sort(gt_overlaps)
  
      if thresholds is None:
          step = 0.05
          thresholds = torch.arange(
              0.5, 0.95 + 1e-5, step, dtype=torch.float32
          )
      recalls = torch.zeros_like(thresholds)
      # compute recall for each iou threshold
      for i, t in enumerate(thresholds):
          recalls[i] = (gt_overlaps >= t).float().sum() / float(num_pos)
      # ar = 2 * np.trapz(recalls, thresholds)
      ar = recalls.mean()
      return {
          "ar": ar,
          "recalls": recalls,
          "thresholds": thresholds,
          "gt_overlaps": gt_overlaps,
          "num_pos": num_pos,
      }
  
imports: import contextlib
  import copy
  import io
  import itertools
  import json
  import logging
  import os
  import pickle
  from collections import OrderedDict
  import numpy
  import torch
  import pandas
  from ..None import comm
  from ...data.registry.catalog import MetadataCatalog
  from ...data.registry.mscoco import convert_to_coco_json
  from ...data.structures import Boxes, BoxMode, pairwise_iou
  from ...data.detection.detection_utils import try_import_pycocotools
label_desc: Use image node_id 2 for calling a global function with example usage: _evaluate_box_proposals(dataset_predictions, coco_api, thresholds, area, limit) and returns: dict