test_irregularysampledsignal.py 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. # -*- coding: utf-8 -*-
  2. """
  3. Tests of the neo.core.irregularlysampledsignal.IrregularySampledSignal class
  4. """
  5. import unittest
  6. import os
  7. import pickle
  8. import numpy as np
  9. import quantities as pq
  10. from numpy.testing import assert_array_equal
  11. try:
  12. from IPython.lib.pretty import pretty
  13. except ImportError as err:
  14. HAVE_IPYTHON = False
  15. else:
  16. HAVE_IPYTHON = True
  17. from neo.core.irregularlysampledsignal import IrregularlySampledSignal
  18. from neo.core import Segment, ChannelIndex
  19. from neo.test.tools import (assert_arrays_almost_equal, assert_arrays_equal,
  20. assert_neo_object_is_compliant,
  21. assert_same_sub_schema)
  22. from neo.test.generate_datasets import (get_fake_value, get_fake_values,
  23. fake_neo, TEST_ANNOTATIONS)
  24. class Test__generate_datasets(unittest.TestCase):
  25. def setUp(self):
  26. np.random.seed(0)
  27. self.annotations = dict([(str(x), TEST_ANNOTATIONS[x]) for x in
  28. range(len(TEST_ANNOTATIONS))])
  29. def test__get_fake_values(self):
  30. self.annotations['seed'] = 0
  31. times = get_fake_value('times', pq.Quantity, seed=0, dim=1)
  32. signal = get_fake_value('signal', pq.Quantity, seed=1, dim=2)
  33. name = get_fake_value('name', str, seed=2,
  34. obj=IrregularlySampledSignal)
  35. description = get_fake_value('description', str, seed=3,
  36. obj='IrregularlySampledSignal')
  37. file_origin = get_fake_value('file_origin', str)
  38. attrs1 = {'name': name,
  39. 'description': description,
  40. 'file_origin': file_origin}
  41. attrs2 = attrs1.copy()
  42. attrs2.update(self.annotations)
  43. res11 = get_fake_values(IrregularlySampledSignal,
  44. annotate=False, seed=0)
  45. res12 = get_fake_values('IrregularlySampledSignal',
  46. annotate=False, seed=0)
  47. res21 = get_fake_values(IrregularlySampledSignal,
  48. annotate=True, seed=0)
  49. res22 = get_fake_values('IrregularlySampledSignal',
  50. annotate=True, seed=0)
  51. assert_array_equal(res11.pop('times'), times)
  52. assert_array_equal(res12.pop('times'), times)
  53. assert_array_equal(res21.pop('times'), times)
  54. assert_array_equal(res22.pop('times'), times)
  55. assert_array_equal(res11.pop('signal'), signal)
  56. assert_array_equal(res12.pop('signal'), signal)
  57. assert_array_equal(res21.pop('signal'), signal)
  58. assert_array_equal(res22.pop('signal'), signal)
  59. self.assertEqual(res11, attrs1)
  60. self.assertEqual(res12, attrs1)
  61. self.assertEqual(res21, attrs2)
  62. self.assertEqual(res22, attrs2)
  63. def test__fake_neo__cascade(self):
  64. self.annotations['seed'] = None
  65. obj_type = IrregularlySampledSignal
  66. cascade = True
  67. res = fake_neo(obj_type=obj_type, cascade=cascade)
  68. self.assertTrue(isinstance(res, IrregularlySampledSignal))
  69. assert_neo_object_is_compliant(res)
  70. self.assertEqual(res.annotations, self.annotations)
  71. def test__fake_neo__nocascade(self):
  72. self.annotations['seed'] = None
  73. obj_type = 'IrregularlySampledSignal'
  74. cascade = False
  75. res = fake_neo(obj_type=obj_type, cascade=cascade)
  76. self.assertTrue(isinstance(res, IrregularlySampledSignal))
  77. assert_neo_object_is_compliant(res)
  78. self.assertEqual(res.annotations, self.annotations)
  79. class TestIrregularlySampledSignalConstruction(unittest.TestCase):
  80. def test_IrregularlySampledSignal_creation_times_units_signal_units(self):
  81. params = {'test2': 'y1', 'test3': True}
  82. sig = IrregularlySampledSignal([1.1, 1.5, 1.7]*pq.ms,
  83. signal=[20., 40., 60.]*pq.mV,
  84. name='test', description='tester',
  85. file_origin='test.file',
  86. test1=1, **params)
  87. sig.annotate(test1=1.1, test0=[1, 2])
  88. assert_neo_object_is_compliant(sig)
  89. assert_array_equal(sig.times, [1.1, 1.5, 1.7]*pq.ms)
  90. assert_array_equal(np.asarray(sig).flatten(), np.array([20., 40., 60.]))
  91. self.assertEqual(sig.units, pq.mV)
  92. self.assertEqual(sig.name, 'test')
  93. self.assertEqual(sig.description, 'tester')
  94. self.assertEqual(sig.file_origin, 'test.file')
  95. self.assertEqual(sig.annotations['test0'], [1, 2])
  96. self.assertEqual(sig.annotations['test1'], 1.1)
  97. self.assertEqual(sig.annotations['test2'], 'y1')
  98. self.assertTrue(sig.annotations['test3'])
  99. def test_IrregularlySampledSignal_creation_units_arg(self):
  100. params = {'test2': 'y1', 'test3': True}
  101. sig = IrregularlySampledSignal([1.1, 1.5, 1.7],
  102. signal=[20., 40., 60.],
  103. units=pq.V, time_units=pq.s,
  104. name='test', description='tester',
  105. file_origin='test.file',
  106. test1=1, **params)
  107. sig.annotate(test1=1.1, test0=[1, 2])
  108. assert_neo_object_is_compliant(sig)
  109. assert_array_equal(sig.times, [1.1, 1.5, 1.7]*pq.s)
  110. assert_array_equal(np.asarray(sig).flatten(), np.array([20., 40., 60.]))
  111. self.assertEqual(sig.units, pq.V)
  112. self.assertEqual(sig.name, 'test')
  113. self.assertEqual(sig.description, 'tester')
  114. self.assertEqual(sig.file_origin, 'test.file')
  115. self.assertEqual(sig.annotations['test0'], [1, 2])
  116. self.assertEqual(sig.annotations['test1'], 1.1)
  117. self.assertEqual(sig.annotations['test2'], 'y1')
  118. self.assertTrue(sig.annotations['test3'])
  119. def test_IrregularlySampledSignal_creation_units_rescale(self):
  120. params = {'test2': 'y1', 'test3': True}
  121. sig = IrregularlySampledSignal([1.1, 1.5, 1.7]*pq.s,
  122. signal=[2., 4., 6.]*pq.V,
  123. units=pq.mV, time_units=pq.ms,
  124. name='test', description='tester',
  125. file_origin='test.file',
  126. test1=1, **params)
  127. sig.annotate(test1=1.1, test0=[1, 2])
  128. assert_neo_object_is_compliant(sig)
  129. assert_array_equal(sig.times, [1100, 1500, 1700]*pq.ms)
  130. assert_array_equal(np.asarray(sig).flatten(), np.array([2000., 4000., 6000.]))
  131. self.assertEqual(sig.units, pq.mV)
  132. self.assertEqual(sig.name, 'test')
  133. self.assertEqual(sig.description, 'tester')
  134. self.assertEqual(sig.file_origin, 'test.file')
  135. self.assertEqual(sig.annotations['test0'], [1, 2])
  136. self.assertEqual(sig.annotations['test1'], 1.1)
  137. self.assertEqual(sig.annotations['test2'], 'y1')
  138. self.assertTrue(sig.annotations['test3'])
  139. def test_IrregularlySampledSignal_different_lens_ValueError(self):
  140. times = [1.1, 1.5, 1.7]*pq.ms
  141. signal = [20., 40., 60., 70.]*pq.mV
  142. self.assertRaises(ValueError, IrregularlySampledSignal, times, signal)
  143. def test_IrregularlySampledSignal_no_signal_units_ValueError(self):
  144. times = [1.1, 1.5, 1.7]*pq.ms
  145. signal = [20., 40., 60.]
  146. self.assertRaises(ValueError, IrregularlySampledSignal, times, signal)
  147. def test_IrregularlySampledSignal_no_time_units_ValueError(self):
  148. times = [1.1, 1.5, 1.7]
  149. signal = [20., 40., 60.]*pq.mV
  150. self.assertRaises(ValueError, IrregularlySampledSignal, times, signal)
  151. class TestIrregularlySampledSignalProperties(unittest.TestCase):
  152. def setUp(self):
  153. self.times = [np.arange(10.0)*pq.s,
  154. np.arange(-100.0, 100.0, 10.0)*pq.ms,
  155. np.arange(100)*pq.ns]
  156. self.data = [np.arange(10.0)*pq.nA,
  157. np.arange(-100.0, 100.0, 10.0)*pq.mV,
  158. np.random.uniform(size=100)*pq.uV]
  159. self.signals = [IrregularlySampledSignal(t, signal=D,
  160. testattr='test')
  161. for D, t in zip(self.data, self.times)]
  162. def test__compliant(self):
  163. for signal in self.signals:
  164. assert_neo_object_is_compliant(signal)
  165. def test__t_start_getter(self):
  166. for signal, times in zip(self.signals, self.times):
  167. self.assertAlmostEqual(signal.t_start,
  168. times[0],
  169. delta=1e-15)
  170. def test__t_stop_getter(self):
  171. for signal, times in zip(self.signals, self.times):
  172. self.assertAlmostEqual(signal.t_stop,
  173. times[-1],
  174. delta=1e-15)
  175. def test__duration_getter(self):
  176. for signal, times in zip(self.signals, self.times):
  177. self.assertAlmostEqual(signal.duration,
  178. times[-1] - times[0],
  179. delta=1e-15)
  180. def test__sampling_intervals_getter(self):
  181. for signal, times in zip(self.signals, self.times):
  182. assert_arrays_almost_equal(signal.sampling_intervals,
  183. np.diff(times),
  184. threshold=1e-15)
  185. def test_IrregularlySampledSignal_repr(self):
  186. sig = IrregularlySampledSignal([1.1, 1.5, 1.7]*pq.s,
  187. signal=[2., 4., 6.]*pq.V,
  188. name='test', description='tester',
  189. file_origin='test.file',
  190. test1=1)
  191. assert_neo_object_is_compliant(sig)
  192. targ = ('<IrregularlySampledSignal(array([[ 2.],\n [ 4.],\n [ 6.]]) * V ' +
  193. 'at times [ 1.1 1.5 1.7] s)>')
  194. res = repr(sig)
  195. self.assertEqual(targ, res)
  196. # def test__children(self):
  197. # signal = self.signals[0]
  198. #
  199. # segment = Segment(name='seg1')
  200. # segment.analogsignals = [signal]
  201. # segment.create_many_to_one_relationship()
  202. #
  203. # rchan = RecordingChannel(name='rchan1')
  204. # rchan.analogsignals = [signal]
  205. # rchan.create_many_to_one_relationship()
  206. #
  207. # self.assertEqual(signal._single_parent_objects,
  208. # ('Segment', 'RecordingChannel'))
  209. # self.assertEqual(signal._multi_parent_objects, ())
  210. #
  211. # self.assertEqual(signal._single_parent_containers,
  212. # ('segment', 'recordingchannel'))
  213. # self.assertEqual(signal._multi_parent_containers, ())
  214. #
  215. # self.assertEqual(signal._parent_objects,
  216. # ('Segment', 'RecordingChannel'))
  217. # self.assertEqual(signal._parent_containers,
  218. # ('segment', 'recordingchannel'))
  219. #
  220. # self.assertEqual(len(signal.parents), 2)
  221. # self.assertEqual(signal.parents[0].name, 'seg1')
  222. # self.assertEqual(signal.parents[1].name, 'rchan1')
  223. #
  224. # assert_neo_object_is_compliant(signal)
  225. class TestIrregularlySampledSignalArrayMethods(unittest.TestCase):
  226. def setUp(self):
  227. self.data1 = np.arange(10.0)
  228. self.data1quant = self.data1 * pq.mV
  229. self.time1 = np.logspace(1, 5, 10)
  230. self.time1quant = self.time1*pq.ms
  231. self.signal1 = IrregularlySampledSignal(self.time1quant,
  232. signal=self.data1quant,
  233. name='spam',
  234. description='eggs',
  235. file_origin='testfile.txt',
  236. arg1='test')
  237. self.signal1.segment = Segment()
  238. self.signal1.channel_index = ChannelIndex([0])
  239. def test__compliant(self):
  240. assert_neo_object_is_compliant(self.signal1)
  241. self.assertEqual(self.signal1.name, 'spam')
  242. self.assertEqual(self.signal1.description, 'eggs')
  243. self.assertEqual(self.signal1.file_origin, 'testfile.txt')
  244. self.assertEqual(self.signal1.annotations, {'arg1': 'test'})
  245. def test__slice_should_return_IrregularlySampledSignal(self):
  246. result = self.signal1[3:8]
  247. self.assertIsInstance(result, IrregularlySampledSignal)
  248. assert_neo_object_is_compliant(result)
  249. self.assertEqual(result.name, 'spam')
  250. self.assertEqual(result.description, 'eggs')
  251. self.assertEqual(result.file_origin, 'testfile.txt')
  252. self.assertEqual(result.annotations, {'arg1': 'test'})
  253. self.assertEqual(result.size, 5)
  254. self.assertEqual(result.t_start, self.time1quant[3])
  255. self.assertEqual(result.t_stop, self.time1quant[7])
  256. assert_array_equal(self.time1quant[3:8], result.times)
  257. assert_array_equal(self.data1[3:8].reshape(-1, 1), result.magnitude)
  258. # Test other attributes were copied over (in this case, defaults)
  259. self.assertEqual(result.file_origin, self.signal1.file_origin)
  260. self.assertEqual(result.name, self.signal1.name)
  261. self.assertEqual(result.description, self.signal1.description)
  262. self.assertEqual(result.annotations, self.signal1.annotations)
  263. def test__getitem_should_return_single_quantity(self):
  264. self.assertEqual(self.signal1[0], 0*pq.mV)
  265. self.assertEqual(self.signal1[9], 9*pq.mV)
  266. self.assertRaises(IndexError, self.signal1.__getitem__, 10)
  267. def test__getitem_out_of_bounds_IndexError(self):
  268. self.assertRaises(IndexError, self.signal1.__getitem__, 10)
  269. def test_comparison_operators(self):
  270. assert_array_equal(self.signal1 >= 5*pq.mV,
  271. np.array([[False, False, False, False, False,
  272. True, True, True, True, True]]).T)
  273. def test__comparison_with_inconsistent_units_should_raise_Exception(self):
  274. self.assertRaises(ValueError, self.signal1.__gt__, 5*pq.nA)
  275. def test_simple_statistics(self):
  276. targmean = self.signal1[:-1]*np.diff(self.time1quant).reshape(-1, 1)
  277. targmean = targmean.sum()/(self.time1quant[-1] - self.time1quant[0])
  278. self.assertEqual(self.signal1.max(), 9*pq.mV)
  279. self.assertEqual(self.signal1.min(), 0*pq.mV)
  280. self.assertEqual(self.signal1.mean(), targmean)
  281. def test_mean_interpolation_NotImplementedError(self):
  282. self.assertRaises(NotImplementedError, self.signal1.mean, True)
  283. def test_resample_NotImplementedError(self):
  284. self.assertRaises(NotImplementedError, self.signal1.resample, True)
  285. def test__rescale_same(self):
  286. result = self.signal1.copy()
  287. result = result.rescale(pq.mV)
  288. self.assertIsInstance(result, IrregularlySampledSignal)
  289. assert_neo_object_is_compliant(result)
  290. self.assertEqual(result.name, 'spam')
  291. self.assertEqual(result.description, 'eggs')
  292. self.assertEqual(result.file_origin, 'testfile.txt')
  293. self.assertEqual(result.annotations, {'arg1': 'test'})
  294. self.assertEqual(result.units, 1*pq.mV)
  295. assert_array_equal(result.magnitude, self.data1.reshape(-1, 1))
  296. assert_array_equal(result.times, self.time1quant)
  297. assert_same_sub_schema(result, self.signal1)
  298. self.assertIsInstance(result.channel_index, ChannelIndex)
  299. self.assertIsInstance(result.segment, Segment)
  300. self.assertIs(result.channel_index, self.signal1.channel_index)
  301. self.assertIs(result.segment, self.signal1.segment)
  302. def test__rescale_new(self):
  303. result = self.signal1.copy()
  304. result = result.rescale(pq.uV)
  305. self.assertIsInstance(result, IrregularlySampledSignal)
  306. assert_neo_object_is_compliant(result)
  307. self.assertEqual(result.name, 'spam')
  308. self.assertEqual(result.description, 'eggs')
  309. self.assertEqual(result.file_origin, 'testfile.txt')
  310. self.assertEqual(result.annotations, {'arg1': 'test'})
  311. self.assertEqual(result.units, 1*pq.uV)
  312. assert_arrays_almost_equal(np.array(result), self.data1.reshape(-1, 1)*1000., 1e-10)
  313. assert_array_equal(result.times, self.time1quant)
  314. self.assertIsInstance(result.channel_index, ChannelIndex)
  315. self.assertIsInstance(result.segment, Segment)
  316. self.assertIs(result.channel_index, self.signal1.channel_index)
  317. self.assertIs(result.segment, self.signal1.segment)
  318. def test__rescale_new_incompatible_ValueError(self):
  319. self.assertRaises(ValueError, self.signal1.rescale, pq.nA)
  320. def test_time_slice(self):
  321. targdataquant = [[1.0], [2.0], [3.0]] * pq.mV
  322. targtime = np.logspace(1, 5, 10)
  323. targtimequant = targtime [1:4] *pq.ms
  324. targ_signal = IrregularlySampledSignal(targtimequant,
  325. signal=targdataquant,
  326. name='spam',
  327. description='eggs',
  328. file_origin='testfile.txt',
  329. arg1='test')
  330. t_start = 15
  331. t_stop = 250
  332. result = self.signal1.time_slice(t_start, t_stop)
  333. assert_array_equal(result, targ_signal)
  334. assert_array_equal(result.times, targtimequant)
  335. self.assertEqual(result.units, 1*pq.mV)
  336. self.assertIsInstance(result, IrregularlySampledSignal)
  337. assert_neo_object_is_compliant(result)
  338. self.assertEqual(result.name, 'spam')
  339. self.assertEqual(result.description, 'eggs')
  340. self.assertEqual(result.file_origin, 'testfile.txt')
  341. self.assertEqual(result.annotations, {'arg1': 'test'})
  342. def test_time_slice_out_of_boundries(self):
  343. targdataquant = self.data1quant
  344. targtimequant = self.time1quant
  345. targ_signal = IrregularlySampledSignal(targtimequant,
  346. signal=targdataquant,
  347. name='spam',
  348. description='eggs',
  349. file_origin='testfile.txt',
  350. arg1='test')
  351. t_start = 0
  352. t_stop = 2500000
  353. result = self.signal1.time_slice(t_start, t_stop)
  354. assert_array_equal(result, targ_signal)
  355. assert_array_equal(result.times, targtimequant)
  356. self.assertEqual(result.units, 1*pq.mV)
  357. self.assertIsInstance(result, IrregularlySampledSignal)
  358. assert_neo_object_is_compliant(result)
  359. self.assertEqual(result.name, 'spam')
  360. self.assertEqual(result.description, 'eggs')
  361. self.assertEqual(result.file_origin, 'testfile.txt')
  362. self.assertEqual(result.annotations, {'arg1': 'test'})
  363. def test_time_slice_empty(self):
  364. targdataquant = [] * pq.mV
  365. targtimequant = [] *pq.ms
  366. targ_signal = IrregularlySampledSignal(targtimequant,
  367. signal=targdataquant,
  368. name='spam',
  369. description='eggs',
  370. file_origin='testfile.txt',
  371. arg1='test')
  372. t_start = 15
  373. t_stop = 250
  374. result = targ_signal.time_slice(t_start, t_stop)
  375. assert_array_equal(result, targ_signal)
  376. assert_array_equal(result.times, targtimequant)
  377. self.assertEqual(result.units, 1*pq.mV)
  378. self.assertIsInstance(result, IrregularlySampledSignal)
  379. assert_neo_object_is_compliant(result)
  380. self.assertEqual(result.name, 'spam')
  381. self.assertEqual(result.description, 'eggs')
  382. self.assertEqual(result.file_origin, 'testfile.txt')
  383. self.assertEqual(result.annotations, {'arg1': 'test'})
  384. def test_time_slice_none_stop(self):
  385. targdataquant = [[1.0], [2.0], [3.0], [4.0], [5.0], [6.0], [7.0], [8.0], [9.0]] * pq.mV
  386. targtime = np.logspace(1, 5, 10)
  387. targtimequant = targtime [1:10] *pq.ms
  388. targ_signal = IrregularlySampledSignal(targtimequant,
  389. signal=targdataquant,
  390. name='spam',
  391. description='eggs',
  392. file_origin='testfile.txt',
  393. arg1='test')
  394. t_start = 15
  395. t_stop = None
  396. result = self.signal1.time_slice(t_start, t_stop)
  397. assert_array_equal(result, targ_signal)
  398. assert_array_equal(result.times, targtimequant)
  399. self.assertEqual(result.units, 1*pq.mV)
  400. self.assertIsInstance(result, IrregularlySampledSignal)
  401. assert_neo_object_is_compliant(result)
  402. self.assertEqual(result.name, 'spam')
  403. self.assertEqual(result.description, 'eggs')
  404. self.assertEqual(result.file_origin, 'testfile.txt')
  405. self.assertEqual(result.annotations, {'arg1': 'test'})
  406. def test_time_slice_none_start(self):
  407. targdataquant = [[0.0], [1.0], [2.0], [3.0]] * pq.mV
  408. targtime = np.logspace(1, 5, 10)
  409. targtimequant = targtime [0:4] *pq.ms
  410. targ_signal = IrregularlySampledSignal(targtimequant,
  411. signal=targdataquant,
  412. name='spam',
  413. description='eggs',
  414. file_origin='testfile.txt',
  415. arg1='test')
  416. t_start = None
  417. t_stop = 250
  418. result = self.signal1.time_slice(t_start, t_stop)
  419. assert_array_equal(result, targ_signal)
  420. assert_array_equal(result.times, targtimequant)
  421. self.assertEqual(result.units, 1*pq.mV)
  422. self.assertIsInstance(result, IrregularlySampledSignal)
  423. assert_neo_object_is_compliant(result)
  424. self.assertEqual(result.name, 'spam')
  425. self.assertEqual(result.description, 'eggs')
  426. self.assertEqual(result.file_origin, 'testfile.txt')
  427. self.assertEqual(result.annotations, {'arg1': 'test'})
  428. def test_time_slice_none_both(self):
  429. targdataquant = [[0.0], [1.0], [2.0], [3.0], [4.0], [5.0], [6.0], [7.0], [8.0], [9.0]] * pq.mV
  430. targtime = np.logspace(1, 5, 10)
  431. targtimequant = targtime [0:10] *pq.ms
  432. targ_signal = IrregularlySampledSignal(targtimequant,
  433. signal=targdataquant,
  434. name='spam',
  435. description='eggs',
  436. file_origin='testfile.txt',
  437. arg1='test')
  438. t_start = None
  439. t_stop = None
  440. result = self.signal1.time_slice(t_start, t_stop)
  441. assert_array_equal(result, targ_signal)
  442. assert_array_equal(result.times, targtimequant)
  443. self.assertEqual(result.units, 1*pq.mV)
  444. self.assertIsInstance(result, IrregularlySampledSignal)
  445. assert_neo_object_is_compliant(result)
  446. self.assertEqual(result.name, 'spam')
  447. self.assertEqual(result.description, 'eggs')
  448. self.assertEqual(result.file_origin, 'testfile.txt')
  449. self.assertEqual(result.annotations, {'arg1': 'test'})
  450. def test_time_slice_differnt_units(self):
  451. targdataquant = [[1.0], [2.0], [3.0]] * pq.mV
  452. targtime = np.logspace(1, 5, 10)
  453. targtimequant = targtime [1:4] *pq.ms
  454. targ_signal = IrregularlySampledSignal(targtimequant,
  455. signal=targdataquant,
  456. name='spam',
  457. description='eggs',
  458. file_origin='testfile.txt',
  459. arg1='test')
  460. t_start = 15
  461. t_stop = 250
  462. t_start = 0.015 * pq.s
  463. t_stop = .250 * pq.s
  464. result = self.signal1.time_slice(t_start, t_stop)
  465. assert_array_equal(result, targ_signal)
  466. assert_array_equal(result.times, targtimequant)
  467. self.assertEqual(result.units, 1*pq.mV)
  468. self.assertIsInstance(result, IrregularlySampledSignal)
  469. assert_neo_object_is_compliant(result)
  470. self.assertEqual(result.name, 'spam')
  471. self.assertEqual(result.description, 'eggs')
  472. self.assertEqual(result.file_origin, 'testfile.txt')
  473. self.assertEqual(result.annotations, {'arg1': 'test'})
  474. def test_as_array(self):
  475. sig_as_arr = self.signal1.as_array()
  476. self.assertIsInstance(sig_as_arr, np.ndarray)
  477. assert_array_equal(self.data1, sig_as_arr.flat)
  478. def test_as_quantity(self):
  479. sig_as_q = self.signal1.as_quantity()
  480. self.assertIsInstance(sig_as_q, pq.Quantity)
  481. assert_array_equal(self.data1, sig_as_q.magnitude.flat)
  482. def test__copy_should_preserve_parent_objects(self):
  483. result = self.signal1.copy()
  484. self.assertIs(result.segment, self.signal1.segment)
  485. self.assertIs(result.channel_index, self.signal1.channel_index)
  486. class TestIrregularlySampledSignalCombination(unittest.TestCase):
  487. def setUp(self):
  488. self.data1 = np.arange(10.0)
  489. self.data1quant = self.data1 * pq.mV
  490. self.time1 = np.logspace(1, 5, 10)
  491. self.time1quant = self.time1*pq.ms
  492. self.signal1 = IrregularlySampledSignal(self.time1quant,
  493. signal=self.data1quant,
  494. name='spam',
  495. description='eggs',
  496. file_origin='testfile.txt',
  497. arg1='test')
  498. def test__compliant(self):
  499. assert_neo_object_is_compliant(self.signal1)
  500. self.assertEqual(self.signal1.name, 'spam')
  501. self.assertEqual(self.signal1.description, 'eggs')
  502. self.assertEqual(self.signal1.file_origin, 'testfile.txt')
  503. self.assertEqual(self.signal1.annotations, {'arg1': 'test'})
  504. def test__add_const_quantity_should_preserve_data_complement(self):
  505. result = self.signal1 + 0.065*pq.V
  506. self.assertIsInstance(result, IrregularlySampledSignal)
  507. assert_neo_object_is_compliant(result)
  508. self.assertEqual(result.name, 'spam')
  509. self.assertEqual(result.description, 'eggs')
  510. self.assertEqual(result.file_origin, 'testfile.txt')
  511. self.assertEqual(result.annotations, {'arg1': 'test'})
  512. assert_array_equal(result.magnitude, self.data1.reshape(-1, 1) + 65)
  513. assert_array_equal(result.times, self.time1quant)
  514. self.assertEqual(self.signal1[9], 9*pq.mV)
  515. self.assertEqual(result[9], 74*pq.mV)
  516. def test__add_two_consistent_signals_should_preserve_data_complement(self):
  517. data2 = np.arange(10.0, 20.0)
  518. data2quant = data2*pq.mV
  519. signal2 = IrregularlySampledSignal(self.time1quant, signal=data2quant)
  520. assert_neo_object_is_compliant(signal2)
  521. result = self.signal1 + signal2
  522. self.assertIsInstance(result, IrregularlySampledSignal)
  523. assert_neo_object_is_compliant(result)
  524. self.assertEqual(result.name, 'spam')
  525. self.assertEqual(result.description, 'eggs')
  526. self.assertEqual(result.file_origin, 'testfile.txt')
  527. self.assertEqual(result.annotations, {'arg1': 'test'})
  528. targ = IrregularlySampledSignal(self.time1quant,
  529. signal=np.arange(10.0, 30.0, 2.0),
  530. units="mV",
  531. name='spam', description='eggs',
  532. file_origin='testfile.txt',
  533. arg1='test')
  534. assert_neo_object_is_compliant(targ)
  535. assert_array_equal(result, targ)
  536. assert_array_equal(self.time1quant, targ.times)
  537. assert_array_equal(result.times, targ.times)
  538. assert_same_sub_schema(result, targ)
  539. def test__add_signals_with_inconsistent_times_AssertionError(self):
  540. signal2 = IrregularlySampledSignal(self.time1quant*2.,
  541. signal=np.arange(10.0), units="mV")
  542. assert_neo_object_is_compliant(signal2)
  543. self.assertRaises(ValueError, self.signal1.__add__, signal2)
  544. def test__add_signals_with_inconsistent_dimension_ValueError(self):
  545. signal2 = np.arange(20).reshape(2, 10)
  546. self.assertRaises(ValueError, self.signal1.__add__, signal2)
  547. def test__subtract_const_should_preserve_data_complement(self):
  548. result = self.signal1 - 65*pq.mV
  549. self.assertIsInstance(result, IrregularlySampledSignal)
  550. assert_neo_object_is_compliant(result)
  551. self.assertEqual(result.name, 'spam')
  552. self.assertEqual(result.description, 'eggs')
  553. self.assertEqual(result.file_origin, 'testfile.txt')
  554. self.assertEqual(result.annotations, {'arg1': 'test'})
  555. self.assertEqual(self.signal1[9], 9*pq.mV)
  556. self.assertEqual(result[9], -56*pq.mV)
  557. assert_array_equal(result.magnitude, (self.data1 - 65).reshape(-1, 1))
  558. assert_array_equal(result.times, self.time1quant)
  559. def test__subtract_from_const_should_return_signal(self):
  560. result = 10*pq.mV - self.signal1
  561. self.assertIsInstance(result, IrregularlySampledSignal)
  562. assert_neo_object_is_compliant(result)
  563. self.assertEqual(result.name, 'spam')
  564. self.assertEqual(result.description, 'eggs')
  565. self.assertEqual(result.file_origin, 'testfile.txt')
  566. self.assertEqual(result.annotations, {'arg1': 'test'})
  567. self.assertEqual(self.signal1[9], 9*pq.mV)
  568. self.assertEqual(result[9], 1*pq.mV)
  569. assert_array_equal(result.magnitude, (10 - self.data1).reshape(-1, 1))
  570. assert_array_equal(result.times, self.time1quant)
  571. def test__mult_signal_by_const_float_should_preserve_data_complement(self):
  572. result = self.signal1*2.
  573. self.assertIsInstance(result, IrregularlySampledSignal)
  574. assert_neo_object_is_compliant(result)
  575. self.assertEqual(result.name, 'spam')
  576. self.assertEqual(result.description, 'eggs')
  577. self.assertEqual(result.file_origin, 'testfile.txt')
  578. self.assertEqual(result.annotations, {'arg1': 'test'})
  579. self.assertEqual(self.signal1[9], 9*pq.mV)
  580. self.assertEqual(result[9], 18*pq.mV)
  581. assert_array_equal(result.magnitude, self.data1.reshape(-1, 1)*2)
  582. assert_array_equal(result.times, self.time1quant)
  583. def test__mult_signal_by_const_array_should_preserve_data_complement(self):
  584. result = self.signal1*np.array(2.)
  585. self.assertIsInstance(result, IrregularlySampledSignal)
  586. assert_neo_object_is_compliant(result)
  587. self.assertEqual(result.name, 'spam')
  588. self.assertEqual(result.description, 'eggs')
  589. self.assertEqual(result.file_origin, 'testfile.txt')
  590. self.assertEqual(result.annotations, {'arg1': 'test'})
  591. self.assertEqual(self.signal1[9], 9*pq.mV)
  592. self.assertEqual(result[9], 18*pq.mV)
  593. assert_array_equal(result.magnitude, self.data1.reshape(-1, 1)*2)
  594. assert_array_equal(result.times, self.time1quant)
  595. def test__divide_signal_by_const_should_preserve_data_complement(self):
  596. result = self.signal1/0.5
  597. self.assertIsInstance(result, IrregularlySampledSignal)
  598. assert_neo_object_is_compliant(result)
  599. self.assertEqual(result.name, 'spam')
  600. self.assertEqual(result.description, 'eggs')
  601. self.assertEqual(result.file_origin, 'testfile.txt')
  602. self.assertEqual(result.annotations, {'arg1': 'test'})
  603. self.assertEqual(self.signal1[9], 9*pq.mV)
  604. self.assertEqual(result[9], 18*pq.mV)
  605. assert_array_equal(result.magnitude, self.data1.reshape(-1, 1)/0.5)
  606. assert_array_equal(result.times, self.time1quant)
  607. @unittest.skipUnless(HAVE_IPYTHON, "requires IPython")
  608. def test__pretty(self):
  609. res = pretty(self.signal1)
  610. signal = self.signal1
  611. targ = (("IrregularlySampledSignal with %d channels of length %d; units %s; datatype %s \n" % (signal.shape[1], signal.shape[0], signal.units.dimensionality.unicode, signal.dtype)) +
  612. ("name: '%s'\ndescription: '%s'\n" % (signal.name, signal.description)) +
  613. ("annotations: %s\n" % str(signal.annotations)) +
  614. ("sample times: %s" % (signal.times[:10],)))
  615. self.assertEqual(res, targ)
  616. class TestAnalogSignalFunctions(unittest.TestCase):
  617. def test__pickle(self):
  618. signal1 = IrregularlySampledSignal(np.arange(10.0)/100*pq.s,
  619. np.arange(10.0), units="mV")
  620. fobj = open('./pickle', 'wb')
  621. pickle.dump(signal1, fobj)
  622. fobj.close()
  623. fobj = open('./pickle', 'rb')
  624. try:
  625. signal2 = pickle.load(fobj)
  626. except ValueError:
  627. signal2 = None
  628. assert_array_equal(signal1, signal2)
  629. fobj.close()
  630. os.remove('./pickle')
  631. class TestIrregularlySampledSignalEquality(unittest.TestCase):
  632. def test__signals_with_different_times_should_be_not_equal(self):
  633. signal1 = IrregularlySampledSignal(np.arange(10.0)/100*pq.s,
  634. np.arange(10.0), units="mV")
  635. signal2 = IrregularlySampledSignal(np.arange(10.0)/100*pq.ms,
  636. np.arange(10.0), units="mV")
  637. self.assertNotEqual(signal1, signal2)
  638. if __name__ == "__main__":
  639. unittest.main()