def test__merge(self): self.signal1.description = None self.signal1.file_origin = None assert_neo_object_is_compliant(self.signal1) data3 = np.arange(1000.0, 1066.0).reshape((11, 6)) * pq.uV data3scale = data3.rescale(self.data1quant.units) signal2 = AnalogSignal(self.data1quant, sampling_rate=1*pq.kHz, name='signal2', description='test signal', file_origin='testfile.txt') signal3 = AnalogSignal(data3, units="uV", sampling_rate=1*pq.kHz, name='signal3', description='test signal', file_origin='testfile.txt') signal4 = AnalogSignal(data3, units="uV", sampling_rate=1*pq.kHz, name='signal4', description='test signal', file_origin='testfile.txt') merged13 = self.signal1.merge(signal3) merged23 = signal2.merge(signal3) merged24 = signal2.merge(signal4) mergeddata13 = np.array(merged13) mergeddata23 = np.array(merged23) mergeddata24 = np.array(merged24) targdata13 = np.hstack([self.data1quant, data3scale]) targdata23 = np.hstack([self.data1quant, data3scale]) targdata24 = np.hstack([self.data1quant, data3scale]) assert_neo_object_is_compliant(signal2) assert_neo_object_is_compliant(signal3) assert_neo_object_is_compliant(merged13) assert_neo_object_is_compliant(merged23) assert_neo_object_is_compliant(merged24) self.assertEqual(merged13[0, 4], 4*pq.mV) self.assertEqual(merged23[0, 4], 4*pq.mV) self.assertEqual(merged13[0, 5], 1*pq.mV) self.assertEqual(merged23[0, 5], 1*pq.mV) self.assertEqual(merged13[10, 10], 1.065*pq.mV) self.assertEqual(merged23[10, 10], 1.065*pq.mV) self.assertEqual(merged13.t_stop, self.signal1.t_stop) self.assertEqual(merged23.t_stop, self.signal1.t_stop) self.assertEqual(merged13.name, 'merge(spam, signal3)') self.assertEqual(merged23.name, 'merge(signal2, signal3)') self.assertEqual(merged13.description, 'merge(None, test signal)') self.assertEqual(merged23.description, 'test signal') self.assertEqual(merged13.file_origin, 'merge(None, testfile.txt)') self.assertEqual(merged23.file_origin, 'testfile.txt') assert_arrays_equal(mergeddata13, targdata13) assert_arrays_equal(mergeddata23, targdata23) assert_arrays_equal(mergeddata24, targdata24)
def test__pickle(self): signal1 = AnalogSignal([1, 2, 3, 4], sampling_period=1 * pq.ms, units=pq.S) signal1.annotations['index'] = 2 signal1.channel_index = ChannelIndex(index=[0]) signal1.array_annotate(**{'anno1': [23], 'anno2': ['A']}) fobj = open('./pickle', 'wb') pickle.dump(signal1, fobj) fobj.close() fobj = open('./pickle', 'rb') try: signal2 = pickle.load(fobj) except ValueError: signal2 = None assert_array_equal(signal1, signal2) assert_array_equal(signal2.channel_index.index, np.array([0])) assert_array_equal(signal2.array_annotations['anno1'], np.array([23])) self.assertIsInstance(signal2.array_annotations, ArrayDict) # Make sure the dict can perform correct checks after unpickling signal2.array_annotations['anno3'] = [2] with self.assertRaises(ValueError): signal2.array_annotations['anno4'] = [2, 1] fobj.close() os.remove('./pickle')
def __getitem__(self, i): ''' Get the item or slice :attr:`i`. ''' obj = super(BaseAnalogSignal, self).__getitem__(i) if isinstance(i, int): return obj elif isinstance(i, tuple): j, k = i if isinstance(k, int): if isinstance(j, slice): # extract an AnalogSignal obj = AnalogSignal(obj, sampling_rate=self.sampling_rate) if j.start: obj.t_start = (self.t_start + j.start * self.sampling_period) # return a Quantity (for some reason quantities does not # return a Quantity in this case) elif isinstance(j, int): obj = pq.Quantity(obj, units=self.units) return obj elif isinstance(j, int): # extract a quantity array # should be a better way to do this obj = pq.Quantity(np.array(obj), units=obj.units) return obj else: return obj elif isinstance(i, slice): if i.start: obj.t_start = self.t_start + i.start * self.sampling_period return obj else: raise IndexError("index should be an integer, tuple or slice")
def test__slice_should_modify_linked_channelindex(self): n = 8 # number of channels signal = AnalogSignal(np.arange(n * 100.0).reshape(100, n), sampling_rate=1*pq.kHz, units="mV") self.assertEqual(signal.shape, (100, n)) signal.channel_index = ChannelIndex(index=np.arange(n, dtype=int), channel_names=["channel{0}".format(i) for i in range(n)]) odd_channels = signal[:, 1::2] self.assertEqual(odd_channels.shape, (100, n//2)) assert_array_equal(odd_channels.channel_index.index, np.arange(n//2, dtype=int)) assert_array_equal(odd_channels.channel_index.channel_names, ["channel{0}".format(i) for i in range(1, n, 2)]) assert_array_equal(signal.channel_index.channel_names, ["channel{0}".format(i) for i in range(n)])
def setUp(self): self.data1 = np.arange(55.0).reshape((11, 5)) self.data1quant = self.data1 * pq.nA self.arr_ann1 = {'anno1': np.arange(5), 'anno2': ['a', 'b', 'c', 'd', 'e']} self.signal1 = AnalogSignal(self.data1quant, sampling_rate=1 * pq.kHz, name='spam', description='eggs', file_origin='testfile.txt', array_annotations=self.arr_ann1, 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.arr_ann2 = {'anno1': [10, 11], 'anno2': ['k', 'l']} self.signal2 = AnalogSignal(self.data2quant, sampling_rate=1.0 * pq.Hz, name='spam', description='eggs', file_origin='testfile.txt', array_annotations=self.arr_ann2, arg1='test')
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 test__pickle(self): a = AnalogSignal([1,2,3,4],sampling_period=1*pq.ms,units=pq.S) a.annotations['index'] = 2 f = open('./pickle','wb') pickle.dump(a,f) f.close() f = open('./pickle','rb') try: b = pickle.load(f) except ValueError: b = None assert_arrays_equal(a, b) f.close() os.remove('./pickle')
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 = Segment() self.signal1.channel_index = ChannelIndex(index=[0])
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 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__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_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__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 test_splice_2channels_inplace(self): arr_ann1 = {'index': np.arange(10, 12)} arr_ann2 = {'index': np.arange(2), 'test': ['a', 'b']} signal = AnalogSignal(np.arange(20.0).reshape((10, 2)), sampling_rate=1 * pq.kHz, units="mV", array_annotations=arr_ann1) signal_for_splicing = AnalogSignal(np.array([[0.1, 0.0], [0.2, 0.0], [0.3, 0.0]]), t_start=3 * pq.ms, array_annotations=arr_ann2, 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 # Array annotations are taken from the main signal assert_array_equal(result.array_annotations['index'], np.arange(10, 12)) self.assertIsInstance(result.array_annotations, ArrayDict) self.assertNotIn('test', result.array_annotations)
def setUp(self): self.data1 = np.arange(55.0).reshape((11, 5)) 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') self.data2 = np.arange(100.0, 155.0).reshape((11, 5)) self.data2quant = self.data2 * pq.mV self.signal2 = AnalogSignal(self.data2quant, sampling_rate=1 * pq.kHz, name='spam', description='eggs', file_origin='testfile.txt', arg1='test')
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__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__slice_should_modify_linked_channelindex(self): n = 8 # number of channels signal = AnalogSignal(np.arange(n * 100.0).reshape(100, n), sampling_rate=1 * pq.kHz, units="mV", name="test") self.assertEqual(signal.shape, (100, n)) signal.channel_index = ChannelIndex(index=np.arange(n, dtype=int), channel_names=["channel{0}".format(i) for i in range(n)]) signal.channel_index.analogsignals.append(signal) odd_channels = signal[:, 1::2] self.assertEqual(odd_channels.shape, (100, n // 2)) assert_array_equal(odd_channels.channel_index.index, np.arange(n // 2, dtype=int)) assert_array_equal(odd_channels.channel_index.channel_names, ["channel{0}".format(i) for i in range(1, n, 2)]) assert_array_equal(signal.channel_index.channel_names, ["channel{0}".format(i) for i in range(n)]) self.assertEqual(odd_channels.channel_index.analogsignals[0].name, signal.name)
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 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_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__pickle(self): signal1 = AnalogSignal([1, 2, 3, 4], sampling_period=1*pq.ms, units=pq.S) signal1.annotations['index'] = 2 fobj = open('./pickle', 'wb') pickle.dump(signal1, fobj) fobj.close() fobj = open('./pickle', 'rb') try: signal2 = pickle.load(fobj) except ValueError: signal2 = None assert_array_equal(signal1, signal2) fobj.close() os.remove('./pickle')
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 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__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 test__pickle(self): signal1 = AnalogSignal([1, 2, 3, 4], sampling_period=1 * pq.ms, units=pq.S, channel_index=42) signal1.annotations["index"] = 2 fobj = open("./pickle", "wb") pickle.dump(signal1, fobj) fobj.close() fobj = open("./pickle", "rb") try: signal2 = pickle.load(fobj) except ValueError: signal2 = None assert_arrays_equal(signal1, signal2) self.assertEqual(signal1.channel_index, signal2.channel_index, 42) fobj.close() os.remove("./pickle")
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_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 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_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", )
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 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 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__pickle(self): a = AnalogSignal([1, 2, 3, 4], sampling_period=1 * pq.ms, units=pq.S, channel_index=42) a.annotations['index'] = 2 f = open('./pickle', 'wb') pickle.dump(a, f) f.close() f = open('./pickle', 'rb') try: b = pickle.load(f) except ValueError: b = None assert_arrays_equal(a, b) self.assertEqual(a.channel_index, b.channel_index, 42) f.close() os.remove('./pickle')
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_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 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_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_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
class TestAnalogSignalArrayMethods(unittest.TestCase): 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__compliant(self): assert_neo_object_is_compliant(self.signal1) def test__slice_should_return_AnalogSignalArray(self): # slice for index in (0, np.int64(0)): result = self.signal1[3:8, index] self.assertIsInstance(result, AnalogSignal) assert_neo_object_is_compliant(result) # should slicing really preserve name and description? self.assertEqual(result.name, 'spam') # perhaps these should be modified to indicate the slice? self.assertEqual(result.description, 'eggs') self.assertEqual(result.file_origin, 'testfile.txt') self.assertEqual(result.annotations, {'arg1': 'test'}) # Array annotations remain the same, because number of signals was not altered self.assertEqual(result.array_annotations, {'anno1': [23], 'anno2': ['A']}) self.assertIsInstance(result.array_annotations, ArrayDict) self.assertEqual(result.size, 5) self.assertEqual(result.sampling_period, self.signal1.sampling_period) self.assertEqual(result.sampling_rate, self.signal1.sampling_rate) self.assertEqual(result.t_start, self.signal1.t_start + 3 * result.sampling_period) self.assertEqual(result.t_stop, result.t_start + 5 * result.sampling_period) assert_array_equal(result.magnitude, self.data1[3:8].reshape(-1, 1)) # Test other attributes were copied over (in this case, defaults) self.assertEqual(result.file_origin, self.signal1.file_origin) self.assertEqual(result.name, self.signal1.name) self.assertEqual(result.description, self.signal1.description) self.assertEqual(result.annotations, self.signal1.annotations) def test__slice_should_let_access_to_parents_objects(self): result = self.signal1.time_slice(1 * pq.ms, 3 * pq.ms) self.assertEqual(result.segment, self.signal1.segment) self.assertEqual(result.channel_index, self.signal1.channel_index) def test__slice_should_change_sampling_period(self): result1 = self.signal1[:2, 0] result2 = self.signal1[::2, 0] result3 = self.signal1[1:7:2, 0] self.assertIsInstance(result1, AnalogSignal) assert_neo_object_is_compliant(result1) self.assertEqual(result1.name, 'spam') self.assertEqual(result1.description, 'eggs') self.assertEqual(result1.file_origin, 'testfile.txt') self.assertEqual(result1.annotations, {'arg1': 'test'}) self.assertEqual(result1.array_annotations, {'anno1': [23], 'anno2': ['A']}) self.assertIsInstance(result1.array_annotations, ArrayDict) self.assertIsInstance(result2, AnalogSignal) assert_neo_object_is_compliant(result2) self.assertEqual(result2.name, 'spam') self.assertEqual(result2.description, 'eggs') self.assertEqual(result2.file_origin, 'testfile.txt') self.assertEqual(result2.annotations, {'arg1': 'test'}) self.assertEqual(result2.array_annotations, {'anno1': [23], 'anno2': ['A']}) self.assertIsInstance(result2.array_annotations, ArrayDict) self.assertIsInstance(result3, AnalogSignal) assert_neo_object_is_compliant(result3) self.assertEqual(result3.name, 'spam') self.assertEqual(result3.description, 'eggs') self.assertEqual(result3.file_origin, 'testfile.txt') self.assertEqual(result3.annotations, {'arg1': 'test'}) self.assertEqual(result3.array_annotations, {'anno1': [23], 'anno2': ['A']}) self.assertIsInstance(result3.array_annotations, ArrayDict) self.assertEqual(result1.sampling_period, self.signal1.sampling_period) self.assertEqual(result2.sampling_period, self.signal1.sampling_period * 2) self.assertEqual(result3.sampling_period, self.signal1.sampling_period * 2) assert_array_equal(result1.magnitude, self.data1[:2].reshape(-1, 1)) assert_array_equal(result2.magnitude, self.data1[::2].reshape(-1, 1)) assert_array_equal(result3.magnitude, self.data1[1:7:2].reshape(-1, 1)) def test__slice_should_modify_linked_channelindex(self): n = 8 # number of channels signal = AnalogSignal(np.arange(n * 100.0).reshape(100, n), sampling_rate=1 * pq.kHz, units="mV", name="test") self.assertEqual(signal.shape, (100, n)) signal.channel_index = ChannelIndex(index=np.arange(n, dtype=int), channel_names=["channel{0}".format(i) for i in range(n)]) signal.channel_index.analogsignals.append(signal) odd_channels = signal[:, 1::2] self.assertEqual(odd_channels.shape, (100, n // 2)) assert_array_equal(odd_channels.channel_index.index, np.arange(n // 2, dtype=int)) assert_array_equal(odd_channels.channel_index.channel_names, ["channel{0}".format(i) for i in range(1, n, 2)]) assert_array_equal(signal.channel_index.channel_names, ["channel{0}".format(i) for i in range(n)]) self.assertEqual(odd_channels.channel_index.analogsignals[0].name, signal.name) def test__copy_should_let_access_to_parents_objects(self): result = self.signal1.copy() self.assertIs(result.segment, self.signal1.segment) self.assertIs(result.channel_index, self.signal1.channel_index) def test__deepcopy_should_let_access_to_parents_objects(self): result = copy.deepcopy(self.signal1) self.assertIsInstance(result.segment, Segment) self.assertIsInstance(result.channel_index, ChannelIndex) assert_same_sub_schema(result.segment, self.signal1.segment) assert_same_sub_schema(result.channel_index, self.signal1.channel_index) def test__getitem_should_return_single_quantity(self): result1 = self.signal1[0, 0] result2 = self.signal1[9, 0] self.assertIsInstance(result1, pq.Quantity) self.assertFalse(hasattr(result1, 'name')) self.assertFalse(hasattr(result1, 'description')) self.assertFalse(hasattr(result1, 'file_origin')) self.assertFalse(hasattr(result1, 'annotations')) self.assertFalse(hasattr(result1, 'array_annotations')) self.assertIsInstance(result2, pq.Quantity) self.assertFalse(hasattr(result2, 'name')) self.assertFalse(hasattr(result2, 'description')) self.assertFalse(hasattr(result2, 'file_origin')) self.assertFalse(hasattr(result2, 'annotations')) self.assertFalse(hasattr(result2, 'array_annotations')) self.assertEqual(result1, 0 * pq.nA) self.assertEqual(result2, 9 * pq.nA) def test__getitem_out_of_bounds_IndexError(self): self.assertRaises(IndexError, self.signal1.__getitem__, (10, 0)) def test_comparison_operators(self): assert_array_equal(self.signal1 >= 5 * pq.nA, np.array( [False, False, False, False, False, True, True, True, True, True]).reshape(-1, 1)) assert_array_equal(self.signal1 >= 5 * pq.pA, np.array( [False, True, True, True, True, True, True, True, True, True]).reshape(-1, 1)) assert_array_equal(self.signal1 == 5 * pq.nA, np.array( [False, False, False, False, False, True, False, False, False, False]).reshape(-1, 1)) assert_array_equal(self.signal1 == self.signal1, np.array( [True, True, True, True, True, True, True, True, True, True]).reshape(-1, 1)) def test__comparison_as_indexing_single_trace(self): self.assertEqual(self.signal1[self.signal1 == 5], [5 * pq.mV]) def test__comparison_as_indexing_double_trace(self): signal = AnalogSignal(np.arange(20).reshape((-1, 2)) * pq.V, sampling_rate=1 * pq.Hz) assert_array_equal(signal[signal < 10], np.array([[0, 2, 4, 6, 8], [1, 3, 5, 7, 9]]).T * pq.V) 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__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__comparison_with_inconsistent_units_should_raise_Exception(self): self.assertRaises(ValueError, self.signal1.__gt__, 5 * pq.mV) def test__simple_statistics(self): self.assertEqual(self.signal1.max(), 9 * pq.nA) self.assertEqual(self.signal1.min(), 0 * pq.nA) self.assertEqual(self.signal1.mean(), 4.5 * pq.nA) def test__rescale_same(self): result = self.signal1.copy() result = result.rescale(pq.nA) 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'}) self.assertEqual(result.array_annotations, {'anno1': [23], 'anno2': ['A']}) self.assertIsInstance(result.array_annotations, ArrayDict) self.assertEqual(result.units, 1 * pq.nA) assert_array_equal(result.magnitude, self.data1.reshape(-1, 1)) assert_same_sub_schema(result, self.signal1) self.assertIsInstance(result.channel_index, ChannelIndex) self.assertIsInstance(result.segment, Segment) self.assertIs(result.channel_index, self.signal1.channel_index) self.assertIs(result.segment, self.signal1.segment) def test__rescale_new(self): result = self.signal1.copy() result = result.rescale(pq.pA) 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'}) self.assertEqual(result.array_annotations, {'anno1': [23], 'anno2': ['A']}) self.assertIsInstance(result.array_annotations, ArrayDict) self.assertEqual(result.units, 1 * pq.pA) assert_arrays_almost_equal(np.array(result), self.data1.reshape(-1, 1) * 1000., 1e-10) self.assertIsInstance(result.channel_index, ChannelIndex) self.assertIsInstance(result.segment, Segment) self.assertIs(result.channel_index, self.signal1.channel_index) self.assertIs(result.segment, self.signal1.segment) def test__rescale_new_incompatible_ValueError(self): self.assertRaises(ValueError, self.signal1.rescale, pq.mV) def test_as_array(self): sig_as_arr = self.signal1.as_array() self.assertIsInstance(sig_as_arr, np.ndarray) assert_array_equal(self.data1, sig_as_arr.flat) def test_as_quantity(self): sig_as_q = self.signal1.as_quantity() self.assertIsInstance(sig_as_q, pq.Quantity) assert_array_equal(self.data1, sig_as_q.magnitude.flat) 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_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, array_annotations={'anno1': [0], 'anno2': ['C']}) 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) 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_splice_2channels_inplace(self): arr_ann1 = {'index': np.arange(10, 12)} arr_ann2 = {'index': np.arange(2), 'test': ['a', 'b']} signal = AnalogSignal(np.arange(20.0).reshape((10, 2)), sampling_rate=1 * pq.kHz, units="mV", array_annotations=arr_ann1) signal_for_splicing = AnalogSignal(np.array([[0.1, 0.0], [0.2, 0.0], [0.3, 0.0]]), t_start=3 * pq.ms, array_annotations=arr_ann2, 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 # Array annotations are taken from the main signal assert_array_equal(result.array_annotations['index'], np.arange(10, 12)) self.assertIsInstance(result.array_annotations, ArrayDict) self.assertNotIn('test', result.array_annotations) def test_splice_1channel_invalid_t_start(self): signal_for_splicing = AnalogSignal([0.1, 0.1, 0.1], t_start=12 * pq.ms, # after 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_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_sampling_rate(self): signal_for_splicing = AnalogSignal([0.1, 0.1, 0.1], t_start=3 * pq.ms, sampling_rate=2 * 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_array_annotations_getitem(self): data = np.arange(15).reshape(5, 3) * pq.mV arr_ann1 = [10, 15, 20] arr_ann2 = ['abc', 'def', 'ghi'] arr_anns = {'index': arr_ann1, 'label': arr_ann2} signal = AnalogSignal(data, sampling_rate=30000 * pq.Hz, array_annotations=arr_anns) # A time slice of all signals is selected, so all array annotations need to remain result1 = signal[0:2] assert_arrays_equal(result1.array_annotations['index'], np.array(arr_ann1)) assert_arrays_equal(result1.array_annotations['label'], np.array(arr_ann2)) self.assertIsInstance(result1.array_annotations, ArrayDict) # Only elements from signal with index 2 are selected, # so only those array_annotations should be returned result2 = signal[1:2, 2] assert_arrays_equal(result2.array_annotations['index'], np.array([20])) assert_arrays_equal(result2.array_annotations['label'], np.array(['ghi'])) self.assertIsInstance(result2.array_annotations, ArrayDict) # Because comparison of list with single element to scalar is possible, # we need to make sure that array_annotations remain arrays self.assertIsInstance(result2.array_annotations['index'], np.ndarray) self.assertIsInstance(result2.array_annotations['label'], np.ndarray) # Signals 0 and 1 are selected completely, # so their respective array_annotations should be returned result3 = signal[:, 0:2] assert_arrays_equal(result3.array_annotations['index'], np.array([10, 15])) assert_arrays_equal(result3.array_annotations['label'], np.array(['abc', 'def'])) self.assertIsInstance(result3.array_annotations, ArrayDict)
class TestAnalogSignalArrayCombination(unittest.TestCase): def setUp(self): self.data1 = np.arange(55.0).reshape((11, 5)) 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') self.data2 = np.arange(100.0, 155.0).reshape((11, 5)) self.data2quant = self.data2 * pq.mV self.signal2 = AnalogSignal(self.data2quant, sampling_rate=1*pq.kHz, name='spam', description='eggs', file_origin='testfile.txt', arg1='test') def test__compliant(self): assert_neo_object_is_compliant(self.signal1) self.assertEqual(self.signal1.name, 'spam') self.assertEqual(self.signal1.description, 'eggs') self.assertEqual(self.signal1.file_origin, 'testfile.txt') self.assertEqual(self.signal1.annotations, {'arg1': 'test'}) assert_neo_object_is_compliant(self.signal2) self.assertEqual(self.signal2.name, 'spam') self.assertEqual(self.signal2.description, 'eggs') self.assertEqual(self.signal2.file_origin, 'testfile.txt') self.assertEqual(self.signal2.annotations, {'arg1': 'test'}) def test__add_const_quantity_should_preserve_data_complement(self): result = self.signal1 + 0.065*pq.V 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'}) # time zero, signal index 4 assert_arrays_equal(result, self.data1 + 65) self.assertEqual(self.signal1[0, 4], 4*pq.mV) self.assertEqual(result[0, 4], 69000*pq.uV) self.assertEqual(self.signal1.t_start, result.t_start) self.assertEqual(self.signal1.sampling_rate, result.sampling_rate) def test__add_two_consistent_signals_should_preserve_data_complement(self): result = self.signal1 + self.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'}) targdata = np.arange(100.0, 210.0, 2.0).reshape((11, 5)) targ = AnalogSignal(targdata, units="mV", sampling_rate=1*pq.kHz, name='spam', description='eggs', file_origin='testfile.txt', arg1='test') assert_neo_object_is_compliant(targ) assert_arrays_equal(result, targdata) assert_same_sub_schema(result, targ) def test__add_signals_with_inconsistent_data_complement_ValueError(self): self.signal2.sampling_rate = 0.5*pq.kHz assert_neo_object_is_compliant(self.signal2) self.assertRaises(ValueError, self.signal1.__add__, self.signal2) def test__subtract_const_should_preserve_data_complement(self): result = self.signal1 - 65*pq.mV 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'}) self.assertEqual(np.array(self.signal1[1, 4]), 9) self.assertEqual(np.array(result[1, 4]), -56) assert_arrays_equal(result, self.data1 - 65) self.assertEqual(self.signal1.sampling_rate, result.sampling_rate) def test__subtract_from_const_should_return_signal(self): result = 10*pq.mV - self.signal1 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'}) self.assertEqual(np.array(self.signal1[1, 4]), 9) self.assertEqual(np.array(result[1, 4]), 1) assert_arrays_equal(result, 10 - self.data1) self.assertEqual(self.signal1.sampling_rate, result.sampling_rate) def test__mult_by_const_float_should_preserve_data_complement(self): result = self.signal1*2 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'}) self.assertEqual(np.array(self.signal1[1, 4]), 9) self.assertEqual(np.array(result[1, 4]), 18) assert_arrays_equal(result, self.data1*2) self.assertEqual(self.signal1.sampling_rate, result.sampling_rate) def test__divide_by_const_should_preserve_data_complement(self): result = self.signal1/0.5 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'}) self.assertEqual(np.array(self.signal1[1, 4]), 9) self.assertEqual(np.array(result[1, 4]), 18) assert_arrays_equal(result, self.data1/0.5) self.assertEqual(self.signal1.sampling_rate, result.sampling_rate) def test__merge(self): self.signal1.description = None self.signal1.file_origin = None assert_neo_object_is_compliant(self.signal1) data3 = np.arange(1000.0, 1066.0).reshape((11, 6)) * pq.uV data3scale = data3.rescale(self.data1quant.units) signal2 = AnalogSignal(self.data1quant, sampling_rate=1*pq.kHz, name='signal2', description='test signal', file_origin='testfile.txt') signal3 = AnalogSignal(data3, units="uV", sampling_rate=1*pq.kHz, name='signal3', description='test signal', file_origin='testfile.txt') signal4 = AnalogSignal(data3, units="uV", sampling_rate=1*pq.kHz, name='signal4', description='test signal', file_origin='testfile.txt') merged13 = self.signal1.merge(signal3) merged23 = signal2.merge(signal3) merged24 = signal2.merge(signal4) mergeddata13 = np.array(merged13) mergeddata23 = np.array(merged23) mergeddata24 = np.array(merged24) targdata13 = np.hstack([self.data1quant, data3scale]) targdata23 = np.hstack([self.data1quant, data3scale]) targdata24 = np.hstack([self.data1quant, data3scale]) assert_neo_object_is_compliant(signal2) assert_neo_object_is_compliant(signal3) assert_neo_object_is_compliant(merged13) assert_neo_object_is_compliant(merged23) assert_neo_object_is_compliant(merged24) self.assertEqual(merged13[0, 4], 4*pq.mV) self.assertEqual(merged23[0, 4], 4*pq.mV) self.assertEqual(merged13[0, 5], 1*pq.mV) self.assertEqual(merged23[0, 5], 1*pq.mV) self.assertEqual(merged13[10, 10], 1.065*pq.mV) self.assertEqual(merged23[10, 10], 1.065*pq.mV) self.assertEqual(merged13.t_stop, self.signal1.t_stop) self.assertEqual(merged23.t_stop, self.signal1.t_stop) self.assertEqual(merged13.name, 'merge(spam, signal3)') self.assertEqual(merged23.name, 'merge(signal2, signal3)') self.assertEqual(merged13.description, 'merge(None, test signal)') self.assertEqual(merged23.description, 'test signal') self.assertEqual(merged13.file_origin, 'merge(None, testfile.txt)') self.assertEqual(merged23.file_origin, 'testfile.txt') assert_arrays_equal(mergeddata13, targdata13) assert_arrays_equal(mergeddata23, targdata23) assert_arrays_equal(mergeddata24, targdata24)
class TestAnalogSignalArrayMethods(unittest.TestCase): 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 = Segment() self.signal1.channel_index = ChannelIndex(index=[0]) def test__compliant(self): assert_neo_object_is_compliant(self.signal1) def test__slice_should_return_AnalogSignalArray(self): # slice for index in (0, np.int64(0)): result = self.signal1[3:8, index] self.assertIsInstance(result, AnalogSignal) assert_neo_object_is_compliant(result) self.assertEqual(result.name, 'spam') # should slicing really preserve name and description? self.assertEqual(result.description, 'eggs') # perhaps these should be modified to indicate the slice? self.assertEqual(result.file_origin, 'testfile.txt') self.assertEqual(result.annotations, {'arg1': 'test'}) self.assertEqual(result.size, 5) self.assertEqual(result.sampling_period, self.signal1.sampling_period) self.assertEqual(result.sampling_rate, self.signal1.sampling_rate) self.assertEqual(result.t_start, self.signal1.t_start+3*result.sampling_period) self.assertEqual(result.t_stop, result.t_start + 5*result.sampling_period) assert_array_equal(result.magnitude, self.data1[3:8].reshape(-1, 1)) # Test other attributes were copied over (in this case, defaults) self.assertEqual(result.file_origin, self.signal1.file_origin) self.assertEqual(result.name, self.signal1.name) self.assertEqual(result.description, self.signal1.description) self.assertEqual(result.annotations, self.signal1.annotations) def test__slice_should_let_access_to_parents_objects(self): result = self.signal1.time_slice(1*pq.ms,3*pq.ms) self.assertEqual(result.segment, self.signal1.segment) self.assertEqual(result.channel_index, self.signal1.channel_index) def test__slice_should_change_sampling_period(self): result1 = self.signal1[:2, 0] result2 = self.signal1[::2, 0] result3 = self.signal1[1:7:2, 0] self.assertIsInstance(result1, AnalogSignal) assert_neo_object_is_compliant(result1) self.assertEqual(result1.name, 'spam') self.assertEqual(result1.description, 'eggs') self.assertEqual(result1.file_origin, 'testfile.txt') self.assertEqual(result1.annotations, {'arg1': 'test'}) self.assertIsInstance(result2, AnalogSignal) assert_neo_object_is_compliant(result2) self.assertEqual(result2.name, 'spam') self.assertEqual(result2.description, 'eggs') self.assertEqual(result2.file_origin, 'testfile.txt') self.assertEqual(result2.annotations, {'arg1': 'test'}) self.assertIsInstance(result3, AnalogSignal) assert_neo_object_is_compliant(result3) self.assertEqual(result3.name, 'spam') self.assertEqual(result3.description, 'eggs') self.assertEqual(result3.file_origin, 'testfile.txt') self.assertEqual(result3.annotations, {'arg1': 'test'}) self.assertEqual(result1.sampling_period, self.signal1.sampling_period) self.assertEqual(result2.sampling_period, self.signal1.sampling_period * 2) self.assertEqual(result3.sampling_period, self.signal1.sampling_period * 2) assert_array_equal(result1.magnitude, self.data1[:2].reshape(-1, 1)) assert_array_equal(result2.magnitude, self.data1[::2].reshape(-1, 1)) assert_array_equal(result3.magnitude, self.data1[1:7:2].reshape(-1, 1)) def test__slice_should_modify_linked_channelindex(self): n = 8 # number of channels signal = AnalogSignal(np.arange(n * 100.0).reshape(100, n), sampling_rate=1*pq.kHz, units="mV", name="test") self.assertEqual(signal.shape, (100, n)) signal.channel_index = ChannelIndex(index=np.arange(n, dtype=int), channel_names=["channel{0}".format(i) for i in range(n)]) signal.channel_index.analogsignals.append(signal) odd_channels = signal[:, 1::2] self.assertEqual(odd_channels.shape, (100, n//2)) assert_array_equal(odd_channels.channel_index.index, np.arange(n//2, dtype=int)) assert_array_equal(odd_channels.channel_index.channel_names, ["channel{0}".format(i) for i in range(1, n, 2)]) assert_array_equal(signal.channel_index.channel_names, ["channel{0}".format(i) for i in range(n)]) self.assertEqual(odd_channels.channel_index.analogsignals[0].name, signal.name) def test__copy_should_let_access_to_parents_objects(self): result = self.signal1.copy() self.assertIs(result.segment, self.signal1.segment) self.assertIs(result.channel_index, self.signal1.channel_index) def test__deepcopy_should_let_access_to_parents_objects(self): result = copy.deepcopy(self.signal1) self.assertIsInstance(result.segment, Segment) self.assertIsInstance(result.channel_index, ChannelIndex) assert_same_sub_schema(result.segment, self.signal1.segment) assert_same_sub_schema(result.channel_index, self.signal1.channel_index) def test__getitem_should_return_single_quantity(self): result1 = self.signal1[0, 0] result2 = self.signal1[9, 0] self.assertIsInstance(result1, pq.Quantity) self.assertFalse(hasattr(result1, 'name')) self.assertFalse(hasattr(result1, 'description')) self.assertFalse(hasattr(result1, 'file_origin')) self.assertFalse(hasattr(result1, 'annotations')) self.assertIsInstance(result2, pq.Quantity) self.assertFalse(hasattr(result2, 'name')) self.assertFalse(hasattr(result2, 'description')) self.assertFalse(hasattr(result2, 'file_origin')) self.assertFalse(hasattr(result2, 'annotations')) self.assertEqual(result1, 0*pq.nA) self.assertEqual(result2, 9*pq.nA) def test__getitem_out_of_bounds_IndexError(self): self.assertRaises(IndexError, self.signal1.__getitem__, (10, 0)) def test_comparison_operators(self): assert_array_equal(self.signal1 >= 5*pq.nA, np.array([False, False, False, False, False, True, True, True, True, True]).reshape(-1, 1)) assert_array_equal(self.signal1 >= 5*pq.pA, np.array([False, True, True, True, True, True, True, True, True, True]).reshape(-1, 1)) def test__comparison_with_inconsistent_units_should_raise_Exception(self): self.assertRaises(ValueError, self.signal1.__gt__, 5*pq.mV) def test__simple_statistics(self): self.assertEqual(self.signal1.max(), 9*pq.nA) self.assertEqual(self.signal1.min(), 0*pq.nA) self.assertEqual(self.signal1.mean(), 4.5*pq.nA) def test__rescale_same(self): result = self.signal1.copy() result = result.rescale(pq.nA) 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'}) self.assertEqual(result.units, 1*pq.nA) assert_array_equal(result.magnitude, self.data1.reshape(-1, 1)) assert_same_sub_schema(result, self.signal1) self.assertIsInstance(result.channel_index, ChannelIndex) self.assertIsInstance(result.segment, Segment) self.assertIs(result.channel_index, self.signal1.channel_index) self.assertIs(result.segment, self.signal1.segment) def test__rescale_new(self): result = self.signal1.copy() result = result.rescale(pq.pA) 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'}) self.assertEqual(result.units, 1*pq.pA) assert_arrays_almost_equal(np.array(result), self.data1.reshape(-1, 1)*1000., 1e-10) self.assertIsInstance(result.channel_index, ChannelIndex) self.assertIsInstance(result.segment, Segment) self.assertIs(result.channel_index, self.signal1.channel_index) self.assertIs(result.segment, self.signal1.segment) def test__rescale_new_incompatible_ValueError(self): self.assertRaises(ValueError, self.signal1.rescale, pq.mV) def test_as_array(self): sig_as_arr = self.signal1.as_array() self.assertIsInstance(sig_as_arr, np.ndarray) assert_array_equal(self.data1, sig_as_arr.flat) def test_as_quantity(self): sig_as_q = self.signal1.as_quantity() self.assertIsInstance(sig_as_q, pq.Quantity) assert_array_equal(self.data1, sig_as_q.magnitude.flat) 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 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 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_splice_1channel_invalid_t_start(self): signal_for_splicing = AnalogSignal([0.1, 0.1, 0.1], t_start=12*pq.ms, # after 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_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_sampling_rate(self): signal_for_splicing = AnalogSignal([0.1, 0.1, 0.1], t_start=3 * pq.ms, sampling_rate=2 * 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 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')
class TestAnalogSignalArrayMethods(unittest.TestCase): 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') def test__compliant(self): assert_neo_object_is_compliant(self.signal1) def test__slice_should_return_AnalogSignal(self): # slice result = self.signal1[3:8] 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'}) self.assertEqual(result.size, 5) self.assertEqual(result.sampling_period, self.signal1.sampling_period) self.assertEqual(result.sampling_rate, self.signal1.sampling_rate) self.assertEqual(result.t_start, self.signal1.t_start+3*result.sampling_period) self.assertEqual(result.t_stop, result.t_start + 5*result.sampling_period) assert_arrays_equal(result, self.data1[3:8]) # Test other attributes were copied over (in this case, defaults) self.assertEqual(result.file_origin, self.signal1.file_origin) self.assertEqual(result.name, self.signal1.name) self.assertEqual(result.description, self.signal1.description) self.assertEqual(result.annotations, self.signal1.annotations) def test__slice_should_change_sampling_period(self): result1 = self.signal1[:2] result2 = self.signal1[::2] result3 = self.signal1[1:7:2] self.assertIsInstance(result1, AnalogSignal) assert_neo_object_is_compliant(result1) self.assertEqual(result1.name, 'spam') self.assertEqual(result1.description, 'eggs') self.assertEqual(result1.file_origin, 'testfile.txt') self.assertEqual(result1.annotations, {'arg1': 'test'}) self.assertIsInstance(result2, AnalogSignal) assert_neo_object_is_compliant(result2) self.assertEqual(result2.name, 'spam') self.assertEqual(result2.description, 'eggs') self.assertEqual(result2.file_origin, 'testfile.txt') self.assertEqual(result2.annotations, {'arg1': 'test'}) self.assertIsInstance(result3, AnalogSignal) assert_neo_object_is_compliant(result3) self.assertEqual(result3.name, 'spam') self.assertEqual(result3.description, 'eggs') self.assertEqual(result3.file_origin, 'testfile.txt') self.assertEqual(result3.annotations, {'arg1': 'test'}) self.assertEqual(result1.sampling_period, self.signal1.sampling_period) self.assertEqual(result2.sampling_period, self.signal1.sampling_period * 2) self.assertEqual(result3.sampling_period, self.signal1.sampling_period * 2) assert_arrays_equal(result1, self.data1[:2]) assert_arrays_equal(result2, self.data1[::2]) assert_arrays_equal(result3, self.data1[1:7:2]) def test__getitem_should_return_single_quantity(self): result1 = self.signal1[0] result2 = self.signal1[9] self.assertIsInstance(result1, pq.Quantity) self.assertFalse(hasattr(result1, 'name')) self.assertFalse(hasattr(result1, 'description')) self.assertFalse(hasattr(result1, 'file_origin')) self.assertFalse(hasattr(result1, 'annotations')) self.assertIsInstance(result2, pq.Quantity) self.assertFalse(hasattr(result2, 'name')) self.assertFalse(hasattr(result2, 'description')) self.assertFalse(hasattr(result2, 'file_origin')) self.assertFalse(hasattr(result2, 'annotations')) self.assertEqual(result1, 0*pq.nA) self.assertEqual(result2, 9*pq.nA) def test__getitem_out_of_bounds_IndexError(self): self.assertRaises(IndexError, self.signal1.__getitem__, 10) def test_comparison_operators(self): assert_arrays_equal(self.signal1 >= 5*pq.nA, np.array([False, False, False, False, False, True, True, True, True, True])) assert_arrays_equal(self.signal1 >= 5*pq.pA, np.array([False, True, True, True, True, True, True, True, True, True])) def test__comparison_with_inconsistent_units_should_raise_Exception(self): self.assertRaises(ValueError, self.signal1.__gt__, 5*pq.mV) def test__simple_statistics(self): self.assertEqual(self.signal1.max(), 9*pq.nA) self.assertEqual(self.signal1.min(), 0*pq.nA) self.assertEqual(self.signal1.mean(), 4.5*pq.nA) def test__rescale_same(self): result = self.signal1.copy() result = result.rescale(pq.nA) 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'}) self.assertEqual(result.units, 1*pq.nA) assert_arrays_equal(result, self.data1) assert_same_sub_schema(result, self.signal1) def test__rescale_new(self): result = self.signal1.copy() result = result.rescale(pq.pA) 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'}) self.assertEqual(result.units, 1*pq.pA) assert_arrays_almost_equal(np.array(result), self.data1*1000., 1e-10) def test__rescale_new_incompatible_ValueError(self): self.assertRaises(ValueError, self.signal1.rescale, pq.mV)
class TestArrayMethods(unittest.TestCase): def setUp(self): self.signal = AnalogSignal(numpy.arange(10.0), units="nA", sampling_rate=1*kHz) def test__slice_should_return_AnalogSignal(self): sub = self.signal[3:8] self.assertIsInstance(sub, AnalogSignal) self.assertEqual(sub.size, 5) self.assertEqual(sub.sampling_period, self.signal.sampling_period) self.assertEqual(sub.sampling_rate, self.signal.sampling_rate) self.assertEqual(sub.t_start, self.signal.t_start+3*sub.sampling_period) self.assertEqual(sub.t_stop, sub.t_start + 5*sub.sampling_period) # Test other attributes were copied over (in this case, defaults) self.assertEqual(sub.file_origin, self.signal.file_origin) self.assertEqual(sub.name, self.signal.name) self.assertEqual(sub.description, self.signal.description) self.assertEqual(sub.annotations, self.signal.annotations) sub = self.signal[3:8] self.assertEqual(sub.file_origin, self.signal.file_origin) self.assertEqual(sub.name, self.signal.name) self.assertEqual(sub.description, self.signal.description) self.assertEqual(sub.annotations, self.signal.annotations) def test__slice_with_attributes(self): # Set attributes, slice, test that they are copied self.signal.file_origin = 'crack.txt' self.signal.name = 'sig' self.signal.description = 'a signal' self.signal.annotate(ratname='Georges') # slice sub = self.signal[3:8] # tests from other slice test self.assertIsInstance(sub, AnalogSignal) self.assertEqual(sub.size, 5) self.assertEqual(sub.sampling_period, self.signal.sampling_period) self.assertEqual(sub.sampling_rate, self.signal.sampling_rate) self.assertEqual(sub.t_start, self.signal.t_start+3*sub.sampling_period) self.assertEqual(sub.t_stop, sub.t_start + 5*sub.sampling_period) # Test other attributes were copied over (in this case, set by user) self.assertEqual(sub.file_origin, self.signal.file_origin) self.assertEqual(sub.name, self.signal.name) self.assertEqual(sub.description, self.signal.description) self.assertEqual(sub.annotations, self.signal.annotations) self.assertEqual(sub.annotations, {'ratname': 'Georges'}) def test__slice_should_change_sampling_period(self): sub = self.signal[:2] self.assertEqual(sub.sampling_period, self.signal.sampling_period) sub = self.signal[::2] self.assertEqual(sub.sampling_period, self.signal.sampling_period * 2) sub = self.signal[1:7:2] self.assertEqual(sub.sampling_period, self.signal.sampling_period * 2) def test__getitem_should_return_single_quantity(self): self.assertEqual(self.signal[0], 0*nA) self.assertEqual(self.signal[9], 9*nA) self.assertRaises(IndexError, self.signal.__getitem__, 10) def test_comparison_operators(self): assert_arrays_equal(self.signal >= 5*nA, numpy.array([False, False, False, False, False, True, True, True, True, True])) assert_arrays_equal(self.signal >= 5*pA, numpy.array([False, True, True, True, True, True, True, True, True, True])) def test__comparison_with_inconsistent_units_should_raise_Exception(self): self.assertRaises(ValueError, self.signal.__gt__, 5*mV) def test_simple_statistics(self): self.assertEqual(self.signal.max(), 9*nA) self.assertEqual(self.signal.min(), 0*nA) self.assertEqual(self.signal.mean(), 4.5*nA)
def setUp(self): self.signal = AnalogSignal(numpy.arange(10.0), units="nA", sampling_rate=1*kHz)
class TestAnalogSignalArrayMethods(unittest.TestCase): 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__compliant(self): assert_neo_object_is_compliant(self.signal1) def test__slice_should_return_AnalogSignalArray(self): # slice result = self.signal1[3:8, 0] self.assertIsInstance(result, AnalogSignal) assert_neo_object_is_compliant(result) self.assertEqual(result.name, 'spam') # should slicing really preserve name and description? self.assertEqual(result.description, 'eggs') # perhaps these should be modified to indicate the slice? self.assertEqual(result.file_origin, 'testfile.txt') self.assertEqual(result.annotations, {'arg1': 'test'}) self.assertEqual(result.size, 5) self.assertEqual(result.sampling_period, self.signal1.sampling_period) self.assertEqual(result.sampling_rate, self.signal1.sampling_rate) self.assertEqual(result.t_start, self.signal1.t_start+3*result.sampling_period) self.assertEqual(result.t_stop, result.t_start + 5*result.sampling_period) assert_array_equal(result.magnitude, self.data1[3:8].reshape(-1, 1)) # Test other attributes were copied over (in this case, defaults) self.assertEqual(result.file_origin, self.signal1.file_origin) self.assertEqual(result.name, self.signal1.name) self.assertEqual(result.description, self.signal1.description) self.assertEqual(result.annotations, self.signal1.annotations) def test__slice_should_let_access_to_parents_objects(self): result = self.signal1.time_slice(1*pq.ms,3*pq.ms) self.assertEqual(result.segment, self.signal1.segment) self.assertEqual(result.channel_index, self.signal1.channel_index) def test__slice_should_change_sampling_period(self): result1 = self.signal1[:2, 0] result2 = self.signal1[::2, 0] result3 = self.signal1[1:7:2, 0] self.assertIsInstance(result1, AnalogSignal) assert_neo_object_is_compliant(result1) self.assertEqual(result1.name, 'spam') self.assertEqual(result1.description, 'eggs') self.assertEqual(result1.file_origin, 'testfile.txt') self.assertEqual(result1.annotations, {'arg1': 'test'}) self.assertIsInstance(result2, AnalogSignal) assert_neo_object_is_compliant(result2) self.assertEqual(result2.name, 'spam') self.assertEqual(result2.description, 'eggs') self.assertEqual(result2.file_origin, 'testfile.txt') self.assertEqual(result2.annotations, {'arg1': 'test'}) self.assertIsInstance(result3, AnalogSignal) assert_neo_object_is_compliant(result3) self.assertEqual(result3.name, 'spam') self.assertEqual(result3.description, 'eggs') self.assertEqual(result3.file_origin, 'testfile.txt') self.assertEqual(result3.annotations, {'arg1': 'test'}) self.assertEqual(result1.sampling_period, self.signal1.sampling_period) self.assertEqual(result2.sampling_period, self.signal1.sampling_period * 2) self.assertEqual(result3.sampling_period, self.signal1.sampling_period * 2) assert_array_equal(result1.magnitude, self.data1[:2].reshape(-1, 1)) assert_array_equal(result2.magnitude, self.data1[::2].reshape(-1, 1)) assert_array_equal(result3.magnitude, self.data1[1:7:2].reshape(-1, 1)) def test__slice_should_modify_linked_channelindex(self): n = 8 # number of channels signal = AnalogSignal(np.arange(n * 100.0).reshape(100, n), sampling_rate=1*pq.kHz, units="mV") self.assertEqual(signal.shape, (100, n)) signal.channel_index = ChannelIndex(index=np.arange(n, dtype=int), channel_names=["channel{0}".format(i) for i in range(n)]) odd_channels = signal[:, 1::2] self.assertEqual(odd_channels.shape, (100, n//2)) assert_array_equal(odd_channels.channel_index.index, np.arange(n//2, dtype=int)) assert_array_equal(odd_channels.channel_index.channel_names, ["channel{0}".format(i) for i in range(1, n, 2)]) assert_array_equal(signal.channel_index.channel_names, ["channel{0}".format(i) for i in range(n)]) def test__copy_should_let_access_to_parents_objects(self): ##copy result = self.signal1.copy() self.assertEqual(result.segment, self.signal1.segment) self.assertEqual(result.channel_index, self.signal1.channel_index) ## deep copy (not fixed yet) #result = copy.deepcopy(self.signal1) #self.assertEqual(result.segment, self.signal1.segment) #self.assertEqual(result.channel_index, self.signal1.channel_index) def test__getitem_should_return_single_quantity(self): result1 = self.signal1[0, 0] result2 = self.signal1[9, 0] self.assertIsInstance(result1, pq.Quantity) self.assertFalse(hasattr(result1, 'name')) self.assertFalse(hasattr(result1, 'description')) self.assertFalse(hasattr(result1, 'file_origin')) self.assertFalse(hasattr(result1, 'annotations')) self.assertIsInstance(result2, pq.Quantity) self.assertFalse(hasattr(result2, 'name')) self.assertFalse(hasattr(result2, 'description')) self.assertFalse(hasattr(result2, 'file_origin')) self.assertFalse(hasattr(result2, 'annotations')) self.assertEqual(result1, 0*pq.nA) self.assertEqual(result2, 9*pq.nA) def test__getitem_out_of_bounds_IndexError(self): self.assertRaises(IndexError, self.signal1.__getitem__, (10, 0)) def test_comparison_operators(self): assert_array_equal(self.signal1 >= 5*pq.nA, np.array([False, False, False, False, False, True, True, True, True, True]).reshape(-1, 1)) assert_array_equal(self.signal1 >= 5*pq.pA, np.array([False, True, True, True, True, True, True, True, True, True]).reshape(-1, 1)) def test__comparison_with_inconsistent_units_should_raise_Exception(self): self.assertRaises(ValueError, self.signal1.__gt__, 5*pq.mV) def test__simple_statistics(self): self.assertEqual(self.signal1.max(), 9*pq.nA) self.assertEqual(self.signal1.min(), 0*pq.nA) self.assertEqual(self.signal1.mean(), 4.5*pq.nA) def test__rescale_same(self): result = self.signal1.copy() result = result.rescale(pq.nA) 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'}) self.assertEqual(result.units, 1*pq.nA) assert_array_equal(result.magnitude, self.data1.reshape(-1, 1)) assert_same_sub_schema(result, self.signal1) def test__rescale_new(self): result = self.signal1.copy() result = result.rescale(pq.pA) 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'}) self.assertEqual(result.units, 1*pq.pA) assert_arrays_almost_equal(np.array(result), self.data1.reshape(-1, 1)*1000., 1e-10) def test__rescale_new_incompatible_ValueError(self): self.assertRaises(ValueError, self.signal1.rescale, pq.mV) def test_as_array(self): sig_as_arr = self.signal1.as_array() self.assertIsInstance(sig_as_arr, np.ndarray) assert_array_equal(self.data1, sig_as_arr.flat) def test_as_quantity(self): sig_as_q = self.signal1.as_quantity() self.assertIsInstance(sig_as_q, pq.Quantity) assert_array_equal(self.data1, sig_as_q.magnitude.flat)
class TestAnalogSignalArrayArrayMethods(unittest.TestCase): def setUp(self): self.data1 = np.arange(55.0).reshape((11, 5)) self.data1quant = self.data1 * pq.nA self.arr_ann1 = {'anno1': np.arange(5), 'anno2': ['a', 'b', 'c', 'd', 'e']} self.signal1 = AnalogSignal(self.data1quant, sampling_rate=1 * pq.kHz, name='spam', description='eggs', file_origin='testfile.txt', array_annotations=self.arr_ann1, 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.arr_ann2 = {'anno1': [10, 11], 'anno2': ['k', 'l']} self.signal2 = AnalogSignal(self.data2quant, sampling_rate=1.0 * pq.Hz, name='spam', description='eggs', file_origin='testfile.txt', array_annotations=self.arr_ann2, arg1='test') def test__compliant(self): assert_neo_object_is_compliant(self.signal1) self.assertEqual(self.signal1.name, 'spam') self.assertEqual(self.signal1.description, 'eggs') self.assertEqual(self.signal1.file_origin, 'testfile.txt') self.assertEqual(self.signal1.annotations, {'arg1': 'test'}) assert_arrays_equal(self.signal1.array_annotations['anno1'], np.arange(5)) assert_arrays_equal(self.signal1.array_annotations['anno2'], np.array(['a', 'b', 'c', 'd', 'e'])) self.assertIsInstance(self.signal1.array_annotations, ArrayDict) assert_neo_object_is_compliant(self.signal2) self.assertEqual(self.signal2.name, 'spam') self.assertEqual(self.signal2.description, 'eggs') self.assertEqual(self.signal2.file_origin, 'testfile.txt') self.assertEqual(self.signal2.annotations, {'arg1': 'test'}) assert_arrays_equal(self.signal2.array_annotations['anno1'], np.array([10, 11])) assert_arrays_equal(self.signal2.array_annotations['anno2'], np.array(['k', 'l'])) self.assertIsInstance(self.signal2.array_annotations, ArrayDict) def test__index_dim1_should_return_single_channel_analogsignalarray(self): result = self.signal1[:, 0] 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([0])) assert_arrays_equal(result.array_annotations['anno2'], np.array(['a'])) self.assertIsInstance(result.array_annotations, ArrayDict) self.assertEqual(result.t_stop, self.signal1.t_stop) self.assertEqual(result.t_start, self.signal1.t_start) self.assertEqual(result.sampling_rate, self.signal1.sampling_rate) assert_arrays_equal(result, self.data1[:, 0].reshape(-1, 1)) def test__index_dim1_and_slice_dim0_should_return_single_channel_analogsignalarray(self): result = self.signal1[2:7, 0] self.assertIsInstance(result, AnalogSignal) assert_neo_object_is_compliant(result) self.assertEqual(result.shape, (5, 1)) 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([0])) assert_arrays_equal(result.array_annotations['anno2'], np.array(['a'])) self.assertIsInstance(result.array_annotations, ArrayDict) self.assertEqual(result.t_start, self.signal1.t_start + 2 * self.signal1.sampling_period) self.assertEqual(result.t_stop, self.signal1.t_start + 7 * self.signal1.sampling_period) self.assertEqual(result.sampling_rate, self.signal1.sampling_rate) assert_arrays_equal(result, self.data1[2:7, 0].reshape(-1, 1)) def test__index_dim0_should_return_quantity_array(self): # i.e. values from all signals for a single point in time result = self.signal1[3, :] self.assertIsInstance(result, pq.Quantity) self.assertFalse(hasattr(result, 'name')) self.assertFalse(hasattr(result, 'description')) self.assertFalse(hasattr(result, 'file_origin')) self.assertFalse(hasattr(result, 'annotations')) self.assertFalse(hasattr(result, 'array_annotations')) self.assertEqual(result.shape, (5,)) self.assertFalse(hasattr(result, "t_start")) self.assertEqual(result.units, pq.nA) assert_arrays_equal(result, self.data1[3, :]) def test__index_dim0_and_slice_dim1_should_return_quantity_array(self): # i.e. values from a subset of signals for a single point in time result = self.signal1[3, 2:5] self.assertIsInstance(result, pq.Quantity) self.assertFalse(hasattr(result, 'name')) self.assertFalse(hasattr(result, 'description')) self.assertFalse(hasattr(result, 'file_origin')) self.assertFalse(hasattr(result, 'annotations')) self.assertFalse(hasattr(result, 'array_annotations')) self.assertEqual(result.shape, (3,)) self.assertFalse(hasattr(result, "t_start")) self.assertEqual(result.units, pq.nA) assert_arrays_equal(result, self.data1[3, 2:5]) def test__index_as_string_IndexError(self): self.assertRaises(IndexError, self.signal1.__getitem__, 5.) def test__slice_both_dimensions_should_return_analogsignalarray(self): result = self.signal1[0:3, 0:3] 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([0, 1, 2])) assert_arrays_equal(result.array_annotations['anno2'], np.array(['a', 'b', 'c'])) self.assertIsInstance(result.array_annotations, ArrayDict) targ = AnalogSignal([[0, 1, 2], [5, 6, 7], [10, 11, 12]], dtype=float, units="nA", sampling_rate=1 * pq.kHz, name='spam', description='eggs', file_origin='testfile.txt', arg1='test') assert_neo_object_is_compliant(targ) self.assertEqual(result.t_stop, targ.t_stop) self.assertEqual(result.t_start, targ.t_start) self.assertEqual(result.sampling_rate, targ.sampling_rate) self.assertEqual(result.shape, targ.shape) assert_same_sub_schema(result, targ) assert_arrays_equal(result, self.data1[0:3, 0:3]) def test__slice_only_first_dimension_should_return_analogsignalarray(self): result = self.signal1[2:7] 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.arange(5)) assert_arrays_equal(result.array_annotations['anno2'], np.array(['a', 'b', 'c', 'd', 'e'])) self.assertIsInstance(result.array_annotations, ArrayDict) self.assertEqual(result.shape, (5, 5)) self.assertEqual(result.t_start, self.signal1.t_start + 2 * self.signal1.sampling_period) self.assertEqual(result.t_stop, self.signal1.t_start + 7 * self.signal1.sampling_period) self.assertEqual(result.sampling_rate, self.signal1.sampling_rate) assert_arrays_equal(result, self.data1[2:7]) def test__getitem_should_return_single_quantity(self): # quantities drops the units in this case self.assertEqual(self.signal1[9, 3], 48000 * pq.pA) self.assertEqual(self.signal1[9][3], self.signal1[9, 3]) self.assertTrue(hasattr(self.signal1[9, 3], 'units')) self.assertRaises(IndexError, self.signal1.__getitem__, (99, 73)) def test_comparison_operators(self): assert_arrays_equal(self.signal1[0:3, 0:3] >= 5 * pq.nA, np.array( [[False, False, False], [True, True, True], [True, True, True]])) assert_arrays_equal(self.signal1[0:3, 0:3] >= 5 * pq.pA, np.array( [[False, True, True], [True, True, True], [True, True, True]])) assert_arrays_equal(self.signal1[0:3, 0:3] == 5 * pq.nA, np.array( [[False, False, False], [True, False, False], [False, False, False]])) assert_arrays_equal(self.signal1[0:3, 0:3] == self.signal1[0:3, 0:3], np.array([[True, True, True], [True, True, True], [True, True, True]])) def test__comparison_with_inconsistent_units_should_raise_Exception(self): self.assertRaises(ValueError, self.signal1.__gt__, 5 * pq.mV) def test__simple_statistics(self): self.assertEqual(self.signal1.max(), 54000 * pq.pA) self.assertEqual(self.signal1.min(), 0 * pq.nA) self.assertEqual(self.signal1.mean(), 27 * pq.nA) self.assertEqual(self.signal1.std(), self.signal1.magnitude.std() * pq.nA) self.assertEqual(self.signal1.var(), self.signal1.magnitude.var() * pq.nA ** 2) def test__rescale_same(self): result = self.signal1.copy() result = result.rescale(pq.nA) 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.arange(5)) assert_arrays_equal(result.array_annotations['anno2'], np.array(['a', 'b', 'c', 'd', 'e'])) self.assertIsInstance(result.array_annotations, ArrayDict) self.assertEqual(result.units, 1 * pq.nA) assert_arrays_equal(result, self.data1) assert_same_sub_schema(result, self.signal1) def test__rescale_new(self): result = self.signal1.copy() result = result.rescale(pq.pA) 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.arange(5)) assert_arrays_equal(result.array_annotations['anno2'], np.array(['a', 'b', 'c', 'd', 'e'])) self.assertIsInstance(result.array_annotations, ArrayDict) self.assertEqual(result.units, 1 * pq.pA) assert_arrays_almost_equal(np.array(result), self.data1 * 1000., 1e-10) def test__time_slice(self): t_start = 2 * pq.s t_stop = 4 * pq.s 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'])) targ = AnalogSignal(np.array([[2., 3.], [2., 3.]]).T, sampling_rate=1.0 * pq.Hz, units='mV', t_start=t_start, name='spam', description='eggs', file_origin='testfile.txt', arg1='test') assert_neo_object_is_compliant(result) self.assertEqual(result.t_stop, t_stop) self.assertEqual(result.t_start, t_start) self.assertEqual(result.sampling_rate, targ.sampling_rate) assert_array_equal(result, targ) assert_same_sub_schema(result, targ) def test__time_slice__out_of_bounds_ValueError(self): t_start_good = 2 * pq.s t_stop_good = 4 * pq.s t_start_bad = -2 * pq.s t_stop_bad = 40 * pq.s self.assertRaises(ValueError, self.signal2.time_slice, t_start_good, t_stop_bad) self.assertRaises(ValueError, self.signal2.time_slice, t_start_bad, t_stop_good) self.assertRaises(ValueError, self.signal2.time_slice, t_start_bad, t_stop_bad) def test__time_equal(self): t_start = 0 * pq.s t_stop = 6 * pq.s 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) self.assertEqual(result.t_stop, t_stop) self.assertEqual(result.t_start, t_start) assert_array_equal(result, self.signal2) assert_same_sub_schema(result, self.signal2) def test__time_slice__offset(self): self.signal2.t_start = 10.0 * pq.s assert_neo_object_is_compliant(self.signal2) t_start = 12 * pq.s t_stop = 14 * pq.s 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 = AnalogSignal(np.array([[2., 3.], [2., 3.]]).T, t_start=12.0 * 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) self.assertEqual(self.signal2.t_start, 10.0 * pq.s) self.assertEqual(result.t_stop, t_stop) self.assertEqual(result.t_start, t_start) self.assertEqual(result.sampling_rate, targ.sampling_rate) assert_arrays_equal(result, targ) assert_same_sub_schema(result, targ) def test__time_slice__different_units(self): self.signal2.t_start = 10.0 * pq.ms assert_neo_object_is_compliant(self.signal2) t_start = 2 * pq.s + 10.0 * pq.ms t_stop = 4 * pq.s + 10.0 * pq.ms 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 = AnalogSignal(np.array([[2., 3.], [2., 3.]]).T, t_start=t_start.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, delta=1e-12 * pq.ms) self.assertAlmostEqual(result.t_start, t_start, 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_arrays_equal(result, targ) assert_same_sub_schema(result, targ) 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)
class TestAnalogSignalArrayCombination(unittest.TestCase): def setUp(self): self.data1 = np.arange(55.0).reshape((11, 5)) self.data1quant = self.data1 * pq.mV self.arr_ann1 = {'anno1': np.arange(5), 'anno2': ['a', 'b', 'c', 'd', 'e']} self.signal1 = AnalogSignal(self.data1quant, sampling_rate=1 * pq.kHz, name='spam', description='eggs', file_origin='testfile.txt', array_annotations=self.arr_ann1, arg1='test') self.data2 = np.arange(100.0, 155.0).reshape((11, 5)) self.data2quant = self.data2 * pq.mV self.arr_ann2 = {'anno1': np.arange(10, 15), 'anno2': ['k', 'l', 'm', 'n', 'o']} self.signal2 = AnalogSignal(self.data2quant, sampling_rate=1 * pq.kHz, name='spam', description='eggs', file_origin='testfile.txt', array_annotations=self.arr_ann2, arg1='test') def test__compliant(self): assert_neo_object_is_compliant(self.signal1) self.assertEqual(self.signal1.name, 'spam') self.assertEqual(self.signal1.description, 'eggs') self.assertEqual(self.signal1.file_origin, 'testfile.txt') self.assertEqual(self.signal1.annotations, {'arg1': 'test'}) assert_arrays_equal(self.signal1.array_annotations['anno1'], np.arange(5)) assert_arrays_equal(self.signal1.array_annotations['anno2'], np.array(['a', 'b', 'c', 'd', 'e'])) self.assertIsInstance(self.signal1.array_annotations, ArrayDict) assert_neo_object_is_compliant(self.signal2) self.assertEqual(self.signal2.name, 'spam') self.assertEqual(self.signal2.description, 'eggs') self.assertEqual(self.signal2.file_origin, 'testfile.txt') self.assertEqual(self.signal2.annotations, {'arg1': 'test'}) assert_arrays_equal(self.signal2.array_annotations['anno1'], np.arange(10, 15)) assert_arrays_equal(self.signal2.array_annotations['anno2'], np.array(['k', 'l', 'm', 'n', 'o'])) self.assertIsInstance(self.signal2.array_annotations, ArrayDict) def test__add_const_quantity_should_preserve_data_complement(self): result = self.signal1 + 0.065 * pq.V 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.arange(5)) assert_arrays_equal(result.array_annotations['anno2'], np.array(['a', 'b', 'c', 'd', 'e'])) self.assertIsInstance(result.array_annotations, ArrayDict) # time zero, signal index 4 assert_arrays_equal(result, self.data1 + 65) self.assertEqual(self.signal1[0, 4], 4 * pq.mV) self.assertEqual(result[0, 4], 69000 * pq.uV) self.assertEqual(self.signal1.t_start, result.t_start) self.assertEqual(self.signal1.sampling_rate, result.sampling_rate) def test__add_two_consistent_signals_should_preserve_data_complement(self): result = self.signal1 + self.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'}) assert_arrays_equal(result.array_annotations['anno1'], np.arange(5)) assert_arrays_equal(result.array_annotations['anno2'], np.array(['a', 'b', 'c', 'd', 'e'])) self.assertIsInstance(result.array_annotations, ArrayDict) targdata = np.arange(100.0, 210.0, 2.0).reshape((11, 5)) targ = AnalogSignal(targdata, units="mV", sampling_rate=1 * pq.kHz, name='spam', description='eggs', file_origin='testfile.txt', arg1='test') assert_neo_object_is_compliant(targ) assert_arrays_equal(result, targdata) assert_same_sub_schema(result, targ) def test__add_signals_with_inconsistent_data_complement_ValueError(self): self.signal2.sampling_rate = 0.5 * pq.kHz assert_neo_object_is_compliant(self.signal2) self.assertRaises(ValueError, self.signal1.__add__, self.signal2) def test__subtract_const_should_preserve_data_complement(self): result = self.signal1 - 65 * pq.mV 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.arange(5)) assert_arrays_equal(result.array_annotations['anno2'], np.array(['a', 'b', 'c', 'd', 'e'])) self.assertIsInstance(result.array_annotations, ArrayDict) self.assertEqual(np.array(self.signal1[1, 4]), 9) self.assertEqual(np.array(result[1, 4]), -56) assert_arrays_equal(result, self.data1 - 65) self.assertEqual(self.signal1.sampling_rate, result.sampling_rate) def test__subtract_from_const_should_return_signal(self): result = 10 * pq.mV - self.signal1 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.arange(5)) assert_arrays_equal(result.array_annotations['anno2'], np.array(['a', 'b', 'c', 'd', 'e'])) self.assertIsInstance(result.array_annotations, ArrayDict) self.assertEqual(np.array(self.signal1[1, 4]), 9) self.assertEqual(np.array(result[1, 4]), 1) assert_arrays_equal(result, 10 - self.data1) self.assertEqual(self.signal1.sampling_rate, result.sampling_rate) def test__mult_by_const_float_should_preserve_data_complement(self): result = self.signal1 * 2 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.arange(5)) assert_arrays_equal(result.array_annotations['anno2'], np.array(['a', 'b', 'c', 'd', 'e'])) self.assertIsInstance(result.array_annotations, ArrayDict) self.assertEqual(np.array(self.signal1[1, 4]), 9) self.assertEqual(np.array(result[1, 4]), 18) assert_arrays_equal(result, self.data1 * 2) self.assertEqual(self.signal1.sampling_rate, result.sampling_rate) def test__divide_by_const_should_preserve_data_complement(self): result = self.signal1 / 0.5 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.arange(5)) assert_arrays_equal(result.array_annotations['anno2'], np.array(['a', 'b', 'c', 'd', 'e'])) self.assertIsInstance(result.array_annotations, ArrayDict) self.assertEqual(np.array(self.signal1[1, 4]), 9) self.assertEqual(np.array(result[1, 4]), 18) assert_arrays_equal(result, self.data1 / 0.5) self.assertEqual(self.signal1.sampling_rate, result.sampling_rate) def test__merge(self): self.signal1.description = None self.signal1.file_origin = None assert_neo_object_is_compliant(self.signal1) data3 = np.arange(1000.0, 1066.0).reshape((11, 6)) * pq.uV data3scale = data3.rescale(self.data1quant.units) arr_ann3 = {'anno1': np.arange(5, 11), 'anno3': ['h', 'i', 'j', 'k', 'l', 'm']} arr_ann4 = {'anno1': np.arange(100, 106), 'anno3': ['o', 'p', 'q', 'r', 's', 't']} signal2 = AnalogSignal(self.data1quant, sampling_rate=1 * pq.kHz, name='signal2', description='test signal', file_origin='testfile.txt', array_annotations=self.arr_ann1) signal3 = AnalogSignal(data3, units="uV", sampling_rate=1 * pq.kHz, name='signal3', description='test signal', file_origin='testfile.txt', array_annotations=arr_ann3) signal4 = AnalogSignal(data3, units="uV", sampling_rate=1 * pq.kHz, name='signal4', description='test signal', file_origin='testfile.txt', array_annotations=arr_ann4) with warnings.catch_warnings(record=True) as w: warnings.filterwarnings('always') merged13 = self.signal1.merge(signal3) merged23 = signal2.merge(signal3) merged24 = signal2.merge(signal4) self.assertTrue(len(w) == 3) self.assertEqual(w[-1].category, UserWarning) self.assertSequenceEqual(str(w[2].message), str(w[0].message)) self.assertSequenceEqual(str(w[2].message), str(w[1].message)) self.assertSequenceEqual(str(w[2].message), "The following array annotations were " "omitted, because they were only present" " in one of the merged objects: " "['anno2'] from the one that was merged " "into and ['anno3'] from the one that " "was merged into the other") mergeddata13 = np.array(merged13) mergeddata23 = np.array(merged23) mergeddata24 = np.array(merged24) targdata13 = np.hstack([self.data1quant, data3scale]) targdata23 = np.hstack([self.data1quant, data3scale]) targdata24 = np.hstack([self.data1quant, data3scale]) assert_neo_object_is_compliant(signal2) assert_neo_object_is_compliant(signal3) assert_neo_object_is_compliant(merged13) assert_neo_object_is_compliant(merged23) assert_neo_object_is_compliant(merged24) self.assertEqual(merged13[0, 4], 4 * pq.mV) self.assertEqual(merged23[0, 4], 4 * pq.mV) self.assertEqual(merged13[0, 5], 1 * pq.mV) self.assertEqual(merged23[0, 5], 1 * pq.mV) self.assertEqual(merged13[10, 10], 1.065 * pq.mV) self.assertEqual(merged23[10, 10], 1.065 * pq.mV) self.assertEqual(merged13.t_stop, self.signal1.t_stop) self.assertEqual(merged23.t_stop, self.signal1.t_stop) self.assertEqual(merged13.name, 'merge(spam, signal3)') self.assertEqual(merged23.name, 'merge(signal2, signal3)') self.assertEqual(merged13.description, 'merge(None, test signal)') self.assertEqual(merged23.description, 'test signal') self.assertEqual(merged13.file_origin, 'merge(None, testfile.txt)') self.assertEqual(merged23.file_origin, 'testfile.txt') assert_arrays_equal(merged13.array_annotations['anno1'], np.arange(11)) self.assertIsInstance(merged13.array_annotations, ArrayDict) self.assertNotIn('anno2', merged13.array_annotations) self.assertNotIn('anno3', merged13.array_annotations) assert_arrays_equal(merged23.array_annotations['anno1'], np.arange(11)) self.assertIsInstance(merged23.array_annotations, ArrayDict) self.assertNotIn('anno2', merged23.array_annotations) self.assertNotIn('anno3', merged23.array_annotations) assert_arrays_equal(merged24.array_annotations['anno1'], np.array([0, 1, 2, 3, 4, 100, 101, 102, 103, 104, 105])) self.assertIsInstance(merged24.array_annotations, ArrayDict) self.assertNotIn('anno2', merged24.array_annotations) self.assertNotIn('anno3', merged24.array_annotations) assert_arrays_equal(mergeddata13, targdata13) assert_arrays_equal(mergeddata23, targdata23) assert_arrays_equal(mergeddata24, targdata24)
def test__merge(self): self.signal1.description = None self.signal1.file_origin = None assert_neo_object_is_compliant(self.signal1) data3 = np.arange(1000.0, 1066.0).reshape((11, 6)) * pq.uV data3scale = data3.rescale(self.data1quant.units) arr_ann3 = {'anno1': np.arange(5, 11), 'anno3': ['h', 'i', 'j', 'k', 'l', 'm']} arr_ann4 = {'anno1': np.arange(100, 106), 'anno3': ['o', 'p', 'q', 'r', 's', 't']} signal2 = AnalogSignal(self.data1quant, sampling_rate=1 * pq.kHz, name='signal2', description='test signal', file_origin='testfile.txt', array_annotations=self.arr_ann1) signal3 = AnalogSignal(data3, units="uV", sampling_rate=1 * pq.kHz, name='signal3', description='test signal', file_origin='testfile.txt', array_annotations=arr_ann3) signal4 = AnalogSignal(data3, units="uV", sampling_rate=1 * pq.kHz, name='signal4', description='test signal', file_origin='testfile.txt', array_annotations=arr_ann4) with warnings.catch_warnings(record=True) as w: warnings.filterwarnings('always') merged13 = self.signal1.merge(signal3) merged23 = signal2.merge(signal3) merged24 = signal2.merge(signal4) self.assertTrue(len(w) == 3) self.assertEqual(w[-1].category, UserWarning) self.assertSequenceEqual(str(w[2].message), str(w[0].message)) self.assertSequenceEqual(str(w[2].message), str(w[1].message)) self.assertSequenceEqual(str(w[2].message), "The following array annotations were " "omitted, because they were only present" " in one of the merged objects: " "['anno2'] from the one that was merged " "into and ['anno3'] from the one that " "was merged into the other") mergeddata13 = np.array(merged13) mergeddata23 = np.array(merged23) mergeddata24 = np.array(merged24) targdata13 = np.hstack([self.data1quant, data3scale]) targdata23 = np.hstack([self.data1quant, data3scale]) targdata24 = np.hstack([self.data1quant, data3scale]) assert_neo_object_is_compliant(signal2) assert_neo_object_is_compliant(signal3) assert_neo_object_is_compliant(merged13) assert_neo_object_is_compliant(merged23) assert_neo_object_is_compliant(merged24) self.assertEqual(merged13[0, 4], 4 * pq.mV) self.assertEqual(merged23[0, 4], 4 * pq.mV) self.assertEqual(merged13[0, 5], 1 * pq.mV) self.assertEqual(merged23[0, 5], 1 * pq.mV) self.assertEqual(merged13[10, 10], 1.065 * pq.mV) self.assertEqual(merged23[10, 10], 1.065 * pq.mV) self.assertEqual(merged13.t_stop, self.signal1.t_stop) self.assertEqual(merged23.t_stop, self.signal1.t_stop) self.assertEqual(merged13.name, 'merge(spam, signal3)') self.assertEqual(merged23.name, 'merge(signal2, signal3)') self.assertEqual(merged13.description, 'merge(None, test signal)') self.assertEqual(merged23.description, 'test signal') self.assertEqual(merged13.file_origin, 'merge(None, testfile.txt)') self.assertEqual(merged23.file_origin, 'testfile.txt') assert_arrays_equal(merged13.array_annotations['anno1'], np.arange(11)) self.assertIsInstance(merged13.array_annotations, ArrayDict) self.assertNotIn('anno2', merged13.array_annotations) self.assertNotIn('anno3', merged13.array_annotations) assert_arrays_equal(merged23.array_annotations['anno1'], np.arange(11)) self.assertIsInstance(merged23.array_annotations, ArrayDict) self.assertNotIn('anno2', merged23.array_annotations) self.assertNotIn('anno3', merged23.array_annotations) assert_arrays_equal(merged24.array_annotations['anno1'], np.array([0, 1, 2, 3, 4, 100, 101, 102, 103, 104, 105])) self.assertIsInstance(merged24.array_annotations, ArrayDict) self.assertNotIn('anno2', merged24.array_annotations) self.assertNotIn('anno3', merged24.array_annotations) assert_arrays_equal(mergeddata13, targdata13) assert_arrays_equal(mergeddata23, targdata23) assert_arrays_equal(mergeddata24, targdata24)