code: def permutation_isc(
      iscs,
      group_assignment=None,
      pairwise=False,  # noqa: C901
      summary_statistic="median",
      n_permutations=1000,
      side="right",
      random_state=None,
  ):
      """Group-level permutation test for ISCs
  
      For ISCs from one or more voxels or ROIs, permute group assignments to
      construct a permutation distribution. Input is a list or ndarray of
      ISCs  for a single voxel/ROI, or an ISCs-by-voxels ndarray. In the
      leave-one-out approach, ISC values for two groups should be stacked
      along first dimension (vertically) and a group_assignment list (or 1d
      array) of same length as the number of subjects should be provided to
      indicate groups. In the pairwise approach, pairwise ISCs should have
      been computed across both groups at once; i.e. the pairwise ISC matrix
      should be shaped N x N where N is the total number of subjects across
      both groups, and should contain between-group ISC pairs. Pairwise ISC
      input should correspond to the vectorized upper triangle of the square
      pairwise ISC correlation matrix containing both groups. In the pairwise
      approach, group_assignment order should match the row/column order of the
      subject-by-subject square ISC matrix even though the input ISCs should be
      supplied as the vectorized upper triangle of the square ISC matrix. If no
      group_assignment is provided, one-sample test is performed using a sign-
      flipping procedure. Performs exact test if number of possible permutations
      (2**N for one-sample sign-flipping, N! for two-sample shuffling) is less
      than or equal to number of requested permutation; otherwise, performs
      approximate permutation test using Monte Carlo resampling. ISC values
      should either be N ISC values for N subjects in the leave-one-out approach
      (pairwise=False) or N(N-1)/2 ISC values for N subjects in the pairwise
      approach (pairwise=True). Returns the observed ISC and permutation-based
      p-value as well as the permutation distribution of summary statistic.
      The p-value corresponds to either a 'two-sided', 'left'-, or 'right'-sided
      (default) test, as specified by side. According to Chen et al., 2016,
      this is the preferred nonparametric approach for controlling false
      positive rates (FPRs) for two-sample tests. Note that the permutation test
      may not strictly control FPRs for one-sample tests.
  
      The implementation is based on the work in [Chen2016]_.
  
      Parameters
      ----------
      iscs : list or ndarray, correlation matrix of ISCs
          ISC values for one or more voxels
  
      group_assignment : list or ndarray, group labels
          Group labels matching order of ISC input
  
      pairwise : bool, default: False
          Indicator of pairwise or leave-one-out, should match ISCs variable
  
      summary_statistic : str, default: 'median'
          Summary statistic, either 'median' (default) or 'mean'
  
      n_permutations : int, default: 1000
          Number of permutation iteration (randomizing group assignment)
  
      side : str
          Perform one-sided ('left' or 'right') or 'two-sided' test
  
      random_state = int, None, or np.random.RandomState, default: None
          Initial random seed
  
      Returns
      -------
      observed : float, ISC summary statistic or difference
          Actual ISC or group difference (excluding between-group ISCs)
  
      p : float, p-value
          p-value based on permutation test
  
      distribution : ndarray, n_permutations by voxels
          Permutation distribution
      """
  
      # Standardize structure of input data
      iscs, n_subjects, n_voxels = _check_isc_input(
          iscs, pairwise=pairwise
      )
  
      # Check for valid summary statistic
      if summary_statistic not in ("mean", "median"):
          raise ValueError(
              "Summary statistic must be 'mean' or 'median'"
          )
  
      # Check match between group labels and ISCs
      group_assignment = _check_group_assignment(
          group_assignment, n_subjects
      )
  
      # Get group parameters
      group_parameters = _get_group_parameters(
          group_assignment, n_subjects, pairwise=pairwise
      )
  
      # Set up permutation type (exact or Monte Carlo)
      if group_parameters["n_groups"] == 1:
          if n_permutations < 2**n_subjects:
              logger.info(
                  "One-sample approximate permutation test using "
                  "sign-flipping procedure with Monte Carlo resampling."
              )
              exact_permutations = None
          else:
              logger.info(
                  "One-sample exact permutation test using "
                  "sign-flipping procedure with 2**{0} "
                  "({1}) iterations.".format(
                      n_subjects, 2**n_subjects
                  )
              )
              exact_permutations = list(
                  product([-1, 1], repeat=n_subjects)
              )
              n_permutations = 2**n_subjects
  
      # Check for exact test for two groups
      else:
          if n_permutations < np.math.factorial(n_subjects):
              logger.info(
                  "Two-sample approximate permutation test using "
                  "group randomization with Monte Carlo resampling."
              )
              exact_permutations = None
          else:
              logger.info(
                  "Two-sample exact permutation test using group "
                  "randomization with {0}! "
                  "({1}) iterations.".format(
                      n_subjects, np.math.factorial(n_subjects)
                  )
              )
              exact_permutations = list(
                  permutations(np.arange(len(group_assignment)))
              )
              n_permutations = np.math.factorial(n_subjects)
  
      # If one group, just get observed summary statistic
      if group_parameters["n_groups"] == 1:
          observed = compute_summary_statistic(
              iscs, summary_statistic=summary_statistic, axis=0
          )[np.newaxis, :]
  
      # If two groups, get the observed difference
      else:
          observed = compute_summary_statistic(
              iscs[
                  group_parameters["group_selector"]
                  == group_parameters["group_labels"][0],
                  :,
              ],
              summary_statistic=summary_statistic,
              axis=0,
          ) - compute_summary_statistic(
              iscs[
                  group_parameters["group_selector"]
                  == group_parameters["group_labels"][1],
                  :,
              ],
              summary_statistic=summary_statistic,
              axis=0,
          )
          observed = np.array(observed)
  
      # Set up an empty list to build our permutation distribution
      distribution = []
  
      # Loop through n permutation iterations and populate distribution
      for i in np.arange(n_permutations):
          # Random seed to be deterministically re-randomized at each iteration
          if exact_permutations:
              prng = None
          elif isinstance(random_state, np.random.RandomState):
              prng = random_state
          else:
              prng = np.random.RandomState(random_state)
  
          # If one group, apply sign-flipping procedure
          if group_parameters["n_groups"] == 1:
              isc_sample = _permute_one_sample_iscs(
                  iscs,
                  group_parameters,
                  i,
                  pairwise=pairwise,
                  summary_statistic=summary_statistic,
                  exact_permutations=exact_permutations,
                  prng=prng,
              )
  
          # If two groups, set up group matrix get the observed difference
          else:
              isc_sample = _permute_two_sample_iscs(
                  iscs,
                  group_parameters,
                  i,
                  pairwise=pairwise,
                  summary_statistic=summary_statistic,
                  exact_permutations=exact_permutations,
                  prng=prng,
              )
  
          # Tack our permuted ISCs onto the permutation distribution
          distribution.append(isc_sample)
  
          # Update random state for next iteration
          if not exact_permutations:
              random_state = np.random.RandomState(
                  prng.randint(0, MAX_RANDOM_SEED)
              )
  
      # Convert distribution to numpy array
      distribution = np.array(distribution)
  
      # Get p-value for actual median from shifted distribution
      if exact_permutations:
          p = p_from_null(
              observed, distribution, side=side, exact=True, axis=0
          )
      else:
          p = p_from_null(
              observed, distribution, side=side, exact=False, axis=0
          )
  
      return observed, p, distribution
  
imports: import numpy
  import logging
  from scipy.spatial.distance import squareform
  from itertools import combinations, permutations, product
  from brainiak.fcma.util import compute_correlation
  from brainiak.utils.utils import array_correlation, phase_randomize, p_from_null, _check_timeseries_input
label_desc: Use image node_id 13 for calling a global function with example usage: permutation_isc(iscs, group_assignment, pairwise, summary_statistic, n_permutations, side, random_state) and returns: observed,  p,  distribution