class_docstr: Analyzer to extract label stats properties for each case(image and label).
  
  Args:
      image_key: the key to find image data in the callable function input (data)
      label_key: the key to find label data in the callable function input (data)
      do_ccp: performs connected component analysis. Default is True.
  
  Examples:
  
  .. code-block:: python
  
      import numpy as np
      from monai.auto3dseg import LabelStats
  
      input = {}
      input['image'] = np.random.rand(1,30,30,30)
      input['label'] = np.ones([30,30,30])
      analyzer = LabelStats(image_key='image', label_key='label')
      print(analyzer(input)["label_stats"])
class_docstr_tok: ["Analyzer","to","extract","label","stats","properties","for","each","case","(","image","and","label",")",".","Args",":","image_key",":","the","key","to","find","image","data","in","the","callable","function","input","(","data",")","label_key",":","the","key","to","find","label","data","in","the","callable","function","input","(","data",")","do_ccp",":","performs","connected","component","analysis",".","Default","is","True",".","Examples",":","..","code-block",":",":","python","import","numpy","as","np","from","monai.auto3dseg","import","LabelStats","input","=","{","}","input","[","'image","'","]","=","np.random.rand","(","1,30,30,30",")","input","[","'label","'","]","=","np.ones","(","[","30,30,30","]",")","analyzer","=","LabelStats","(","image_key='image","'",",","label_key='label","'",")","print","(","analyzer","(","input",")","[","``","label_stats","''","]",")"]
docstr: Callable to execute the pre-defined functions.
  
  Returns:
      A dictionary. The dict has the key in self.report_format and value
      in a list format. Each element of the value list has stats pre-defined
      by SampleOperations (max, min, ....).
  
  Examples:
      output dict contains {
          LabelStatsKeys.LABEL_UID:[0,1,3],
          LabelStatsKeys.IMAGE_INTST: {...},
          LabelStatsKeys.LABEL:[
              {
                  LabelStatsKeys.PIXEL_PCT: 0.8,
                  LabelStatsKeys.IMAGE_INTST: {...},
                  LabelStatsKeys.LABEL_SHAPE: [...],
                  LabelStatsKeys.LABEL_NCOMP: 1
              }
              {
                  LabelStatsKeys.PIXEL_PCT: 0.1,
                  LabelStatsKeys.IMAGE_INTST: {...},
                  LabelStatsKeys.LABEL_SHAPE: [...],
                  LabelStatsKeys.LABEL_NCOMP: 1
              }
              {
                  LabelStatsKeys.PIXEL_PCT: 0.1,
                  LabelStatsKeys.IMAGE_INTST: {...},
                  LabelStatsKeys.LABEL_SHAPE: [...],
                  LabelStatsKeys.LABEL_NCOMP: 1
              }
          ]
          }
  
  Raises:
      RuntimeError if the stats report generated is not consistent with the pre-
          defined report_format.
  
  Notes:
      The label class_ID of the dictionary in LabelStatsKeys.LABEL IS NOT the
      index. Instead, the class_ID is the LabelStatsKeys.LABEL_UID with the same
      index. For instance, the last dict in LabelStatsKeys.LABEL in the Examples
      is 3, which is the last element under LabelStatsKeys.LABEL_UID.
  
      The stats operation uses numpy and torch to compute max, min, and other
      functions. If the input has nan/inf, the stats results will be nan/inf.
docstr_tok: ["Callable","to","execute","the","pre-defined","functions",".","Returns",":","A","dictionary",".","The","dict","has","the","key","in","self.report_format","and","value","in","a","list","format",".","Each","element","of","the","value","list","has","stats","pre-defined","by","SampleOperations","(","max",",","min",",","....",")",".","Examples",":","output","dict","contains","{","LabelStatsKeys.LABEL_UID",":","[","0,1,3","]",",","LabelStatsKeys.IMAGE_INTST",":","{","...","}",",","LabelStatsKeys.LABEL",":","[","{","LabelStatsKeys.PIXEL_PCT",":","0.8",",","LabelStatsKeys.IMAGE_INTST",":","{","...","}",",","LabelStatsKeys.LABEL_SHAPE",":","[","...","]",",","LabelStatsKeys.LABEL_NCOMP",":","1","}","{","LabelStatsKeys.PIXEL_PCT",":","0.1",",","LabelStatsKeys.IMAGE_INTST",":","{","...","}",",","LabelStatsKeys.LABEL_SHAPE",":","[","...","]",",","LabelStatsKeys.LABEL_NCOMP",":","1","}","{","LabelStatsKeys.PIXEL_PCT",":","0.1",",","LabelStatsKeys.IMAGE_INTST",":","{","...","}",",","LabelStatsKeys.LABEL_SHAPE",":","[","...","]",",","LabelStatsKeys.LABEL_NCOMP",":","1","}","]","}","Raises",":","RuntimeError","if","the","stats","report","generated","is","not","consistent","with","the","pre-","defined","report_format",".","Notes",":","The","label","class_ID","of","the","dictionary","in","LabelStatsKeys.LABEL","IS","NOT","the","index",".","Instead",",","the","class_ID","is","the","LabelStatsKeys.LABEL_UID","with","the","same","index",".","For","instance",",","the","last","dict","in","LabelStatsKeys.LABEL","in","the","Examples","is","3",",","which","is","the","last","element","under","LabelStatsKeys.LABEL_UID",".","The","stats","operation","uses","numpy","and","torch","to","compute","max",",","min",",","and","other","functions",".","If","the","input","has","nan\/inf",",","the","stats","results","will","be","nan\/inf","."]
code: def __call__(
      self, data: Mapping[Hashable, MetaTensor]
  ) -> dict[Hashable, MetaTensor | dict]:
      """
      Callable to execute the pre-defined functions.
  
      Returns:
          A dictionary. The dict has the key in self.report_format and value
          in a list format. Each element of the value list has stats pre-defined
          by SampleOperations (max, min, ....).
  
      Examples:
          output dict contains {
              LabelStatsKeys.LABEL_UID:[0,1,3],
              LabelStatsKeys.IMAGE_INTST: {...},
              LabelStatsKeys.LABEL:[
                  {
                      LabelStatsKeys.PIXEL_PCT: 0.8,
                      LabelStatsKeys.IMAGE_INTST: {...},
                      LabelStatsKeys.LABEL_SHAPE: [...],
                      LabelStatsKeys.LABEL_NCOMP: 1
                  }
                  {
                      LabelStatsKeys.PIXEL_PCT: 0.1,
                      LabelStatsKeys.IMAGE_INTST: {...},
                      LabelStatsKeys.LABEL_SHAPE: [...],
                      LabelStatsKeys.LABEL_NCOMP: 1
                  }
                  {
                      LabelStatsKeys.PIXEL_PCT: 0.1,
                      LabelStatsKeys.IMAGE_INTST: {...},
                      LabelStatsKeys.LABEL_SHAPE: [...],
                      LabelStatsKeys.LABEL_NCOMP: 1
                  }
              ]
              }
  
      Raises:
          RuntimeError if the stats report generated is not consistent with the pre-
              defined report_format.
  
      Notes:
          The label class_ID of the dictionary in LabelStatsKeys.LABEL IS NOT the
          index. Instead, the class_ID is the LabelStatsKeys.LABEL_UID with the same
          index. For instance, the last dict in LabelStatsKeys.LABEL in the Examples
          is 3, which is the last element under LabelStatsKeys.LABEL_UID.
  
          The stats operation uses numpy and torch to compute max, min, and other
          functions. If the input has nan/inf, the stats results will be nan/inf.
      """
      d: dict[Hashable, MetaTensor] = dict(data)
      start = time.time()
      if (
          isinstance(d[self.image_key], (torch.Tensor, MetaTensor))
          and d[self.image_key].device.type == "cuda"
      ):
          using_cuda = True
      else:
          using_cuda = False
      restore_grad_state = torch.is_grad_enabled()
      torch.set_grad_enabled(False)
  
      ndas: list[MetaTensor] = [d[self.image_key][i] for i in range(d[self.image_key].shape[0])]  # type: ignore
      ndas_label: MetaTensor = d[self.label_key].astype(
          torch.int8
      )  # (H,W,D)
  
      if ndas_label.shape != ndas[0].shape:
          raise ValueError(
              f"Label shape {ndas_label.shape} is different from image shape {ndas[0].shape}"
          )
  
      nda_foregrounds: list[torch.Tensor] = [
          get_foreground_label(nda, ndas_label) for nda in ndas
      ]
      nda_foregrounds = [
          nda if nda.numel() > 0 else torch.Tensor([0])
          for nda in nda_foregrounds
      ]
  
      unique_label = unique(ndas_label)
      if isinstance(ndas_label, (MetaTensor, torch.Tensor)):
          unique_label = unique_label.data.cpu().numpy()
  
      unique_label = unique_label.astype(np.int8).tolist()
  
      label_substats = []  # each element is one label
      pixel_sum = 0
      pixel_arr = []
      for index in unique_label:
          start_label = time.time()
          label_dict: dict[str, Any] = {}
          mask_index = ndas_label == index
  
          nda_masks = [nda[mask_index] for nda in ndas]
          label_dict[LabelStatsKeys.IMAGE_INTST] = [
              self.ops[LabelStatsKeys.IMAGE_INTST].evaluate(nda_m)
              for nda_m in nda_masks
          ]
  
          pixel_count = sum(mask_index)
          pixel_arr.append(pixel_count)
          pixel_sum += pixel_count
          if self.do_ccp:  # apply connected component
              if using_cuda:
                  # The back end of get_label_ccp is CuPy
                  # which is unable to automatically release CUDA GPU memory held by PyTorch
                  del nda_masks
                  torch.cuda.empty_cache()
              shape_list, ncomponents = get_label_ccp(mask_index)
              label_dict[LabelStatsKeys.LABEL_SHAPE] = shape_list
              label_dict[LabelStatsKeys.LABEL_NCOMP] = ncomponents
  
          label_substats.append(label_dict)
          logger.debug(
              f" label {index} stats takes {time.time() - start_label}"
          )
  
      for i, _ in enumerate(unique_label):
          label_substats[i].update(
              {
                  LabelStatsKeys.PIXEL_PCT: float(
                      pixel_arr[i] / pixel_sum
                  )
              }
          )
  
      report = deepcopy(self.get_report_format())
      report[LabelStatsKeys.LABEL_UID] = unique_label
      report[LabelStatsKeys.IMAGE_INTST] = [
          self.ops[LabelStatsKeys.IMAGE_INTST].evaluate(nda_f)
          for nda_f in nda_foregrounds
      ]
      report[LabelStatsKeys.LABEL] = label_substats
  
      if not verify_report_format(report, self.get_report_format()):
          raise RuntimeError(
              f"report generated by {self.__class__} differs from the report format."
          )
  
      d[self.stats_name] = report  # type: ignore[assignment]
  
      torch.set_grad_enabled(restore_grad_state)
      logger.debug(f"Get label stats spent {time.time()-start}")
      return d
  
imports: from __future__ import annotations
  import time
  from abc import ABC, abstractmethod
  from collections.abc import Hashable, Mapping
  from copy import deepcopy
  from typing import Any
  import numpy
  import torch
  from monai.apps.utils import get_logger
  from monai.auto3dseg.operations import Operations, SampleOperations, SummaryOperations
  from monai.auto3dseg.utils import concat_multikeys_to_dict, concat_val_to_np, get_foreground_image, get_foreground_label, get_label_ccp, verify_report_format
  from monai.bundle.config_parser import ConfigParser
  from monai.bundle.utils import ID_SEP_KEY
  from monai.data import MetaTensor, affine_to_spacing
  from monai.transforms.transform import MapTransform
  from monai.transforms.utils_pytorch_numpy_unification import sum, unique
  from monai.utils import convert_to_numpy
  from monai.utils.enums import DataStatsKeys, ImageStatsKeys, LabelStatsKeys
  from monai.utils.misc import ImageMetaKey, label_union
label_desc: Use image node_id 2 for calling the LabelStats obj's underlying member method code with example usage: obj.__call__(data) and returns: d