class_docstr: Computes matching between predictions and ground truth.
  Args:
      center_radius (int | float, optional): Ground truth center size
          to judge whether a prior is in center. Default 2.5.
      candidate_topk (int, optional): The candidate top-k which used to
          get top-k ious to calculate dynamic-k. Default 10.
      iou_weight (int | float, optional): The scale factor for regression
          iou cost. Default 3.0.
      cls_weight (int | float, optional): The scale factor for classification
          cost. Default 1.0.
      num_classes (int): The num_classes of dataset.
      use_vfl (int): Whether to use varifocal_loss when calculating the cost matrix.
class_docstr_tok: ["Computes","matching","between","predictions","and","ground","truth",".","Args",":","center_radius","(","int","|","float",",","optional",")",":","Ground","truth","center","size","to","judge","whether","a","prior","is","in","center",".","Default","2.5.","candidate_topk","(","int",",","optional",")",":","The","candidate","top-k","which","used","to","get","top-k","ious","to","calculate","dynamic-k",".","Default","10.","iou_weight","(","int","|","float",",","optional",")",":","The","scale","factor","for","regression","iou","cost",".","Default","3.0.","cls_weight","(","int","|","float",",","optional",")",":","The","scale","factor","for","classification","cost",".","Default","1.0.","num_classes","(","int",")",":","The","num_classes","of","dataset",".","use_vfl","(","int",")",":","Whether","to","use","varifocal_loss","when","calculating","the","cost","matrix","."]
docstr: Assign gt to priors using SimOTA.
  TODO: add comment.
  Returns:
      assign_result: The assigned result.
docstr_tok: ["Assign","gt","to","priors","using","SimOTA",".","TODO",":","add","comment",".","Returns",":","assign_result",":","The","assigned","result","."]
code: def __call__(
      self,
      flatten_cls_pred_scores,
      flatten_center_and_stride,
      flatten_bboxes,
      gt_bboxes,
      gt_labels,
      eps=1e-7,
  ):
      """Assign gt to priors using SimOTA.
      TODO: add comment.
      Returns:
          assign_result: The assigned result.
      """
      num_gt = gt_bboxes.shape[0]
      num_bboxes = flatten_bboxes.shape[0]
  
      if num_gt == 0 or num_bboxes == 0:
          # No ground truth or boxes
          label = (
              np.ones([num_bboxes], dtype=np.int64) * self.num_classes
          )
          label_weight = np.ones([num_bboxes], dtype=np.float32)
          bbox_target = np.zeros_like(flatten_center_and_stride)
          return 0, label, label_weight, bbox_target
  
      (
          is_in_gts_or_centers_all,
          is_in_gts_or_centers_all_inds,
          is_in_boxes_and_center,
      ) = self.get_in_gt_and_in_center_info(
          flatten_center_and_stride, gt_bboxes
      )
  
      # bboxes and scores to calculate matrix
      valid_flatten_bboxes = flatten_bboxes[
          is_in_gts_or_centers_all_inds
      ]
      valid_cls_pred_scores = flatten_cls_pred_scores[
          is_in_gts_or_centers_all_inds
      ]
      num_valid_bboxes = valid_flatten_bboxes.shape[0]
  
      pairwise_ious = batch_bbox_overlaps(
          valid_flatten_bboxes, gt_bboxes
      )  # [num_points,num_gts]
      if self.use_vfl:
          gt_vfl_labels = (
              gt_labels.squeeze(-1)
              .unsqueeze(0)
              .tile([num_valid_bboxes, 1])
              .reshape([-1])
          )
          valid_pred_scores = (
              valid_cls_pred_scores.unsqueeze(1)
              .tile([1, num_gt, 1])
              .reshape([-1, self.num_classes])
          )
          vfl_score = np.zeros(valid_pred_scores.shape)
          vfl_score[
              np.arange(0, vfl_score.shape[0]), gt_vfl_labels.numpy()
          ] = pairwise_ious.reshape([-1])
          vfl_score = paddle.to_tensor(vfl_score)
          losses_vfl = varifocal_loss(
              valid_pred_scores, vfl_score, use_sigmoid=False
          ).reshape([num_valid_bboxes, num_gt])
          losses_giou = batch_bbox_overlaps(
              valid_flatten_bboxes, gt_bboxes, mode="giou"
          )
          cost_matrix = (
              losses_vfl * self.cls_weight
              + losses_giou * self.iou_weight
              + paddle.logical_not(is_in_boxes_and_center).cast(
                  "float32"
              )
              * 100000000
          )
      else:
          iou_cost = -paddle.log(pairwise_ious + eps)
          gt_onehot_label = (
              F.one_hot(
                  gt_labels.squeeze(-1).cast(paddle.int64),
                  flatten_cls_pred_scores.shape[-1],
              )
              .cast("float32")
              .unsqueeze(0)
              .tile([num_valid_bboxes, 1, 1])
          )
  
          valid_pred_scores = valid_cls_pred_scores.unsqueeze(1).tile(
              [1, num_gt, 1]
          )
          cls_cost = F.binary_cross_entropy(
              valid_pred_scores, gt_onehot_label, reduction="none"
          ).sum(-1)
  
          cost_matrix = (
              cls_cost * self.cls_weight
              + iou_cost * self.iou_weight
              + paddle.logical_not(is_in_boxes_and_center).cast(
                  "float32"
              )
              * 100000000
          )
  
      (
          match_gt_inds_to_fg,
          match_fg_mask_inmatrix,
      ) = self.dynamic_k_matching(cost_matrix, pairwise_ious, num_gt)
  
      # sample and assign results
      assigned_gt_inds = np.zeros([num_bboxes], dtype=np.int64)
      match_fg_mask_inall = np.zeros_like(assigned_gt_inds)
      match_fg_mask_inall[
          is_in_gts_or_centers_all.numpy()
      ] = match_fg_mask_inmatrix
  
      assigned_gt_inds[match_fg_mask_inall.astype(np.bool_)] = (
          match_gt_inds_to_fg + 1
      )
  
      (
          pos_inds,
          neg_inds,
          pos_gt_bboxes,
          pos_assigned_gt_inds,
      ) = self.get_sample(assigned_gt_inds, gt_bboxes.numpy())
  
      bbox_target = np.zeros(
          flatten_bboxes.shape,
          paddle.common_ops_import.convert_dtype(flatten_bboxes.dtype),
      )
      bbox_weight = np.zeros_like(bbox_target)
      label = np.ones([num_bboxes], dtype=np.int64) * self.num_classes
      label_weight = np.zeros([num_bboxes], dtype=np.float32)
  
      if len(pos_inds) > 0:
          gt_labels = gt_labels.numpy()
          pos_bbox_targets = pos_gt_bboxes
          bbox_target[pos_inds, :] = pos_bbox_targets
          bbox_weight[pos_inds, :] = 1.0
          if not np.any(gt_labels):
              label[pos_inds] = 0
          else:
              label[pos_inds] = gt_labels.squeeze(-1)[
                  pos_assigned_gt_inds
              ]
  
          label_weight[pos_inds] = 1.0
      if len(neg_inds) > 0:
          label_weight[neg_inds] = 1.0
  
      pos_num = max(pos_inds.size, 1)
  
      return pos_num, label, label_weight, bbox_target
  
file_path: PaddleDetection/ppdet/modeling/assigners/simota_assigner.py
imports: import paddle
  import numpy
  import paddle.nn.functional
  from ppdet.modeling.losses.varifocal_loss import varifocal_loss
  from ppdet.modeling.bbox_utils import batch_bbox_overlaps
  from ppdet.core.workspace import register
label_desc: Use image node_id 5 for calling the SimOTAAssigner obj's underlying member method code with example usage: obj.__call__(flatten_cls_pred_scores, flatten_center_and_stride, flatten_bboxes, gt_bboxes, gt_labels, eps) and returns: pos_num,  label,  label_weight,  bbox_target, int,  label,  label_weight,  bbox_target