class_docstr: Tracker for OC-SORT.
  
  Args:
      motion (dict): Configuration of motion. Defaults to None.
      obj_score_thrs (float): Detection score threshold for matching objects.
          Defaults to 0.3.
      init_track_thr (float): Detection score threshold for initializing a
          new tracklet. Defaults to 0.7.
      weight_iou_with_det_scores (bool): Whether using detection scores to
          weight IOU which is used for matching. Defaults to True.
      match_iou_thr (float): IOU distance threshold for matching between two
          frames. Defaults to 0.3.
      num_tentatives (int, optional): Number of continuous frames to confirm
          a track. Defaults to 3.
      vel_consist_weight (float): Weight of the velocity consistency term in
          association (OCM term in the paper).
      vel_delta_t (int): The difference of time step for calculating of the
          velocity direction of tracklets.
      init_cfg (dict or list[dict], optional): Initialization config dict.
          Defaults to None.
docstr: Tracking forward function.
  NOTE: this implementation is slightly different from the original
  OC-SORT implementation (https://github.com/noahcao/OC_SORT)that we
  do association between detections and tentative/non-tentative tracks
  independently while the original implementation combines them together.
  
  Args:
      data_sample (:obj:`DetDataSample`): The data sample.
          It includes information such as `pred_instances`.
  
  Returns:
      :obj:`InstanceData`: Tracking results of the input images.
      Each InstanceData usually contains ``bboxes``, ``labels``,
      ``scores`` and ``instances_id``.
docstr_tok: ["Tracking","forward","function",".","NOTE",":","this","implementation","is","slightly","different","from","the","original","OC-SORT","implementation","(","https",":","\/\/github.com\/noahcao\/OC_SORT",")","that","we","do","association","between","detections","and","tentative\/non-tentative","tracks","independently","while","the","original","implementation","combines","them","together",".","Args",":","data_sample","(",":","obj",":","`","DetDataSample","`",")",":","The","data","sample",".","It","includes","information","such","as","`","pred_instances","`",".","Returns",":",":","obj",":","`","InstanceData","`",":","Tracking","results","of","the","input","images",".","Each","InstanceData","usually","contains","``","bboxes","``",",","``","labels","``",",","``","scores","``","and","``","instances_id","``","."]
code: def track(self, data_sample: DetDataSample, **kwargs) -> InstanceData:
      """Tracking forward function.
      NOTE: this implementation is slightly different from the original
      OC-SORT implementation (https://github.com/noahcao/OC_SORT)that we
      do association between detections and tentative/non-tentative tracks
      independently while the original implementation combines them together.
  
      Args:
          data_sample (:obj:`DetDataSample`): The data sample.
              It includes information such as `pred_instances`.
  
      Returns:
          :obj:`InstanceData`: Tracking results of the input images.
          Each InstanceData usually contains ``bboxes``, ``labels``,
          ``scores`` and ``instances_id``.
      """
      metainfo = data_sample.metainfo
      bboxes = data_sample.pred_instances.bboxes
      labels = data_sample.pred_instances.labels
      scores = data_sample.pred_instances.scores
      frame_id = metainfo.get("frame_id", -1)
      if frame_id == 0:
          self.reset()
      if not hasattr(self, "kf"):
          self.kf = self.motion
  
      if self.empty or bboxes.size(0) == 0:
          valid_inds = scores > self.init_track_thr
          scores = scores[valid_inds]
          bboxes = bboxes[valid_inds]
          labels = labels[valid_inds]
          num_new_tracks = bboxes.size(0)
          ids = torch.arange(
              self.num_tracks, self.num_tracks + num_new_tracks
          ).to(labels)
          self.num_tracks += num_new_tracks
      else:
          # 0. init
          ids = torch.full(
              (bboxes.size(0),),
              -1,
              dtype=labels.dtype,
              device=labels.device,
          )
  
          # get the detection bboxes for the first association
          det_inds = scores > self.obj_score_thr
          det_bboxes = bboxes[det_inds]
          det_labels = labels[det_inds]
          det_scores = scores[det_inds]
          det_ids = ids[det_inds]
  
          # 1. predict by Kalman Filter
          for id in self.confirmed_ids:
              # track is lost in previous frame
              if self.tracks[id].frame_ids[-1] != frame_id - 1:
                  self.tracks[id].mean[7] = 0
              if self.tracks[id].tracked:
                  self.tracks[id].saved_attr.mean = self.tracks[id].mean
                  self.tracks[id].saved_attr.covariance = self.tracks[
                      id
                  ].covariance
              (
                  self.tracks[id].mean,
                  self.tracks[id].covariance,
              ) = self.kf.predict(
                  self.tracks[id].mean, self.tracks[id].covariance
              )
  
          # 2. match detections and tracks' predicted locations
          match_track_inds, raw_match_det_inds = self.ocm_assign_ids(
              self.confirmed_ids,
              det_bboxes,
              det_labels,
              det_scores,
              self.weight_iou_with_det_scores,
              self.match_iou_thr,
          )
          # '-1' mean a detection box is not matched with tracklets in
          # previous frame
          valid = raw_match_det_inds > -1
          det_ids[valid] = torch.tensor(self.confirmed_ids)[
              raw_match_det_inds[valid]
          ].to(labels)
  
          match_det_bboxes = det_bboxes[valid]
          match_det_labels = det_labels[valid]
          match_det_scores = det_scores[valid]
          match_det_ids = det_ids[valid]
          assert (match_det_ids > -1).all()
  
          # unmatched tracks and detections
          unmatch_det_bboxes = det_bboxes[~valid]
          unmatch_det_labels = det_labels[~valid]
          unmatch_det_scores = det_scores[~valid]
          unmatch_det_ids = det_ids[~valid]
          assert (unmatch_det_ids == -1).all()
  
          # 3. use unmatched detection bboxes from the first match to match
          # the unconfirmed tracks
          (
              tentative_match_track_inds,
              tentative_match_det_inds,
          ) = self.ocm_assign_ids(
              self.unconfirmed_ids,
              unmatch_det_bboxes,
              unmatch_det_labels,
              unmatch_det_scores,
              self.weight_iou_with_det_scores,
              self.match_iou_thr,
          )
          valid = tentative_match_det_inds > -1
          unmatch_det_ids[valid] = torch.tensor(self.unconfirmed_ids)[
              tentative_match_det_inds[valid]
          ].to(labels)
  
          match_det_bboxes = torch.cat(
              (match_det_bboxes, unmatch_det_bboxes[valid]), dim=0
          )
          match_det_labels = torch.cat(
              (match_det_labels, unmatch_det_labels[valid]), dim=0
          )
          match_det_scores = torch.cat(
              (match_det_scores, unmatch_det_scores[valid]), dim=0
          )
          match_det_ids = torch.cat(
              (match_det_ids, unmatch_det_ids[valid]), dim=0
          )
          assert (match_det_ids > -1).all()
  
          unmatch_det_bboxes = unmatch_det_bboxes[~valid]
          unmatch_det_labels = unmatch_det_labels[~valid]
          unmatch_det_scores = unmatch_det_scores[~valid]
          unmatch_det_ids = unmatch_det_ids[~valid]
          assert (unmatch_det_ids == -1).all()
  
          all_track_ids = [id for id, _ in self.tracks.items()]
          unmatched_track_inds = torch.tensor(
              [ind for ind in all_track_ids if ind not in match_det_ids]
          )
  
          if len(unmatched_track_inds) > 0:
              # 4. still some tracks not associated yet, perform OCR
              last_observations = []
              for id in unmatched_track_inds:
                  last_box = self.last_obs(self.tracks[id.item()])
                  last_observations.append(last_box)
              last_observations = torch.stack(last_observations)
              last_track_labels = torch.tensor(
                  [
                      self.tracks[id.item()]["labels"][-1]
                      for id in unmatched_track_inds
                  ]
              ).to(det_bboxes.device)
  
              remain_det_ids = torch.full(
                  (unmatch_det_bboxes.size(0),),
                  -1,
                  dtype=labels.dtype,
                  device=labels.device,
              )
  
              _, ocr_match_det_inds = self.ocr_assign_ids(
                  last_observations,
                  last_track_labels,
                  unmatch_det_bboxes,
                  unmatch_det_labels,
                  unmatch_det_scores,
                  self.weight_iou_with_det_scores,
                  self.match_iou_thr,
              )
  
              valid = ocr_match_det_inds > -1
              remain_det_ids[valid] = unmatched_track_inds.clone()[
                  ocr_match_det_inds[valid]
              ].to(labels)
  
              ocr_match_det_bboxes = unmatch_det_bboxes[valid]
              ocr_match_det_labels = unmatch_det_labels[valid]
              ocr_match_det_scores = unmatch_det_scores[valid]
              ocr_match_det_ids = remain_det_ids[valid]
              assert (ocr_match_det_ids > -1).all()
  
              ocr_unmatch_det_bboxes = unmatch_det_bboxes[~valid]
              ocr_unmatch_det_labels = unmatch_det_labels[~valid]
              ocr_unmatch_det_scores = unmatch_det_scores[~valid]
              ocr_unmatch_det_ids = remain_det_ids[~valid]
              assert (ocr_unmatch_det_ids == -1).all()
  
              unmatch_det_bboxes = ocr_unmatch_det_bboxes
              unmatch_det_labels = ocr_unmatch_det_labels
              unmatch_det_scores = ocr_unmatch_det_scores
              unmatch_det_ids = ocr_unmatch_det_ids
              match_det_bboxes = torch.cat(
                  (match_det_bboxes, ocr_match_det_bboxes), dim=0
              )
              match_det_labels = torch.cat(
                  (match_det_labels, ocr_match_det_labels), dim=0
              )
              match_det_scores = torch.cat(
                  (match_det_scores, ocr_match_det_scores), dim=0
              )
              match_det_ids = torch.cat(
                  (match_det_ids, ocr_match_det_ids), dim=0
              )
  
          # 5. summarize the track results
          for i in range(len(match_det_ids)):
              det_bbox = match_det_bboxes[i]
              track_id = match_det_ids[i].item()
              if not self.tracks[track_id].tracked:
                  # the track is lost before this step
                  self.online_smooth(self.tracks[track_id], det_bbox)
  
          for track_id in all_track_ids:
              if track_id not in match_det_ids:
                  self.tracks[track_id].tracked = False
                  self.tracks[track_id].obs.append(None)
  
          bboxes = torch.cat(
              (match_det_bboxes, unmatch_det_bboxes), dim=0
          )
          labels = torch.cat(
              (match_det_labels, unmatch_det_labels), dim=0
          )
          scores = torch.cat(
              (match_det_scores, unmatch_det_scores), dim=0
          )
          ids = torch.cat((match_det_ids, unmatch_det_ids), dim=0)
          # 6. assign new ids
          new_track_inds = ids == -1
  
          ids[new_track_inds] = torch.arange(
              self.num_tracks, self.num_tracks + new_track_inds.sum()
          ).to(labels)
          self.num_tracks += new_track_inds.sum()
  
      self.update(
          ids=ids,
          bboxes=bboxes,
          labels=labels,
          scores=scores,
          frame_ids=frame_id,
      )
  
      # update pred_track_instances
      pred_track_instances = InstanceData()
      pred_track_instances.bboxes = bboxes
      pred_track_instances.labels = labels
      pred_track_instances.scores = scores
      pred_track_instances.instances_id = ids
      return pred_track_instances
  
imports: from typing import List, Optional, Tuple
  import numpy
  import torch
  from addict import Dict
  from mmengine.structures import InstanceData
  from mmdet.registry import MODELS
  from mmdet.structures import DetDataSample
  from mmdet.structures.bbox import bbox_cxcyah_to_xyxy, bbox_overlaps, bbox_xyxy_to_cxcyah
  from .sort_tracker import SORTTracker
label_desc: Use image node_id 12 for calling the OCSORTTracker obj's underlying member method code with example usage: obj.track(data_sample) and returns: pred_track_instances