def ripple_spiking_statisitics(ripple_events, data_directory,position_data, ep, bin_size): #For inspecting the spiking profile for different SWR events.. #Useful for inspecting the no of ripple events passing a specific statistical criterion from wrappers import loadSpikeData from functions import computeAngularTuningCurves, findHDCells spikes, shanks = loadSpikeData(data_directory) tuning_curves = (computeAngularTuningCurves(spikes, position_data, ep, 61)) hd_idx, stats = findHDCells(tuning_curves) ripple_events = ripple_events.values spikes_hd = {k:spikes[k] for k in hd_idx} #print(spikes_hd) d = 1000000/2 ripple_epochs = make_Epochs((ep['start'].values[0] + (ripple_events[:,1]*1000000) - d), (ep['start'].values[0] + (ripple_events[:,1]*1000000) + d)) #print(ripple_epochs.as_units('ms')) val_array = [] edges = [] for i in range(len(ripple_epochs)): val = 0 for k in hd_idx: spk = spikes_hd[k].restrict(ripple_epochs.iloc[[i]]).as_units('ms').index.values val_emp, edge = np.histogram(spk, np.arange(ripple_epochs.as_units('ms').iloc[[i]].start.values[0], ripple_epochs.as_units('ms').iloc[[i]].end.values[0], bin_size)) print(len(np.nonzero(val_emp))) val = val + val_emp val_array.append(val) edges.append(edge) print(val_array) return val_array, edges
This scripts will show you how to compute the auto and cross-correlograms of neurons The data should be found in StarterPack/data_raw/A1110-180621/ The main function crossCorr is already written in StarterPack/python/functions.py ''' import numpy as np import pandas as pd import neuroseries as nts from pylab import * # First let's get some spikes data_directory = '../data_raw/KA28-190405' from wrappers import loadSpikeData spikes, shank = loadSpikeData(data_directory) # Let's restrict the spikes to the wake episode from wrappers import loadEpoch wake_ep = loadEpoch(data_directory, 'wake') # Let's make the autocorrelogram of the first neuron neuron_0 = spikes[0] # restricted for wake neuron_0 = neuron_0.restrict(wake_ep) # transforming the times in millisecond neuron_0 = neuron_0.as_units('ms') # and extracting the index to feed the function crossCorr
# You call the function by giving the generalinfo dictionnary shankStructure = loadShankStructure(generalinfo) # You check your variable by typing : shankStructure # And now each region is associated with a list of number. # Each number indicates the index of a shank # For example, the thalamus shanks index are : shankStructure['thalamus'] # Therefore we have here 8 shanks in the thalamus # This will be useful to know which spikes were recorded in the thalamus # Now we can load the spikes in Mouse12-120806_SpikeData.mat by using another wrapper from wrappers import loadSpikeData # and we want only the spikes from the thalamus # So you need to pass the shankStructure of the thalamus as an argument of the function spikes, shank = loadSpikeData(data_directory, shankStructure['thalamus']) # To acces one neuron: spikes[0] # It returns a Ts object with the time occurence of spikes on the left column and NaN in the right columns # Which neurons of the thalamus are head-direction neurons? # To know that, you need to load Mouse12-120806_HDCells.mat # But first, you need to give the index of the thalamic neuron for which we are interested here # The neuron index is given by the keys of the dictionnary spikes # You can extract the keys and put them in another variable with : my_thalamus_neuron_index = list(spikes.keys()) # Now you can call the function to load HD info from wrappers import loadHDCellInfo hd_neuron_index = loadHDCellInfo(data_directory + '/Analysis/HDCells.mat', my_thalamus_neuron_index) # You have now a new array of neuron index
def ripple_Decoding(ripple_event, data_dir, epoch, lfp, save_pdf = False): #Purpose: Decoding the ripple event to the Head-Direction angle data ''' NOTE ON function arguments: ripple_event : pandas Dataframe with info about ripple events in the following form : [start time, peak time, end time, Average Power, Instantanous Frequency of ripple]. data_dir : path to the directory where all the session data is stored. epoch : name of epoch in which decoding is needed to be done. lfp : Downasampled neuroseries Time Series with single channel. It can be obtained using loadLFP() function to obtain a time series from a single channel. ''' from matplotlib.backends.backend_pdf import PdfPages import itertools bin_size_un = 20 #ms bin_size_ov = 100 #ms percent_overlap = 0.75 d1,d2 = plot_sharing_calc(bin_size_un, bin_size_ov, (500 * 1000)) ripple_event = ripple_event.values #Loading the correct angular position wrt time from Positions.h5 file. positions = load_Positions(data_directory, epoch) ep = correct_Epochs(positions) #Loading the spike and shank data from wrappers import loadSpikeData, loadEpoch, loadPosition, loadXML spikes, shank = loadSpikeData(data_dir) n_channels, fs, shank_to_channel = loadXML(data_dir) #Loading the wakefulness period data for decoding as it is required to calculate tuning curves and occupancy pos_wake = load_Positions(data_directory, 'wake') wake_ep = correct_Epochs(pos_wake) #Computing Angular Tuning curves for the detection of head-direction cells using Reyleigh's test. #NOTE: Use wakefulness position data to calculate tuning curves and occupancy from functions import computeAngularTuningCurves tuning_curves = computeAngularTuningCurves(spikes, pos_wake['angle'], wake_ep, 61) #spikes: spike data, angle : angle data from all the, no of bins for angles #Defining correct HD Cells using Reileigh's test on angular tuning curves. from functions import findHDCells hd_idx, stat = findHDCells(tuning_curves) tuning_curves = tuning_curves[hd_idx] #To calculate prior using Poisson spiking assumption from functions import decodeHD, decodeHD_overlap2 spikes_hd = {k:spikes[k] for k in hd_idx} occupancy = np.histogram(pos_wake['angle'], np.linspace(0, 2*np.pi, 61), weights = np.ones_like(pos_wake['angle'])/float(len(pos_wake['angle'])))[0] #Here, we will try to decode the HD angle during wake state to see whether the decoding priors like Ocuupancy map and tuning curves are correct or not. wake_dec, prob_wake_dec = decodeHD(tuning_curves, spikes_hd, wake_ep, occupancy, 200) posterior_wake = nts.Tsd(t = prob_wake_dec.index.values, d = prob_wake_dec.max(1).values, time_units = 'ms') ''' figure() subplot(2,1,1) subplot(2,1,1).set_title('Bayesian Decoding during Wakefulness') plot(pos_wake['angle'].restrict(wake_ep), label = 'True HD') plot(wake_dec, label = 'Decoded HD(Bayesian)') legend() subplot(2,1,2) subplot(2,1,2).set_title('Posterior Probability(Bayesian Decoding)') matshow(prob_wake_dec) legend() show() ''' print(ripple_event.shape) #So far, we have calculated the general information that we need for decoding such as occupancy map and spikes of HD cells. They are #important irrespective of the event we are trying to decode. #Now, we will calculate the decoding and probable_angle(wrt time) for each ripple event d = 500 * 1000 ripple_epochs1 = make_Epochs((ep['start'].values[0] + (ripple_event[:,1]*1000000) - d1), (ep['start'].values[0] + (ripple_event[:,1]*1000000) + d1)) #ripple_event is in seconds here... ripple_epochs2 = make_Epochs((ep['start'].values[0] + (ripple_event[:,1]*1000000) - d2), (ep['start'].values[0] + (ripple_event[:,1]*1000000) + d2)) ripple_epochs = make_Epochs((ep['start'].values[0] + (ripple_event[:,1]*1000000) - d), (ep['start'].values[0] + (ripple_event[:,1]*1000000) + d)) proba_angle = [] #Since there are multiple events to decode, the proba_angle will now be a list of decodings for each of the ripple event decoded = [] #e = 67 #signal = signal.as_units('s') if save_pdf == True: print("Initiating Ripple Plotting..") with PdfPages("Ripple_plots_all.pdf") as Pdf: #Some preprocessing to display LFP together... low_cut = 200 high_cut = 400 frequency = 1250 signal = bandPass_filt(lfp_unfiltered = lfp, low_cut = low_cut, high_cut = high_cut, sampling_freq = frequency) ts = np.arange(len(signal))/frequency signal = nts.TsdFrame(ts, signal, time_units = 's') for e in range(5): #for e in range(len(ripple_epochs.index.values)): #Decoding using Non-overlapping equal width bins decoding, p_angle = decodeHD(tuning_curves, spikes_hd, ripple_epochs1[e], occupancy, bin_size_un) #posterior_prob = nts.Tsd(t = p_angle.index.values, d = p_angle.max(1).values, time_units = 'ms') p_mat = p_angle.values entropy1 = -(p_angle*np.log2(p_angle)).sum(1) #print(entropy1) #entropy1 = nts.Tsd(t = p_angle.index.values, d = ent1, time_units = 'ms') #Decoding using Overlapping bins decoding2, p_angle2 = decodeHD_overlap2(tuning_curves, spikes_hd, ripple_epochs2[e], occupancy, bin_size_ov, percent_overlap = percent_overlap) if type(decoding2).__name__ == 'NoneType': continue p_mat2 = p_angle2.values entropy2 = -(p_angle2*np.log2(p_angle2)).sum(1) #print(entropy2) #posterior_prob2 = nts.Tsd(t = p_angle2.index.values, d = p_angle2.max(1).values, time_units = 'ms') #entropy2 = nts.Tsd(t = p_angle2.index.values, d = [-p*math.log(p) for p in posterior_prob2.values], time_units = 'ms') frac = (1/len(spikes_hd)) ind_dix = pd.DataFrame(hd_idx, index = [tuning_curves[k].idxmax() for k in hd_idx], columns = ["cell_id"]) #ind_dix = {tuning_curves[k].idxmax():k for k in hd_idx} w = ind_dix.sort_index() #print(hd_idx) lfp_view = signal.restrict(ripple_epochs[e]) #lfp_view = signal[((ep.as_units('s')['start'].values[0]) + (ripple_event[int(e),0]) - resolution) : ((ep.as_units('s')['start'].values[0]) + (ripple_event[int(e),2]) + resolution)] print("Plotting Figure "+ str(e+1)+".") figure() ax1 = plt.subplot(4,1,1) ax1.set_title('LFP Bandpassed('+ str(low_cut) + '-' + str(high_cut) + 'Hz)') ax1.set_ylabel('mV') ax1.plot(lfp_view) ax1.plot(lfp.restrict(ripple_epochs[e])) ax2 = plt.subplot(4,1,2, sharex = ax1) [[ax2.axvline(_x, linewidth=1, color='r', ymin = i*frac, ymax = (i+1)*frac) for _x in spikes_hd[col].restrict(ripple_epochs[e]).index.values] for col,i in itertools.zip_longest(w['cell_id'].values, np.arange(len(spikes_hd)))] #[ax2.axhline((2*i +1)*frac/2, linewidth=1, color='black') for i in range(len(spikes_hd)+1)] ax2.axis('tight') ax2.set_yticks([(2*i + 1)*frac/2 for i in range(len(hd_idx)+1)]) ax2.set_yticklabels([str('%.2f'%i) for i in w.index.values]) #ax2.set_title('Rastor Plot') ax2.set_ylabel('HD Neuron acc. Preferred Angle') ax3 = plt.subplot(4,1,3, sharex = ax2) #ax3.set_title('Bayesian Decoding') ax3.plot(positions['angle'].restrict(ripple_epochs[e]), label = 'True HD') ax3.plot(decoding, label = 'Decoded HD') ax3.set_ylabel('Decoded Angle(Radians)') ax3.plot(decoding2, label = 'Decoded HD(overlapping)') #ax3.axvline(x = (ripple_epochs.iloc[[e]])['start'].values[0], color = 'green', label = 'Starting point of SWR') #ax3.axvline(x = (ripple_epochs.iloc[[e]])['end'].values[0], color = 'red', label = 'End point of SWR') ax3.legend() ax4 = plt.subplot(4,1,4) #ax4.set_title('Posterior Prob(Bayesian)') ax4.plot(entropy1, label = 'Entropy') ax4.plot(entropy2, label = 'Entropy(Overlapping)') ax4.set_ylabel('Entropy of Decoding') #ax4.axvline(x = (ripple_epochs.iloc[[e]])['start'].values[0], color = 'green', label = 'Starting point of SWR') #ax4.axvline(x = (ripple_epochs.iloc[[e]])['end'].values[0], color = 'red', label = 'End point of SWR') ax4.legend() mng = plt.get_current_fig_manager() mng.window.showMaximized() plt.pause(0.2) try: Pdf.savefig(dpi = 600) except ValueError: continue #legend() #show() plt.close() print("All Plotted. Done!") #sys.exit() entropy_un = [] entropy_b = [] decoded2 = [] decoded = [] print("trying decoding") for i in range(len(ripple_epochs2)): #decoding, p_angle = decodeHD(tuning_curves, spikes_hd, ripple_epochs1[i], occupancy, bin_size_un) #decoded.append(decoding) #decoding, p_angle = decodeHD(tuning_curves, spikes_hd, ripple_epochs.iloc[[i]], occupancy, 20) decoding2, p_angle2 = decodeHD_overlap2(tuning_curves, spikes_hd, ripple_epochs2[i], occupancy, bin_size_ov, percent_overlap = percent_overlap) print(len(decoding2)) decoded2.append(decoding2) #entropy1 = -(p_angle*np.log2(p_angle)).sum(1) #entropy_un.append(entropy1) #decoded.append(decoding) #proba_angle.append(p_angle) #entropy1 = -(p_angle*np.log2(p_angle)).sum(1) #entropy_un.append(entropy1) p_mat2 = p_angle2.values entropy2 = -(p_angle2*np.log2(p_angle2)).sum(1) entropy_b.append(entropy2) print("Done with "+ str(i)) return entropy_b, decoded2