예제 #1
0
def test_peak_finder():
    """Test the peak detection method."""
    # check for random data
    rng = np.random.RandomState(42)
    peak_inds, peak_mags = peak_finder(rng.randn(20))

    assert_equal(peak_inds.dtype, np.dtype('int64'))
    assert_equal(peak_mags.dtype, np.dtype('float64'))

    # check for empty array as created in the #5025
    with pytest.raises(ValueError):
        peak_finder(np.arange(2, 1, 0.05))

    # check for empty array
    with pytest.raises(ValueError):
        peak_finder([])

    # check for monotonic function
    peak_inds, peak_mags = peak_finder(np.arange(1, 2, 0.05))

    assert_equal(peak_inds.dtype, np.dtype('int64'))
    assert_equal(peak_mags.dtype, np.dtype('float64'))

    # check for no peaks
    peak_inds, peak_mags = peak_finder(np.zeros(20))

    assert_equal(peak_inds.dtype, np.dtype('int64'))
    assert_equal(peak_mags.dtype, np.dtype('float64'))

    # check values
    peak_inds, peak_mags = peak_finder([0, 2, 5, 0, 6, -1])
    assert_array_equal(peak_inds, [2, 4])
예제 #2
0
def process(fname, plot=False, histogram=False):
    print("Loading", fname)
    data, times, raw = load_vhdr(fname)
    datavector = data.reshape(-1)
    threshold = (max(datavector) - min(datavector)) / 30
    print("threshold", threshold)
    print("standard deviation", datavector.std())

    # Einspeisen des Datenvektors in peakfinder
    peak_loc, peak_mag = peak_finder(datavector, thresh=threshold, extrema=-1)
    peak_times = times[peak_loc]

    plt.figure(path.basename(fname))
    plt.xlabel(u"Intervalllänge")
    plt.hist(np.diff(peak_times),
             bins=np.linspace(0, 7.5, num=100),
             label="Verteilung der Atmungsintervalllaengen",
             density=True)
    if plot:
        plt.figure(path.basename(fname) + ": resp")
        plot_resp(times, peak_times, datavector)

    if histogram:
        plt.figure(path.basename(fname) + ": resp distribution")
        plt.hist(datavector, bins=np.linspace(-1.5, 1, num=100), density=True)
예제 #3
0
def find_oscillation_events(arr, direction, sfreq, h_freq=5, thresh=None):
    '''
    Idiosyncratic function designed to detect motion/null events in
    botfly oscillation-motion recordings. Roughly, works by:
        1. Filter: lowpass filters stimulus (drum) recording to smooth input signal.
        2. Peak finding: identify minima and maxima of drum signal.
        3. Events: Reorganize info as an [Nx3] array of [start, stop, condition], 
        where {CCW = 1, CW = 2}
           
   INPUTS
   -- arr: stimulus (drum) signal
   -- direction: CCW or CW
   -- sfreq: sampling frequency
   -- h_freq: lowpass frequency. If set to False, no lowpass applied.
    '''
    assert direction == 'CCW' or direction == 'CW'

    ## Filter data.
    if h_freq:
        arr = filter_data(arr,
                          sfreq,
                          l_freq=None,
                          h_freq=h_freq,
                          phase='zero',
                          verbose=False)

    ## Identify extrema.
    maxima, _ = peak_finder(arr, thresh=thresh, extrema=1)
    minima, _ = peak_finder(arr, thresh=thresh, extrema=-1)

    ## Re-organize into events.
    events = np.sort(np.concatenate([maxima, minima]))
    events = np.array([events[i:i + 2] for i in range(events.size - 1)])
    if not events.size:
        raise ValueError('No events detected. Check paramaters.')

    ## Demarcate null/motion events.
    events = np.concatenate(
        [events, np.zeros(events.shape[0], dtype=int).reshape(-1, 1)], axis=-1)
    if direction == 'CCW':
        events[np.in1d(events[:, 0], maxima), -1] = 1
        events[np.in1d(events[:, 0], minima), -1] = 2
    else:
        events[np.in1d(events[:, 0], maxima), -1] = 2
        events[np.in1d(events[:, 0], minima), -1] = 1

    return events
예제 #4
0
def plot_test_range(times, a=3000, b=3300):
    """
    Plot the respiration data in the range from a to b (seconds)
    """
    a = np.where(times >= a)[0][0]
    b = np.where(times <= b)[0][-1]
    tresp = resp[a:b]
    thres = default
    tpeak_loc, _ = peak_finder(tresp, thresh=thres, extrema=-1)
    tpeak_times = times[a:b][tpeak_loc]
    plt.vlines(x=tpeak_times, ymin=-1, ymax=1)
    plt.plot(times[a:b], tresp)
예제 #5
0
def search_for_blinks(epochs,window_size=5,window_overlap=0.05,thresh=25e-6,
                      min_index=None,max_index=None,return_average=False):
  window_step = window_size-window_overlap/2
  window_half_size = window_size/2 + window_overlap/2

  blinks = []
  count = 0
  bar = progressbar.ProgressBar(max_value=len(epochs.selection)-1)

  events = raw.time_as_index(np.arange(raw.times[0],raw.times[-1],window_step))
  evt_mat = np.stack([events,
                      np.zeros(len(events)),
                      np.ones(len(events))]).astype('int_')

  picks = mne.pick_types(raw.info,eeg=False,eog=True,selection=['IO1','IO2'])
  window_start = np.floor(raw.info['sfreq']*-window_half_size).astype('int_')

  oldout = sys.stdout
  null = open(os.devnull,'w')
  for evoked in epochs.iter_evoked():
    bar.update(count)
    if min_index != None and count < min_index:
      continue
    if max_index != None and count > max_index:
      break

    index_offset = evt_mat[0,epochs.selection[count]] + window_start
    # print "index_offset: ", index_offset

    channel_average = np.mean(evoked.data[picks,:],axis=0)
    sys.stdout = null
    indices,_ = peak_finder(np.abs(channel_average),thresh)
    sys.stdout = oldout
    blinks = np.concatenate([blinks,(indices + index_offset).astype('int_')])
    count += 1

    # if len(indices) > 0:
    #   print indices
    #   print count
    #   break

  null.close()

  if return_average:
    return np.unique(blinks), channel_average
  else:
    return np.unique(blinks)
예제 #6
0
def test_peak_finder():
    """Test the peak detection method"""
    x = [0, 2, 5, 0, 6, -1]
    peak_inds, peak_mags = peak_finder(x)
    assert_array_equal(peak_inds, [2, 4])
예제 #7
0
def phase_locked_amplitude(inst,
                           freqs_phase,
                           freqs_amp,
                           ix_ph,
                           ix_amp,
                           tmin=-.5,
                           tmax=.5,
                           mask_times=None):
    """Calculate the average amplitude of a signal at a phase of another.

    Parameters
    ----------
    inst : instance of mne.Epochs or mne.io.Raw
        The data to be used in phase locking computation
    freqs_phase : np.array
        The frequencies to use in phase calculation. The phase of each
        frequency will be averaged together.
    freqs_amp : np.array
        The frequencies to use in amplitude calculation.
    ix_ph : int
        The index of the signal to be used for phase calculation
    ix_amp : int
        The index of the signal to be used for amplitude calculation
    tmin : float
        The time to include before each phase peak
    tmax : float
        The time to include after each phase peak
    mask_times : np.array, dtype bool, shape (inst.n_times,)
        If inst is an instance of Raw, this will only include times contained
        in mask_times.

    Returns
    -------
    data_amp : np.array
        The mean amplitude values for the frequencies specified in freqs_amp,
        time-locked to peaks of the low-frequency phase.
    data_phase : np.array
        The mean low-frequency signal, phase-locked to low-frequency phase
        peaks.
    times : np.array
        The times before / after each phase peak.
    """
    sfreq = inst.info['sfreq']
    # Pull the amplitudes/phases using Morlet
    data_ph, data_amp = _pull_data(inst, ix_ph, ix_amp)
    angle_ph, band_ph, amp = _extract_phase_and_amp(data_ph, data_amp, sfreq,
                                                    freqs_phase, freqs_amp)

    angle_ph = angle_ph.mean(0)  # Mean across freq bands
    band_ph = band_ph.mean(0)

    # Find peaks in the phase for time-locking
    phase_peaks, vals = peak_finder.peak_finder(angle_ph)
    ixmin, ixmax = [t * sfreq for t in [tmin, tmax]]
    # Remove peaks w/o buffer
    phase_peaks = phase_peaks[(phase_peaks > np.abs(ixmin)) *
                              (phase_peaks < len(angle_ph) - ixmax)]

    if mask_times is not None:
        # Set datapoints outside out times to nan so we can drop later
        if len(mask_times) != angle_ph.shape[-1]:
            raise ValueError('mask_times must be == in length to data')
        band_ph[..., ~mask_times] = np.nan

    data_phase, times, msk_window = _array_raw_to_epochs(
        band_ph[np.newaxis, :], sfreq, phase_peaks, tmin, tmax)
    data_amp, times, msk_window = _array_raw_to_epochs(amp, sfreq, phase_peaks,
                                                       tmin, tmax)
    data_phase, data_amp = [i.squeeze() for i in data_phase, data_amp]

    # Drop any peak events where there was a nan
    keep_rows = np.where(~np.isnan(data_phase).any(-1))[0]
    data_phase, data_amp = [i[keep_rows, ...] for i in [data_phase, data_amp]]

    # Average across phase peak events
    data_amp = data_amp.mean(0)
    data_phase = data_phase.mean(0)
    return data_amp, data_phase, times
예제 #8
0
def phase_locked_amplitude(inst, freqs_phase, freqs_amp, ix_ph, ix_amp,
                           tmin=-.5, tmax=.5, mask_times=None):
    """Calculate the average amplitude of a signal at a phase of another.

    Parameters
    ----------
    inst : instance of mne.Epochs | mne.io.Raw
        The data to be used in phase locking computation.
    freqs_phase : np.array
        The frequencies to use in phase calculation. The phase of each
        frequency will be averaged together.
    freqs_amp : np.array
        The frequencies to use in amplitude calculation.
    ix_ph : int
        The index of the signal to be used for phase calculation.
    ix_amp : int
        The index of the signal to be used for amplitude calculation.
    tmin : float
        The time to include before each phase peak.
    tmax : float
        The time to include after each phase peak.
    mask_times : np.array, dtype bool, shape (inst.n_times,)
        If `inst` is an instance of Raw, this will only include times contained
        in `mask_times`. Defaults to using all times.

    Returns
    -------
    data_am : np.array
        The mean amplitude values for the frequencies specified in `freqs_amp`,
        time-locked to peaks of the low-frequency phase.
    data_ph : np.array
        The mean low-frequency signal, phase-locked to low-frequency phase
        peaks.
    times : np.array
        The times before / after each phase peak.
    """
    sfreq = inst.info['sfreq']
    # Pull the amplitudes/phases using Morlet
    data_ph, data_am = _pull_data(inst, ix_ph, ix_amp)
    angle_ph, band_ph, amp = _extract_phase_and_amp(
        data_ph, data_am, sfreq, freqs_phase, freqs_amp)

    angle_ph = angle_ph.mean(0)  # Mean across freq bands
    band_ph = band_ph.mean(0)

    # Find peaks in the phase for time-locking
    phase_peaks, vals = peak_finder.peak_finder(angle_ph)
    ixmin, ixmax = [t * sfreq for t in [tmin, tmax]]
    # Remove peaks w/o buffer
    phase_peaks = phase_peaks[(phase_peaks > np.abs(ixmin)) *
                              (phase_peaks < len(angle_ph) - ixmax)]

    if mask_times is not None:
        # Set datapoints outside out times to nan so we can drop later
        if len(mask_times) != angle_ph.shape[-1]:
            raise ValueError('mask_times must be == in length to data')
        band_ph[..., ~mask_times] = np.nan

    data_ph, times, msk_window = _raw_to_epochs_array(
        band_ph[np.newaxis, :], sfreq, phase_peaks, tmin, tmax)
    data_am, times, msk_window = _raw_to_epochs_array(
        amp, sfreq, phase_peaks, tmin, tmax)
    data_ph = data_ph.squeeze()
    data_am = data_am.squeeze()

    # Drop any peak events where there was a nan
    keep_rows = np.where(~np.isnan(data_ph).any(-1))[0]
    data_ph = data_ph[keep_rows, ...]
    data_am = data_am[keep_rows, ...]

    # Average across phase peak events
    data_am = data_am.mean(0)
    data_ph = data_ph.mean(0)
    return data_am, data_ph, times
def af_blocks(fname, dauer=30, schritt=1.45, start=0, endzeit=None):
    """
    return af /min Zeit(xAchse), peak loc: Peaks des eindimensionalen datavectors
    times: Zeitpunkte der Peaks, peak_mag: Aulenkung der Peaks.

    """
    print(start)
    data, times, raw = load_vhdr(fname)
    datavector = data.reshape(-1)
    threshold = 0.6 * datavector.std()

    peak_loc, peak_mag = peak_finder(datavector, thresh=threshold, extrema=-1)
    peak_times = times[peak_loc]

    anzahlpeaks = peak_loc.size
    atemzugdauer_mittelwert = (times[-1] - times[0]) / anzahlpeaks

    if endzeit is None:
        endzeit = times[-1]
    # stop = start + dauer
    freq = []
    point = []
    while start <= endzeit:
        s = start - 0.5 * dauer
        e = s + dauer
        indices = np.where((peak_times >= s) & (peak_times <= e))
        # display(indices)
        if np.size(indices) > 0:
            mini = np.min(indices)
            if mini > 0:
                dauer_erster_atemzug = peak_times[mini] - peak_times[mini - 1]
            else:
                dauer_erster_atemzug = atemzugdauer_mittelwert
            fremdanteil_erster_atemzug = peak_times[mini] - s

            maxi = np.max(indices)
            if maxi < (peak_times.size - 1):
                dauer_letzter_atemzug = peak_times[maxi] - peak_times[maxi + 1]
            else:
                dauer_letzter_atemzug = atemzugdauer_mittelwert

            fremdanteil_letzter_atemzug = e - peak_times[maxi]
            anzahl = (
                number_peaks(peak_times, s, e)
                + (fremdanteil_erster_atemzug / dauer_erster_atemzug)
                + (fremdanteil_letzter_atemzug / dauer_letzter_atemzug)
            )

            point.append(start)
            if s < 0:
                freq.append(anzahl / (e))
            else:
                if e > endzeit:
                    freq.append(anzahl / (endzeit - s))
                else:
                    freq.append(anzahl / dauer)
        else:
            point.append(start)
        #  freq.append(-1.0)
        # display("Murks am Ende")
        start = start + schritt
    return freq, point