def _cwt(X, Ws, mode="same", decim=1, use_fft=True):
    if mode not in ['same', 'valid', 'full']:
        raise ValueError("`mode` must be 'same', 'valid' or 'full', "
                         "got %s instead." % mode)
    if mode == 'full' and (not use_fft):
        # XXX JRK: full wavelet decomposition needs to be implemented
        raise ValueError('`full` decomposition with convolution is currently' +
                         ' not supported.')
    X = np.asarray(X)

    # Precompute wavelets for given frequency range to save time
    n_signals, n_times = X.shape
    n_freqs = len(Ws)

    Ws_max_size = max(W.size for W in Ws)
    size = n_times + Ws_max_size - 1
    # Always use 2**n-sized FFT
    fsize = 2 ** int(np.ceil(np.log2(size)))

    # precompute FFTs of Ws
    if use_fft:
        fft_Ws = np.empty((n_freqs, fsize), dtype=np.complex128)
    for i, W in enumerate(Ws):
        if len(W) > n_times:
            raise ValueError('Wavelet is too long for such a short signal. '
                             'Reduce the number of cycles.')
        if use_fft:
            fft_Ws[i] = fftn(W, [fsize])

    # Decimating is performed after centering the convolution, and can
    # therefore lead to one extra time sample.
    n_times_out = n_times // decim + bool(n_times % decim)

    # Make generator looping across signals
    tfr = np.zeros((n_freqs, n_times_out), dtype=np.complex128)
    for x in X:
        if use_fft:
            fft_x = fftn(x, [fsize])

        # Loop across wavelets
        for ii, W in enumerate(Ws):
            if use_fft:
                ret = ifftn(fft_x * fft_Ws[ii])[:n_times + W.size - 1]
            else:
                ret = np.convolve(x, W, mode=mode)

            # Center and decimate decomposition
            if mode == "valid":
                sz = abs(W.size - n_times) + 1
                offset = (n_times - sz) / 2
                this_slice = slice(offset // decim, (offset + sz) // decim)
                if use_fft:
                    ret = _centered(ret, sz)
                tfr[ii, this_slice] = ret[::decim]
            else:
                if use_fft:
                    ret = _centered(ret, n_times)
                tfr[ii, :] = ret[::decim]
        yield tfr
Compute cwt with fft based convolutions or temporal convolutions.
dataset/ETHPy150Open mne-tools/mne-python/mne/time_frequency/tfr.py/_cwt