def cube2map(data_cube, layout):
    r"""Cube to Map

    This method transforms the input data from a 3D cube to a 2D map with a
    specified layout

    Parameters
    ----------
    data_cube : np.ndarray
        Input data cube, 3D array of 2D images
    Layout : tuple
        2D layout of 2D images

    Returns
    -------
    np.ndarray 2D map

    Raises
    ------
    ValueError
        For invalid data dimensions
    ValueError
        For invalid layout

    Examples
    --------
    >>> from modopt.base.transform import cube2map
    >>> a = np.arange(16).reshape((4, 2, 2))
    >>> cube2map(a, (2, 2))
    array([[ 0,  1,  4,  5],
           [ 2,  3,  6,  7],
           [ 8,  9, 12, 13],
           [10, 11, 14, 15]])

    """

    if data_cube.ndim != 3:
        raise ValueError('The input data must have 3 dimensions.')

    if data_cube.shape[0] != np.prod(layout):
        raise ValueError('The desired layout must match the number of input '
                         'data layers.')

    return np.vstack([np.hstack(data_cube[slice(layout[1] * i, layout[1] *
                      (i + 1))]) for i in range(layout[0])])
r"""Cube to Map

    This method transforms the input data from a 3D cube to a 2D map with a
    specified layout

    Parameters
    ----------
    data_cube : np.ndarray
        Input data cube, 3D array of 2D images
    Layout : tuple
        2D layout of 2D images

    Returns
    -------
    np.ndarray 2D map

    Raises
    ------
    ValueError
        For invalid data dimensions
    ValueError
        For invalid layout

    Examples
    --------
    >>> from modopt.base.transform import cube2map
    >>> a = np.arange(16).reshape((4, 2, 2))
    >>> cube2map(a, (2, 2))
    array([[ 0,  1,  4,  5],
           [ 2,  3,  6,  7],
           [ 8,  9, 12, 13],
           [10, 11, 14, 15]])