test_spike_train_correlation.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. # -*- coding: utf-8 -*-
  2. """
  3. Unit tests for the spike_train_correlation module.
  4. :copyright: Copyright 2015-2016 by the Elephant team, see AUTHORS.txt.
  5. :license: Modified BSD, see LICENSE.txt for details.
  6. """
  7. import unittest
  8. import numpy as np
  9. from numpy.testing.utils import assert_array_equal, assert_array_almost_equal
  10. import quantities as pq
  11. import neo
  12. import elephant.conversion as conv
  13. import elephant.spike_train_correlation as sc
  14. class covariance_TestCase(unittest.TestCase):
  15. def setUp(self):
  16. # These two arrays must be such that they do not have coincidences
  17. # spanning across two neighbor bins assuming ms bins [0,1),[1,2),...
  18. self.test_array_1d_0 = [
  19. 1.3, 7.56, 15.87, 28.23, 30.9, 34.2, 38.2, 43.2]
  20. self.test_array_1d_1 = [
  21. 1.02, 2.71, 18.82, 28.46, 28.79, 43.6]
  22. # Build spike trains
  23. self.st_0 = neo.SpikeTrain(
  24. self.test_array_1d_0, units='ms', t_stop=50.)
  25. self.st_1 = neo.SpikeTrain(
  26. self.test_array_1d_1, units='ms', t_stop=50.)
  27. # And binned counterparts
  28. self.binned_st = conv.BinnedSpikeTrain(
  29. [self.st_0, self.st_1], t_start=0 * pq.ms, t_stop=50. * pq.ms,
  30. binsize=1 * pq.ms)
  31. def test_covariance_binned(self):
  32. '''
  33. Test covariance between two binned spike trains.
  34. '''
  35. # Calculate clipped and unclipped
  36. res_clipped = sc.covariance(
  37. self.binned_st, binary=True)
  38. res_unclipped = sc.covariance(
  39. self.binned_st, binary=False)
  40. # Check dimensions
  41. self.assertEqual(len(res_clipped), 2)
  42. self.assertEqual(len(res_unclipped), 2)
  43. # Check result unclipped against result calculated from scratch for
  44. # the off-diagonal element
  45. mat = self.binned_st.to_array()
  46. mean_0 = np.mean(mat[0])
  47. mean_1 = np.mean(mat[1])
  48. target_from_scratch = \
  49. np.dot(mat[0] - mean_0, mat[1] - mean_1) / (len(mat[0]) - 1)
  50. # Check result unclipped against result calculated by numpy.corrcoef
  51. target_numpy = np.cov(mat)
  52. self.assertAlmostEqual(target_from_scratch, target_numpy[0][1])
  53. self.assertAlmostEqual(res_unclipped[0][1], target_from_scratch)
  54. self.assertAlmostEqual(res_unclipped[1][0], target_from_scratch)
  55. # Check result clipped against result calculated from scratch for
  56. # the off-diagonal elemant
  57. mat = self.binned_st.to_bool_array()
  58. mean_0 = np.mean(mat[0])
  59. mean_1 = np.mean(mat[1])
  60. target_from_scratch = \
  61. np.dot(mat[0] - mean_0, mat[1] - mean_1) / (len(mat[0]) - 1)
  62. # Check result unclipped against result calculated by numpy.corrcoef
  63. target_numpy = np.cov(mat)
  64. self.assertAlmostEqual(target_from_scratch, target_numpy[0][1])
  65. self.assertAlmostEqual(res_clipped[0][1], target_from_scratch)
  66. self.assertAlmostEqual(res_clipped[1][0], target_from_scratch)
  67. def test_covariance_binned_same_spiketrains(self):
  68. '''
  69. Test if the covariation between two identical binned spike
  70. trains evaluates to the expected 2x2 matrix.
  71. '''
  72. # Calculate correlation
  73. binned_st = conv.BinnedSpikeTrain(
  74. [self.st_0, self.st_0], t_start=0 * pq.ms, t_stop=50. * pq.ms,
  75. binsize=1 * pq.ms)
  76. target = sc.covariance(binned_st)
  77. # Check dimensions
  78. self.assertEqual(len(target), 2)
  79. # Check result
  80. assert_array_equal(target[0][0], target[1][1])
  81. def test_covariance_binned_short_input(self):
  82. '''
  83. Test if input list of only one binned spike train yields correct result
  84. that matches numpy.cov (covariance with itself)
  85. '''
  86. # Calculate correlation
  87. binned_st = conv.BinnedSpikeTrain(
  88. self.st_0, t_start=0 * pq.ms, t_stop=50. * pq.ms,
  89. binsize=1 * pq.ms)
  90. target = sc.covariance(binned_st)
  91. # Check result unclipped against result calculated by numpy.corrcoef
  92. mat = binned_st.to_bool_array()
  93. target_numpy = np.cov(mat)
  94. # Check result and dimensionality of result
  95. self.assertEqual(target.ndim, target_numpy.ndim)
  96. self.assertAlmostEqual(target, target_numpy)
  97. class corrcoeff_TestCase(unittest.TestCase):
  98. def setUp(self):
  99. # These two arrays must be such that they do not have coincidences
  100. # spanning across two neighbor bins assuming ms bins [0,1),[1,2),...
  101. self.test_array_1d_0 = [
  102. 1.3, 7.56, 15.87, 28.23, 30.9, 34.2, 38.2, 43.2]
  103. self.test_array_1d_1 = [
  104. 1.02, 2.71, 18.82, 28.46, 28.79, 43.6]
  105. # Build spike trains
  106. self.st_0 = neo.SpikeTrain(
  107. self.test_array_1d_0, units='ms', t_stop=50.)
  108. self.st_1 = neo.SpikeTrain(
  109. self.test_array_1d_1, units='ms', t_stop=50.)
  110. # And binned counterparts
  111. self.binned_st = conv.BinnedSpikeTrain(
  112. [self.st_0, self.st_1], t_start=0 * pq.ms, t_stop=50. * pq.ms,
  113. binsize=1 * pq.ms)
  114. def test_corrcoef_binned(self):
  115. '''
  116. Test the correlation coefficient between two binned spike trains.
  117. '''
  118. # Calculate clipped and unclipped
  119. res_clipped = sc.corrcoef(
  120. self.binned_st, binary=True)
  121. res_unclipped = sc.corrcoef(
  122. self.binned_st, binary=False)
  123. # Check dimensions
  124. self.assertEqual(len(res_clipped), 2)
  125. self.assertEqual(len(res_unclipped), 2)
  126. # Check result unclipped against result calculated from scratch for
  127. # the off-diagonal element
  128. mat = self.binned_st.to_array()
  129. mean_0 = np.mean(mat[0])
  130. mean_1 = np.mean(mat[1])
  131. target_from_scratch = \
  132. np.dot(mat[0] - mean_0, mat[1] - mean_1) / \
  133. np.sqrt(
  134. np.dot(mat[0] - mean_0, mat[0] - mean_0) *
  135. np.dot(mat[1] - mean_1, mat[1] - mean_1))
  136. # Check result unclipped against result calculated by numpy.corrcoef
  137. target_numpy = np.corrcoef(mat)
  138. self.assertAlmostEqual(target_from_scratch, target_numpy[0][1])
  139. self.assertAlmostEqual(res_unclipped[0][1], target_from_scratch)
  140. self.assertAlmostEqual(res_unclipped[1][0], target_from_scratch)
  141. # Check result clipped against result calculated from scratch for
  142. # the off-diagonal elemant
  143. mat = self.binned_st.to_bool_array()
  144. mean_0 = np.mean(mat[0])
  145. mean_1 = np.mean(mat[1])
  146. target_from_scratch = \
  147. np.dot(mat[0] - mean_0, mat[1] - mean_1) / \
  148. np.sqrt(
  149. np.dot(mat[0] - mean_0, mat[0] - mean_0) *
  150. np.dot(mat[1] - mean_1, mat[1] - mean_1))
  151. # Check result unclipped against result calculated by numpy.corrcoef
  152. target_numpy = np.corrcoef(mat)
  153. self.assertAlmostEqual(target_from_scratch, target_numpy[0][1])
  154. self.assertAlmostEqual(res_clipped[0][1], target_from_scratch)
  155. self.assertAlmostEqual(res_clipped[1][0], target_from_scratch)
  156. def test_corrcoef_binned_same_spiketrains(self):
  157. '''
  158. Test if the correlation coefficient between two identical binned spike
  159. trains evaluates to a 2x2 matrix of ones.
  160. '''
  161. # Calculate correlation
  162. binned_st = conv.BinnedSpikeTrain(
  163. [self.st_0, self.st_0], t_start=0 * pq.ms, t_stop=50. * pq.ms,
  164. binsize=1 * pq.ms)
  165. target = sc.corrcoef(binned_st)
  166. # Check dimensions
  167. self.assertEqual(len(target), 2)
  168. # Check result
  169. assert_array_equal(target, 1.)
  170. def test_corrcoef_binned_short_input(self):
  171. '''
  172. Test if input list of one binned spike train yields 1.0.
  173. '''
  174. # Calculate correlation
  175. binned_st = conv.BinnedSpikeTrain(
  176. self.st_0, t_start=0 * pq.ms, t_stop=50. * pq.ms,
  177. binsize=1 * pq.ms)
  178. target = sc.corrcoef(binned_st)
  179. # Check result and dimensionality of result
  180. self.assertEqual(target.ndim, 0)
  181. self.assertEqual(target, 1.)
  182. class cross_correlation_histogram_TestCase(unittest.TestCase):
  183. def setUp(self):
  184. # These two arrays must be such that they do not have coincidences
  185. # spanning across two neighbor bins assuming ms bins [0,1),[1,2),...
  186. self.test_array_1d_1 = [
  187. 1.3, 7.56, 15.87, 28.23, 30.9, 34.2, 38.2, 43.2]
  188. self.test_array_1d_2 = [
  189. 1.02, 2.71, 18.82, 28.46, 28.79, 43.6]
  190. # Build spike trains
  191. self.st_1 = neo.SpikeTrain(
  192. self.test_array_1d_1, units='ms', t_stop=50.)
  193. self.st_2 = neo.SpikeTrain(
  194. self.test_array_1d_2, units='ms', t_stop=50.)
  195. # And binned counterparts
  196. self.binned_st1 = conv.BinnedSpikeTrain(
  197. [self.st_1], t_start=0 * pq.ms, t_stop=50. * pq.ms,
  198. binsize=1 * pq.ms)
  199. self.binned_st2 = conv.BinnedSpikeTrain(
  200. [self.st_2], t_start=0 * pq.ms, t_stop=50. * pq.ms,
  201. binsize=1 * pq.ms)
  202. self.binned_sts = conv.BinnedSpikeTrain(
  203. [self.st_1, self.st_2], t_start=0 * pq.ms, t_stop=50. * pq.ms,
  204. binsize=1 * pq.ms)
  205. # Binned sts to check errors raising
  206. self.st_check_binsize = conv.BinnedSpikeTrain(
  207. [self.st_1], t_start=0 * pq.ms, t_stop=50. * pq.ms,
  208. binsize=5 * pq.ms)
  209. self.st_check_t_start = conv.BinnedSpikeTrain(
  210. [self.st_1], t_start=1 * pq.ms, t_stop=50. * pq.ms,
  211. binsize=1 * pq.ms)
  212. self.st_check_t_stop = conv.BinnedSpikeTrain(
  213. [self.st_1], t_start=0 * pq.ms, t_stop=40. * pq.ms,
  214. binsize=1 * pq.ms)
  215. self.st_check_dimension = conv.BinnedSpikeTrain(
  216. [self.st_1, self.st_2], t_start=0 * pq.ms, t_stop=50. * pq.ms,
  217. binsize=1 * pq.ms)
  218. def test_cross_correlation_histogram(self):
  219. '''
  220. Test generic result of a cross-correlation histogram between two binned
  221. spike trains.
  222. '''
  223. # Calculate CCH using Elephant (normal and binary version) with
  224. # mode equal to 'full' (whole spike trains are correlated)
  225. cch_clipped, bin_ids_clipped = sc.cross_correlation_histogram(
  226. self.binned_st1, self.binned_st2, window='full',
  227. binary=True)
  228. cch_unclipped, bin_ids_unclipped = sc.cross_correlation_histogram(
  229. self.binned_st1, self.binned_st2, window='full', binary=False)
  230. cch_clipped_mem, bin_ids_clipped_mem = sc.cross_correlation_histogram(
  231. self.binned_st1, self.binned_st2, window='full',
  232. binary=True, method='memory')
  233. cch_unclipped_mem, bin_ids_unclipped_mem = \
  234. sc.cross_correlation_histogram(
  235. self.binned_st1, self.binned_st2, window='full',
  236. binary=False, method='memory')
  237. # Check consistency two methods
  238. assert_array_equal(
  239. np.squeeze(cch_clipped.magnitude), np.squeeze(
  240. cch_clipped_mem.magnitude))
  241. assert_array_equal(
  242. np.squeeze(cch_clipped.times), np.squeeze(
  243. cch_clipped_mem.times))
  244. assert_array_equal(
  245. np.squeeze(cch_unclipped.magnitude), np.squeeze(
  246. cch_unclipped_mem.magnitude))
  247. assert_array_equal(
  248. np.squeeze(cch_unclipped.times), np.squeeze(
  249. cch_unclipped_mem.times))
  250. assert_array_almost_equal(bin_ids_clipped, bin_ids_clipped_mem)
  251. assert_array_almost_equal(bin_ids_unclipped, bin_ids_unclipped_mem)
  252. # Check normal correlation Note: Use numpy correlate to verify result.
  253. # Note: numpy conventions for input array 1 and input array 2 are
  254. # swapped compared to Elephant!
  255. mat1 = self.binned_st1.to_array()[0]
  256. mat2 = self.binned_st2.to_array()[0]
  257. target_numpy = np.correlate(mat2, mat1, mode='full')
  258. assert_array_equal(
  259. target_numpy, np.squeeze(cch_unclipped.magnitude))
  260. # Check cross correlation function for several displacements tau
  261. # Note: Use Elephant corrcoeff to verify result
  262. tau = [-25.0, 0.0, 13.0] # in ms
  263. for t in tau:
  264. # adjust t_start, t_stop to shift by tau
  265. t0 = np.min([self.st_1.t_start + t * pq.ms, self.st_2.t_start])
  266. t1 = np.max([self.st_1.t_stop + t * pq.ms, self.st_2.t_stop])
  267. st1 = neo.SpikeTrain(self.st_1.magnitude + t, units='ms',
  268. t_start=t0 * pq.ms, t_stop=t1 * pq.ms)
  269. st2 = neo.SpikeTrain(self.st_2.magnitude, units='ms',
  270. t_start=t0 * pq.ms, t_stop=t1 * pq.ms)
  271. binned_sts = conv.BinnedSpikeTrain([st1, st2],
  272. binsize=1 * pq.ms,
  273. t_start=t0 * pq.ms,
  274. t_stop=t1 * pq.ms)
  275. # caluclate corrcoef
  276. corrcoef = sc.corrcoef(binned_sts)[1, 0]
  277. # expand t_stop to have two spike trains with same length as st1,
  278. # st2
  279. st1 = neo.SpikeTrain(self.st_1.magnitude, units='ms',
  280. t_start=self.st_1.t_start,
  281. t_stop=self.st_1.t_stop + np.abs(t) * pq.ms)
  282. st2 = neo.SpikeTrain(self.st_2.magnitude, units='ms',
  283. t_start=self.st_2.t_start,
  284. t_stop=self.st_2.t_stop + np.abs(t) * pq.ms)
  285. binned_st1 = conv.BinnedSpikeTrain(
  286. st1, t_start=0 * pq.ms, t_stop=(50 + np.abs(t)) * pq.ms,
  287. binsize=1 * pq.ms)
  288. binned_st2 = conv.BinnedSpikeTrain(
  289. st2, t_start=0 * pq.ms, t_stop=(50 + np.abs(t)) * pq.ms,
  290. binsize=1 * pq.ms)
  291. # calculate CCHcoef and take value at t=tau
  292. CCHcoef, _ = sc.cch(binned_st1, binned_st2,
  293. cross_corr_coef=True)
  294. left_edge = - binned_st1.num_bins + 1
  295. tau_bin = int(t / float(binned_st1.binsize.magnitude))
  296. assert_array_equal(
  297. corrcoef, CCHcoef[tau_bin - left_edge].magnitude)
  298. # Check correlation using binary spike trains
  299. mat1 = np.array(self.binned_st1.to_bool_array()[0], dtype=int)
  300. mat2 = np.array(self.binned_st2.to_bool_array()[0], dtype=int)
  301. target_numpy = np.correlate(mat2, mat1, mode='full')
  302. assert_array_equal(
  303. target_numpy, np.squeeze(cch_clipped.magnitude))
  304. # Check the time axis and bin IDs of the resulting AnalogSignal
  305. assert_array_almost_equal(
  306. (bin_ids_clipped - 0.5) * self.binned_st1.binsize,
  307. cch_unclipped.times)
  308. assert_array_almost_equal(
  309. (bin_ids_clipped - 0.5) * self.binned_st1.binsize,
  310. cch_clipped.times)
  311. # Calculate CCH using Elephant (normal and binary version) with
  312. # mode equal to 'valid' (only completely overlapping intervals of the
  313. # spike trains are correlated)
  314. cch_clipped, bin_ids_clipped = sc.cross_correlation_histogram(
  315. self.binned_st1, self.binned_st2, window='valid',
  316. binary=True)
  317. cch_unclipped, bin_ids_unclipped = sc.cross_correlation_histogram(
  318. self.binned_st1, self.binned_st2, window='valid',
  319. binary=False)
  320. cch_clipped_mem, bin_ids_clipped_mem = sc.cross_correlation_histogram(
  321. self.binned_st1, self.binned_st2, window='valid',
  322. binary=True, method='memory')
  323. cch_unclipped_mem, bin_ids_unclipped_mem = \
  324. sc.cross_correlation_histogram(
  325. self.binned_st1, self.binned_st2, window='valid',
  326. binary=False, method='memory')
  327. # Check consistency two methods
  328. assert_array_equal(
  329. np.squeeze(cch_clipped.magnitude), np.squeeze(
  330. cch_clipped_mem.magnitude))
  331. assert_array_equal(
  332. np.squeeze(cch_clipped.times), np.squeeze(
  333. cch_clipped_mem.times))
  334. assert_array_equal(
  335. np.squeeze(cch_unclipped.magnitude), np.squeeze(
  336. cch_unclipped_mem.magnitude))
  337. assert_array_equal(
  338. np.squeeze(cch_unclipped.times), np.squeeze(
  339. cch_unclipped_mem.times))
  340. assert_array_equal(bin_ids_clipped, bin_ids_clipped_mem)
  341. assert_array_equal(bin_ids_unclipped, bin_ids_unclipped_mem)
  342. # Check normal correlation Note: Use numpy correlate to verify result.
  343. # Note: numpy conventions for input array 1 and input array 2 are
  344. # swapped compared to Elephant!
  345. mat1 = self.binned_st1.to_array()[0]
  346. mat2 = self.binned_st2.to_array()[0]
  347. target_numpy = np.correlate(mat2, mat1, mode='valid')
  348. assert_array_equal(
  349. target_numpy, np.squeeze(cch_unclipped.magnitude))
  350. # Check correlation using binary spike trains
  351. mat1 = np.array(self.binned_st1.to_bool_array()[0], dtype=int)
  352. mat2 = np.array(self.binned_st2.to_bool_array()[0], dtype=int)
  353. target_numpy = np.correlate(mat2, mat1, mode='valid')
  354. assert_array_equal(
  355. target_numpy, np.squeeze(cch_clipped.magnitude))
  356. # Check the time axis and bin IDs of the resulting AnalogSignal
  357. assert_array_equal(
  358. (bin_ids_clipped - 0.5) * self.binned_st1.binsize,
  359. cch_unclipped.times)
  360. assert_array_equal(
  361. (bin_ids_clipped - 0.5) * self.binned_st1.binsize,
  362. cch_clipped.times)
  363. # Check for wrong window parameter setting
  364. self.assertRaises(
  365. KeyError, sc.cross_correlation_histogram, self.binned_st1,
  366. self.binned_st2, window='dsaij')
  367. self.assertRaises(
  368. KeyError, sc.cross_correlation_histogram, self.binned_st1,
  369. self.binned_st2, window='dsaij', method='memory')
  370. def test_raising_error_wrong_inputs(self):
  371. '''Check that an exception is thrown if the two spike trains are not
  372. fullfilling the requirement of the function'''
  373. # Check the binsizes are the same
  374. self.assertRaises(
  375. AssertionError,
  376. sc.cross_correlation_histogram, self.binned_st1,
  377. self.st_check_binsize)
  378. # Check different t_start and t_stop
  379. self.assertRaises(
  380. AssertionError, sc.cross_correlation_histogram,
  381. self.st_check_t_start, self.binned_st2)
  382. self.assertRaises(
  383. AssertionError, sc.cross_correlation_histogram,
  384. self.st_check_t_stop, self.binned_st2)
  385. # Check input are one dimensional
  386. self.assertRaises(
  387. AssertionError, sc.cross_correlation_histogram,
  388. self.st_check_dimension, self.binned_st2)
  389. self.assertRaises(
  390. AssertionError, sc.cross_correlation_histogram,
  391. self.binned_st2, self.st_check_dimension)
  392. def test_window(self):
  393. '''Test if the window parameter is correctly interpreted.'''
  394. cch_win, bin_ids = sc.cch(
  395. self.binned_st1, self.binned_st2, window=[-30, 30])
  396. cch_win_mem, bin_ids_mem = sc.cch(
  397. self.binned_st1, self.binned_st2, window=[-30, 30])
  398. assert_array_equal(bin_ids, np.arange(-30, 31, 1))
  399. assert_array_equal(
  400. (bin_ids - 0.5) * self.binned_st1.binsize, cch_win.times)
  401. assert_array_equal(bin_ids_mem, np.arange(-30, 31, 1))
  402. assert_array_equal(
  403. (bin_ids_mem - 0.5) * self.binned_st1.binsize, cch_win.times)
  404. assert_array_equal(cch_win, cch_win_mem)
  405. cch_unclipped, _ = sc.cross_correlation_histogram(
  406. self.binned_st1, self.binned_st2, window='full', binary=False)
  407. assert_array_equal(cch_win, cch_unclipped[19:80])
  408. _, bin_ids = sc.cch(
  409. self.binned_st1, self.binned_st2, window=[20, 30])
  410. _, bin_ids_mem = sc.cch(
  411. self.binned_st1, self.binned_st2, window=[20, 30], method='memory')
  412. assert_array_equal(bin_ids, np.arange(20, 31, 1))
  413. assert_array_equal(bin_ids_mem, np.arange(20, 31, 1))
  414. _, bin_ids = sc.cch(
  415. self.binned_st1, self.binned_st2, window=[-30, -20])
  416. _, bin_ids_mem = sc.cch(
  417. self.binned_st1, self.binned_st2, window=[-30, -20],
  418. method='memory')
  419. assert_array_equal(bin_ids, np.arange(-30, -19, 1))
  420. assert_array_equal(bin_ids_mem, np.arange(-30, -19, 1))
  421. # Check for wrong assignments to the window parameter
  422. # Test for window longer than the total length of the spike trains
  423. self.assertRaises(
  424. ValueError, sc.cross_correlation_histogram, self.binned_st1,
  425. self.binned_st2, window=[-60, 50])
  426. self.assertRaises(
  427. ValueError, sc.cross_correlation_histogram, self.binned_st1,
  428. self.binned_st2, window=[-50, 60])
  429. # Test for no integer or wrong string in input
  430. self.assertRaises(
  431. KeyError, sc.cross_correlation_histogram, self.binned_st1,
  432. self.binned_st2, window=[-25.5, 25.5])
  433. self.assertRaises(
  434. KeyError, sc.cross_correlation_histogram, self.binned_st1,
  435. self.binned_st2, window='test')
  436. def test_border_correction(self):
  437. '''Test if the border correction for bins at the edges is correctly
  438. performed'''
  439. cch_corrected, _ = sc.cross_correlation_histogram(
  440. self.binned_st1, self.binned_st2, window='full',
  441. border_correction=True, binary=False, kernel=None)
  442. cch_corrected_mem, _ = sc.cross_correlation_histogram(
  443. self.binned_st1, self.binned_st2, window='full',
  444. border_correction=True, binary=False, kernel=None, method='memory')
  445. cch, _ = sc.cross_correlation_histogram(
  446. self.binned_st1, self.binned_st2, window='full',
  447. border_correction=False, binary=False, kernel=None)
  448. cch_mem, _ = sc.cross_correlation_histogram(
  449. self.binned_st1, self.binned_st2, window='full',
  450. border_correction=False, binary=False, kernel=None,
  451. method='memory')
  452. self.assertNotEqual(cch.all(), cch_corrected.all())
  453. self.assertNotEqual(cch_mem.all(), cch_corrected_mem.all())
  454. def test_kernel(self):
  455. '''Test if the smoothing kernel is correctly defined, and wheter it is
  456. applied properly.'''
  457. smoothed_cch, _ = sc.cross_correlation_histogram(
  458. self.binned_st1, self.binned_st2, kernel=np.ones(3))
  459. smoothed_cch_mem, _ = sc.cross_correlation_histogram(
  460. self.binned_st1, self.binned_st2, kernel=np.ones(3),
  461. method='memory')
  462. cch, _ = sc.cross_correlation_histogram(
  463. self.binned_st1, self.binned_st2, kernel=None)
  464. cch_mem, _ = sc.cross_correlation_histogram(
  465. self.binned_st1, self.binned_st2, kernel=None, method='memory')
  466. self.assertNotEqual(smoothed_cch.all, cch.all)
  467. self.assertNotEqual(smoothed_cch_mem.all, cch_mem.all)
  468. self.assertRaises(
  469. ValueError, sc.cch, self.binned_st1, self.binned_st2,
  470. kernel=np.ones(100))
  471. self.assertRaises(
  472. ValueError, sc.cch, self.binned_st1, self.binned_st2,
  473. kernel=np.ones(100), method='memory')
  474. self.assertRaises(
  475. ValueError, sc.cch, self.binned_st1, self.binned_st2, kernel='BOX')
  476. self.assertRaises(
  477. ValueError, sc.cch, self.binned_st1, self.binned_st2, kernel='BOX',
  478. method='memory')
  479. def test_exist_alias(self):
  480. '''
  481. Test if alias cch still exists.
  482. '''
  483. self.assertEqual(sc.cross_correlation_histogram, sc.cch)
  484. class SpikeTimeTilingCoefficientTestCase(unittest.TestCase):
  485. def setUp(self):
  486. # These two arrays must be such that they do not have coincidences
  487. # spanning across two neighbor bins assuming ms bins [0,1),[1,2),...
  488. self.test_array_1d_1 = [
  489. 1.3, 7.56, 15.87, 28.23, 30.9, 34.2, 38.2, 43.2]
  490. self.test_array_1d_2 = [
  491. 1.02, 2.71, 18.82, 28.46, 28.79, 43.6]
  492. # Build spike trains
  493. self.st_1 = neo.SpikeTrain(
  494. self.test_array_1d_1, units='ms', t_stop=50.)
  495. self.st_2 = neo.SpikeTrain(
  496. self.test_array_1d_2, units='ms', t_stop=50.)
  497. def test_sttc(self):
  498. # test for result
  499. target = 0.8748350567
  500. self.assertAlmostEqual(target, sc.sttc(self.st_1, self.st_2,
  501. 0.005 * pq.s))
  502. # test no spiketrains
  503. self.assertTrue(np.isnan(sc.sttc([], [])))
  504. # test one spiketrain
  505. self.assertTrue(np.isnan(sc.sttc(self.st_1, [])))
  506. # test for one spike in a spiketrain
  507. st1 = neo.SpikeTrain([1], units='ms', t_stop=1.)
  508. st2 = neo.SpikeTrain([5], units='ms', t_stop=10.)
  509. self.assertEqual(sc.sttc(st1, st2), 1.0)
  510. self.assertTrue(bool(sc.sttc(st1, st2, 0.1 * pq.ms) < 0))
  511. # test for high value of dt
  512. self.assertEqual(sc.sttc(self.st_1, self.st_2, dt=5 * pq.s), 1.0)
  513. def test_exist_alias(self):
  514. # Test if alias cch still exists.
  515. self.assertEqual(sc.spike_time_tiling_coefficient, sc.sttc)
  516. if __name__ == '__main__':
  517. unittest.main()