コード例 #1
0
def notch(ts, freq_hz, bandwidth_hz=1.0):
    """notch filter to remove remove a particular frequency
    Adapted from code by Sturla Molden
    """
    orig_ndim = ts.ndim
    if ts.ndim is 1:
        ts = ts[:, np.newaxis]
    channels = ts.shape[1]
    fs = (len(ts) - 1.0) / (ts.tspan[-1] - ts.tspan[0])
    nyq = 0.5 * fs
    freq = freq_hz / nyq
    bandwidth = bandwidth_hz / nyq
    R = 1.0 - 3.0 * (bandwidth / 2.0)
    K = ((1.0 - 2.0 * R * np.cos(np.pi * freq) + R**2) /
         (2.0 - 2.0 * np.cos(np.pi * freq)))
    b, a = np.zeros(3), np.zeros(3)
    a[0] = 1.0
    a[1] = -2.0 * R * np.cos(np.pi * freq)
    a[2] = R**2
    b[0] = K
    b[1] = -2 * K * np.cos(np.pi * freq)
    b[2] = K
    if not np.all(np.abs(np.roots(a)) < 1.0):
        raise ValueError('Filter will not be stable with these values.')
    dtype = ts.dtype
    output = np.zeros((len(ts), channels), dtype)
    for i in range(channels):
        output[:, i] = signal.filtfilt(b, a, ts[:, i])
    if orig_ndim is 1:
        output = output[:, 0]
    return Timeseries(output, ts.tspan, labels=ts.labels)
コード例 #2
0
ファイル: misc.py プロジェクト: jamesbrownlow/nsim
def autocorrelation(ts, normalized=False, unbiased=False):
    """
    Returns the discrete, linear convolution of a time series with itself, 
    optionally using unbiased normalization. 

    N.B. Autocorrelation estimates are necessarily inaccurate for longer lags,
    as there are less pairs of points to convolve separated by that lag.
    Therefore best to throw out the results except for shorter lags, e.g. 
    keep lags from tau=0 up to one quarter of the total time series length.

    Args:
      normalized (boolean): If True, the time series will first be normalized
        to a mean of 0 and variance of 1. This gives autocorrelation 1 at
        zero lag.

      unbiased (boolean): If True, the result at each lag m will be scaled by
        1/(N-m). This gives an unbiased estimation of the autocorrelation of a
        stationary process from a finite length sample.

    Ref: S. J. Orfanidis (1996) "Optimum Signal Processing", 2nd Ed.
    """
    ts = np.squeeze(ts)
    if ts.ndim <= 1:
        if normalized:
            ts = (ts - ts.mean()) / ts.std()
        N = ts.shape[0]
        ar = np.asarray(ts)
        acf = np.correlate(ar, ar, mode='full')
        outlen = (acf.shape[0] + 1) / 2
        acf = acf[(outlen - 1):]
        if unbiased:
            factor = np.array([1.0 / (N - m) for m in range(0, outlen)])
            acf = acf * factor
        dt = (ts.tspan[-1] - ts.tspan[0]) / (len(ts) - 1.0)
        lags = np.arange(outlen) * dt
        return Timeseries(acf, tspan=lags, labels=ts.labels)
    else:
        # recursively handle arrays of dimension > 1
        lastaxis = ts.ndim - 1
        m = ts.shape[lastaxis]
        acfs = [
            ts[..., i].autocorrelation(normalized, unbiased)[..., np.newaxis]
            for i in range(m)
        ]
        res = distob.concatenate(acfs, axis=lastaxis)
        res.labels[lastaxis] = ts.labels[lastaxis]
        return res
コード例 #3
0
def highpass(ts, cutoff_hz, order=3):
    """forward-backward butterworth high-pass filter"""
    orig_ndim = ts.ndim
    if ts.ndim is 1:
        ts = ts[:, np.newaxis]
    channels = ts.shape[1]
    fs = (len(ts) - 1.0) / (ts.tspan[-1] - ts.tspan[0])
    nyq = 0.5 * fs
    cutoff = cutoff_hz / nyq
    b, a = signal.butter(order, cutoff, btype='highpass')
    if not np.all(np.abs(np.roots(a)) < 1.0):
        raise ValueError('Filter will not be stable with these values.')
    dtype = ts.dtype
    output = np.zeros((len(ts), channels), dtype)
    for i in range(channels):
        output[:, i] = signal.filtfilt(b, a, ts[:, i])
    if orig_ndim is 1:
        output = output[:, 0]
    return Timeseries(output, ts.tspan, labels=ts.labels)
コード例 #4
0
def hilbert_phase(ts):
    """Phase of the analytic signal, using the Hilbert transform"""
    output = np.angle(signal.hilbert(signal.detrend(ts, axis=0), axis=0))
    return Timeseries(output, ts.tspan, labels=ts.labels)
コード例 #5
0
def hilbert_amplitude(ts):
    """Amplitude of the analytic signal, using the Hilbert transform"""
    output = np.abs(signal.hilbert(signal.detrend(ts, axis=0), axis=0))
    return Timeseries(output, ts.tspan, labels=ts.labels)
コード例 #6
0
def hilbert(ts):
    """Analytic signal, using the Hilbert transform"""
    output = signal.hilbert(signal.detrend(ts, axis=0), axis=0)
    return Timeseries(output, ts.tspan, labels=ts.labels)
コード例 #7
0
def variability_fp(ts, freqs=None, ncycles=6, plot=True):
    """Example variability function.
    Gives two continuous, time-resolved measures of the variability of a
    time series, ranging between -1 and 1. 
    The two measures are based on variance of the centroid frequency and 
    variance of the height of the spectral peak, respectively.
    (Centroid frequency meaning the power-weighted average frequency)
    These measures are calculated over sliding time windows of variable size.
    See also: Blenkinsop et al. (2012) The dynamic evolution of focal-onset 
              epilepsies - combining theoretical and clinical observations
    Args:
      ts  Timeseries of m variables, shape (n, m). Assumed constant timestep.
      freqs   (optional) List of frequencies to examine. If None, defaults to
              50 frequency bands ranging 1Hz to 60Hz, logarithmically spaced.
      ncycles  Window size, in number of cycles of the centroid frequency.
      plot  bool  Whether to display the output

    Returns:
      variability   Timeseries of shape (n, m, 2)  
                    variability[:, :, 0] gives a measure of variability 
                    between -1 and 1 based on variance of centroid frequency.
                    variability[:, :, 1] gives a measure of variability 
                    between -1 and 1 based on variance of maximum power.
    """
    if freqs is None:
        freqs = np.logspace(np.log10(1.0), np.log10(60.0), 50)
    else:
        freqs = np.array(freqs)
    orig_ndim = ts.ndim
    if ts.ndim is 1:
        ts = ts[:, np.newaxis]
    channels = ts.shape[1]
    n = len(ts)
    dt = (1.0 * ts.tspan[-1] - ts.tspan[0]) / (n - 1)
    fs = 1.0 / dt
    dtype = ts.dtype
    # Estimate time-resolved power spectra using continuous wavelet transform
    coefs = ts.cwt(freqs, wavelet=cwtmorlet, plot=False)
    # this is a huge array so try to do operations in place
    powers = np.square(np.abs(coefs, coefs), coefs).real.astype(dtype,
                                                                copy=False)
    del coefs
    max_power = np.max(powers, axis=1)
    total_power = np.sum(powers, axis=1, keepdims=True)
    rel_power = np.divide(powers, total_power, powers)
    del powers
    centroid_freq = np.tensordot(freqs, rel_power, axes=(0, 1))  # shape (n, m)
    del rel_power
    # hw is half window size (in number of samples)
    hw = np.int64(np.ceil(0.5 * ncycles * fs / centroid_freq))  # shape (n, m)
    allchannels_variability = np.zeros((n, channels, 2), dtype)  # output array
    for i in range(channels):
        logvar_centfreq = np.zeros(n, dtype)
        logvar_maxpower = np.zeros(n, dtype)
        for j in range(n):
            # compute variance of two chosen signal properties over a
            # window of 2*hw+1 samples centered on sample number j
            wstart = j - hw[j, i]
            wend = j + hw[j, i]
            if wstart >= 0 and wend < n:
                logvar_centfreq[j] = np.log(centroid_freq[wstart:wend +
                                                          1].var())
                logvar_maxpower[j] = np.log(max_power[wstart:wend + 1].var())
            else:
                logvar_centfreq[j] = np.nan
                logvar_maxpower[j] = np.nan
        allchannels_variability[:, i, 0] = _rescale(logvar_centfreq)
        allchannels_variability[:, i, 1] = _rescale(logvar_maxpower)
    allchannels_variability = Timeseries(allchannels_variability,
                                         ts.tspan,
                                         labels=ts.labels)
    if plot:
        _plot_variability(ts, allchannels_variability)
    return allchannels_variability