class_docstr: CenterNetUpdateHead is an improved version of CenterNet in CenterNet2.
  Paper link `<https://arxiv.org/abs/2103.07461>`_.
  
  Args:
      num_classes (int): Number of categories excluding the background
          category.
      in_channels (int): Number of channel in the input feature map.
      regress_ranges (Sequence[Tuple[int, int]]): Regress range of multiple
          level points.
      hm_min_radius (int): Heatmap target minimum radius of cls branch.
          Defaults to 4.
      hm_min_overlap (float): Heatmap target minimum overlap of cls branch.
          Defaults to 0.8.
      more_pos_thresh (float): The filtering threshold when the cls branch
          adds more positive samples. Defaults to 0.2.
      more_pos_topk (int): The maximum number of additional positive samples
          added to each gt. Defaults to 9.
      soft_weight_on_reg (bool): Whether to use the soft target of the
          cls branch as the soft weight of the bbox branch.
          Defaults to False.
      loss_cls (:obj:`ConfigDict` or dict): Config of cls loss. Defaults to
          dict(type='GaussianFocalLoss', loss_weight=1.0)
      loss_bbox (:obj:`ConfigDict` or dict): Config of bbox loss. Defaults to
           dict(type='GIoULoss', loss_weight=2.0).
      norm_cfg (:obj:`ConfigDict` or dict, optional): dictionary to construct
          and config norm layer.  Defaults to
          ``norm_cfg=dict(type='GN', num_groups=32, requires_grad=True)``.
      train_cfg (:obj:`ConfigDict` or dict, optional): Training config.
          Unused in CenterNet. Reserved for compatibility with
          SingleStageDetector.
      test_cfg (:obj:`ConfigDict` or dict, optional): Testing config
          of CenterNet.
docstr: Compute classification and bbox targets for a single image.
docstr_tok: ["Compute","classification","and","bbox","targets","for","a","single","image","."]
code: def _get_targets_single(
      self,
      gt_instances: InstanceData,
      points: Tensor,
      regress_ranges: Tensor,
      strides: Tensor,
  ) -> Tuple[Tensor, Tensor]:
      """Compute classification and bbox targets for a single image."""
      num_points = points.size(0)
      num_gts = len(gt_instances)
      gt_bboxes = gt_instances.bboxes
      gt_labels = gt_instances.labels
  
      if num_gts == 0:
          return gt_labels.new_full(
              (num_points, self.num_classes), self.num_classes
          ), gt_bboxes.new_full((num_points, 4), -1)
  
      # Calculate the regression tblr target corresponding to all points
      points = points[:, None].expand(num_points, num_gts, 2)
      gt_bboxes = gt_bboxes[None].expand(num_points, num_gts, 4)
      strides = strides[:, None, None].expand(num_points, num_gts, 2)
  
      bbox_target = bbox2distance(points, gt_bboxes)  # M x N x 4
  
      # condition1: inside a gt bbox
      inside_gt_bbox_mask = bbox_target.min(dim=2)[0] > 0  # M x N
  
      # condition2: Calculate the nearest points from
      # the upper, lower, left and right ranges from
      # the center of the gt bbox
      centers = (gt_bboxes[..., [0, 1]] + gt_bboxes[..., [2, 3]]) / 2
      centers_discret = (
          (centers / strides).int() * strides
      ).float() + strides / 2
  
      centers_discret_dist = points - centers_discret
      dist_x = centers_discret_dist[..., 0].abs()
      dist_y = centers_discret_dist[..., 1].abs()
      inside_gt_center3x3_mask = (dist_x <= strides[..., 0]) & (
          dist_y <= strides[..., 0]
      )
  
      # condition3: limit the regression range for each location
      bbox_target_wh = bbox_target[..., :2] + bbox_target[..., 2:]
      crit = (bbox_target_wh**2).sum(dim=2) ** 0.5 / 2
      inside_fpn_level_mask = (crit >= regress_ranges[:, [0]]) & (
          crit <= regress_ranges[:, [1]]
      )
      bbox_target_mask = (
          inside_gt_bbox_mask
          & inside_gt_center3x3_mask
          & inside_fpn_level_mask
      )
  
      # Calculate the distance weight map
      gt_center_peak_mask = (centers_discret_dist**2).sum(dim=2) == 0
      weighted_dist = ((points - centers) ** 2).sum(dim=2)  # M x N
      weighted_dist[gt_center_peak_mask] = 0
  
      areas = (gt_bboxes[..., 2] - gt_bboxes[..., 0]) * (
          gt_bboxes[..., 3] - gt_bboxes[..., 1]
      )
      radius = self.delta**2 * 2 * areas
      radius = torch.clamp(radius, min=self.hm_min_radius**2)
      weighted_dist = weighted_dist / radius
  
      # Calculate bbox_target
      bbox_weighted_dist = weighted_dist.clone()
      bbox_weighted_dist[bbox_target_mask == 0] = INF * 1.0
      min_dist, min_inds = bbox_weighted_dist.min(dim=1)
      bbox_target = bbox_target[
          range(len(bbox_target)), min_inds
      ]  # M x N x 4 --> M x 4
      bbox_target[min_dist == INF] = -INF
  
      # Convert to feature map scale
      bbox_target /= strides[:, 0, :].repeat(1, 2)
  
      # Calculate cls_target
      cls_target = self._create_heatmaps_from_dist(
          weighted_dist, gt_labels
      )
  
      return cls_target, bbox_target
  
imports: from typing import Dict, List, Optional, Sequence, Tuple
  import torch
  import torch.nn
  from mmcv.cnn import Scale
  from mmengine.structures import InstanceData
  from torch import Tensor
  from mmdet.registry import MODELS
  from mmdet.structures.bbox import bbox2distance
  from mmdet.utils import ConfigType, InstanceList, OptConfigType, OptInstanceList, reduce_mean
  from ..utils import multi_apply
  from .anchor_free_head import AnchorFreeHead
label_desc: Use image node_id 7 for calling the CenterNetUpdateHead obj's underlying member method code with example usage: obj._get_targets_single(gt_instances, points, regress_ranges, strides) and returns: cls_target,  bbox_target, gt_labels,  gt_bboxes