Ejemplo n.º 1
0
 def test_window_derivative(self):
     """Test if the derivative of a window function is calculated
     properly."""
     window = hanning(210)
     derivative = derive_window(window)
     ix_win_maxima = np.argmax(window)
     self.assertAlmostEqual(derivative[ix_win_maxima], 0.0, places=3)
Ejemplo n.º 2
0
 def test_window_derivative(self):
     """Test if the derivative of a window function is calculated
     properly."""
     window = hanning(210)
     derivative = derive_window(window)
     ix_win_maxima = np.argmax(window)
     self.assertAlmostEqual(derivative[ix_win_maxima], 0.0, places=3)
Ejemplo n.º 3
0
 def test_derive_window(self):
     """Test derivative of window function."""
     from scipy.signal import gaussian
     g = gaussian(129, 10)
     dwindow = utils.derive_window(g)
     self.assertEqual(dwindow[64], 0)
     self.assertTrue(np.all(dwindow[:64] >= 0))
     self.assertTrue(np.all(dwindow[64:] <= 0))
Ejemplo n.º 4
0
 def test_derive_window(self):
     """Test derivative of window function."""
     from scipy.signal import gaussian
     g = gaussian(129, 10)
     dwindow = utils.derive_window(g)
     self.assertEqual(dwindow[64], 0)
     self.assertTrue(np.all(dwindow[:64] >= 0))
     self.assertTrue(np.all(dwindow[64:] <= 0))
Ejemplo n.º 5
0
 def test_window_derivative(self):
     window = hanning(210)
     derivative = derive_window(window)
     ix_win_maxima = np.argmax(window)
     self.assertAlmostEqual(derivative[ix_win_maxima], 0.0, places=3)
Ejemplo n.º 6
0
def pseudo_margenau_hill(signal, timestamps=None, n_fbins=None, fwindow=None):
    """pseudo_margenau_hill

    :param signal:
    :param timestamps:
    :param n_fbins:
    :param fwindow:
    :type signal:
    :type timestamps:
    :type n_fbins:
    :type fwindow:
:return:
:rtype:
    """
    xrow = signal.shape[0]
    if timestamps is None:
        timestamps = np.arange(signal.shape[0])
    if n_fbins is None:
        n_fbins = signal.shape[0]
    tcol = timestamps.shape[0]

    if fwindow is None:
        hlength = np.floor(n_fbins / 4.0)
        if hlength % 2 == 0:
            hlength += 1
        fwindow = ssig.hamming(hlength)
    elif fwindow.shape[0] % 2 == 0:
        raise ValueError('The smoothing fwindow must have an odd length.')
    lh = (fwindow.shape[0] - 1) / 2
    fwindow = fwindow / fwindow[lh]

    tfr = np.zeros((n_fbins, tcol), dtype=complex)
    tf2 = np.zeros((n_fbins, tcol), dtype=complex)
    dh = derive_window(fwindow)
    tfr = np.zeros((n_fbins, tcol), dtype=complex)
    for icol in range(tcol):
        ti = timestamps[icol]
        start = min([np.round(n_fbins / 2.0) - 1, lh, xrow - ti])
        end = min([np.round(n_fbins / 2.0) - 1, lh, ti - 1])
        tau = np.arange(-start, end + 1)
        indices = np.remainder(n_fbins + tau, n_fbins)
        tfr[indices, icol] = fwindow[lh + tau] * signal[ti - 1] * \
            np.conj(signal[ti - tau - 1])
        tf2[indices, icol] = dh[lh + tau] * signal[ti - 1] * \
            np.conj(signal[ti - tau - 1])

    tfr = np.fft.fft(tfr, axis=0)
    tf2 = np.fft.fft(tf2, axis=0)
    tfr = tfr.ravel()
    tf2 = tf2.ravel()
    no_warn_mask = tfr != 0
    tf2[no_warn_mask] *= n_fbins / tfr[no_warn_mask] / (2 * np.pi)
    tf2[no_warn_mask] = np.round(tf2[no_warn_mask])
    tfr = np.real(tfr)
    tf2 = np.imag(tf2)
    tfr = tfr.reshape(n_fbins, tcol)
    tf2 = tf2.reshape(n_fbins, tcol)

    rtfr = np.zeros((n_fbins, tcol), dtype=complex)
    threshold = 1.0e-6 * (np.abs(signal) ** 2).mean()

    for icol in range(tcol):
        for jcol in range(n_fbins):
            if np.abs(tfr[jcol, icol]) > threshold:
                jcolhat = jcol - tf2[jcol, icol]
                jcolhat = (((jcolhat - 1) % n_fbins) + n_fbins) % n_fbins
                jcolhat += 1
                rtfr[jcolhat - 1, icol] += tfr[jcol, icol]
                tf2[jcol, icol] = jcolhat
            else:
                tf2[jcol, icol] = np.inf
                rtfr[jcol, icol] += tfr[jcol, icol]

    return tfr, rtfr, tf2
Ejemplo n.º 7
0
def spectrogram(signal, time_samples=None, n_fbins=None, window=None):
    """Compute the spectrogram and reassigned spectrogram.

    :param signal: signal to be analzsed
    :param time_samples: time instants (default: np.arange(len(signal)))
    :param n_fbins: number of frequency bins (default: len(signal))
    :param window: frequency smoothing window (default: Hamming with \
        size=len(signal)/4)
    :type signal: array-like
    :type time_samples: array-like
    :type n_fbins: int
    :type window: array-like

    :return: spectrogram, reassigned specstrogram and matrix of reassignment \
        vectors
    :rtype: tuple(array-like)
    """
    if time_samples is None:
        time_samples = np.arange(signal.shape[0])
    elif np.unique(np.diff(time_samples)).shape[0] > 1:
        raise ValueError('Time instants must be regularly sampled.')
    if n_fbins is None:
        n_fbins = signal.shape[0]
    if window is None:
        wlength = int(np.floor(signal.shape[0] / 4.0))
        wlength += 1 - np.remainder(wlength, 2)
        window = ssig.hamming(wlength)
    elif window.shape[0] % 2 == 0:
        raise ValueError('The smoothing window must have an odd length.')

    tfr = np.zeros((n_fbins, time_samples.shape[0]), dtype=complex)
    tf2 = np.zeros((n_fbins, time_samples.shape[0]), dtype=complex)
    tf3 = np.zeros((n_fbins, time_samples.shape[0]), dtype=complex)
    lh = (window.shape[0] - 1) // 2
    th = window * np.arange(-lh, lh + 1)
    dwin = derive_window(window)

    for icol in range(time_samples.shape[0]):
        ti = time_samples[icol]
        tau = np.arange(-np.min([np.round(n_fbins / 2) - 1, lh, ti]),
                        np.min([np.round(n_fbins / 2) - 1, lh,
                                signal.shape[0] - ti]) + 1).astype(int)
        indices = np.remainder(n_fbins + tau, n_fbins)
        norm_h = np.linalg.norm(window[lh + tau], ord=2)
        tfr[indices, icol] = signal[ti + tau - 1] * np.conj(window[lh + tau]) / norm_h
        tf2[indices, icol] = signal[ti + tau - 1] * np.conj(th[lh + tau]) / norm_h
        tf3[indices, icol] = signal[ti + tau - 1] * np.conj(dwin[lh + tau]) / norm_h

    tfr = np.fft.fft(tfr, axis=0).ravel()
    tf2 = np.fft.fft(tf2, axis=0).ravel()
    tf3 = np.fft.fft(tf3, axis=0).ravel()

    no_warn_mask = tfr != 0
    tf2[no_warn_mask] = np.round(np.real(tf2[no_warn_mask] / tfr[no_warn_mask]))
    tf3[no_warn_mask] = np.round(
        np.imag(n_fbins * tf3[no_warn_mask] / tfr[no_warn_mask] / (2 * np.pi)))

    tfr = np.abs(tfr) ** 2
    tfr = tfr.reshape(n_fbins, time_samples.shape[0])
    tf2 = tf2.reshape(n_fbins, time_samples.shape[0])
    tf3 = tf3.reshape(n_fbins, time_samples.shape[0])
    tf3 = np.real(tf3)

    rtfr = np.zeros((n_fbins, time_samples.shape[0]), dtype=complex)
    ix = np.arange(time_samples.min(), time_samples.max() + 1) - 1
    threshold = 1e-6 * np.mean(np.abs(signal[ix])**2)
    for icol in range(time_samples.shape[0]):
        for jcol in range(n_fbins):
            if np.abs(tfr[jcol, icol]) > threshold:
                icolhat = icol + tf2[jcol, icol]
                icolhat = np.min([np.max([icolhat, 1]), time_samples.shape[0]])
                jcolhat = jcol - tf3[jcol, icol]
                jcolhat = (((jcolhat - 1) % n_fbins) + n_fbins) % n_fbins
                rtfr[int(jcolhat), int(icolhat) - 1] += tfr[jcol, icol]
                tf2[jcol, icol] = jcolhat + 1j * icolhat
            else:
                tf2[jcol, icol] = np.inf
                rtfr[jcol, icol] += tfr[jcol, icol]
    return tfr, rtfr, tf2
Ejemplo n.º 8
0
def smoothed_pseudo_wigner_ville(signal, timestamps=None, n_fbins=None,
                                 twindow=None, fwindow=None):
    """smoothed_pseudo_wigner_ville

    :param signal:
    :param timestamps:
    :param n_fbins:
    :param twindow:
    :param fwindow:
    :type signal:
    :type timestamps:
    :type n_fbins:
    :type twindow:
    :type fwindow:

    :return:
    :rtype:
    """
    xrow = signal.shape[0]

    if timestamps is None:
        timestamps = np.arange(signal.shape[0])
    if n_fbins is None:
        n_fbins = signal.shape[0]
    if fwindow is None:
        hlength = np.floor(n_fbins / 4.0)
        hlength += 1 - (hlength % 2)
        fwindow = ssig.hamming(hlength)
    elif fwindow.shape[0] % 2 == 0:
        raise ValueError('The smoothing window must have an odd length.')
    lh = (fwindow.shape[0] - 1) / 2

    if twindow is None:
        glength = np.floor(n_fbins / 4.0)
        glength += 1 - (glength % 2)
        twindow = ssig.hamming(glength)
    elif twindow.shape[0] % 2 == 0:
        raise ValueError('The smoothing window must have an odd length.')
    lg = (twindow.shape[0] - 1) / 2

    tcol = timestamps.shape[0]
    deltat = timestamps[1:] - timestamps[:-1]
    if deltat.min() != deltat.max():
        raise ValueError("Time instants must be regularly sampled.")
    else:
        dt = deltat.min()

    tfr = np.zeros((n_fbins, tcol), dtype=complex)
    tf2 = np.zeros((n_fbins, tcol), dtype=complex)
    tf3 = np.zeros((n_fbins, tcol), dtype=complex)
    dh = derive_window(fwindow)

    for icol in range(tcol):
        ti = timestamps[icol]
        taumax = min([ti + lg - 1, xrow - ti + lg, np.round(n_fbins / 2.0) - 1,
                      lh])
        points = np.arange(-min([lg, xrow - ti]), min([lg, ti - 1]) + 1)
        g2 = twindow[lg + points]
        g2 = g2 / g2.sum()
        tg2 = g2 * points
        xx = signal[ti - 1 - points] * np.conj(signal[ti - 1 - points])
        tfr[0, icol] = (g2 * xx).sum()
        tf2[0, icol] = (tg2 * xx).sum()
        tf3[0, icol] = dh[lh + 1] * tfr[0, icol]

        for tau in range(int(taumax)):
            points = np.arange(-min([lg, xrow - ti - tau]),
                               min([lg, ti - tau - 1]) + 1)
            g2 = twindow[lg + points]
            g2 = g2 / g2.sum()
            tg2 = g2 * points
            xx = signal[ti + tau - 1 - points] * np.conj(signal[ti - tau - 1 - points])
            tfr[tau, icol] = (g2 * xx).sum() * fwindow[lh + tau]
            tf2[tau, icol] = fwindow[lh + tau] * (tg2 * xx).sum()
            tf3[tau, icol] = dh[lh + tau] * (g2 * xx).sum()
            tfr[n_fbins - tau - 1, icol] = (g2 * np.conj(xx)).sum() * fwindow[lh - tau]
            tf2[n_fbins - tau - 1, icol] = (tg2 * np.conj(xx)).sum() * fwindow[lh - tau]
            tf3[n_fbins - tau - 1, icol] = dh[lh - tau] * (g2 * np.conj(xx)).sum()

    tfr = np.real(np.fft.fft(tfr, axis=0)).ravel()
    tf2 = np.real(np.fft.fft(tf2, axis=0)).ravel()
    tf3 = np.imag(np.fft.fft(tf3, axis=0)).ravel()

    no_warn_mask = tfr != 0
    tf2[no_warn_mask] = np.round(tf2[no_warn_mask] / tfr[no_warn_mask] / dt)
    tf3[no_warn_mask] = np.round(
        n_fbins * tf3[no_warn_mask] / tfr[no_warn_mask] / (2 * np.pi))
    tfr, tf2, tf3 = [x.reshape(n_fbins, tcol).astype(complex) for x in (tfr, tf2, tf3)]
    tf3 = np.real(tf3)

    rtfr = np.zeros((n_fbins, tcol), dtype=complex)
    ex = np.mean(np.abs(signal) ** 2)
    threshold = ex * 1.0e-6

    for icol in range(tcol):
        for jcol in range(n_fbins):
            if np.abs(tfr[jcol, icol]) > threshold:
                icolhat = min(max([icol - tf2[jcol, icol], 1]), tcol)
                jcolhat = jcol - tf3[jcol, icol]
                jcolhat = (((int(jcolhat) - 1) % n_fbins) + n_fbins) % n_fbins + 1
                rtfr[jcol, icol] += tfr[jcol, icol]
                tf2[jcol, icol] = jcolhat + 1j * icolhat
            else:
                tf2[jcol, icol] = np.inf * (1 + 1j)
                rtfr[jcol, icol] += tfr[jcol, icol]

    return tfr, rtfr, tf2
Ejemplo n.º 9
0
def pseudo_wigner_ville(signal, timestamps=None, n_fbins=None, fwindow=None):
    """pseudo_wigner_ville

    :param signal:
    :param timestamps:
    :param n_fbins:
    :param fwindow:
    :type signal:
    :type timestamps:
    :type n_fbins:
    :type fwindow:
:return:
:rtype:
    """
    xrow = signal.shape[0]
    if timestamps is None:
        timestamps = np.arange(signal.shape[0])
    if n_fbins is None:
        n_fbins = signal.shape[0]
    tcol = timestamps.shape[0]

    if fwindow is None:
        hlength = np.floor(n_fbins / 4.0)
        if hlength % 2 == 0:
            hlength += 1
        fwindow = ssig.hamming(int(hlength))
    elif fwindow.shape[0] % 2 == 0:
        raise ValueError('The smoothing fwindow must have an odd length.')
    lh = (fwindow.shape[0] - 1) // 2
    fwindow = fwindow / fwindow[lh]

    tfr = np.zeros((n_fbins, tcol), dtype=complex)
    tf2 = np.zeros((n_fbins, tcol), dtype=complex)
    dh = derive_window(fwindow)
    for icol in range(tcol):
        ti = timestamps[icol]
        taumax = min([ti - 1, xrow - ti, np.round(n_fbins / 2.0) - 1, lh])
        tau = np.arange(-taumax, taumax + 1)
        indices = np.remainder(n_fbins + tau, n_fbins) + 1
        tfr[indices - 1, icol] = fwindow[lh + tau] * signal[ti + tau - 1] * \
            np.conj(signal[ti - tau - 1])
        tf2[indices - 1, icol] = dh[lh + tau] * signal[ti + tau - 1] * \
            np.conj(signal[ti - tau - 1])
        tau = np.round(n_fbins / 2)
        if (ti <= (xrow - tau)) and (ti > (tau + 1)) and (tau <= lh):
            _x = fwindow[lh + 1 + tau] * signal[ti + tau] * np.conj(signal[ti - tau])
            _y = fwindow[lh + 1 - tau] * signal[ti - tau] * np.conj(signal[ti + tau])
            tfr[tau + 1, icol] = (_x + _y) * 0.5
            _x = dh[lh + 1 + tau] * signal[ti + tau] * np.conj(signal[ti - tau])
            _y = dh[lh + 1 - tau] * signal[ti - tau] * np.conj(signal[ti + tau])
            tf2[tau + 1, icol] = (_x + _y) * 0.5
    tfr = np.real(np.fft.fft(tfr, axis=0))
    tf2 = np.imag(np.fft.fft(tf2, axis=0))
    tfr = tfr.ravel()
    tf2 = tf2.ravel()
    no_warn_mask = tfr != 0
    tf2[no_warn_mask] *= n_fbins / tfr[no_warn_mask] / (2 * np.pi)
    tf2[no_warn_mask] = np.round(tf2[no_warn_mask])
    tfr = tfr.reshape(n_fbins, tcol)
    tf2 = tf2.reshape(n_fbins, tcol)

    rtfr = np.zeros((n_fbins, tcol), dtype=complex)
    tmin = timestamps.min()
    tmax = timestamps.max()
    threshold = 1.0e-6 * (np.abs(signal[tmin:(tmax + 1)]) ** 2).mean()

    for icol in range(tcol):
        for jcol in range(n_fbins):
            if np.abs(tfr[jcol, icol]) > threshold:
                jcolhat = jcol - int(tf2[jcol, icol])
                jcolhat = (((jcolhat - 1) % n_fbins) + n_fbins) % n_fbins
                jcolhat += 1
                rtfr[jcolhat - 1, icol] += tfr[jcol, icol]
                tf2[jcol, icol] = jcolhat
            else:
                tf2[jcol, icol] = np.inf
                rtfr[jcol, icol] += tfr[jcol, icol]

    return tfr, rtfr, tf2
Ejemplo n.º 10
0
def pseudo_margenau_hill(signal, timestamps=None, n_fbins=None, fwindow=None):
    """pseudo_margenau_hill

    :param signal:
    :param timestamps:
    :param n_fbins:
    :param fwindow:
    :type signal:
    :type timestamps:
    :type n_fbins:
    :type fwindow:
:return:
:rtype:
    """
    xrow = signal.shape[0]
    if timestamps is None:
        timestamps = np.arange(signal.shape[0])
    if n_fbins is None:
        n_fbins = signal.shape[0]
    tcol = timestamps.shape[0]

    if fwindow is None:
        hlength = np.floor(n_fbins / 4.0)
        if hlength % 2 == 0:
            hlength += 1
        fwindow = ssig.hamming(hlength)
    elif fwindow.shape[0] % 2 == 0:
        raise ValueError('The smoothing fwindow must have an odd length.')
    lh = (fwindow.shape[0] - 1) / 2
    fwindow = fwindow / fwindow[lh]

    tfr = np.zeros((n_fbins, tcol), dtype=complex)
    tf2 = np.zeros((n_fbins, tcol), dtype=complex)
    dh = derive_window(fwindow)
    tfr = np.zeros((n_fbins, tcol), dtype=complex)
    for icol in range(tcol):
        ti = timestamps[icol]
        start = min([np.round(n_fbins / 2.0) - 1, lh, xrow - ti])
        end = min([np.round(n_fbins / 2.0) - 1, lh, ti - 1])
        tau = np.arange(-start, end + 1)
        indices = np.remainder(n_fbins + tau, n_fbins)
        tfr[indices, icol] = fwindow[lh + tau] * signal[ti - 1] * np.conj(signal[ti - tau - 1])
        tf2[indices, icol] = dh[lh + tau] * signal[ti - 1] * np.conj(signal[ti - tau - 1])

    tfr = np.fft.fft(tfr, axis=0)
    tf2 = np.fft.fft(tf2, axis=0)
    tfr = tfr.ravel()
    tf2 = tf2.ravel()
    no_warn_mask = tfr != 0
    tf2[no_warn_mask] *= n_fbins / tfr[no_warn_mask] / (2 * np.pi)
    tf2[no_warn_mask] = np.round(tf2[no_warn_mask])
    tfr = np.real(tfr)
    tf2 = np.imag(tf2)
    tfr = tfr.reshape(n_fbins, tcol)
    tf2 = tf2.reshape(n_fbins, tcol)

    rtfr = np.zeros((n_fbins, tcol), dtype=complex)
    threshold = 1.0e-6 * (np.abs(signal) ** 2).mean()

    for icol in range(tcol):
        for jcol in range(n_fbins):
            if np.abs(tfr[jcol, icol]) > threshold:
                jcolhat = jcol - tf2[jcol, icol]
                jcolhat = np.remainder(np.remainder(jcolhat - 1,
                                                    n_fbins) + n_fbins, n_fbins)
                jcolhat += 1
                rtfr[jcolhat - 1, icol] += tfr[jcol, icol]
                tf2[jcol, icol] = jcolhat
            else:
                tf2[jcol, icol] = np.inf
                rtfr[jcol, icol] += tfr[jcol, icol]

    return tfr, rtfr, tf2
Ejemplo n.º 11
0
def spectrogram(signal, time_samples=None, n_fbins=None, window=None):
    """Compute the spectrogram and reassigned spectrogram.

    :param signal: signal to be analzsed
    :param time_samples: time instants (default: np.arange(len(signal)))
    :param n_fbins: number of frequency bins (default: len(signal))
    :param window: frequency smoothing window (default: Hamming with \
        size=len(signal)/4)
    :type signal: array-like
    :type time_samples: array-like
    :type n_fbins: int
    :type window: array-like
    :return: spectrogram, reassigned specstrogram and matrix of reassignment
    vectors
    :rtype: tuple(array-like)
    """

    if time_samples is None:
        time_samples = np.arange(signal.shape[0])
    elif np.unique(np.diff(time_samples)).shape[0] > 1:
        raise ValueError('Time instants must be regularly sampled.')
    if n_fbins is None:
        n_fbins = signal.shape[0]
    if window is None:
        wlength = int(np.floor(signal.shape[0] / 4.0))
        wlength += 1 - np.remainder(wlength, 2)
        window = ssig.hamming(wlength)
    elif window.shape[0] % 2 == 0:
        raise ValueError('The smoothing window must have an odd length.')

    tfr = np.zeros((n_fbins, time_samples.shape[0]), dtype=complex)
    tf2 = np.zeros((n_fbins, time_samples.shape[0]), dtype=complex)
    tf3 = np.zeros((n_fbins, time_samples.shape[0]), dtype=complex)
    lh = (window.shape[0] - 1) / 2
    th = window * np.arange(-lh, lh + 1)
    dwin = derive_window(window)

    for icol in range(time_samples.shape[0]):
        ti = time_samples[icol]
        tau = np.arange(-np.min([np.round(n_fbins / 2) - 1, lh, ti]),
                        np.min([np.round(n_fbins / 2) - 1, lh, signal.shape[0] - ti]) + 1)
        indices = np.remainder(n_fbins + tau, n_fbins)
        norm_h = np.linalg.norm(window[lh + tau], ord=2)
        tfr[indices, icol] = signal[ti + tau - 1] * np.conj(window[lh + tau]) / norm_h
        tf2[indices, icol] = signal[ti + tau - 1] * np.conj(th[lh + tau]) / norm_h
        tf3[indices, icol] = signal[ti + tau - 1] * np.conj(dwin[lh + tau]) / norm_h

    tfr = np.fft.fft(tfr, axis=0).ravel()
    tf2 = np.fft.fft(tf2, axis=0).ravel()
    tf3 = np.fft.fft(tf3, axis=0).ravel()

    no_warn_mask = tfr != 0
    tf2[no_warn_mask] = np.round(np.real(tf2[no_warn_mask] / tfr[no_warn_mask]))
    tf3[no_warn_mask] = np.round(np.imag(n_fbins * tf3[no_warn_mask] / tfr[no_warn_mask] / (2 * np.pi)))

    tfr = np.abs(tfr) ** 2
    tfr = tfr.reshape(n_fbins, time_samples.shape[0])
    tf2 = tf2.reshape(n_fbins, time_samples.shape[0])
    tf3 = tf3.reshape(n_fbins, time_samples.shape[0])
    tf3 = np.real(tf3)

    rtfr = np.zeros((n_fbins, time_samples.shape[0]), dtype=complex)
    ix = np.arange(time_samples.min(), time_samples.max() + 1) - 1
    threshold = 1e-6 * np.mean(np.abs(signal[ix])**2)
    for icol in range(time_samples.shape[0]):
        for jcol in range(n_fbins):
            if np.abs(tfr[jcol, icol]) > threshold:
                icolhat = icol + tf2[jcol, icol]
                icolhat = np.min([np.max([icolhat, 1]), time_samples.shape[0]])
                jcolhat = jcol - tf3[jcol, icol]
                jcolhat = np.remainder(np.remainder(jcolhat - 1, n_fbins) + n_fbins,
                                       n_fbins)
                rtfr[int(jcolhat), int(icolhat) - 1] += tfr[jcol, icol]
                tf2[jcol, icol] = jcolhat + 1j * icolhat
            else:
                tf2[jcol, icol] = np.inf
                rtfr[jcol, icol] += tfr[jcol, icol]
    return tfr, rtfr, tf2
Ejemplo n.º 12
0
def smoothed_pseudo_wigner_ville(signal, timestamps=None, n_fbins=None,
        twindow=None, fwindow=None):
    """smoothed_pseudo_wigner_ville

    :param signal:
    :param timestamps:
    :param n_fbins:
    :param twindow:
    :param fwindow:
    :type signal:
    :type timestamps:
    :type n_fbins:
    :type twindow:
    :type fwindow:
:return:
:rtype:
    """
    xrow = signal.shape[0]

    if timestamps is None:
        timestamps = np.arange(signal.shape[0])
    if n_fbins is None:
        n_fbins = signal.shape[0]
    if fwindow is None:
        hlength = np.floor(n_fbins / 4.0)
        hlength += 1 - (hlength % 2)
        fwindow = ssig.hamming(hlength)
    elif fwindow.shape[0] % 2 == 0:
        raise ValueError('The smoothing window must have an odd length.')
    lh = (fwindow.shape[0] - 1) / 2

    if twindow is None:
        glength = np.floor(n_fbins / 4.0)
        glength += 1 - (glength % 2)
        twindow = ssig.hamming(glength)
    elif twindow.shape[0] % 2 == 0:
        raise ValueError('The smoothing window must have an odd length.')
    lg = (twindow.shape[0] - 1) / 2

    tcol = timestamps.shape[0]
    deltat = timestamps[1:] - timestamps[:-1]
    if deltat.min() != deltat.max():
        raise ValueError("Time instants must be regularly sampled.")
    else:
        dt = deltat.min()

    tfr = np.zeros((n_fbins, tcol), dtype=complex)
    tf2 = np.zeros((n_fbins, tcol), dtype=complex)
    tf3 = np.zeros((n_fbins, tcol), dtype=complex)
    dh = derive_window(fwindow)

    for icol in range(tcol):
        ti = timestamps[icol]
        taumax = min([ti + lg - 1, xrow - ti + lg, np.round(n_fbins / 2.0) - 1,
                      lh])
        points = np.arange(-min([lg, xrow - ti]), min([lg, ti - 1]) + 1)
        g2 = twindow[lg + points]
        g2 = g2 / g2.sum()
        tg2 = g2 * points
        xx = signal[ti - 1 - points] * np.conj(signal[ti - 1 - points])
        tfr[0, icol] = (g2 * xx).sum()
        tf2[0, icol] = (tg2 * xx).sum()
        tf3[0, icol] = dh[lh + 1] * tfr[0, icol]

        for tau in range(int(taumax)):
            points = np.arange(-min([lg, xrow - ti - tau]),
                               min([lg, ti - tau - 1]) + 1)
            g2 = twindow[lg + points]
            g2 = g2 / g2.sum()
            tg2 = g2 * points
            xx = signal[ti + tau - 1 - points] * np.conj(signal[ti - tau - 1 - points])
            tfr[tau, icol] = (g2 * xx).sum() * fwindow[lh + tau]
            tf2[tau, icol] = fwindow[lh + tau] * (tg2 * xx).sum()
            tf3[tau, icol] = dh[lh + tau] * (g2 * xx).sum()
            tfr[n_fbins - tau - 1, icol] = (g2 * np.conj(xx)).sum() * fwindow[lh - tau]
            tf2[n_fbins - tau - 1, icol] = (tg2 * np.conj(xx)).sum() * fwindow[lh - tau]
            tf3[n_fbins - tau - 1, icol] = dh[lh - tau] * (g2 * np.conj(xx)).sum()

    tfr = np.real(np.fft.fft(tfr, axis=0)).ravel()
    tf2 = np.real(np.fft.fft(tf2, axis=0)).ravel()
    tf3 = np.imag(np.fft.fft(tf3, axis=0)).ravel()

    no_warn_mask = tfr != 0
    tf2[no_warn_mask] = np.round(tf2[no_warn_mask] / tfr[no_warn_mask] / dt)
    tf3[no_warn_mask] = np.round(n_fbins * tf3[no_warn_mask] /
            tfr[no_warn_mask] / (2 * np.pi))
    tfr, tf2, tf3 = [x.reshape(n_fbins, tcol).astype(complex) for x in (tfr, tf2, tf3)]
    tf3 = np.real(tf3)

    rtfr = np.zeros((n_fbins, tcol), dtype=complex)
    ex = np.mean(np.abs(signal) ** 2)
    threshold = ex * 1.0e-6

    for icol in range(tcol):
        for jcol in range(n_fbins):
            if np.abs(tfr[jcol, icol]) > threshold:
                icolhat = min(max([icol - tf2[jcol, icol], 1]), tcol)
                jcolhat = jcol - tf3[jcol, icol]
                jcolhat = (((int(jcolhat) - 1) % n_fbins) + n_fbins) % n_fbins + 1
                rtfr[jcol, icol] += tfr[jcol, icol]
                tf2[jcol, icol] = jcolhat + 1j * icolhat
            else:
                tf2[jcol, icol] = np.inf * (1 + 1j)
                rtfr[jcol, icol] += tfr[jcol, icol]

    return tfr, rtfr, tf2
Ejemplo n.º 13
0
def pseudo_wigner_ville(signal, timestamps=None, n_fbins=None, fwindow=None):
    """pseudo_wigner_ville

    :param signal:
    :param timestamps:
    :param n_fbins:
    :param fwindow:
    :type signal:
    :type timestamps:
    :type n_fbins:
    :type fwindow:
:return:
:rtype:
    """
    xrow = signal.shape[0]
    if timestamps is None:
        timestamps = np.arange(signal.shape[0])
    if n_fbins is None:
        n_fbins = signal.shape[0]
    tcol = timestamps.shape[0]

    if fwindow is None:
        hlength = np.floor(n_fbins / 4.0)
        if hlength % 2 == 0:
            hlength += 1
        fwindow = ssig.hamming(hlength)
    elif fwindow.shape[0] % 2 == 0:
        raise ValueError('The smoothing fwindow must have an odd length.')
    lh = (fwindow.shape[0] - 1) / 2
    fwindow = fwindow / fwindow[lh]

    tfr = np.zeros((n_fbins, tcol), dtype=complex)
    tf2 = np.zeros((n_fbins, tcol), dtype=complex)
    dh = derive_window(fwindow)
    for icol in range(tcol):
        ti = timestamps[icol]
        taumax = min([ti - 1, xrow - ti, np.round(n_fbins / 2.0) - 1, lh])
        tau = np.arange(-taumax, taumax + 1)
        indices = np.remainder(n_fbins + tau, n_fbins) + 1
        tfr[indices - 1, icol] = fwindow[lh + tau] * signal[ti + tau - 1] * np.conj(signal[ti - tau - 1])
        tf2[indices - 1, icol] = dh[lh + tau] * signal[ti + tau - 1] * np.conj(signal[ti - tau - 1])
        tau = np.round(n_fbins / 2)
        if (ti <= (xrow - tau)) and (ti > (tau + 1)) and (tau <= lh):
            _x = fwindow[lh + 1 + tau] * signal[ti + tau] * np.conj(signal[ti - tau])
            _y = fwindow[lh + 1 - tau] * signal[ti - tau] * np.conj(signal[ti + tau])
            tfr[tau + 1, icol] = (_x + _y) * 0.5
            _x = dh[lh + 1 + tau] * signal[ti + tau] * np.conj(signal[ti - tau])
            _y = dh[lh + 1 - tau] * signal[ti - tau] * np.conj(signal[ti + tau])
            tf2[tau + 1, icol] = (_x + _y) * 0.5
    tfr = np.real(np.fft.fft(tfr, axis=0))
    tf2 = np.imag(np.fft.fft(tf2, axis=0))
    tfr = tfr.ravel()
    tf2 = tf2.ravel()
    no_warn_mask = tfr != 0
    tf2[no_warn_mask] *= n_fbins / tfr[no_warn_mask] / (2 * np.pi)
    tf2[no_warn_mask] = np.round(tf2[no_warn_mask])
    tfr = tfr.reshape(n_fbins, tcol)
    tf2 = tf2.reshape(n_fbins, tcol)

    rtfr = np.zeros((n_fbins, tcol), dtype=complex)
    tmin = timestamps.min()
    tmax = timestamps.max()
    threshold = 1.0e-6 * (np.abs(signal[tmin:(tmax + 1)]) ** 2).mean()

    for icol in range(tcol):
        for jcol in range(n_fbins):
            if np.abs(tfr[jcol, icol]) > threshold:
                jcolhat = jcol - tf2[jcol, icol]
                jcolhat = np.remainder(np.remainder(jcolhat - 1,
                                                    n_fbins) + n_fbins, n_fbins)
                jcolhat += 1
                rtfr[jcolhat - 1, icol] += tfr[jcol, icol]
                tf2[jcol, icol] = jcolhat
            else:
                tf2[jcol, icol] = np.inf
                rtfr[jcol, icol] += tfr[jcol, icol]

    return tfr, rtfr, tf2
Ejemplo n.º 14
0
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
#
# Copyright © 2015 jaidev <jaidev@newton>
#
# Distributed under terms of the MIT license.

"""

"""

import matplotlib.pyplot as plt
from scipy.signal import hanning
from tftb.processing.utils import derive_window

window = hanning(210)
plt.subplot(211), plt.plot(window)
plt.xlim(0, 210)
plt.grid()
plt.title('Hanning window')
plt.subplot(212), plt.plot(derive_window(window))
plt.xlim(0, 210)
plt.grid()
plt.title('Approximate derivative')
plt.show()
Ejemplo n.º 15
0
 def test_window_derivative(self):
     window = hanning(210)
     derivative = derive_window(window)
     ix_win_maxima = np.argmax(window)
     self.assertAlmostEqual(derivative[ix_win_maxima], 0.0, places=3)
Ejemplo n.º 16
0
def pseudo_page(signal, timestamps=None, n_fbins=None, fwindow=None):
    """pseudo_page

    :param signal:
    :param timestamps:
    :param n_fbins:
    :param fwindow:
    :type signal:
    :type timestamps:
    :type n_fbins:
    :type fwindow:
:return:
:rtype:
    """
    timestamps, n_fbins = init_default_args(signal,
                                            timestamps=timestamps,
                                            n_fbins=n_fbins)
    tcol = timestamps.shape[0]

    if fwindow is None:
        hlength = np.floor(n_fbins / 4.0)
        if hlength % 2 == 0:
            hlength += 1
        fwindow = ssig.hamming(hlength)
    elif fwindow.shape[0] % 2 == 0:
        raise ValueError('The smoothing fwindow must have an odd length.')
    lh = (fwindow.shape[0] - 1) / 2
    fwindow = fwindow / fwindow[lh]

    tfr = np.zeros((n_fbins, tcol), dtype=complex)
    tf2 = np.zeros((n_fbins, tcol), dtype=complex)
    dh = derive_window(fwindow)

    for icol in xrange(tcol):
        tau = np.arange(min([n_fbins - 1, lh, icol - 1]) + 1)
        indices = np.remainder(n_fbins + tau, n_fbins) + 1
        tfr[indices, icol] = fwindow[lh + tau] * signal[icol] * np.conj(
            signal[icol - tau])
        tf2[indices,
            icol] = dh[lh + tau] * signal[icol] * np.conj(signal[icol - tau])
        tf2[0, icol] += signal[icol] * np.conj(signal[icol])

    tfr = np.fft.fft(tfr, axis=0)
    tf2 = np.fft.fft(tf2, axis=0)
    tfr = tfr.ravel()
    tf2 = tf2.ravel()
    no_warn_mask = tfr != 0
    tf2[no_warn_mask] *= n_fbins / tfr[no_warn_mask] / (2 * np.pi)
    tf2[no_warn_mask] = np.round(tf2[no_warn_mask])
    tfr = np.real(tfr)
    tf2 = np.imag(tf2)
    tfr = tfr.reshape(n_fbins, tcol)
    tf2 = tf2.reshape(n_fbins, tcol)

    rtfr = np.zeros((n_fbins, tcol), dtype=complex)
    threshold = 1.0e-6 * (np.abs(signal)**2).mean()

    for icol in xrange(tcol):
        for jcol in xrange(n_fbins):
            if np.abs(tfr[jcol, icol]) > threshold:
                jcolhat = jcol - tf2[jcol, icol]
                jcolhat = np.remainder(
                    np.remainder(jcolhat - 1, n_fbins) + n_fbins, n_fbins)
                jcolhat += 1
                rtfr[jcolhat - 1, icol] += tfr[jcol, icol]
                tf2[jcol, icol] = jcolhat
            else:
                tf2[jcol, icol] = np.inf
                rtfr[jcol, icol] += tfr[jcol, icol]

    return tfr, rtfr, tf2