def test__create_from_np_array(self): data = np.arange(10.0) rate = 1 * pq.kHz signal = AnalogSignal(data, sampling_rate=rate, units="uV") assert_neo_object_is_compliant(signal) self.assertEqual(signal.t_start, 0 * pq.ms) self.assertEqual(signal.t_stop, data.size / rate) self.assertEqual(signal[9, 0], 0.009 * pq.mV)
def test__create_from_list(self): data = range(10) rate = 1000 * pq.Hz signal = AnalogSignal(data, sampling_rate=rate, units="mV") assert_neo_object_is_compliant(signal) self.assertEqual(signal.t_start, 0 * pq.ms) self.assertEqual(signal.t_stop, len(data) / rate) self.assertEqual(signal[9, 0], 9000 * pq.uV)
def test__create_from_quantities_array(self): data = np.arange(10.0) * pq.mV rate = 5000 * pq.Hz signal = AnalogSignal(data, sampling_rate=rate) assert_neo_object_is_compliant(signal) self.assertEqual(signal.t_start, 0 * pq.ms) self.assertEqual(signal.t_stop, data.size / rate) self.assertEqual(signal[9, 0], 0.009 * pq.V)
def test__create2D_with_copy_false_should_return_view(self): data = np.arange(10.0) * pq.mV data = data.reshape((5, 2)) rate = 5000 * pq.Hz signal = AnalogSignal(data, copy=False, sampling_rate=rate) data[3, 0] = 99 * pq.mV assert_neo_object_is_compliant(signal) self.assertEqual(signal[3, 0], 99 * pq.mV)
def setUp(self): self.data1 = np.arange(55.0).reshape((11, 5)) self.data1quant = self.data1 * pq.nA self.signal1 = AnalogSignal(self.data1quant, sampling_rate=1 * pq.kHz, name='spam', description='eggs', file_origin='testfile.txt', arg1='test') self.data2 = np.array([[0, 1, 2, 3, 4, 5], [0, 1, 2, 3, 4, 5]]).T self.data2quant = self.data2 * pq.mV self.signal2 = AnalogSignal(self.data2quant, sampling_rate=1.0 * pq.Hz, name='spam', description='eggs', file_origin='testfile.txt', arg1='test')
def setUp(self): self.data1 = np.arange(10.0) self.data1quant = self.data1 * pq.mV self.signal1 = AnalogSignal(self.data1quant, sampling_rate=1*pq.kHz, name='spam', description='eggs', file_origin='testfile.txt', arg1='test')
def test__create_with_additional_argument(self): signal = AnalogSignal([1, 2, 3], units="mV", sampling_rate=1*pq.kHz, file_origin='crack.txt', ratname='Nicolas') assert_neo_object_is_compliant(signal) self.assertEqual(signal.annotations, {'ratname': 'Nicolas'}) # This one is universally recommended and handled by BaseNeo self.assertEqual(signal.file_origin, 'crack.txt')
def test__create_from_quantities_array(self): data = np.arange(20.0).reshape((10, 2)) * pq.mV rate = 5000 * pq.Hz signal = AnalogSignal(data, sampling_rate=rate) assert_neo_object_is_compliant(signal) self.assertEqual(signal.t_start, 0 * pq.ms) self.assertEqual(signal.t_stop, data.shape[0] / rate) self.assertEqual(signal[9, 0], 18000 * pq.uV)
def test__indexing_keeps_order_across_channels(self): # AnalogSignals with 10 traces each having 5 samples (eg. data[0] = [0,10,20,30,40]) data = np.array([range(10), range(10, 20), range(20, 30), range(30, 40), range(40, 50)]) mask = np.full((5, 10), fill_value=False, dtype=bool) # selecting one entry per trace mask[[0, 1, 0, 3, 0, 2, 4, 3, 1, 4], range(10)] = True signal = AnalogSignal(np.array(data) * pq.V, sampling_rate=1 * pq.Hz) assert_array_equal(signal[mask], np.array([[0, 11, 2, 33, 4, 25, 46, 37, 18, 49]]) * pq.V)
def test__add_signals_with_inconsistent_data_complement_ValueError(self): self.signal1.t_start = 0.0*pq.ms assert_neo_object_is_compliant(self.signal1) signal2 = AnalogSignal(np.arange(10.0), units="mV", t_start=100.0*pq.ms, sampling_rate=0.5*pq.kHz) assert_neo_object_is_compliant(signal2) self.assertRaises(ValueError, self.signal1.__add__, signal2)
def test__create_from_list(self): data = [(i, i, i) for i in range(10)] # 3 signals each with 10 samples rate = 1000 * pq.Hz signal = AnalogSignal(data, sampling_rate=rate, units="mV") assert_neo_object_is_compliant(signal) self.assertEqual(signal.shape, (10, 3)) self.assertEqual(signal.t_start, 0 * pq.ms) self.assertEqual(signal.t_stop, len(data) / rate) self.assertEqual(signal[9, 0], 9000 * pq.uV)
def setUp(self): self.data1 = np.arange(10.0) self.data1quant = self.data1 * pq.nA self.arr_ann = {'anno1': [23], 'anno2': ['A']} self.signal1 = AnalogSignal(self.data1quant, sampling_rate=1 * pq.kHz, name='spam', description='eggs', file_origin='testfile.txt', arg1='test', array_annotations=self.arr_ann) self.signal1.segment = Segment() self.signal1.channel_index = ChannelIndex(index=[0])
def test__create_from_numpy_array(self): data = np.arange(20.0).reshape((10, 2)) rate = 1 * pq.kHz signal = AnalogSignal(data, sampling_rate=rate, units="uV") assert_neo_object_is_compliant(signal) self.assertEqual(signal.t_start, 0 * pq.ms) self.assertEqual(signal.t_stop, data.shape[0] / rate) self.assertEqual(signal[9, 0], 0.018 * pq.mV) self.assertEqual(signal[9, 1], 19 * pq.uV)
def setUp(self): self.t_start = [0.0*pq.ms, 100*pq.ms, -200*pq.ms] self.rates = [1*pq.kHz, 420*pq.Hz, 999*pq.Hz] self.data = [np.arange(10.0).reshape((5, 2))*pq.nA, np.arange(-100.0, 100.0, 10.0).reshape((4, 5))*pq.mV, np.random.uniform(size=(100, 4))*pq.uV] self.signals = [AnalogSignal(D, sampling_rate=r, t_start=t) for r, D, t in zip(self.rates, self.data, self.t_start)]
def test_splice_1channel_invalid_t_stop(self): signal_for_splicing = AnalogSignal( [0.1, 0.1, 0.1], t_start=8 * pq.ms, # too close to the end of the signal sampling_rate=self.signal1.sampling_rate, units=pq.uA) self.assertRaises(ValueError, self.signal1.splice, signal_for_splicing, copy=False)
def test_splice_1channel_invalid_units(self): signal_for_splicing = AnalogSignal( [0.1, 0.1, 0.1], t_start=3 * pq.ms, sampling_rate=self.signal1.sampling_rate, units=pq.uV) self.assertRaises(ValueError, self.signal1.splice, signal_for_splicing, copy=False)
def test_splice_1channel_inplace(self): signal_for_splicing = AnalogSignal([0.1, 0.1, 0.1], t_start=3 * pq.ms, sampling_rate=self.signal1.sampling_rate, units=pq.uA) result = self.signal1.splice(signal_for_splicing, copy=False) assert_array_equal(result.magnitude.flatten(), np.array([0.0, 1.0, 2.0, 100.0, 100.0, 100.0, 6.0, 7.0, 8.0, 9.0])) assert_array_equal(self.signal1, result) # in-place self.assertEqual(result.segment, self.signal1.segment) self.assertEqual(result.channel_index, self.signal1.channel_index)
def setUp(self): self.data1 = np.arange(10.0) self.data1quant = self.data1 * pq.nA self.signal1 = AnalogSignal(self.data1quant, sampling_rate=1 * pq.kHz, name='spam', description='eggs', file_origin='testfile.txt', arg1='test') self.signal1.segment = 1 self.signal1.channel_index = ChannelIndex(index=[0])
def test_splice_2channels_inplace(self): signal = AnalogSignal(np.arange(20.0).reshape((10, 2)), sampling_rate=1 * pq.kHz, units="mV") signal_for_splicing = AnalogSignal(np.array([[0.1, 0.0], [0.2, 0.0], [0.3, 0.0]]), t_start=3 * pq.ms, sampling_rate=self.signal1.sampling_rate, units=pq.V) result = signal.splice(signal_for_splicing, copy=False) assert_array_equal(result.magnitude, np.array([[0.0, 1.0], [2.0, 3.0], [4.0, 5.0], [100.0, 0.0], [200.0, 0.0], [300.0, 0.0], [12.0, 13.0], [14.0, 15.0], [16.0, 17.0], [18.0, 19.0]])) assert_array_equal(signal, result) # in-place
def test__subtracting_a_signal_from_a_constant_should_return_a_signal( self): signal = AnalogSignal(numpy.arange(10.0), units="mV", sampling_rate=1 * kHz, name="foo") signal_with_offset = 10 * mV - signal self.assertEqual(signal[9], 9 * mV) self.assertEqual(signal_with_offset[9], 1 * mV) for attr in "t_start", "sampling_rate": self.assertEqual(getattr(signal, attr), getattr(signal_with_offset, attr))
def test__subtracting_a_constant_from_a_signal_should_preserve_data_complement( self): signal = AnalogSignal(numpy.arange(10.0), units="mV", sampling_rate=1 * kHz, name="foo") signal_with_offset = signal - 65 * mV self.assertEqual(signal[9], 9 * mV) self.assertEqual(signal_with_offset[9], -56 * mV) for attr in "t_start", "sampling_rate": self.assertEqual(getattr(signal, attr), getattr(signal_with_offset, attr))
def setUp(self): self.t_start = [0.0*pq.ms, 100*pq.ms, -200*pq.ms] self.rates = [1*pq.kHz, 420*pq.Hz, 999*pq.Hz] self.rates2 = [2*pq.kHz, 290*pq.Hz, 1111*pq.Hz] self.data = [np.arange(10.0)*pq.nA, np.arange(-100.0, 100.0, 10.0)*pq.mV, np.random.uniform(size=100)*pq.uV] self.signals = [AnalogSignal(D, sampling_rate=r, t_start=t, testattr='test') for r, D, t in zip(self.rates, self.data, self.t_start)]
def test__dividing_a_signal_by_a_constant_should_preserve_data_complement( self): signal = AnalogSignal(numpy.arange(10.0), units="mV", sampling_rate=1 * kHz, name="foo") amplified_signal = signal / 0.5 self.assertEqual(signal[9], 9 * mV) self.assertEqual(amplified_signal[9], 18 * mV) for attr in "t_start", "sampling_rate": self.assertEqual(getattr(signal, attr), getattr(amplified_signal, attr))
def setUp(self): self.t_start = [0.0 * ms, 100 * ms, -200 * ms] self.rates = [1 * kHz, 420 * Hz, 999 * Hz] self.data = [ numpy.arange(10.0) * nA, numpy.arange(-100.0, 100.0, 10.0) * mV, numpy.random.uniform(size=100) * uV ] self.signals = [ AnalogSignal(D, sampling_rate=r, t_start=t) for r, D, t in zip(self.rates, self.data, self.t_start) ]
def test__indexing_keeps_order_across_time(self): # AnalogSignals with 10 traces each having 5 samples (eg. data[0] = [0,10,20,30,40]) data = np.array([range(10), range(10, 20), range(20, 30), range(30, 40), range(40, 50)]) mask = np.full((5, 10), fill_value=False, dtype=bool) # selecting two entries per trace temporal_ids = [0, 1, 0, 3, 1, 2, 4, 2, 1, 4] + [4, 3, 2, 1, 0, 1, 2, 3, 2, 1] mask[temporal_ids, list(range(10)) + list(range(10))] = True signal = AnalogSignal(np.array(data) * pq.V, sampling_rate=1 * pq.Hz) assert_array_equal(signal[mask], np.array([[0, 11, 2, 13, 4, 15, 26, 27, 18, 19], [40, 31, 22, 33, 14, 25, 46, 37, 28, 49]]) * pq.V)
def test_splice_1channel_with_copy(self): signal_for_splicing = AnalogSignal([0.1, 0.1, 0.1], t_start=3 * pq.ms, sampling_rate=self.signal1.sampling_rate, units=pq.uA) result = self.signal1.splice(signal_for_splicing, copy=True) assert_array_equal(result.magnitude.flatten(), np.array([0.0, 1.0, 2.0, 100.0, 100.0, 100.0, 6.0, 7.0, 8.0, 9.0])) assert_array_equal(self.signal1.magnitude.flatten(), np.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0])) self.assertIs(result.segment, None) self.assertIs(result.channel_index, None)
def resample(self, sample_count, **kwargs): """ Resample the data points of the signal. This method interpolates the signal and returns a new signal with a fixed number of samples defined by `sample_count`. This function is a wrapper of scipy.signal.resample and accepts the same set of keyword arguments, except for specifying the axis of resampling which is fixed to the first axis here, and the sample positions. . Parameters: ----------- sample_count: integer Number of desired samples. The resulting signal starts at the same sample as the original and is sampled regularly. Returns: -------- resampled_signal: :class:`AnalogSignal` New instance of a :class:`AnalogSignal` object containing the resampled data points. The original :class:`AnalogSignal` is not modified. """ if not HAVE_SCIPY: raise ImportError( 'Resampling requires availability of scipy.signal') # Resampling is only permitted along the time axis (axis=0) if 'axis' in kwargs: kwargs.pop('axis') if 't' in kwargs: kwargs.pop('t') resampled_data, resampled_times = scipy.signal.resample( self.magnitude, sample_count, t=self.times.magnitude, axis=0, **kwargs) new_sampling_rate = (sample_count - 1) / self.duration resampled_signal = AnalogSignal( resampled_data, units=self.units, dtype=self.dtype, t_start=self.t_start, sampling_rate=new_sampling_rate, array_annotations=self.array_annotations.copy(), **self.annotations.copy()) # since the number of channels stays the same, we can also copy array annotations here resampled_signal.array_annotations = self.array_annotations.copy() return resampled_signal
def test__add_two_consistent_signals_should_preserve_data_complement(self): data2 = np.arange(10.0, 20.0) data2quant = data2*pq.mV signal2 = AnalogSignal(data2quant, sampling_rate=1*pq.kHz) assert_neo_object_is_compliant(signal2) result = self.signal1 + signal2 self.assertIsInstance(result, AnalogSignal) assert_neo_object_is_compliant(result) self.assertEqual(result.name, 'spam') self.assertEqual(result.description, 'eggs') self.assertEqual(result.file_origin, 'testfile.txt') self.assertEqual(result.annotations, {'arg1': 'test'}) targ = AnalogSignal(np.arange(10.0, 30.0, 2.0), units="mV", sampling_rate=1*pq.kHz, name='spam', description='eggs', file_origin='testfile.txt', arg1='test') assert_neo_object_is_compliant(targ) assert_array_equal(result, targ) assert_same_sub_schema(result, targ)
def test_splice_1channel_inplace(self): signal_for_splicing = AnalogSignal([0.1, 0.1, 0.1], t_start=3 * pq.ms, sampling_rate=self.signal1.sampling_rate, units=pq.uA, array_annotations={'anno1': [0], 'anno2': ['C']}) result = self.signal1.splice(signal_for_splicing, copy=False) assert_array_equal(result.magnitude.flatten(), np.array([0.0, 1.0, 2.0, 100.0, 100.0, 100.0, 6.0, 7.0, 8.0, 9.0])) assert_array_equal(self.signal1, result) # in-place self.assertEqual(result.segment, self.signal1.segment) self.assertEqual(result.channel_index, self.signal1.channel_index) assert_array_equal(result.array_annotations['anno1'], np.array([23])) assert_array_equal(result.array_annotations['anno2'], np.array(['A'])) self.assertIsInstance(result.array_annotations, ArrayDict)
def test__time_slice__no_explicit_time(self): self.signal2.t_start = 10.0 * pq.ms assert_neo_object_is_compliant(self.signal2) t1 = 2 * pq.s + 10.0 * pq.ms t2 = 4 * pq.s + 10.0 * pq.ms for t_start, t_stop in [(t1, None), (None, None), (None, t2)]: t_start_targ = t1 if t_start is not None else self.signal2.t_start t_stop_targ = t2 if t_stop is not None else self.signal2.t_stop result = self.signal2.time_slice(t_start, t_stop) self.assertIsInstance(result, AnalogSignal) assert_neo_object_is_compliant(result) self.assertEqual(result.name, 'spam') self.assertEqual(result.description, 'eggs') self.assertEqual(result.file_origin, 'testfile.txt') self.assertEqual(result.annotations, {'arg1': 'test'}) assert_arrays_equal(result.array_annotations['anno1'], np.array([10, 11])) assert_arrays_equal(result.array_annotations['anno2'], np.array(['k', 'l'])) self.assertIsInstance(result.array_annotations, ArrayDict) targ_ind = np.where((self.signal2.times >= t_start_targ) & (self.signal2.times < t_stop_targ)) targ_array = self.signal2.magnitude[targ_ind] targ = AnalogSignal(targ_array, t_start=t_start_targ.rescale(pq.ms), sampling_rate=1.0 * pq.Hz, units='mV', name='spam', description='eggs', file_origin='testfile.txt', arg1='test') assert_neo_object_is_compliant(result) assert_neo_object_is_compliant(self.signal2) self.assertEqual(self.signal2.t_start, 10.0 * pq.ms) self.assertAlmostEqual(result.t_stop, t_stop_targ, delta=1e-12 * pq.ms) self.assertAlmostEqual(result.t_start, t_start_targ, delta=1e-12 * pq.ms) assert_arrays_almost_equal(result.times, targ.times, 1e-12 * pq.ms) self.assertEqual(result.sampling_rate, targ.sampling_rate) assert_array_equal(result.magnitude, targ.magnitude) assert_same_sub_schema(result, targ)