def get_vlr_region(self,
                       bboxes,
                       num_level_bboxes,
                       gt_bboxes,
                       gt_bboxes_ignore=None,
                       gt_labels=None):
        """get vlr region for ld distillation.
        Args:
            bboxes (np.array): Bounding boxes to be assigned, shape(n, 4).
            num_level_bboxes (List): num of bboxes in each level
            gt_bboxes (np.array): Groundtruth boxes, shape (k, 4).
            gt_bboxes_ignore (np.array, optional): Ground truth bboxes that are
                labelled as `ignored`, e.g., crowd boxes in COCO.
            gt_labels (np.array, optional): Label of gt_bboxes, shape (k, ).
        """
        bboxes = bboxes[:, :4]

        num_gt, num_bboxes = gt_bboxes.shape[0], bboxes.shape[0]

        # compute iou between all bbox and gt
        overlaps = bbox_overlaps(bboxes, gt_bboxes)

        # compute diou between all bbox and gt
        diou = bbox_overlaps(bboxes, gt_bboxes, mode='diou')

        # assign 0 by default
        assigned_gt_inds = np.zeros((num_bboxes, ), dtype=np.int64)

        vlr_region_iou = (assigned_gt_inds + 0).astype(np.float32)

        if num_gt == 0 or num_bboxes == 0:
            # No ground truth or boxes, return empty assignment
            max_overlaps = np.zeros((num_bboxes, ))
            if num_gt == 0:
                # No truth, assign everything to background
                assigned_gt_inds[:] = 0
            if not np.any(gt_labels):
                assigned_labels = None
            else:
                assigned_labels = -np.ones((num_bboxes, ), dtype=np.int64)
            return assigned_gt_inds, max_overlaps

        # compute center distance between all bbox and gt
        gt_cx = (gt_bboxes[:, 0] + gt_bboxes[:, 2]) / 2.0
        gt_cy = (gt_bboxes[:, 1] + gt_bboxes[:, 3]) / 2.0
        gt_points = np.stack((gt_cx, gt_cy), axis=1)

        bboxes_cx = (bboxes[:, 0] + bboxes[:, 2]) / 2.0
        bboxes_cy = (bboxes[:, 1] + bboxes[:, 3]) / 2.0
        bboxes_points = np.stack((bboxes_cx, bboxes_cy), axis=1)

        distances = np.sqrt(
            np.power((bboxes_points[:, None, :] - gt_points[None, :, :]), 2)
            .sum(-1))

        # Selecting candidates based on the center distance
        candidate_idxs = []
        candidate_idxs_t = []
        start_idx = 0
        for bboxes_per_level in num_level_bboxes:
            # on each pyramid level, for each gt,
            # select k bbox whose center are closest to the gt center
            end_idx = start_idx + bboxes_per_level
            distances_per_level = distances[start_idx:end_idx, :]
            selectable_t = min(self.topk, bboxes_per_level)
            selectable_k = bboxes_per_level  #k for all
            _, topt_idxs_per_level = topk_(
                distances_per_level, selectable_t, axis=0, largest=False)
            _, topk_idxs_per_level = topk_(
                distances_per_level, selectable_k, axis=0, largest=False)
            candidate_idxs_t.append(topt_idxs_per_level + start_idx)
            candidate_idxs.append(topk_idxs_per_level + start_idx)
            start_idx = end_idx

        candidate_idxs_t = np.concatenate(candidate_idxs_t, axis=0)
        candidate_idxs = np.concatenate(candidate_idxs, axis=0)

        # get corresponding iou for the these candidates, and compute the
        # mean and std, set mean + std as the iou threshold
        candidate_overlaps_t = overlaps[candidate_idxs_t, np.arange(num_gt)]

        # compute tdiou
        t_diou = diou[candidate_idxs, np.arange(num_gt)]

        overlaps_mean_per_gt = candidate_overlaps_t.mean(0)
        overlaps_std_per_gt = candidate_overlaps_t.std(
            0, ddof=1)  # NOTE: use Bessel correction
        overlaps_thr_per_gt = overlaps_mean_per_gt + overlaps_std_per_gt

        # compute region        
        is_pos = (t_diou < overlaps_thr_per_gt[None, :]) & (
            t_diou >= 0.25 * overlaps_thr_per_gt[None, :])

        # limit the positive sample's center in gt
        for gt_idx in range(num_gt):
            candidate_idxs[:, gt_idx] += gt_idx * num_bboxes

        candidate_idxs = candidate_idxs.reshape(-1)

        # if an anchor box is assigned to multiple gts,
        # the one with the highest IoU will be selected.
        overlaps_inf = -np.inf * np.ones_like(overlaps).T.reshape(-1)
        index = candidate_idxs.reshape(-1)[is_pos.reshape(-1)]

        overlaps_inf[index] = overlaps.T.reshape(-1)[index]
        overlaps_inf = overlaps_inf.reshape(num_gt, -1).T

        max_overlaps = overlaps_inf.max(axis=1)
        argmax_overlaps = overlaps_inf.argmax(axis=1)

        overlaps_inf = -np.inf * np.ones_like(overlaps).T.reshape(-1)
        overlaps_inf = overlaps_inf.reshape(num_gt, -1).T

        assigned_gt_inds[max_overlaps !=
                         -np.inf] = argmax_overlaps[max_overlaps != -np.inf] + 1

        vlr_region_iou[max_overlaps !=
                       -np.inf] = max_overlaps[max_overlaps != -np.inf] + 0

        return vlr_region_iou
get vlr region for ld distillation.
        Args:
            bboxes (np.array): Bounding boxes to be assigned, shape(n, 4).
            num_level_bboxes (List): num of bboxes in each level
            gt_bboxes (np.array): Groundtruth boxes, shape (k, 4).
            gt_bboxes_ignore (np.array, optional): Ground truth bboxes that are
                labelled as `ignored`, e.g., crowd boxes in COCO.
            gt_labels (np.array, optional): Label of gt_bboxes, shape (k, ).
        
ppdet/data/transform/atss_assigner.py