def test_dither_spikes_with_refractory_period_output_format(self): spiketrain = neo.SpikeTrain([90, 93, 97, 100, 105, 150, 180, 350] * pq.ms, t_stop=.5 * pq.s) n_surrogates = 2 dither = 10 * pq.ms surrogate_trains = surr.dither_spikes(spiketrain, dither=dither, n_surrogates=n_surrogates, refractory_period=4 * pq.ms) self.assertIsInstance(surrogate_trains, list) self.assertEqual(len(surrogate_trains), n_surrogates) self.assertIsInstance(surrogate_trains[0], neo.SpikeTrain) for surrogate_train in surrogate_trains: self.assertEqual(surrogate_train.units, spiketrain.units) self.assertEqual(surrogate_train.t_start, spiketrain.t_start) self.assertEqual(surrogate_train.t_stop, spiketrain.t_stop) self.assertEqual(len(surrogate_train), len(spiketrain)) # Check that refractory period is conserved self.assertLessEqual(np.min(np.diff(spiketrain)), np.min(np.diff(surrogate_train))) sigma_displacement = np.std(surrogate_train - spiketrain) # Check that spikes are moved self.assertLessEqual(dither / 10, sigma_displacement) # Spikes are not moved more than dither self.assertLessEqual(sigma_displacement, dither) self.assertRaises(ValueError, surr.dither_spikes, spiketrain, dither=dither, refractory_period=3)
def test_dither_spikes_empty_train(self): st = neo.SpikeTrain([] * pq.ms, t_stop=500 * pq.ms) dither = 10 * pq.ms surrog = surr.dither_spikes(st, dither=dither, n=1)[0] self.assertEqual(len(surrog), 0)
def test_dither_spikes_with_refractory_period_empty_train(self): spiketrain = neo.SpikeTrain([] * pq.ms, t_stop=500 * pq.ms) dither = 10 * pq.ms surrogate_train = surr.dither_spikes( spiketrain, dither=dither, n_surrogates=1, refractory_period=4 * pq.ms)[0] self.assertEqual(len(surrogate_train), 0)
def test_dither_spikes_false_edges(self): st = neo.SpikeTrain([90, 150, 180, 350] * pq.ms, t_stop=500 * pq.ms) nr_surr = 2 dither = 10 * pq.ms surrs = surr.dither_spikes(st, dither=dither, n=nr_surr, edges=False) for surrog in surrs: for i in range(len(surrog)): self.assertLessEqual(surrog[i], st.t_stop)
def test_dither_spikes_output_decimals(self): st = neo.SpikeTrain([90, 150, 180, 350] * pq.ms, t_stop=500 * pq.ms) nr_surr = 2 dither = 10 * pq.ms surrs = surr.dither_spikes(st, dither=dither, decimals=3, n=nr_surr) for surrog in surrs: for i in range(len(surrog)): self.assertNotEqual(surrog[i] - int(surrog[i]) * pq.ms, surrog[i] - surrog[i])
def test_dither_spikes_output_format(self): st = neo.SpikeTrain([90, 150, 180, 350] * pq.ms, t_stop=500 * pq.ms) nr_surr = 2 dither = 10 * pq.ms surrs = surr.dither_spikes(st, dither=dither, n=nr_surr) self.assertIsInstance(surrs, list) self.assertEqual(len(surrs), nr_surr) for surrog in surrs: self.assertIsInstance(surrs[0], neo.SpikeTrain) self.assertEqual(surrog.units, st.units) self.assertEqual(surrog.t_start, st.t_start) self.assertEqual(surrog.t_stop, st.t_stop) self.assertEqual(len(surrog), len(st))
def test_dither_spikes_output_decimals(self): st = neo.SpikeTrain([90, 150, 180, 350] * pq.ms, t_stop=500 * pq.ms) nr_surr = 2 dither = 10 * pq.ms np.random.seed(42) surrs = surr.dither_spikes(st, dither=dither, decimals=3, n=nr_surr) np.random.seed(42) dither_values = np.random.random_sample((nr_surr, len(st))) expected_non_dithered = np.sum(dither_values==0) observed_non_dithered = 0 for surrog in surrs: for i in range(len(surrog)): if surrog[i] - int(surrog[i]) * pq.ms == surrog[i] - surrog[i]: observed_non_dithered += 1 self.assertEqual(observed_non_dithered, expected_non_dithered)
def test_dither_spikes_output_format(self): spiketrain = neo.SpikeTrain([90, 93, 97, 100, 105, 150, 180, 350] * pq.ms, t_stop=.5 * pq.s) spiketrain.t_stop = .5 * pq.s n_surrogates = 2 dither = 10 * pq.ms surrogate_trains = surr.dither_spikes( spiketrain, dither=dither, n_surrogates=n_surrogates) self.assertIsInstance(surrogate_trains, list) self.assertEqual(len(surrogate_trains), n_surrogates) self.assertIsInstance(surrogate_trains[0], neo.SpikeTrain) for surrogate_train in surrogate_trains: self.assertEqual(surrogate_train.units, spiketrain.units) self.assertEqual(surrogate_train.t_start, spiketrain.t_start) self.assertEqual(surrogate_train.t_stop, spiketrain.t_stop) self.assertEqual(len(surrogate_train), len(spiketrain)) assert_array_less(0., np.diff(surrogate_train)) # check ordering
def pvspec(sts, wndlen, width, dither, n, min_z=2, min_c=2, verbose=False): ''' compute the p-value spectrum of pattern signatures extracted from surrogates of parallel spike trains *sts*, under the null hypothesis of spiking independence. * *n* surrogates are obtained from each spike train by spike dithering (--> elephant.core.surrogates.gensurr_dither()) * closed frequent itemsets (CFISs) are collected from each surrogate data (--> fpgrowth()) * the signatures (size, support) of all CFISs are computed, and their occurrence probability estimated by their occurrence frequency * CFISs in *sts* whose signatures are significant are returned Parameters ---------- sts [list] list of neo.core.SpikeTrain objects, interpreted as parallel spike trains, or list of (ID, train) pairs. The IDs must be hashable. If not specified, they are set to integers 0,1,2,... width [quantity.Quantity] time span for evaluating spike synchrony. * if *method* == 'd', this is the width of the time bins used by fpgrowth() routine * if *method* == 'c', this is the width of the sliding window used by the coconad() routine dither [quantity.Quantity] spike dithering amplitude. Surrogates are generated by randomly dithering each spike around its original position by +/- *dither* n [int] amount of surrogates to generate to compute the p-value spectrum. Should be large (n>=1000 recommended for 100 spike trains in *sts*) min_z [int] minimum size for a set of synchronous spikes to be considered a pattern min_c [int] minimum support for patterns to be considered frequent method [str. Default: 'd'] which frequent itemset mining method to use to determine patterns of synchronous spikes: * 'd'|'discrete' : use fpgrowth() (time discretization into bins) * 'c'|'continuous': use coconad() (sliding window) 'c' captures imprecise coincidences much better, but is slower. Output ------ a list of triplets (z,c,p), where (z,c) is a pattern signature and p is the corresponding p-value (fraction of surrogates containing signatures (z*,c*)>=(z,c)). Signatures whose empirical p-value is 0 are not listed. ''' MultiTimer("pvspec start") comm = MPI.COMM_WORLD # create MPI communicator rank = comm.Get_rank() # get rank of current MPI task size = comm.Get_size() # get tot number of MPI tasks len_partition = n // size # length of each MPI task len_remainder = n if len_partition == 0 else n % len_partition # If *sts* is a list of SpikeTrains if not all([type(elem) == neo.core.SpikeTrain for elem in sts]): raise TypeError('*sts* must be either a list of SpikeTrains or a' + 'list of (id, train) pairs') # For each surrogate collect the signatures (z,c) such that (z*,c*)>=(z,c) # exists in that surrogate. Group such signatures (with repetition) # list of all signatures found in surrogates, initialized to [] SurrSgnts = [] if rank == 0: for i in xrange(len_partition + len_remainder): #Surrs = [surr.dither_spikes( # xx, dither=dither, n=1)[0] for xx in sts] Surrs = [] for xx in sts: Surrs.append(surr.dither_spikes(xx, dither=dither, n=1)[0]) MultiTimer(" pvspec list step surrs step") MultiTimer("pvspec list step surrs") # Find all pattern signatures in the current surrogate data set SurrTrans = st2trans(Surrs, wndlen, width=width) MultiTimer("pvspec list step st2trans") SurrSgnt = [(a, b) for (a, b, c) in fpgrowth( SurrTrans, target='c', min_z=min_z, min_c=min_c, report='#')] MultiTimer("pvspec list step fpgrowth") # List all signatures (z,c) <= (z*, c*), for each (z*,c*) in the # current surrogate, and add it to the list of all signatures FilledSgnt = [] for (z, c) in SurrSgnt: for j in xrange(min_z, z + 1): for k in xrange(min_c, c + 1): FilledSgnt.append((j, k)) MultiTimer("pvspec list step list") SurrSgnts.extend(list(set(FilledSgnt))) MultiTimer("pvspec list step end") else: for i in xrange(len_partition): Surrs = [ surr.dither_spikes(xx, dither=dither, n=1)[0] for xx in sts ] # Find all pattern signatures in the current surrogate data set SurrTrans = st2trans(Surrs, wndlen, width=width) SurrSgnt = [(a, b) for (a, b, c) in fpgrowth( SurrTrans, target='c', min_z=min_z, min_c=min_c, report='#')] # List all signatures (z,c) <= (z*, c*), for each (z*,c*) in the # current surrogate, and add it to the list of all signatures FilledSgnt = [] for (z, c) in SurrSgnt: for j in xrange(min_z, z + 1): for k in xrange(min_c, c + 1): FilledSgnt.append((j, k)) SurrSgnts.extend(list(set(FilledSgnt))) MultiTimer("pvspec middle") if rank != 0: comm.send(SurrSgnts, dest=0) if rank == 0: for i in xrange(1, size): recv_list = comm.recv(source=i) SurrSgnts.extend(recv_list) # Compute the p-value spectrum, and return it PvSpec = {} for (z, c) in SurrSgnts: PvSpec[(z, c)] = 0 for (z, c) in SurrSgnts: PvSpec[(z, c)] += 1 scale = 1. / n PvSpec = [(a, b, c * scale) for (a, b), c in PvSpec.items()] if verbose is True: print ' end of pvspec' MultiTimer("pvspec end") return PvSpec