code: def prepare_fcma_data(
      images,
      conditions,
      mask1,
      mask2=None,
      random=RandomType.NORANDOM,
      comm=MPI.COMM_WORLD,
  ):
      """Prepare data for correlation-based computation and analysis.
  
      Generate epochs of interests, then broadcast to all workers.
  
      Parameters
      ----------
      images: Iterable[SpatialImage]
          Data.
      conditions: List[UniqueLabelConditionSpec]
          Condition specification.
      mask1: np.ndarray
          Mask to apply to each image.
      mask2: Optional[np.ndarray]
          Mask to apply to each image.
          If it is not specified, the method will assign None to the returning
          variable raw_data2 and the self-correlation on raw_data1 will be
          computed
      random: Optional[RandomType]
          Randomize the image data within subject or not.
      comm: MPI.Comm
          MPI communicator to use for MPI operations.
  
      Returns
      -------
      raw_data1: list of 2D array in shape [epoch length, nVoxels]
          the data organized in epochs, specified by the first mask.
          len(raw_data) equals the number of epochs
      raw_data2: Optional, list of 2D array in shape [epoch length, nVoxels]
          the data organized in epochs, specified by the second mask if any.
          len(raw_data2) equals the number of epochs
      labels: list of 1D array
          the condition labels of the epochs
          len(labels) labels equals the number of epochs
      """
      rank = comm.Get_rank()
      labels = []
      raw_data1 = []
      raw_data2 = []
      if rank == 0:
          logger.info("start to apply masks and separate epochs")
          if mask2 is not None:
              masks = (mask1, mask2)
              activity_data1, activity_data2 = zip(
                  *multimask_images(images, masks, np.float32)
              )
              _randomize_subject_list(activity_data2, random)
              raw_data2, _ = _separate_epochs(
                  activity_data2, conditions
              )
          else:
              activity_data1 = list(
                  mask_images(images, mask1, np.float32)
              )
          _randomize_subject_list(activity_data1, random)
          raw_data1, labels = _separate_epochs(
              activity_data1, conditions
          )
          time1 = time.time()
      raw_data_length = len(raw_data1)
      raw_data_length = comm.bcast(raw_data_length)
      # broadcast the data subject by subject to prevent size overflow
      for i in range(raw_data_length):
          if rank != 0:
              raw_data1.append(None)
              if mask2 is not None:
                  raw_data2.append(None)
          raw_data1[i] = comm.bcast(raw_data1[i], root=0)
          if mask2 is not None:
              raw_data2[i] = comm.bcast(raw_data2[i], root=0)
  
      if comm.Get_size() > 1:
          labels = comm.bcast(labels, root=0)
          if rank == 0:
              time2 = time.time()
              logger.info(
                  "data broadcasting done, takes %.2f s"
                  % (time2 - time1)
              )
      if mask2 is None:
          raw_data2 = None
      return raw_data1, raw_data2, 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 4 for calling a global function with example usage: prepare_fcma_data(images, conditions, mask1, mask2, random, comm) and returns: raw_data1,  raw_data2,  labels