code: def eval_detection(pred_all, gt_all, ovthresh=0.25, processes=4):
      """Generic functions to compute precision/recall for object detection
      for multiple classes.
      Input:
          pred_all: map of {img_id: [BoxData]}
          gt_all: map of {img_id: [BoxData]}
          ovthresh: scalar, iou threshold
          processes: number of threads to use
      Output:
          rec: {classname: rec}
          prec: {classname: prec_all}
          ap: {classname: scalar}
      """
      pred = {}  # map {classname: pred}
      gt = {}  # map {classname: gt}
      for img_id in pred_all.keys():
          for box in pred_all[img_id]:
              if box.classname not in pred:
                  pred[box.classname] = {}
              if img_id not in pred[box.classname]:
                  pred[box.classname][img_id] = []
              if box.classname not in gt:
                  gt[box.classname] = {}
              if img_id not in gt[box.classname]:
                  gt[box.classname][img_id] = []
              pred[box.classname][img_id].append(
                  (box.corners3d, box.score)
              )
      for img_id in gt_all.keys():
          for box in gt_all[img_id]:
              if box.classname not in gt:
                  gt[box.classname] = {}
              if img_id not in gt[box.classname]:
                  gt[box.classname][img_id] = []
              gt[box.classname][img_id].append(box.corners3d)
  
      rec = {}
      prec = {}
      ap = {}
      p = Pool(processes=processes)
      ret_values = p.map(
          eval_det_cls_wrapper,
          [
              (pred[classname], gt[classname], ovthresh)
              for classname in gt.keys()
              if classname in pred
          ],
      )
      p.close()
      for i, classname in enumerate(gt.keys()):
          if classname in pred:
              (
                  rec[classname],
                  prec[classname],
                  ap[classname],
              ) = ret_values[i]
          else:
              rec[classname] = 0
              prec[classname] = 0
              ap[classname] = 0
  
      return rec, prec, ap
  
imports: import numpy
  from multiprocessing import Pool
  from torch_points3d.utils.box_utils import box3d_iou
  from torch_points3d.datasets.object_detection.box_data import BoxData
label_desc: Use image node_id 4 for calling a global function with example usage: eval_detection(pred_all, gt_all, ovthresh, processes) and returns: rec,  prec,  ap