示例#1
0
def test_detect_lines():
    """
    Tests detect_lines utility in the reliable low-SNR scenario.
    """
    N = 1000
    fft_pow = int(np.ceil(np.log2(N) + 2))
    NW = 4
    lines = np.sort(np.random.randint(100, 2**(fft_pow - 4), size=(3, )))
    while np.any(np.diff(lines) < 2 * NW):
        lines = np.sort(np.random.randint(2**(fft_pow - 4), size=(3, )))
    lines = lines.astype('d')
    #lines += np.random.randn(3) # displace from grid locations
    lines /= 2.0**(fft_pow - 2)  # ensure they are well separated

    phs = np.random.rand(3) * 2 * np.pi
    # amps approximately such that RMS power = 1 +/- N(0,1)
    amps = np.sqrt(2) / 2 + np.abs(np.random.randn(3))

    nz_sig = 0.05
    tx = np.arange(N)

    harmonics = amps[:, None] * np.cos(2 * np.pi * tx * lines[:, None] +
                                       phs[:, None])
    harmonic = np.sum(harmonics, axis=0)
    nz = np.random.randn(N) * nz_sig
    sig = harmonic + nz

    f, b = utils.detect_lines(sig, (NW, 2 * NW),
                              low_bias=True,
                              NFFT=2**fft_pow)
    h_est = 2 * (b[:, None] * np.exp(2j * np.pi * tx * f[:, None])).real

    npt.assert_(
        len(f) == 3, 'The wrong number of harmonic components were detected')

    err = harmonic - np.sum(h_est, axis=0)
    phs_est = np.angle(b)
    phs_est[phs_est < 0] += 2 * np.pi

    phs_err = np.linalg.norm(phs_est - phs)**2
    amp_err = np.linalg.norm(amps - 2 * np.abs(b))**2 / np.linalg.norm(amps)**2
    freq_err = np.linalg.norm(lines - f)**2

    # FFT bin detections should be exact
    npt.assert_equal(lines, f)
    # amplitude estimation should be pretty good
    npt.assert_(amp_err < 1e-4, 'Harmonic amplitude was poorly estimated')
    # phase estimation should be decent
    npt.assert_(phs_err < 1e-3, 'Harmonic phase was poorly estimated')
    # the error relative to the noise power should be below 1
    rel_mse = np.mean(err**2) / nz_sig**2
    npt.assert_(
        rel_mse < 1,
        'The error in detected harmonic components is too high relative to '\
        'the noise level: %1.2e'%rel_mse
        )
示例#2
0
def test_detect_lines():
    """
    Tests detect_lines utility in the reliable low-SNR scenario.
    """

    N = 1000
    fft_pow = int( np.ceil(np.log2(N) + 2) )
    NW = 4
    lines = np.sort(np.random.randint(100, 2**(fft_pow-4), size=(3,)))
    while np.any( np.diff(lines) < 2*NW ):
        lines = np.sort(np.random.randint(2**(fft_pow-4), size=(3,)))
    lines = lines.astype('d')
    #lines += np.random.randn(3) # displace from grid locations
    lines /= 2.0**(fft_pow-2) # ensure they are well separated

    phs = np.random.rand(3) * 2 * np.pi
    # amps approximately such that RMS power = 1 +/- N(0,1)
    amps = np.sqrt(2)/2 + np.abs( np.random.randn(3) )

    nz_sig = 0.05
    tx = np.arange(N)

    harmonics = amps[:,None]*np.cos( 2*np.pi*tx*lines[:,None] + phs[:,None] )
    harmonic = np.sum(harmonics, axis=0)
    nz = np.random.randn(N) * nz_sig
    sig = harmonic + nz

    f, b = utils.detect_lines(sig, (NW, 2*NW), low_bias=True, NFFT=2**fft_pow)
    h_est = 2*(b[:,None]*np.exp(2j*np.pi*tx*f[:,None])).real

    nt.assert_true(
        len(f) == 3, 'The wrong number of harmonic components were detected'
        )

    err = harmonic - np.sum(h_est, axis=0)
    phs_est = np.angle(b)
    phs_est[phs_est < 0] += 2*np.pi

    phs_err = np.linalg.norm(phs_est - phs)**2
    amp_err = np.linalg.norm(amps - 2*np.abs(b))**2 / np.linalg.norm(amps)**2
    freq_err = np.linalg.norm(lines - f)**2

    # FFT bin detections should be exact
    npt.assert_equal(lines, f)
    # amplitude estimation should be pretty good
    nt.assert_true(amp_err < 1e-4, 'Harmonic amplitude was poorly estimated')
    # phase estimation should be decent
    nt.assert_true(phs_err < 1e-3, 'Harmonic phase was poorly estimated')
    # the error relative to the noise power should be below 1
    rel_mse = np.mean(err**2)/nz_sig**2
    nt.assert_true(
        rel_mse < 1,
        'The error in detected harmonic components is too high relative to '\
        'the noise level: %1.2e'%rel_mse
        )
示例#3
0
文件: test_utils.py 项目: nipy/nitime
def test_detect_lines_2dmode():
    """
    Test multi-sequence operation
    """

    N = 1000

    sig = np.cos(2 * np.pi * np.arange(N) * 20.0 / N) + np.random.randn(N) * 0.01

    sig2d = np.row_stack((sig, sig, sig))

    lines = utils.detect_lines(sig2d, (4, 8), low_bias=True, NFFT=2 ** 12)

    npt.assert_(len(lines) == 3, "Detect lines failed multi-sequence mode")

    consistent1 = (lines[0][0] == lines[1][0]).all() and (lines[1][0] == lines[2][0]).all()
    consistent2 = (lines[0][1] == lines[1][1]).all() and (lines[1][1] == lines[2][1]).all()

    npt.assert_(consistent1 and consistent2, "Inconsistent results")
示例#4
0
def test_detect_lines_2dmode():
    """
    Test multi-sequence operation
    """

    N = 1000

    sig = np.cos(2 * np.pi * np.arange(N) * 20. / N) + np.random.randn(N) * .01

    sig2d = np.row_stack((sig, sig, sig))

    lines = utils.detect_lines(sig2d, (4, 8), low_bias=True, NFFT=2**12)

    npt.assert_(len(lines) == 3, 'Detect lines failed multi-sequence mode')

    consistent1 = (lines[0][0] == lines[1][0]).all() and \
      (lines[1][0] == lines[2][0]).all()
    consistent2 = (lines[0][1] == lines[1][1]).all() and \
      (lines[1][1] == lines[2][1]).all()

    npt.assert_(consistent1 and consistent2, 'Inconsistent results')
示例#5
0
pp.title('Signal in noise')
pp.gcf().tight_layout()
"""

.. image:: fig/mtm_harmonic_test_01.png

"""
"""
Here we'll use the :func:`utils.detect_lines` function with the given
Slepian properties (NW), and we'll ensure that we limit spectral bias
by choosing Slepians with concentration factors greater than 0.9. The
arrays returned include the detected line frequencies (f) and their
complex coefficients (b). The frequencies are normalized from :math:`(0,\frac{1}{2})`
"""

f, b = nt_ut.detect_lines(sig, (NW, 2 * NW), low_bias=True, NFFT=2**fft_pow)
h_est = 2 * (b[:, None] * np.exp(2j * np.pi * tx * f[:, None])).real

pp.figure()
pp.subplot(211)
pp.plot(harmonics.T, 'c', linewidth=3)
pp.plot(h_est.T, 'r--', linewidth=2)
pp.title('%d lines detected' % h_est.shape[0])
pp.xlim(*(np.array([0.2, 0.3]) * N).astype('i'))
pp.subplot(212)
err = harmonic - np.sum(h_est, axis=0)
pp.plot(err**2)
pp.title('Error signal')
pp.show()
"""
示例#6
0
p_noise = 1 / NFFT * frequency_p_noise

selem = np.ones((frequency_smooth), dtype=np.uint8)

chunk_size_samples = 1024 * 1024
assert chunk_size_samples % N == 0

timestamps_freq_signal = []
timestamps_freq_noise = []
for ichannel in range(nchannels):
    ioffset = 0
    while ioffset < nsamples:
        ilast = min(nsamples, ioffset + chunk_size_samples) // N * N
        song_reshaped1 = np.reshape(song[ioffset:ilast, ichannel], (-1, N))
        f = utils.detect_lines(song_reshaped1, (NW, 2 * NW),
                               low_bias=True,
                               NFFT=NFFT,
                               p=p_signal)
        timestamps_f1 = [2 * i + 0 for (i, ii) in enumerate(f) if ii != ()]

        ilast -= N // 2
        song_reshaped2 = np.reshape(song[ioffset + N // 2:ilast, ichannel],
                                    (-1, N))
        f = utils.detect_lines(song_reshaped2, (NW, 2 * NW),
                               low_bias=True,
                               NFFT=NFFT,
                               p=p_signal)
        timestamps_f2 = [2 * i + 1 for (i, ii) in enumerate(f) if ii != ()]

        song_thresholded = np.zeros(
            (len(song_reshaped1) + len(song_reshaped2)), dtype=np.uint8)
        song_thresholded[np.concatenate(
示例#7
0
.. image:: fig/mtm_harmonic_test_01.png

"""

"""

Here we'll use the :func:`utils.detect_lines` function with the given
Slepian properties (NW), and we'll ensure that we limit spectral bias
by choosing Slepians with concentration factors greater than 0.9. The
arrays returned include the detected line frequencies (f) and their
complex coefficients (b). The frequencies are normalized from :math:`(0,\frac{1}{2})`

"""

f, b = nt_ut.detect_lines(sig, (NW, 2*NW), low_bias=True, NFFT=2**fft_pow)
h_est = 2*(b[:,None]*np.exp(2j*np.pi*tx*f[:,None])).real

pp.figure()
pp.subplot(211)
pp.plot(harmonics.T, 'c', linewidth=3)
pp.plot(h_est.T, 'r--', linewidth=2)
pp.title('%d lines detected' % h_est.shape[0])
pp.xlim(*(np.array([0.2, 0.3])*N).astype('i'))
pp.subplot(212)
err = harmonic - np.sum(h_est, axis=0)
pp.plot(err**2)
pp.title('Error signal')
pp.show()

"""