code: def test_evaldetection(self):
      box = box_corners_from_param(
          torch.tensor([1, 1, 1]).float(),
          0,
          torch.tensor([0.5, 0.5, 0.5]),
      )
  
      # Image1 -> 1 class1 and 1 class2
      # Image2 -> 1 class1
      gt = {
          "0": [BoxData("class1", box), BoxData("class2", box)],
          "1": [BoxData("class1", box)],
      }
  
      pred = {
          "0": [
              BoxData("class1", box, score=0.5),
              BoxData("class2", box, score=0.5),
          ],
          "1": [BoxData("class2", box, score=1)],
      }
      rec, prec, ap = eval_detection(pred, gt)
      np.testing.assert_allclose(rec["class2"], np.asarray([0, 1]))
      np.testing.assert_allclose(prec["class2"], np.asarray([0, 0.5]))
      self.assertAlmostEqual(ap["class2"], 0.5)
  
imports: import os
  import sys
  import unittest
  import torch
  import numpy
  from torch_points3d.utils.box_utils import box_corners_from_param, box3d_vol, intersection_area, convex_hull_graham, nms_samecls, box3d_iou
  from torch_points3d.modules.VoteNet.votenet_results import VoteNetResults
  from torch_points3d.metrics.box_detection.ap import eval_detection
  from torch_points3d.datasets.object_detection.box_data import BoxData
label_desc: Use image node_id 1 for calling the TestAP obj's underlying member method code with example usage: obj.test_evaldetection() without return types