Cut continuous signal into segments.

    Parameters
    ----------
    x2d : array, shape (m, n)
        Input data with m signals and n samples.
    tr : list of int
        Trigger positions.
    start : int
        Window start (offset relative to trigger).
    stop : int
        Window end (offset relative to trigger).

    Returns
    -------
    x3d : array, shape (len(tr), m, stop-start)
        Segments cut from data. Individual segments are stacked along the first
        dimension.

    See also
    --------
    cat_trials : Concatenate segments.

    Examples
    --------
    >>> data = np.random.randn(5, 1000)  # 5 channels, 1000 samples
    >>> tr = [750, 500, 250]  # three segments
    >>> x3d = cut_segments(data, tr, 50, 100)  # each segment is 50 samples
    >>> x3d.shape
    (3, 5, 50)

def cut_segments(x2d, tr, start, stop):
    """Cut continuous signal into segments.

    Parameters
    ----------
    x2d : array, shape (m, n)
        Input data with m signals and n samples.
    tr : list of int
        Trigger positions.
    start : int
        Window start (offset relative to trigger).
    stop : int
        Window end (offset relative to trigger).

    Returns
    -------
    x3d : array, shape (len(tr), m, stop-start)
        Segments cut from data. Individual segments are stacked along the first
        dimension.

    See also
    --------
    cat_trials : Concatenate segments.

    Examples
    --------
    >>> data = np.random.randn(5, 1000)  # 5 channels, 1000 samples
    >>> tr = [750, 500, 250]  # three segments
    >>> x3d = cut_segments(data, tr, 50, 100)  # each segment is 50 samples
    >>> x3d.shape
    (3, 5, 50)
    """
    if start != int(start):
        raise ValueError("start index must be an integer")
    if stop != int(stop):
        raise ValueError("stop index must be an integer")

    x2d = np.atleast_2d(x2d)
    tr = np.asarray(tr, dtype=int).ravel()
    win = np.arange(start, stop, dtype=int)
    return np.concatenate([x2d[np.newaxis, :, t + win] for t in tr])