def _compute_window_inds(
    starts,
    stops,
    start_offset,
    stop_offset,
    size,
    stride,
    drop_last_window,
    accepted_bads_ratio,
):
    """Compute window start and stop indices.

    Create window starts from trial onsets (shifted by start_offset) to trial
    end (shifted by stop_offset) separated by stride, as long as window size
    fits into trial.

    Parameters
    ----------
    starts: array-like
        Trial starts in samples.
    stops: array-like
        Trial stops in samples.
    start_offset: int
        Start offset from original trial onsets in samples.
    stop_offset: int
        Stop offset from original trial stop in samples.
    size: int
        Window size.
    stride: int
        Stride between windows.
    drop_last_window: bool
        Toggles of shifting last window within range or dropping last samples.
    accepted_bads_ratio: float
        Acceptable proportion of bad trials within a raw. If the number of
        trials whose length is exceeded by the window size is smaller than
        this, then only the corresponding trials are dropped, but the
        computation continues. Otherwise, an error is raised.

    Returns
    -------
    result_lists: (list, list, list, list)
        Trial, i_window_in_trial, start sample and stop sample of windows.
    """
    starts = np.array([starts]) if isinstance(starts, int) else starts
    stops = np.array([stops]) if isinstance(stops, int) else stops

    starts += start_offset
    stops += stop_offset
    if any(size > (stops - starts)):
        bads_mask = size > (stops - starts)
        min_duration = (stops - starts).min()
        if sum(bads_mask) <= accepted_bads_ratio * len(starts):
            starts = starts[np.logical_not(bads_mask)]
            stops = stops[np.logical_not(bads_mask)]
            warnings.warn(
                f"Trials {np.where(bads_mask)[0]} are being dropped as the "
                f"window size ({size}) exceeds their duration {min_duration}."
            )
        else:
            current_ratio = sum(bads_mask) / len(starts)
            raise ValueError(
                f"Window size {size} exceeds trial duration "
                f"({min_duration}) for too many trials "
                f"({current_ratio * 100}%). Set "
                f"accepted_bads_ratio to at least {current_ratio}"
                "and restart training to be able to continue."
            )

    i_window_in_trials, i_trials, window_starts = [], [], []
    for start_i, (start, stop) in enumerate(zip(starts, stops)):
        # Generate possible window starts, with given stride, between original
        # trial onsets and stops (shifted by start_offset and stop_offset,
        # respectively)
        possible_starts = np.arange(start, stop, stride)

        # Possible window start is actually a start, if window size fits in
        # trial start and stop
        for i_window, s in enumerate(possible_starts):
            if (s + size) <= stop:
                window_starts.append(s)
                i_window_in_trials.append(i_window)
                i_trials.append(start_i)

        # If the last window start + window size is not the same as
        # stop + stop_offset, create another window that overlaps and stops
        # at onset + stop_offset
        if not drop_last_window:
            if window_starts[-1] + size != stop:
                window_starts.append(stop - size)
                i_window_in_trials.append(i_window_in_trials[-1] + 1)
                i_trials.append(start_i)

    # Set window stops to be event stops (rather than trial stops)
    window_stops = np.array(window_starts) + size
    if not (len(i_window_in_trials) == len(window_starts) == len(window_stops)):
        raise ValueError(
            f"{len(i_window_in_trials)} == {len(window_starts)} == {len(window_stops)}"
        )

    return i_trials, i_window_in_trials, window_starts, window_stops
Compute window start and stop indices.

    Create window starts from trial onsets (shifted by start_offset) to trial
    end (shifted by stop_offset) separated by stride, as long as window size
    fits into trial.

    Parameters
    ----------
    starts: array-like
        Trial starts in samples.
    stops: array-like
        Trial stops in samples.
    start_offset: int
        Start offset from original trial onsets in samples.
    stop_offset: int
        Stop offset from original trial stop in samples.
    size: int
        Window size.
    stride: int
        Stride between windows.
    drop_last_window: bool
        Toggles of shifting last window within range or dropping last samples.
    accepted_bads_ratio: float
        Acceptable proportion of bad trials within a raw. If the number of
        trials whose length is exceeded by the window size is smaller than
        this, then only the corresponding trials are dropped, but the
        computation continues. Otherwise, an error is raised.

    Returns
    -------
    result_lists: (list, list, list, list)
        Trial, i_window_in_trial, start sample and stop sample of windows.
    
braindecode/preprocessing/windowers.py