Beispiel #1
0
def test_scipy_resample():
    """ Tests scipy signal's resample function
    """
    # create a freq list with max freq < 16 Hz
    freq_list = np.random.randint(0, high=15, size=5)
    # make a test signal with sampling freq = 64 Hz
    a = [
        np.sin(2 * np.pi * f * np.linspace(0, 1, 64, endpoint=False))
        for f in freq_list
    ]
    tst = np.array(a).sum(axis=0)
    # interpolate to 128 Hz sampling
    t_up = signaltools.resample(tst, 128)
    np.testing.assert_array_almost_equal(t_up[::2], tst)
    # downsample to 32 Hz
    t_dn = signaltools.resample(tst, 32)
    np.testing.assert_array_almost_equal(t_dn, tst[::2])

    # downsample to 48 Hz, and compute the sampling analytically for comparison
    dn_samp_ana = np.array([
        np.sin(2 * np.pi * f * np.linspace(0, 1, 48, endpoint=False))
        for f in freq_list
    ]).sum(axis=0)
    t_dn2 = signaltools.resample(tst, 48)
    npt.assert_array_almost_equal(t_dn2, dn_samp_ana)
Beispiel #2
0
def test_coherence_linear_dependence():
    """
    Tests that the coherence between two linearly dependent time-series
    behaves as expected.
    
    From William Wei's book, according to eq. 14.5.34, if two time-series are
    linearly related through:

    y(t)  = alpha*x(t+time_shift)

    then the coherence between them should be equal to:

    .. :math:
    
    C(\nu) = \frac{1}{1+\frac{fft_{noise}(\nu)}{fft_{x}(\nu) \cdot \alpha^2}}
    
    """
    t = np.linspace(0,16*np.pi,2**14)
    x = np.sin(t) + np.sin(2*t) + np.sin(3*t) + 0.1 *np.random.rand(t.shape[-1])
    N = x.shape[-1]

    alpha = 10
    m = 3
    noise = 0.1 * np.random.randn(t.shape[-1])
    y = alpha*(np.roll(x,m)) + noise

    f_noise = np.fft.fft(noise)[0:N/2]
    f_x = np.fft.fft(x)[0:N/2]

    c_t = ( 1/( 1 + ( f_noise/( f_x*(alpha**2)) ) ) )

    f,c = tsa.coherence(np.vstack([x,y]))
    c_t = np.abs(signaltools.resample(c_t,c.shape[-1]))

    np.testing.assert_array_almost_equal(c[0,1],c_t,2)
Beispiel #3
0
def test_scipy_resample():
    """ Tests scipy signal's resample function
    """
    # create a freq list with max freq < 16 Hz
    freq_list = np.random.randint(0,high=15,size=5)
    # make a test signal with sampling freq = 64 Hz
    a = [np.sin(2*np.pi*f*np.linspace(0,1,64,endpoint=False))
         for f in freq_list]
    tst = np.array(a).sum(axis=0)
    # interpolate to 128 Hz sampling
    t_up = signaltools.resample(tst, 128)
    np.testing.assert_array_almost_equal(t_up[::2], tst)
    # downsample to 32 Hz
    t_dn = signaltools.resample(tst, 32)
    np.testing.assert_array_almost_equal(t_dn, tst[::2])

    # downsample to 48 Hz, and compute the sampling analytically for comparison
    dn_samp_ana = np.array([np.sin(2*np.pi*f*np.linspace(0,1,48,endpoint=False))
                            for f in freq_list]).sum(axis=0)
    t_dn2 = signaltools.resample(tst, 48)
    npt.assert_array_almost_equal(t_dn2, dn_samp_ana)
Beispiel #4
0
def _is_VF(signal):
    """
    This function checks if a signal array meets the criteria to be
    considered a Ventricular Fibrillation following the method explained in:
    'Amann: Detecting Ventricular Fibrillation by Time-Delay Methods. 2007'.
    In our case, the measured variable is the Pearson's goodness of fit
    statistic instead of the recurrence rate of the original paper.
    """
    dfreq = 50
    window = 8*dfreq
    #The threshold is the 0.99 quantile of the chi square distribution.
    thr = 6.64
    tau = int(0.5*dfreq)
    #The signal is filtered and resampled to 50 Hz
    signal = fft_filt(signal, (0.5, 25), SAMPLING_FREQ)
    signal = resample(signal, int(len(signal) * dfreq / SAMPLING_FREQ))
    n = int(math.ceil(len(signal)/float(window)))
    isvf = True
    #The conditions are validated in fragments of *window* size
    for i in range(n):
        if i == n-1 and n > 1:
            frag = signal[-window-tau:-tau]
            dfrag = signal[-min(len(frag), window):]
        else:
            frag = signal[i*window:(i+1)*window]
            dfrag = signal[i*window+tau:(i+1)*window+tau]
            frag = frag[:len(dfrag)] if len(frag) > len(dfrag) else frag
        #Constant arrays cannot be flutters.
        if len(frag) > 1 and not np.allclose(frag, frag[0]):
            #The size of the histogram scales with the size of the signal.
            nbins = int(math.ceil(math.sqrt(len(frag)*40.0**2/window)))
            H, _, _ = np.histogram2d(frag, dfrag, nbins)
            H /= len(frag)
            Ei = 1.0/(nbins*nbins)
            #The measured variable for the dispersion is the statistic of the
            #Pearson's goodnes of fit test (agains the uniform distribution).
            det = np.sum((H-Ei)**2/Ei)
            isvf = isvf and det < thr
        else:
            isvf = False
        if not isvf:
            break
    return isvf
Beispiel #5
0
def test_coherence_linear_dependence():
    """
    Tests that the coherence between two linearly dependent time-series
    behaves as expected.

    From William Wei's book, according to eq. 14.5.34, if two time-series are
    linearly related through:

    y(t)  = alpha*x(t+time_shift)

    then the coherence between them should be equal to:

    .. :math:

    C(\nu) = \frac{1}{1+\frac{fft_{noise}(\nu)}{fft_{x}(\nu) \cdot \alpha^2}}

    """
    t = np.linspace(0, 16 * np.pi, 2**14)
    x = (np.sin(t) + np.sin(2 * t) + np.sin(3 * t) +
         0.1 * np.random.rand(t.shape[-1]))
    N = x.shape[-1]

    alpha = 10
    m = 3
    noise = 0.1 * np.random.randn(t.shape[-1])
    y = alpha * np.roll(x, m) + noise

    f_noise = fftpack.fft(noise)[0:N // 2]
    f_x = fftpack.fft(x)[0:N // 2]

    c_t = (1 / (1 + (f_noise / (f_x * (alpha**2)))))

    method = {"this_method": 'welch', "NFFT": 2048, "Fs": 2 * np.pi}

    f, c = tsa.coherence(np.vstack([x, y]), csd_method=method)
    c_t = np.abs(signaltools.resample(c_t, c.shape[-1]))

    npt.assert_array_almost_equal(c[0, 1], c_t, 2)
Beispiel #6
0
    # define the sfa node
    sfaNode = mdp.nodes.SFANode(output_dim=sfaNum)
    
    # define the ica node
    icaNode = mdp.nodes.FastICANode()
    icaNode.set_output_dim(icaNum)

    #define the flow
    flow = mdp.Flow(resNode + sfaNode + icaNode)
    #train the flow
    flow.train(sensorData.T)
    # 
    icaOutput = flow.execute(sensorData.T)
    
    #resample the ica layer output back to 50 times the length 
    icaOutputLong = resample(icaOutput, location.shape[0])

    # number of components to plot
    plotsNum = 20
    
    plt.subplot(plotsNum + 1, 1, 1)
    # first subplot of the numbered location of the robot
    plt.plot(location)
    # plot the independent components
    for i in range(plotsNum):
        plt.subplot(plotsNum + 1, 1, i + 2)
        plt.plot(icaOutputLong[:, i])
    plt.show()
    

Beispiel #7
0
    resNode.initialize()

    # define the sfa node
    sfaNode = mdp.nodes.SFANode(output_dim=sfaNum)

    # define the ica node
    icaNode = mdp.nodes.FastICANode()
    icaNode.set_output_dim(icaNum)

    #define the flow
    flow = mdp.Flow(resNode + sfaNode + icaNode)
    #train the flow
    flow.train(sensorData.T)
    #
    icaOutput = flow.execute(sensorData.T)

    #resample the ica layer output back to 50 times the length
    icaOutputLong = resample(icaOutput, location.shape[0])

    # number of components to plot
    plotsNum = 20

    plt.subplot(plotsNum + 1, 1, 1)
    # first subplot of the numbered location of the robot
    plt.plot(location)
    # plot the independent components
    for i in range(plotsNum):
        plt.subplot(plotsNum + 1, 1, i + 2)
        plt.plot(icaOutputLong[:, i])
    plt.show()
Beispiel #8
0
def preprocess_signal(raw_sig: np.ndarray,
                      fs: Real,
                      config: Optional[ED] = None) -> Dict[str, np.ndarray]:
    """ finished, checked,

    Parameters
    ----------
    raw_sig: ndarray,
        the raw ecg signal
    fs: real number,
        sampling frequency of `raw_sig`
    config: dict, optional,
        extra process configuration,
        `PreprocCfg` will be updated by this `config`

    Returns
    -------
    retval: dict,
        with items
        - 'filtered_ecg': the array of the processed ecg signal
        - 'rpeaks': the array of indices of rpeaks; empty if 'rpeaks' in `config` is not set

    NOTE
    ----
    output (`retval`) are resampled to have sampling frequency
    equal to `config.fs` (if `config` has item `fs`) or `PreprocCfg.fs`
    """
    filtered_ecg = raw_sig.copy()

    cfg = deepcopy(PreprocCfg)
    cfg.update(deepcopy(config) or {})

    if fs != cfg.fs:
        filtered_ecg = resample(filtered_ecg,
                                int(round(len(filtered_ecg) * cfg.fs / fs)))

    # remove baseline
    if 'baseline' in cfg.preproc:
        window1 = 2 * (cfg.baseline_window1 //
                       2) + 1  # window size must be odd
        window2 = 2 * (cfg.baseline_window2 // 2) + 1
        baseline = median_filter(filtered_ecg, size=window1, mode='nearest')
        baseline = median_filter(baseline, size=window2, mode='nearest')
        filtered_ecg = filtered_ecg - baseline

    # filter signal
    if 'bandpass' in cfg.preproc:
        filtered_ecg = filter_signal(
            signal=filtered_ecg,
            ftype='FIR',
            band='bandpass',
            order=int(0.3 * fs),
            sampling_rate=fs,
            frequency=cfg.filter_band,
        )['signal']

    if cfg.rpeaks and cfg.rpeaks.lower() not in DL_QRS_DETECTORS:
        # dl detectors not for parallel computing using `mp`
        detector = QRS_DETECTORS[cfg.rpeaks.lower()]
        rpeaks = detector(sig=filtered_ecg, fs=fs).astype(int)
    else:
        rpeaks = np.array([], dtype=int)

    retval = ED({
        "filtered_ecg": filtered_ecg,
        "rpeaks": rpeaks,
    })

    return retval