code: def bbox2bucket(
      proposals,
      gt,
      num_buckets,
      scale_factor,
      offset_topk=2,
      offset_upperbound=1.0,
      cls_ignore_neighbor=True,
  ):
      """Generate buckets estimation and fine regression targets.
  
      Args:
          proposals (Tensor): Shape (n, 4)
          gt (Tensor): Shape (n, 4)
          num_buckets (int): Number of buckets.
          scale_factor (float): Scale factor to rescale proposals.
          offset_topk (int): Topk buckets are used to generate
               bucket fine regression targets. Defaults to 2.
          offset_upperbound (float): Offset allowance to generate
               bucket fine regression targets.
               To avoid too large offset displacements. Defaults to 1.0.
          cls_ignore_neighbor (bool): Ignore second nearest bucket or Not.
               Defaults to True.
  
      Returns:
          tuple[Tensor]: (offsets, offsets_weights, bucket_labels, cls_weights).
  
              - offsets: Fine regression targets. \
                  Shape (n, num_buckets*2).
              - offsets_weights: Fine regression weights. \
                  Shape (n, num_buckets*2).
              - bucket_labels: Bucketing estimation labels. \
                  Shape (n, num_buckets*2).
              - cls_weights: Bucketing estimation weights. \
                  Shape (n, num_buckets*2).
      """
      assert proposals.size() == gt.size()
  
      # generate buckets
      proposals = proposals.float()
      gt = gt.float()
      (
          bucket_w,
          bucket_h,
          l_buckets,
          r_buckets,
          t_buckets,
          d_buckets,
      ) = generat_buckets(proposals, num_buckets, scale_factor)
  
      gx1 = gt[..., 0]
      gy1 = gt[..., 1]
      gx2 = gt[..., 2]
      gy2 = gt[..., 3]
  
      # generate offset targets and weights
      # offsets from buckets to gts
      l_offsets = (l_buckets - gx1[:, None]) / bucket_w[:, None]
      r_offsets = (r_buckets - gx2[:, None]) / bucket_w[:, None]
      t_offsets = (t_buckets - gy1[:, None]) / bucket_h[:, None]
      d_offsets = (d_buckets - gy2[:, None]) / bucket_h[:, None]
  
      # select top-k nearset buckets
      l_topk, l_label = l_offsets.abs().topk(
          offset_topk, dim=1, largest=False, sorted=True
      )
      r_topk, r_label = r_offsets.abs().topk(
          offset_topk, dim=1, largest=False, sorted=True
      )
      t_topk, t_label = t_offsets.abs().topk(
          offset_topk, dim=1, largest=False, sorted=True
      )
      d_topk, d_label = d_offsets.abs().topk(
          offset_topk, dim=1, largest=False, sorted=True
      )
  
      offset_l_weights = l_offsets.new_zeros(l_offsets.size())
      offset_r_weights = r_offsets.new_zeros(r_offsets.size())
      offset_t_weights = t_offsets.new_zeros(t_offsets.size())
      offset_d_weights = d_offsets.new_zeros(d_offsets.size())
      inds = torch.arange(0, proposals.size(0)).to(proposals).long()
  
      # generate offset weights of top-k nearset buckets
      for k in range(offset_topk):
          if k >= 1:
              offset_l_weights[inds, l_label[:, k]] = (
                  l_topk[:, k] < offset_upperbound
              ).float()
              offset_r_weights[inds, r_label[:, k]] = (
                  r_topk[:, k] < offset_upperbound
              ).float()
              offset_t_weights[inds, t_label[:, k]] = (
                  t_topk[:, k] < offset_upperbound
              ).float()
              offset_d_weights[inds, d_label[:, k]] = (
                  d_topk[:, k] < offset_upperbound
              ).float()
          else:
              offset_l_weights[inds, l_label[:, k]] = 1.0
              offset_r_weights[inds, r_label[:, k]] = 1.0
              offset_t_weights[inds, t_label[:, k]] = 1.0
              offset_d_weights[inds, d_label[:, k]] = 1.0
  
      offsets = torch.cat(
          [l_offsets, r_offsets, t_offsets, d_offsets], dim=-1
      )
      offsets_weights = torch.cat(
          [
              offset_l_weights,
              offset_r_weights,
              offset_t_weights,
              offset_d_weights,
          ],
          dim=-1,
      )
  
      # generate bucket labels and weight
      side_num = int(np.ceil(num_buckets / 2.0))
      labels = torch.stack(
          [l_label[:, 0], r_label[:, 0], t_label[:, 0], d_label[:, 0]],
          dim=-1,
      )
  
      batch_size = labels.size(0)
      bucket_labels = (
          F.one_hot(labels.view(-1), side_num)
          .view(batch_size, -1)
          .float()
      )
      bucket_cls_l_weights = (l_offsets.abs() < 1).float()
      bucket_cls_r_weights = (r_offsets.abs() < 1).float()
      bucket_cls_t_weights = (t_offsets.abs() < 1).float()
      bucket_cls_d_weights = (d_offsets.abs() < 1).float()
      bucket_cls_weights = torch.cat(
          [
              bucket_cls_l_weights,
              bucket_cls_r_weights,
              bucket_cls_t_weights,
              bucket_cls_d_weights,
          ],
          dim=-1,
      )
      # ignore second nearest buckets for cls if necessay
      if cls_ignore_neighbor:
          bucket_cls_weights = (
              ~((bucket_cls_weights == 1) & (bucket_labels == 0))
          ).float()
      else:
          bucket_cls_weights[:] = 1.0
      return offsets, offsets_weights, bucket_labels, bucket_cls_weights
  
file_path: insightface/detection/scrfd/mmdet/core/bbox/coder/bucketing_bbox_coder.py
imports: import numpy
  import torch
  import torch.nn.functional
  from ..builder import BBOX_CODERS
  from ..transforms import bbox_rescale
  from .base_bbox_coder import BaseBBoxCoder
label_desc: Use image node_id 2 for calling a global function with example usage: bbox2bucket(proposals, gt, num_buckets, scale_factor, offset_topk, offset_upperbound, cls_ignore_neighbor) and returns: offsets,  offsets_weights,  bucket_labels,  bucket_cls_weights