<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 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