code: def prepare_searchlight_mvpa_data(
      images,
      conditions,
      data_type=np.float32,
      random=RandomType.NORANDOM,
  ):
      """obtain the data for activity-based voxel selection using Searchlight
  
      Average the activity within epochs and z-scoring within subject,
      while maintaining the 3D brain structure. In order to save memory,
      the data is processed subject by subject instead of reading all in before
      processing. Assuming all subjects live in the identical cube.
  
      Parameters
      ----------
      images: Iterable[SpatialImage]
          Data.
      conditions: List[UniqueLabelConditionSpec]
          Condition specification.
      data_type
          Type to cast image to.
      random: Optional[RandomType]
          Randomize the image data within subject or not.
  
      Returns
      -------
      processed_data: 4D array in shape [brain 3D + epoch]
          averaged epoch by epoch processed data
  
      labels: 1D array
          contains labels of the data
      """
      time1 = time.time()
      epoch_info = generate_epochs_info(conditions)
      num_epochs = len(epoch_info)
      processed_data = None
      logger.info(
          "there are %d subjects, and in total %d epochs"
          % (len(conditions), num_epochs)
      )
      labels = np.empty(num_epochs)
      # assign labels
      for idx, epoch in enumerate(epoch_info):
          labels[idx] = epoch[0]
      # counting the epochs per subject for z-scoring
      subject_count = np.zeros(len(conditions), dtype=np.int32)
  
      logger.info("start to apply masks and separate epochs")
      for sid, f in enumerate(images):
          data = f.get_fdata().astype(data_type)
          [d1, d2, d3, d4] = data.shape
          if random == RandomType.REPRODUCIBLE:
              data = data.reshape((d1 * d2 * d3, d4))
              _randomize_single_subject(data, seed=sid)
              data = data.reshape((d1, d2, d3, d4))
          elif random == RandomType.UNREPRODUCIBLE:
              data = data.reshape((d1 * d2 * d3, d4))
              _randomize_single_subject(data)
              data = data.reshape((d1, d2, d3, d4))
          if processed_data is None:
              processed_data = np.empty(
                  [d1, d2, d3, num_epochs], dtype=data_type
              )
          # averaging
          for idx, epoch in enumerate(epoch_info):
              if sid == epoch[1]:
                  subject_count[sid] += 1
                  processed_data[:, :, :, idx] = np.mean(
                      data[:, :, :, epoch[2] : epoch[3]], axis=3
                  )
  
          logger.debug(
              "file %s is loaded and processed, with data shape %s",
              f.get_filename(),
              data.shape,
          )
      # z-scoring
      cur_epoch = 0
      for i in subject_count:
          if i > 1:
              processed_data[
                  :, :, :, cur_epoch : cur_epoch + i
              ] = zscore(
                  processed_data[:, :, :, cur_epoch : cur_epoch + i],
                  axis=3,
                  ddof=0,
              )
          cur_epoch += i
      # if zscore fails (standard deviation is zero),
      # set all values to be zero
      processed_data = np.nan_to_num(processed_data)
      time2 = time.time()
      logger.info(
          "data processed for activity-based voxel selection, takes %.2f s"
          % (time2 - time1)
      )
  
      return processed_data, labels
  
file_path: brainiak/brainiak/fcma/preprocessing.py
imports: import math
  import time
  import numpy
  import logging
  from scipy.stats.mstats import zscore
  from mpi4py import MPI
  from enum import Enum
  from ..image import mask_images, multimask_images
label_desc: Use image node_id 7 for calling a global function with example usage: prepare_searchlight_mvpa_data(images, conditions, data_type, random) and returns: processed_data,  labels