docstr: Add current model predictions (usually the result of a batch) to the tracking
  if tracking boxes, you must provide a labeled "data" object with the following attributes:
      - id_scan: id of the scan to which the boxes belong to
      - instance_box_cornerimport torchnet as tnts - gt box corners
      - box_label_mask - mask for boxes (0 = no box)
      - sem_cls_label - semantic label for each box
docstr_tok: ["Add","current","model","predictions","(","usually","the","result","of","a","batch",")","to","the","tracking","if","tracking","boxes",",","you","must","provide","a","labeled","``","data","''","object","with","the","following","attributes",":","-","id_scan",":","id","of","the","scan","to","which","the","boxes","belong","to","-","instance_box_cornerimport","torchnet","as","tnts","-","gt","box","corners","-","box_label_mask","-","mask","for","boxes","(","0","=","no","box",")","-","sem_cls_label","-","semantic","label","for","each","box"]
code: def track(
      self,
      model: TrackerInterface,
      data=None,
      track_boxes=False,
      **kwargs,
  ):
      """Add current model predictions (usually the result of a batch) to the tracking
      if tracking boxes, you must provide a labeled "data" object with the following attributes:
          - id_scan: id of the scan to which the boxes belong to
          - instance_box_cornerimport torchnet as tnts - gt box corners
          - box_label_mask - mask for boxes (0 = no box)
          - sem_cls_label - semantic label for each box
      """
      super().track(model)
  
      outputs: VoteNetResults = model.get_output()
  
      total_num_proposal = (
          outputs.objectness_label.shape[0]
          * outputs.objectness_label.shape[1]
      )
      pos_ratio = torch.sum(
          outputs.objectness_label.float()
      ).item() / float(total_num_proposal)
      self._pos_ratio.add(pos_ratio)
      self._neg_ratio.add(
          torch.sum(outputs.objectness_mask.float()).item()
          / float(total_num_proposal)
          - pos_ratio
      )
  
      obj_pred_val = torch.argmax(outputs.objectness_scores, 2)  # B,K
      self._obj_acc.add(
          torch.sum(
              (obj_pred_val == outputs.objectness_label.long()).float()
              * outputs.objectness_mask
          ).item()
          / (torch.sum(outputs.objectness_mask) + 1e-6).item()
      )
  
      if data is None or self._stage == "train" or not track_boxes:
          return
  
      self._add_box_pred(outputs, data, model.conv_type)
  
imports: from typing import Dict, List, Any
  import torchnet
  import torch
  from collections import OrderedDict
  from torch_points3d.models.model_interface import TrackerInterface
  from torch_points3d.metrics.base_tracker import BaseTracker, meter_value
  from torch_points3d.metrics.meters import APMeter
  from torch_points3d.datasets.segmentation import IGNORE_LABEL
  from torch_points3d.modules.VoteNet import VoteNetResults
  from torch_points3d.datasets.object_detection.box_data import BoxData
  from .box_detection.ap import eval_detection
label_desc: Use image node_id 4 for calling the ObjectDetectionTracker obj's underlying member method code with example usage: obj.track(model, data, track_boxes) without return types