class_docstr: Correlation-based voxel selection component of FCMA.
  
  Parameters
  ----------
  
  labels: list of 1D array
      the condition labels of the epochs
      len(labels) labels equals the number of epochs
  
  epochs_per_subj: int
      The number of epochs of each subject
  
  num_folds: int
      The number of folds to be conducted in the cross validation
  
  raw_data: list of 2D array in shape [epoch length, nVoxels]
      Assumption: 1. all activity data contains the same number of voxels
                  2. the activity data has been z-scored,
                     ready to compute correlation as matrix multiplication
                  3. all subjects have the same number of epochs
                  4. epochs belonging to the same subject are adjacent
                     in the list
                  5. if MPI jobs are running on multiple nodes, the path
                     used must be on a filesystem shared by all nodes
  
  raw_data2: Optional, list of 2D array in shape [epoch length, nVoxels]
      raw_data2 shares the data structure of the assumptions of raw_data
      If raw_data2 is None, the correlation will be computed as
      raw_data by raw_data.
      If raw_data2 is specified, len(raw_data) MUST equal len(raw_data2),
      the correlation will be computed as raw_data by raw_data2.
  
  voxel_unit: int, default 64
      The number of voxels assigned to a worker each time
  
  process_num: Optional[int]
      The maximum number of processes used in cross validation.
      If None, the number of processes will equal
      the number of available hardware threads, considering cpusets
      restrictions.
      If 0, cross validation will not use python multiprocessing.
  
  master_rank: int, default 0
      The process which serves as the master
code: def __init__(
      self,
      labels,
      epochs_per_subj,
      num_folds,
      raw_data,
      raw_data2=None,
      voxel_unit=64,
      process_num=4,
      master_rank=0,
  ):
      self.labels = labels
      self.epochs_per_subj = epochs_per_subj
      self.num_folds = num_folds
      self.raw_data = raw_data
      self.num_voxels = raw_data[0].shape[1]
      self.raw_data2 = raw_data2
      self.num_voxels2 = (
          raw_data2[0].shape[1]
          if raw_data2 is not None
          else self.num_voxels
      )
      self.voxel_unit = voxel_unit
      usable_cpus = usable_cpu_count()
      if process_num is None:
          self.process_num = usable_cpus
      else:
          self.process_num = np.min((process_num, usable_cpus))
      if self.process_num == 0:
          self.use_multiprocessing = False
      else:
          self.use_multiprocessing = True
      self.master_rank = master_rank
      if self.raw_data2 is not None and len(self.raw_data) != len(
          self.raw_data2
      ):
          raise ValueError(
              "The raw data lists must have the same number "
              "of elements for computing the correlations "
              "element by element"
          )
      if self.num_voxels == 0 or self.num_voxels2 == 0:
          raise ValueError("Zero processed voxels")
      if MPI.COMM_WORLD.Get_size() == 1:
          raise RuntimeError(
              "one process cannot run the " "master-worker model"
          )
      if self.master_rank >= MPI.COMM_WORLD.Get_size():
          logger.warn(
              "Master rank exceeds the number of "
              "launched processes, set to 0"
          )
          self.master_rank = 0
  
imports: import numpy
  import time
  from mpi4py import MPI
  from scipy.stats.mstats import zscore
  from sklearn import model_selection
  import sklearn
  from .None import fcma_extension
  from .None import cython_blas
  from ..utils.utils import usable_cpu_count
  import logging
  import multiprocessing
label_desc: Use image node_id 1 to create a new VoxelSelector object  with example: obj = VoxelSelector(labels, epochs_per_subj, num_folds, raw_data, raw_data2, voxel_unit, process_num, master_rank)