code: def _do_permutations(
      X_full,
      slices,
      threshold,
      tail,
      adjacency,
      stat_fun,
      max_step,
      include,
      partitions,
      t_power,
      orders,
      sample_shape,
      buffer_size,
      progress_bar,
  ):
      n_samp, n_vars = X_full.shape
  
      if buffer_size is not None and n_vars <= buffer_size:
          buffer_size = None  # don't use buffer for few variables
  
      # allocate space for output
      max_cluster_sums = np.empty(len(orders), dtype=np.double)
  
      if buffer_size is not None:
          # allocate buffer, so we don't need to allocate memory during loop
          X_buffer = [
              np.empty(
                  (len(X_full[s]), buffer_size), dtype=X_full.dtype
              )
              for s in slices
          ]
  
      for seed_idx, order in enumerate(orders):
          # shuffle sample indices
          assert order is not None
          idx_shuffle_list = [order[s] for s in slices]
  
          if buffer_size is None:
              # shuffle all data at once
              X_shuffle_list = [
                  X_full[idx, :] for idx in idx_shuffle_list
              ]
              t_obs_surr = stat_fun(*X_shuffle_list)
          else:
              # only shuffle a small data buffer, so we need less memory
              t_obs_surr = np.empty(n_vars, dtype=X_full.dtype)
  
              for pos in range(0, n_vars, buffer_size):
                  # number of variables for this loop
                  n_var_loop = min(pos + buffer_size, n_vars) - pos
  
                  # fill buffer
                  for i, idx in enumerate(idx_shuffle_list):
                      X_buffer[i][:, :n_var_loop] = X_full[
                          idx, pos : pos + n_var_loop
                      ]
  
                  # apply stat_fun and store result
                  tmp = stat_fun(*X_buffer)
                  t_obs_surr[pos : pos + n_var_loop] = tmp[:n_var_loop]
  
          # The stat should have the same shape as the samples for no adj.
          if adjacency is None:
              t_obs_surr.shape = sample_shape
  
          # Find cluster on randomized stats
          out = _find_clusters(
              t_obs_surr,
              threshold=threshold,
              tail=tail,
              max_step=max_step,
              adjacency=adjacency,
              partitions=partitions,
              include=include,
              t_power=t_power,
          )
          perm_clusters_sums = out[1]
  
          if len(perm_clusters_sums) > 0:
              max_cluster_sums[seed_idx] = np.max(perm_clusters_sums)
          else:
              max_cluster_sums[seed_idx] = 0
  
          progress_bar.update(seed_idx + 1)
  
      return max_cluster_sums
  
imports: import numpy
  from scipy import ndimage, sparse
  from scipy.sparse.csgraph import connected_components
  from scipy.stats import f
  from scipy.stats import t
  from ..fixes import has_numba, jit
  from ..parallel import parallel_func
  from ..source_estimate import MixedSourceEstimate, SourceEstimate, VolSourceEstimate
  from ..source_space import SourceSpaces
  from ..utils import ProgressBar, _check_option, _pl, _validate_type, check_random_state, logger, split_list, verbose, warn
  from .parametric import f_oneway, ttest_1samp_no_p
label_desc: Use image node_id 20 for calling a global function with example usage: _do_permutations(X_full, slices, threshold, tail, adjacency, stat_fun, max_step, include, partitions, t_power, orders, sample_shape, buffer_size, progress_bar) and returns: max_cluster_sums