code: def get_clusters_table(
      stat_img,
      stat_threshold,
      cluster_threshold=None,
      two_sided=False,
      min_distance=8.0,
      return_label_maps=False,
  ):
      """Create pandas dataframe with img cluster statistics.
  
      This function should work on any statistical maps where more extreme values
      indicate greater statistical significance.
      For example, z-statistic or -log10(p) maps are valid inputs, but a p-value
      map is not.
  
      .. important::
  
          For binary clusters (clusters comprised of only one value),
          the table reports the center of mass of the cluster,
          rather than any peaks/subpeaks.
  
          This center of mass may, in some cases, appear outside of the cluster.
  
          .. versionchanged:: 0.9.2
              In this case, the cluster voxel nearest to the center of mass is
              reported.
  
      Parameters
      ----------
      stat_img : Niimg-like object
         Statistical image to threshold and summarize.
  
      stat_threshold : :obj:`float`
          Cluster forming threshold. This value must be in the same scale as
          ``stat_img``.
  
      cluster_threshold : :obj:`int` or None, default=None
          Cluster size threshold, in :term:`voxels<voxel>`.
          If None, then no cluster size threshold will be applied.
  
      two_sided : :obj:`bool`, default=False
          Whether to employ two-sided thresholding or to evaluate positive values
          only.
  
      min_distance : :obj:`float`, default=8
          Minimum distance between subpeaks, in millimeters.
  
          .. note::
              If two different clusters are closer than ``min_distance``, it can
              result in peaks closer than ``min_distance``.
  
      return_label_maps : :obj:`bool`, default=False
          Whether or not to additionally output cluster label map images.
  
          .. versionadded:: 0.10.1
  
      Returns
      -------
      df : :obj:`pandas.DataFrame`
          Table with peaks and subpeaks from thresholded ``stat_img``.
          The columns in this table include:
  
          ================== ====================================================
          Cluster ID         The cluster number. Subpeaks have letters after the
                             number.
          X/Y/Z              The coordinate for the peak, in millimeters.
          Peak Stat          The statistical value associated with the peak.
                             The statistic type is dependent on the type of the
                             statistical image.
          Cluster Size (mm3) The size of the cluster, in millimeters cubed.
                             Rows corresponding to subpeaks will not have a value
                             in this column.
          ================== ====================================================
  
      label_maps : :obj:`list`
          Returned if return_label_maps=True
          List of Niimg-like objects of cluster label maps.
          If two_sided==True, first and second maps correspond
          to positive and negative tails.
  
          .. versionadded:: 0.10.1
  
      """
      cols = [
          "Cluster ID",
          "X",
          "Y",
          "Z",
          "Peak Stat",
          "Cluster Size (mm3)",
      ]
      # Replace None with 0
      cluster_threshold = (
          0 if cluster_threshold is None else cluster_threshold
      )
  
      # check that stat_img is niimg-like object and 3D
      stat_img = check_niimg_3d(stat_img)
      affine = stat_img.affine
      shape = stat_img.shape
  
      # Apply threshold(s) to image
      stat_img = threshold_img(
          img=stat_img,
          threshold=stat_threshold,
          cluster_threshold=cluster_threshold,
          two_sided=two_sided,
          mask_img=None,
          copy=True,
      )
  
      # If cluster threshold is used, there is chance that stat_map will be
      # modified, therefore copy is needed
      stat_map = safe_get_data(
          stat_img,
          ensure_finite=True,
          copy_data=(cluster_threshold is not None),
      )
  
      # Define array for 6-connectivity, aka NN1 or "faces"
      bin_struct = generate_binary_structure(rank=3, connectivity=1)
  
      voxel_size = np.prod(stat_img.header.get_zooms())
  
      signs = [1, -1] if two_sided else [1]
      no_clusters_found = True
      rows = []
      label_maps = []
      for sign in signs:
          # Flip map if necessary
          temp_stat_map = stat_map * sign
  
          # Binarize using cluster-defining threshold
          binarized = temp_stat_map > stat_threshold
          binarized = binarized.astype(int)
  
          # If the stat threshold is too high simply return an empty dataframe
          if np.sum(binarized) == 0:
              warnings.warn(
                  "Attention: No clusters "
                  f'with stat {"higher" if sign == 1 else "lower"} '
                  f"than {stat_threshold * sign}",
                  category=UserWarning,
                  stacklevel=2,
              )
              continue
  
          # Now re-label and create table
          label_map = label(binarized, bin_struct)[0]
          clust_ids = sorted(list(np.unique(label_map)[1:]))
          peak_vals = np.array(
              [
                  np.max(temp_stat_map * (label_map == c))
                  for c in clust_ids
              ]
          )
          # Sort by descending max value
          clust_ids = [clust_ids[c] for c in (-peak_vals).argsort()]
  
          if return_label_maps:
              # Relabel label_map based on sorted ids
              relabel_idx = (
                  np.insert(clust_ids, 0, 0).argsort().astype(np.int32)
              )
              relabel_map = relabel_idx[label_map.flatten()].reshape(
                  shape
              )
              # Save label maps as nifti objects
              label_maps.append(
                  new_img_like(stat_img, relabel_map, affine=affine)
              )
  
          for c_id, c_val in enumerate(clust_ids):
              cluster_mask = label_map == c_val
              masked_data = temp_stat_map * cluster_mask
  
              cluster_size_mm = int(np.sum(cluster_mask) * voxel_size)
  
              # Get peaks, subpeaks and associated statistics
              subpeak_ijk, subpeak_vals = _local_max(
                  masked_data,
                  stat_img.affine,
                  min_distance=min_distance,
              )
              subpeak_vals *= sign  # flip signs if necessary
              subpeak_xyz = np.asarray(
                  coord_transform(
                      subpeak_ijk[:, 0],
                      subpeak_ijk[:, 1],
                      subpeak_ijk[:, 2],
                      stat_img.affine,
                  )
              ).tolist()
              subpeak_xyz = np.array(subpeak_xyz).T
  
              # Only report peak and, at most, top 3 subpeaks.
              n_subpeaks = np.min((len(subpeak_vals), 4))
              for subpeak in range(n_subpeaks):
                  if subpeak == 0:
                      row = [
                          c_id + 1,
                          subpeak_xyz[subpeak, 0],
                          subpeak_xyz[subpeak, 1],
                          subpeak_xyz[subpeak, 2],
                          subpeak_vals[subpeak],
                          cluster_size_mm,
                      ]
                  else:
                      # Subpeak naming convention is cluster num+letter:
                      # 1a, 1b, etc
                      sp_id = (
                          f"{c_id + 1}{ascii_lowercase[subpeak - 1]}"
                      )
                      row = [
                          sp_id,
                          subpeak_xyz[subpeak, 0],
                          subpeak_xyz[subpeak, 1],
                          subpeak_xyz[subpeak, 2],
                          subpeak_vals[subpeak],
                          "",
                      ]
                  rows += [row]
  
          # If we reach this point, there are clusters in this sign
          no_clusters_found = False
  
      if no_clusters_found:
          df = pd.DataFrame(columns=cols)
      else:
          df = pd.DataFrame(columns=cols, data=rows)
  
      return (df, label_maps) if return_label_maps else df
  
file_path: nilearn/nilearn/reporting/get_clusters_table.py
imports: import warnings
  from string import ascii_lowercase
  import nibabel
  import numpy
  import pandas
  from scipy.ndimage import center_of_mass, generate_binary_structure, label, maximum_filter, minimum_filter
  from nilearn._utils import check_niimg_3d
  from nilearn._utils.niimg import safe_get_data
  from nilearn.image import new_img_like, threshold_img
  from nilearn.image.resampling import coord_transform
label_desc: Use image node_id 6 for calling a global function with example usage: get_clusters_table(stat_img, stat_threshold, cluster_threshold, two_sided, min_distance, return_label_maps) and returns: unknown