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])
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)
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
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)
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)
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])
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
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