def test_analogsignal_isempty(): x = np.array([]) time = np.array([]) analogsignal = nept.AnalogSignal(x, time) assert analogsignal.isempty
def perievent_slice(analogsignal, events, t_before, t_after, dt=None): """Slices the analogsignal data into perievent chunks. Unlike time_slice, the resulting AnalogSignal will be multidimensional. Only works for 1D signals. Parameters ---------- analogsignal : nept.AnalogSignal events : np.array t_before : float t_after : float dt : float Returns ------- nept.AnalogSignal """ if analogsignal.dimensions != 1: raise ValueError("AnalogSignal must be 1D.") if dt is None: dt = np.median(np.diff(analogsignal.time)) time = np.arange(-t_before, t_after+dt, dt) data = np.zeros((len(time), len(events))) for i, event in enumerate(events): sliced = analogsignal.time_slice(event-t_before, event+t_after) data[:, i] = np.interp(time+event, sliced.time, np.squeeze(sliced.data)) return nept.AnalogSignal(data, time)
def test_analogsignal_data_ndim_big(): x = np.zeros((2, 3, 4)) time = np.array([0., 1., 2.]) with pytest.raises(ValueError) as excinfo: analogsignal = nept.AnalogSignal(x, time) assert str(excinfo.value) == "data must be vector or 2D array"
def test_analogsignal_time_not_vector(): x = np.array([1., 2.]) time = np.array([[1., 2.], [2., 3.]]) with pytest.raises(ValueError) as excinfo: analogsignal = nept.AnalogSignal(x, time) assert str(excinfo.value) == "time must be a vector"
def test_analogsignal_n_data_time(): x = np.array([1., 2., 3.]) time = np.array([0., 1.]) with pytest.raises(ValueError) as excinfo: analogsignal = nept.AnalogSignal(x, time) assert str(excinfo.value) == "data and time should be the same length"
def test_analogsignal_mismatch(): data = np.array([[9., 7., 5., 3.], [1., 2., 2., 3.]]) time = np.array([0., 1., 2., 3., 4.]) with pytest.raises(ValueError) as excinfo: analogsignal = nept.AnalogSignal(data, time) assert str( excinfo.value) == "must have same number of time and data samples"
def test_analogsignal_notempty(): x = np.array([9., 7., 5., 3., 1.]) y = np.array([9., 7., 5., 3., 1.]) time = np.array([0., 1., 2., 3., 4.]) data = np.hstack( [np.array(x)[..., np.newaxis], np.array(y)[..., np.newaxis]]) analogsignal = nept.AnalogSignal(data, time) assert not analogsignal.isempty
def test_analogsignal_time_slice_1d(): data = np.array([9., 7., 5., 3., 1.]) time = np.array([0., 1., 2., 3., 4.]) analogsignal = nept.AnalogSignal(data, time) start = 1. stop = 3. sliced_analogsignal = analogsignal.time_slice(start, stop) assert np.allclose(sliced_analogsignal.data, np.array([[7.], [5.], [3.]])) assert np.allclose(sliced_analogsignal.time, np.array([1., 2., 3.]))
def test_bayesian_prob_smalltc(): tuning_curve = np.array([[0., 0., 1.]]) counts = nept.AnalogSignal(np.array([[10.], [5.]]), np.array([1.])) binsize = 1.0 likelihood = nept.bayesian_prob(counts, tuning_curve, binsize, min_neurons=1, min_spikes=1) assert np.sum(np.isnan(likelihood)) == likelihood.size
def test_bayesian_prob_onetime(): tuning_curve = np.array([[0., 0., 2.]]) counts = nept.AnalogSignal(np.array([[10.]]), np.array([1.])) binsize = 1.0 likelihood = nept.bayesian_prob(counts, tuning_curve, binsize, min_neurons=1, min_spikes=1) assert np.allclose(likelihood[0][2], 1.0)
def test_analogsignal_time_slices_1d_length_error(): x = np.array([9., 7., 5., 3., 1.]) time = np.array([0., 1., 2., 3., 4.]) analogsignal = nept.AnalogSignal(x, time) starts = [0.1] stops = [1.5, 6.] with pytest.raises(ValueError) as excinfo: sliced_analogsignal = analogsignal.time_slice(starts, stops) assert str( excinfo.value) == "must have same number of start and stop times"
def test_mean_coherence_with_itself(): fs = 500 dt = 1./fs time = np.arange(0, 2+dt, dt) cycles = 100 data1 = np.sin(2 * np.pi * cycles * time) perievent1 = nept.AnalogSignal(data1, time) window = 250 fs = 125 freq, coherence = nept.mean_coherence(perievent1, perievent1, window, fs) assert np.allclose(np.ones(len(coherence)), coherence)
def test_mean_csd_with_itself(): fs = 500 dt = 1./fs time = np.arange(0, 2+dt, dt) cycles = 100 data1 = np.sin(2 * np.pi * cycles * time) perievent1 = nept.AnalogSignal(data1, time) window = 250 fs = 125 freq, csd = nept.mean_csd(perievent1, perievent1, window, fs) assert freq[np.where(csd == np.max(csd))[0][0]] == 25.0
def test_bayesian_prob_multtc(): tuning_curve = np.array([[2., 0., 0.], [0., 5., 0.], [0., 0., 5.]]) counts = nept.AnalogSignal(np.array([[0.], [4.], [2.]]), np.array([1.])) binsize = 1.0 likelihood = nept.bayesian_prob(counts, tuning_curve, binsize, min_neurons=1, min_spikes=1) assert np.allclose(likelihood, np.array([[0.02997459, 0.93271674, 0.03730867]]))
def test_perievent_slice_simple(): data = np.array([9., 7., 5., 3., 1.]) time = np.array([0., 1., 2., 3., 4.]) analogsignal = nept.AnalogSignal(data, time) events = np.array([1.]) perievent_lfp = nept.perievent_slice(analogsignal, events, t_before=1., t_after=1.) assert np.allclose(perievent_lfp.data, np.array([[9.], [7.], [5.]])) assert np.allclose(perievent_lfp.time, np.array([-1., 0., 1.]))
def test_analogsignal_time_slices_1d_none_start(): x = np.array([9., 7., 5., 3., 1.]) time = np.array([0., 1., 2., 3., 4.]) analogsignal = nept.AnalogSignal(x, time) starts = [None, 3] stops = [1.5, 4.] sliced_analogsignal = analogsignal.time_slice(starts, stops) assert np.allclose(sliced_analogsignal.data, np.array([[9.], [7.], [3.], [1.]])) assert np.allclose(sliced_analogsignal.time, np.array([0., 1., 3., 4.]))
def test_mean_coherencegram_with_itself(): fs = 500 dt = 1./fs time = np.arange(0, 2+dt, dt) cycles = 100 data1 = np.sin(2 * np.pi * cycles * time) perievent1 = nept.AnalogSignal(data1, time) window = 250 fs = 125 dt = 1 timebins, freq, coherencegram = nept.mean_coherencegram(perievent1, perievent1, dt, window, fs) assert np.allclose(coherencegram[0], np.array([1., 0., 0.]))
def test_bayesian_prob_emptytcbin(): tuning_curve = np.array([[0., 1., 0.], [0., 5., 0.], [0., 0., 5.]]) counts = nept.AnalogSignal(np.array([[0.], [2.], [2.]]), np.array([1.])) binsize = 1.0 likelihood = nept.bayesian_prob(counts, tuning_curve, binsize, min_neurons=1, min_spikes=1) assert np.isnan(likelihood[0][0]) assert np.allclose(likelihood[0][1], 0.5) assert np.allclose(likelihood[0][2], 0.5)
def bin_spikes(spikes, t_start, t_stop, dt, lastbin=False, window=None, gaussian_std=None, normalized=True): """Bins spikes using a sliding window. Parameters ---------- spikes: list Of nept.SpikeTrain t_start: float t_stop: float window: float or None Length of the sliding window, in seconds. If None, will default to dt. dt: float gaussian_std: float or None normalized: boolean Returns ------- binned_spikes: nept.AnalogSignal """ if window is None: window = dt bin_edges = get_edges(t_start, t_stop, dt, lastbin=lastbin) given_n_bins = window / dt n_bins = int(round(given_n_bins)) if abs(n_bins - given_n_bins) > 0.01: warnings.warn("dt does not divide window evenly. " "Using window %g instead." % (n_bins*dt)) if normalized: square_filter = np.ones(n_bins) * (1 / n_bins) else: square_filter = np.ones(n_bins) counts = np.zeros((len(spikes), len(bin_edges) - 1)) for idx, spiketrain in enumerate(spikes): counts[idx] = np.convolve(np.histogram(spiketrain.time, bins=bin_edges)[0].astype(float), square_filter, mode="same") if gaussian_std is not None: counts = gaussian_filter(counts, gaussian_std, dt=dt, normalized=normalized, axis=1) return nept.AnalogSignal(counts, bin_edges[:-1])
def detect_swr_hilbert(lfp, fs, thresh, z_thresh, merge_thresh, min_length, times_for_z=None): """Finds sharp-wave ripple (SWR) times and indices. Parameters ---------- lfp : nept.LocalFieldPotential fs : int Experiment-specific, something in the range of 2000 typical. thresh : tuple With format (lowcut, highcut). Typically (140.0, 250.0) for sharp-wave ripple detection. z_thres : int or float min_length : float Any sequence less than this amount is not considered a sharp-wave ripple. times_for_z : nept.Epoch or None Portion of LFP used for z thresh. Returns ------- swrs : nept.Epoch Containing nept.LocalFieldPotential for each SWR event """ # Filtering signal with butterworth fitler filtered_butter = butter_bandpass(lfp.data, thresh, fs) # Get LFP power (using Hilbert) and z-score the power # Zero padding to nearest regular number to speed up fast fourier transforms (FFT) computed in the hilbert function. # Regular numbers are composites of the prime factors 2, 3, and 5. hilbert_n = next_regular(lfp.n_samples) power = np.abs(scipy.signal.hilbert(filtered_butter, N=hilbert_n)) # removing the zero padding now that the power is computed power_lfp = nept.AnalogSignal(power[:lfp.n_samples], lfp.time) swrs = get_epoch_from_zscored_thresh(power_lfp, thresh=z_thresh, times_for_z=times_for_z) # Merging epochs that are closer - in time - than the merge_threshold. swrs = swrs.merge(gap=merge_thresh) # Removing epochs that are shorter - in time - than the min_length value. keep_indices = swrs.durations >= min_length swrs = nept.Epoch(swrs.starts[keep_indices], swrs.stops[keep_indices]) return swrs
def test_bayesian_prob_multtimepos(): tuning_curve = np.array([[3., 0., 0.]]) counts = nept.AnalogSignal(np.array([[0., 2., 4.]]), np.array([1., 2., 3.])) binsize = 1.0 likelihood = nept.bayesian_prob(counts, tuning_curve, binsize, min_neurons=1, min_spikes=1) assert np.sum(np.isnan(likelihood[0])) == 3 assert np.allclose(likelihood[1][0], 1.0) assert np.sum(np.isnan(likelihood[1])) == 2 assert np.allclose(likelihood[2][0], 1.0) assert np.sum(np.isnan(likelihood[2])) == 2
def test_analogsignal_time_slice_2d(): x = np.array([9., 7., 5., 3., 1.]) y = np.array([9., 7., 5., 3., 1.]) time = np.array([0., 1., 2., 3., 4.]) data = np.hstack( [np.array(x)[..., np.newaxis], np.array(y)[..., np.newaxis]]) analogsignal = nept.AnalogSignal(data, time) start = 1. stop = 3. sliced_analogsignal = analogsignal.time_slice(start, stop) assert np.allclose(sliced_analogsignal.data, np.array([[7., 7.], [5., 5.], [3., 3.]])) assert np.allclose(sliced_analogsignal.time, np.array([1., 2., 3.]))
def test_analogsignal_time_slices_2d_none_stop(): x = np.array([9., 7., 5., 3., 1.]) y = np.array([9., 7., 5., 3., 1.]) time = np.array([0., 1., 2., 3., 4.]) data = np.hstack( [np.array(x)[..., np.newaxis], np.array(y)[..., np.newaxis]]) analogsignal = nept.AnalogSignal(data, time) starts = np.array([0.1, 3.]) stops = np.array([1.5, None]) sliced_analogsignal = analogsignal.time_slice(starts, stops) assert np.allclose(sliced_analogsignal.data, np.array([[7., 7.], [3., 3.], [1., 1.]])) assert np.allclose(sliced_analogsignal.time, np.array([1., 3., 4.]))
def test_perievent_slice_2d(): x = np.array([9., 7., 5., 3., 1.]) y = np.array([9., 7., 5., 3., 1.]) time = np.array([0., 1., 2., 3., 4.]) data = np.hstack( [np.array(x)[..., np.newaxis], np.array(y)[..., np.newaxis]]) analogsignal = nept.AnalogSignal(data, time) events = np.array([1.]) with pytest.raises(ValueError) as excinfo: perievent_lfp = nept.perievent_slice(analogsignal, events, t_before=1., t_after=1.) assert str(excinfo.value) == "AnalogSignal must be 1D."
def test_bayesian_prob_multneurons(): tuning_curve = np.array([[2., 0., 0.], [0., 5., 0.], [0., 0., 5.]]) counts = nept.AnalogSignal( np.array([[0., 8, 0.], [4., 0., 1.], [0., 1., 3.]]).T, np.array([1., 2., 3.])) binsize = 1.0 likelihood = nept.bayesian_prob(counts, tuning_curve, binsize, min_neurons=1, min_spikes=1) assert np.allclose(likelihood[0], np.array([0.0310880460, 0.967364171, 0.00154778267])) assert np.allclose(likelihood[1], np.array([0.998834476, 0.000194254064, 0.000971270319])) assert np.allclose(likelihood[2], np.array([0.133827265, 0.0333143360, 0.832858399]))