def test_error_kernels(self): """ Test of various error cases in the kernels module. """ self.assertRaises( TypeError, kernels.RectangularKernel, sigma=2.0) self.assertRaises( ValueError, kernels.RectangularKernel, sigma=-0.03 * pq.s) self.assertRaises( ValueError, kernels.AlphaKernel, sigma=2.0 * pq.ms, invert=2) rec_kernel = kernels.RectangularKernel(sigma=0.3 * pq.ms) self.assertRaises( TypeError, rec_kernel, [1, 2, 3]) self.assertRaises( TypeError, rec_kernel, [1, 2, 3] * pq.V) kernel = kernels.Kernel(sigma=0.3 * pq.ms) self.assertRaises( NotImplementedError, kernel._evaluate, [1, 2, 3] * pq.V) self.assertRaises( NotImplementedError, kernel.boundary_enclosing_area_fraction, fraction=0.9) self.assertRaises(TypeError, rec_kernel.boundary_enclosing_area_fraction, [1, 2]) self.assertRaises(ValueError, rec_kernel.boundary_enclosing_area_fraction, -10) self.assertEqual(kernel.is_symmetric(), False) self.assertEqual(rec_kernel.is_symmetric(), True)
def test_trim_as_convolve_mode(self): cutoff = 5 sampling_period = 0.01 * pq.s t_spikes = np.linspace(-cutoff, cutoff, num=(2 * cutoff + 1)) * pq.s spiketrain = neo.SpikeTrain(t_spikes, t_start=t_spikes[0], t_stop=t_spikes[-1]) kernel = kernels.RectangularKernel(sigma=1 * pq.s) assert cutoff > kernel.min_cutoff, "Choose larger cutoff" kernel_types = tuple(kern_cls for kern_cls in kernels.__dict__.values() if isinstance(kern_cls, type) and issubclass(kern_cls, kernels.SymmetricKernel) and kern_cls is not kernels.SymmetricKernel) kernels_symmetric = [ kern_cls(sigma=1 * pq.s, invert=False) for kern_cls in kernel_types ] for kernel in kernels_symmetric: for trim in (False, True): rate_centered = statistics.instantaneous_rate( spiketrain, sampling_period=sampling_period, kernel=kernel, cutoff=cutoff, trim=trim) rate_convolve = statistics.instantaneous_rate( spiketrain, sampling_period=sampling_period, kernel=kernel, cutoff=cutoff, trim=trim, center_kernel=False) assert_array_almost_equal(rate_centered, rate_convolve)
def _get_rates(_spiketrains): kernel_sigma = kernel_width / 2. / np.sqrt(3.) kernel = kernels.RectangularKernel(sigma=kernel_sigma) rates = [statistics.instantaneous_rate( st, kernel=kernel, sampling_period=1 * pq.ms) for st in _spiketrains] return rates
def test_recovered_firing_rate_profile(self): np.random.seed(54) t_start = 0 * pq.s t_stop = 4 * np.round(np.pi, decimals=3) * pq.s # 2 full periods sampling_period = 0.001 * pq.s # an arbitrary rate profile profile = 0.5 * (1 + np.sin( np.arange(t_start.item(), t_stop.item(), sampling_period.item()))) time_generation = 0 n_trials = 200 rtol = 0.05 # 5% of deviation allowed kernel = kernels.RectangularKernel(sigma=0.25 * pq.s) for rate in (10 * pq.Hz, 100 * pq.Hz): rate_profile = neo.AnalogSignal(rate * profile, sampling_period=sampling_period) # the recovered firing rate profile should not depend on the # shape factor; here we test float and integer values of the shape # factor: the method supports float values that is not trivial # for inhomogeneous gamma process generation for shape_factor in (1, 2.5, 10.): spiketrains = \ [stgen.inhomogeneous_gamma_process( rate_profile, shape_factor=shape_factor) for _ in range(n_trials)] rate_recovered = instantaneous_rate( spiketrains, sampling_period=sampling_period, kernel=kernel, t_start=t_start, t_stop=t_stop, trim=True).sum(axis=1) / n_trials rate_recovered = rate_recovered.flatten().magnitude trim = (rate_profile.shape[0] - rate_recovered.shape[0]) // 2 rate_profile_valid = rate_profile.magnitude.squeeze() rate_profile_valid = rate_profile_valid[trim:-trim - 1] assert_allclose(rate_recovered, rate_profile_valid, rtol=0, atol=rtol * rate.item())
def correlate_to_stim(sp_neo, var, kernel_sigmas, mode='g', plot_tgl=False): ''' Calculate the correlation between a spike train and an analog signal. Smooths the observed spike train with a user defined kernel in order to get a continuous rate estimate :param sp_neo: a neo spiketrain :param var: a 1D numpy array, neo analog signal, or quantity to correlate the spike rate with :param kernel_sigmas: list or numpy array of sigma values defining the kernel to smooth the spike train :param mode: type of kernel to smooth the spike train with ['g': gaussian,'b'/'r': box or rectangular] :return corr_: A numpy array of correlation values between the spiketrain and desired variable. Each entry corresponds to a different smoothing parameter as indicated in 'kernel_sigmas' :return kernel_sigmas: The numpy array of kernel sigma values used ''' # map var to a numpy array if needed if type(var) == neo.core.AnalogSignal or type( var) == quantities.quantity.Quantity: var = var.magnitude # init correlation output corr_ = np.empty(kernel_sigmas.shape[0]) # loop over all sigma values for ii, sigma in enumerate(kernel_sigmas): # get the appropriate kernel with corresponding sigma if mode == 'b' or mode == 'r': kernel = kernels.RectangularKernel(sigma=sigma * pq.ms) elif mode == 'g': kernel = kernels.GaussianKernel(sigma=sigma * pq.ms) else: raise ValueError('Kernel mode not defined') r = instantaneous_rate(sp_neo, sampling_period=pq.ms, kernel=kernel) corr_[ii] = np.corrcoef(r.squeeze(), var)[0, 1] if plot_tgl: plt.plot(kernel_sigmas, corr_, 'k') return (corr_, kernel_sigmas)