def generate_correlated_spike_trains(corr_coef, fr, tmax, n_cells=10, gamma_a=2.): mother_spike_train = homogeneous_gamma_process(gamma_a, fr, 0*ms, tmax) spiketrains = [homogeneous_gamma_process(gamma_a, fr, 0*ms, tmax) for i in range(n_cells)] for st in spiketrains: n = min(len(mother_spike_train), len(st)) exchange = np.random.rand(n) < corr_coef st[:n][exchange] = mother_spike_train[:n][exchange] st.sort() return spiketrains
def test_compare_with_as_array(self): a = 3. b = 10 * pq.Hz np.random.seed(27) spiketrain = stgen.homogeneous_gamma_process(a=a, b=b) self.assertIsInstance(spiketrain, neo.SpikeTrain) np.random.seed(27) spiketrain_array = stgen.homogeneous_gamma_process(a=a, b=b, as_array=True) # don't check with isinstance: pq.Quantity is a subclass of np.ndarray self.assertTrue(isinstance(spiketrain_array, np.ndarray)) assert_array_almost_equal(spiketrain.times.magnitude, spiketrain_array)
def test_statistics(self): # There is a statistical test and has a non-zero chance of failure during normal operation. # Re-run the test to see if the error persists. a = 3.0 for b in (67.0*Hz, 0.067*kHz): for t_stop in (2345*ms, 2.345*second): spiketrain = stgen.homogeneous_gamma_process(a, b, t_stop=t_stop) intervals = isi(spiketrain) expected_spike_count = int((b/a * t_stop).simplified) self.assertLess(pdiff(expected_spike_count, spiketrain.size), 0.25) # should fail about 1 time in 1000 expected_mean_isi = (a/b).rescale(ms) self.assertLess(pdiff(expected_mean_isi, intervals.mean()), 0.3) expected_first_spike = 0*ms self.assertLess(spiketrain[0] - expected_first_spike, 4*expected_mean_isi) expected_last_spike = t_stop self.assertLess(expected_last_spike - spiketrain[-1], 4*expected_mean_isi) # Kolmogorov-Smirnov test D, p = kstest(intervals.rescale(t_stop.units), "gamma", args=(a, 0, (1/b).rescale(t_stop.units)), # args are (a, loc, scale) alternative='two-sided') self.assertGreater(p, 0.001) self.assertLess(D, 0.25)
def test_timescale_calculation(self): ''' Test the timescale generation using an alpha-shaped ISI distribution, see [1, eq. 1.68]. This is equivalent to a homogeneous gamma process with alpha=2 and beta=2*nu where nu is the rate. For this process, the autocorrelation function is given by a sum of a delta peak and a (negative) exponential, see [1, eq. 1.69]. The exponential decays with \tau_corr = 1 / (4*nu), thus this fixes timescale. [1] Lindner, B. (2009). A brief introduction to some simple stochastic processes. Stochastic Methods in Neuroscience, 1. ''' nu = 25 / pq.s T = 15 * pq.min binsize = 1 * pq.ms timescale = 1 / (4 * nu) timescale_num = [] for _ in range(10): spikes = homogeneous_gamma_process(2, 2 * nu, 0 * pq.ms, T) spikes_bin = conv.BinnedSpikeTrain(spikes, binsize) timescale_i = sc.spike_train_timescale(spikes_bin, 10 * timescale) timescale_i.units = timescale.units timescale_num.append(timescale_i.magnitude) target = np.allclose(timescale.magnitude, timescale_num, rtol=2e-1) self.assertTrue(target)
def test_timescale_calculation(self): """ Test the timescale generation using an alpha-shaped ISI distribution, see [1, eq. 1.68]. This is equivalent to a homogeneous gamma process with alpha=2 and beta=2*nu where nu is the rate. For this process, the autocorrelation function is given by a sum of a delta peak and a (negative) exponential, see [1, eq. 1.69]. The exponential decays with \tau_corr = 1 / (4*nu), thus this fixes timescale. [1] Lindner, B. (2009). A brief introduction to some simple stochastic processes. Stochastic Methods in Neuroscience, 1. """ nu = 25 / pq.s T = 15 * pq.min bin_size = 1 * pq.ms timescale = 1 / (4 * nu) np.random.seed(35) for _ in range(10): spikes = homogeneous_gamma_process(2, 2 * nu, 0 * pq.ms, T) spikes_bin = conv.BinnedSpikeTrain(spikes, bin_size) timescale_i = sc.spike_train_timescale(spikes_bin, 10 * timescale) assert_array_almost_equal(timescale, timescale_i, decimal=3)
def test_statistics(self): # This is a statistical test that has a non-zero chance of failure # during normal operation. Thus, we set the random seed to a value that # creates a realization passing the test. np.random.seed(seed=12345) a = 3.0 for b in (67.0*Hz, 0.067*kHz): for t_stop in (2345*ms, 2.345*second): spiketrain = stgen.homogeneous_gamma_process(a, b, t_stop=t_stop) intervals = isi(spiketrain) expected_spike_count = int((b/a * t_stop).simplified) self.assertLess(pdiff(expected_spike_count, spiketrain.size), 0.25) # should fail about 1 time in 1000 expected_mean_isi = (a/b).rescale(ms) self.assertLess(pdiff(expected_mean_isi, intervals.mean()), 0.3) expected_first_spike = 0*ms self.assertLess(spiketrain[0] - expected_first_spike, 4*expected_mean_isi) expected_last_spike = t_stop self.assertLess(expected_last_spike - spiketrain[-1], 4*expected_mean_isi) # Kolmogorov-Smirnov test D, p = kstest(intervals.rescale(t_stop.units), "gamma", args=(a, 0, (1/b).rescale(t_stop.units)), # args are (a, loc, scale) alternative='two-sided') self.assertGreater(p, 0.001) self.assertLess(D, 0.25)
def generate_spikes(self): """ Generate spike trains based on default_params of the SpikeTrainGenerator class. self.spiketrains contains the newly generated spike trains """ if not self._has_spiketrains: self.spiketrains = [] idx = 0 for n in np.arange(self.n_neurons): if not self.changing and not self.intermittent: rate = self.params['rates'][n] if self.params['process'] == 'poisson': st = stg.homogeneous_poisson_process( rate, self.params['t_start'], self.params['t_stop']) elif self.params['process'] == 'gamma': st = stg.homogeneous_gamma_process( self.params['gamma_shape'], rate, self.params['t_start'], self.params['t_stop']) else: raise NotImplementedError( 'Changing and intermittent spiketrains are not impleented yet' ) self.spiketrains.append(st) self.spiketrains[-1].annotate(fr=rate) if 'n_exc' in self.params.keys( ) and 'n_inh' in self.params.keys(): if idx < self.params['n_exc']: self.spiketrains[-1].annotate(type='E') else: self.spiketrains[-1].annotate(type='I') idx += 1 # check consistency and remove spikes below refractory period for idx, st in enumerate(self.spiketrains): isi = stat.isi(st) idx_remove = np.where(isi < self.params['ref_per'])[0] spikes_to_remove = len(idx_remove) unit = st.times.units while spikes_to_remove > 0: new_times = np.delete(st.times, idx_remove[0]) * unit st = neo.SpikeTrain(new_times, t_start=self.params['t_start'], t_stop=self.params['t_stop']) isi = stat.isi(st) idx_remove = np.where(isi < self.params['ref_per'])[0] spikes_to_remove = len(idx_remove) st.annotations = self.spiketrains[idx].annotations self.set_spiketrain(idx, st) else: print( "SpikeTrainGenerator initialized with existing spike trains!")