def test_event_onsets(self): eventFn = 'all_channels.events' spikesFn = 'Tetrode2.spikes' eventFile = os.path.join(testDataDir,eventFn) spikesFile = os.path.join(testDataDir,spikesFn) eventData = loadopenephys.Events(eventFile) dataSpikes = loadopenephys.DataSpikes(spikesFile) spikeTimestamps = dataSpikes.timestamps eventOnsetTimes = eventData.get_event_onset_times() #convert to seconds samplingRate = eventData.samplingRate spikeTimestamps = spikeTimestamps/samplingRate eventOnsetTimes = eventOnsetTimes/samplingRate assert len(eventOnsetTimes)==513 timeRange = [-0.5, 1.0] #Remove events except from frist pulse in laser train eventOnsetTimes = spikesanalysis.minimum_event_onset_diff(eventOnsetTimes, 0.5) assert len(eventOnsetTimes)==103 (spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial) = spikesanalysis.eventlocked_spiketimes(spikeTimestamps, eventOnsetTimes, timeRange) plt.plot(spikeTimesFromEventOnset, trialIndexForEachSpike, '.')
def test_event_onsets(self): eventFn = 'all_channels.events' spikesFn = 'Tetrode2.spikes' eventFile = os.path.join(testDataDir, eventFn) spikesFile = os.path.join(testDataDir, spikesFn) eventData = loadopenephys.Events(eventFile) dataSpikes = loadopenephys.DataSpikes(spikesFile) spikeTimestamps = dataSpikes.timestamps eventOnsetTimes = eventData.get_event_onset_times() #convert to seconds samplingRate = eventData.samplingRate spikeTimestamps = spikeTimestamps / samplingRate eventOnsetTimes = eventOnsetTimes / samplingRate assert len(eventOnsetTimes) == 513 timeRange = [-0.5, 1.0] #Remove events except from frist pulse in laser train eventOnsetTimes = spikesanalysis.minimum_event_onset_diff( eventOnsetTimes, 0.5) assert len(eventOnsetTimes) == 103 (spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial) = spikesanalysis.eventlocked_spiketimes( spikeTimestamps, eventOnsetTimes, timeRange) plt.plot(spikeTimesFromEventOnset, trialIndexForEachSpike, '.')
def calculate_laser_train_ratio(self, dataframe=None): #Use the whole database by default if dataframe is None: dataframe = self.db #Laser train response, ratio of pulse avg spikes trainRatio = np.empty(len(dataframe)) timeRange = [-0.1, 1] #For initial alignment baseRange = [0, 0.05] #Base range is response to first pulse responseRange = [0.2, 0.25] #Response to 3rd pulse for indCell, cell in dataframe.iterrows(): spikeData, eventData = dataloader.get_session_ephys( cell, 'lasertrain') eventOnsetTimes = eventData.get_event_onset_times() eventOnsetTimes = spikesanalysis.minimum_event_onset_diff( eventOnsetTimes, 0.5) if spikeData.timestamps is not None: (spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial) = spikesanalysis.eventlocked_spiketimes( spikeData.timestamps, eventOnsetTimes, timeRange) avgSpikesBase = spikesanalysis.spiketimes_to_spikecounts( spikeTimesFromEventOnset, indexLimitsEachTrial, baseRange).mean() avgSpikesResp = spikesanalysis.spiketimes_to_spikecounts( spikeTimesFromEventOnset, indexLimitsEachTrial, responseRange).mean() ratio = avgSpikesResp / avgSpikesBase trainRatio[indCell] = ratio else: trainRatio[indCell] = None dataframe['trainRatio'] = trainRatio
def laser_response(ephysData, baseRange=[-0.05, -0.04], responseRange=[0.0, 0.01]): '''Compares firing rate during laser response range and base range. Inputs: ephysData: full dictionary of ephys data for laser pulse (or train) session baseRange: time range (relative to laser onset) to be used as baseline, list of [start time, end time] responseRange: time range (relative to laser onset) to be used as response, list of [start time, end time] Outputs: testStatistic: U test statistic of ranksums test between baseline and response pVal: p-value of ranksums test between baseline and response laserChangeFR: change in firing rate from baseline to response ''' fullTimeRange = [baseRange[0], responseRange[1]] eventOnsetTimes = ephysData['events']['laserOn'] eventOnsetTimes = spikesanalysis.minimum_event_onset_diff( eventOnsetTimes, minEventOnsetDiff=0.5) spikeTimestamps = ephysData['spikeTimes'] spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = \ spikesanalysis.eventlocked_spiketimes(spikeTimestamps, eventOnsetTimes, fullTimeRange) baseSpikeCountMat = spikesanalysis.spiketimes_to_spikecounts( spikeTimesFromEventOnset, indexLimitsEachTrial, baseRange) laserSpikeCountMat = spikesanalysis.spiketimes_to_spikecounts( spikeTimesFromEventOnset, indexLimitsEachTrial, responseRange) [testStatistic, pVal] = stats.ranksums(laserSpikeCountMat, baseSpikeCountMat) laserChangeFR = np.mean(laserSpikeCountMat - baseSpikeCountMat) return testStatistic, pVal, laserChangeFR
def get_sound_onset_times(ephysData, sessionType): eventOnsetTimes = ephysData['events']['soundDetectorOn'] if len(eventOnsetTimes ) == 0: #some cells recorded before sound detector installed eventOnsetTimes = ephysData['events']['stimOn'] + AVERAGE_JITTER[ sessionType] #correction for onset times, determined by comparing sound detector onset to stim event onset eventOnsetTimes = spikesanalysis.minimum_event_onset_diff( eventOnsetTimes, minEventOnsetDiff=0.2) return eventOnsetTimes
def plot_raster_and_PSTH(sessiontype, gs, color='k'): axRaster = plt.subplot(gs[0]) ephysData, bdata = cell.load(sessiontype) eventOnsetTimes = ephysData['events']['stimOn'] eventOnsetTimes = spikesanalysis.minimum_event_onset_diff( eventOnsetTimes, minEventOnsetDiff=0.5) timeRange = [-0.3, 1.0] (spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial) = spikesanalysis.eventlocked_spiketimes( ephysData['spikeTimes'], eventOnsetTimes, timeRange) # pRaster, hCond, zLine = extraplots.raster_plot(spikeTimesFromEventOnset, # indexLimitsEachTrial, # timeRange) axRaster.plot(spikeTimesFromEventOnset, trialIndexForEachSpike, 'k.', ms=1, rasterized=True) # plt.setp(pRaster, ms=1) axRaster.set_xlim(timeRange) axRaster.set_xticks([]) # axRaster.axis('off') extraplots.boxoff(axRaster) axRaster.set_yticks([len(eventOnsetTimes)]) axPSTH = plt.subplot(gs[1]) smoothPSTH = True psthLineWidth = 2 smoothWinSize = 1 binsize = 10 #in milliseconds binEdges = np.around(np.arange(timeRange[0] - (binsize / 1000.0), timeRange[1] + 2 * (binsize / 1000.0), (binsize / 1000.0)), decimals=2) winShape = np.concatenate((np.zeros(smoothWinSize), np.ones(smoothWinSize))) # Square (causal) winShape = winShape / np.sum(winShape) psthTimeBase = np.linspace(timeRange[0], timeRange[1], num=len(binEdges) - 1) spikeCountMat = spikesanalysis.spiketimes_to_spikecounts( spikeTimesFromEventOnset, indexLimitsEachTrial, binEdges) thisPSTH = np.mean(spikeCountMat, axis=0) if smoothPSTH: thisPSTH = np.convolve(thisPSTH, winShape, mode='same') ratePSTH = thisPSTH / float(binsize / 1000.0) axPSTH.plot(psthTimeBase, ratePSTH, '-', color=color, lw=psthLineWidth) displayRange = timeRange axPSTH.set_xlim(displayRange) extraplots.boxoff(axPSTH) axPSTH.set_ylim([0, max(ratePSTH)]) axPSTH.set_yticks([0, np.floor(np.max(ratePSTH))]) # axPSTH.set_ylabel('spk/s', fontsize=fontSizeLabels) axPSTH.set_ylabel('spk/s')
def calculate_highest_significant_sync_rate(self, dataframe=None): #Use the whole database by default if dataframe is None: dataframe = self.db #Highest significant sync rate #TODO: I need to unit test this part highestSync = np.empty(len(dataframe)) for indCell, cell in dataframe.iterrows(): spikeData, eventData = dataloader.get_session_ephys(cell, 'am') bdata = dataloader.get_session_bdata(cell, 'am') eventOnsetTimes = eventData.get_event_onset_times(eventChannel=5) eventOnsetTimes = spikesanalysis.minimum_event_onset_diff( eventOnsetTimes, 0.5) if spikeData.samples is not None: #NOTE: This is where I am ignoring the onset response. is 50msec sufficient?? timeRange = [0.05, 0.5] freqEachTrial = bdata['currentFreq'] possibleFreq = np.unique(freqEachTrial) (spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial) = spikesanalysis.eventlocked_spiketimes( spikeData.timestamps, eventOnsetTimes, timeRange) allRayleighPvals = np.zeros(len(possibleFreq)) for indFreq, oneFreq in enumerate(possibleFreq): trialsThisFreq = np.flatnonzero(freqEachTrial == oneFreq) spikeTimesThisFreq = spikeTimesFromEventOnset[np.in1d( trialIndexForEachSpike, trialsThisFreq)] #Number of radians in one second for this stimulus frequency radsPerSec = oneFreq * 2 * np.pi period = 1.0 / oneFreq spikeRads = (spikeTimesThisFreq * radsPerSec) % (2 * np.pi) #Compute average vector length and angle strength, phase = signal.vectorstrength( spikeTimesThisFreq, period) #Compute prob for the rayleigh statistic p = self.rayleigh_test(strength, len(spikeTimesThisFreq)) allRayleighPvals[indFreq] = p if np.any(allRayleighPvals < 0.05): hs = np.max(possibleFreq[allRayleighPvals < 0.05]) else: hs = 0 highestSync[indCell] = hs else: highestSync[indCell] = 0 dataframe['highestSync'] = highestSync
def get_sound_onset_times(ephysData, sessionType): '''Corrects onset times using estimated average jitter for data collected before installation of sound detector. Inputs: ephysData: full dictionary of ephys data for session in question sessionType: string, type of session (for finding proper correction to use) Outputs: eventOnsetTimes: time stamps of event onset, either according to sound detector (if that data exists) or estimated from stimOn and correction ''' eventOnsetTimes = ephysData['events']['soundDetectorOn'] if len(eventOnsetTimes)==0: #some cells recorded before sound detector installed eventOnsetTimes = ephysData['events']['stimOn'] + AVERAGE_JITTER[sessionType] #correction for onset times, determined by comparing sound detector onset to stim event onset eventOnsetTimes = spikesanalysis.minimum_event_onset_diff(eventOnsetTimes, minEventOnsetDiff=0.2) return eventOnsetTimes
def am_example(cell, timeRange=[-0.2, 0.7]): #Plot histograms of spikes relative to stimulus period? plotCycleHists = False spikeData, eventData = celldatabase.get_session_ephys(cell, 'am') eventOnsetTimes = eventData.get_event_onset_times(eventID=1, eventChannel=0) eventOnsetTimes = spikesanalysis.minimum_event_onset_diff(eventOnsetTimes, minEventOnsetDiff=0.7) bdata = celldatabase.get_session_bdata(cell, 'am') colors = get_colors(len(np.unique(bdata['currentFreq']))) #Raster plt.clf() if plotCycleHists: plt.subplot2grid((11, 3), (0, 0), rowspan=11, colspan=2) else: plt.subplot(111) ms=6 #4 sortArray = bdata['currentFreq'] trialsEachCond = behavioranalysis.find_trials_each_type( sortArray, np.unique(sortArray)) labels = ['%.1f' % f for f in np.unique(sortArray)] spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes( spikeData.timestamps, eventOnsetTimes, timeRange) pRaster, hcond, zline = extraplots.raster_plot( spikeTimesFromEventOnset, indexLimitsEachTrial, timeRange, trialsEachCond=trialsEachCond, labels=labels, colorEachCond=colors) plt.setp(pRaster, ms=ms) fontsize = 20 plt.ylabel('AM rate', fontsize=fontsize) plt.xlabel('Time from stimulus onset (s)', fontsize=fontsize) if plotCycleHists: #Want to plot a hist of spike times from 0 to 2pi # ax3 = plt.subplot(313) plt.hold(True) for indFreq, (freq, spikeTimesThisFreq, trialIndicesThisFreq) in enumerate(spiketimes_each_frequency(spikeTimesFromEventOnset, trialIndexForEachSpike, sortArray)): radsPerSec=freq*2*np.pi spikeRads = (spikeTimesThisFreq*radsPerSec)%(2*np.pi) ax = plt.subplot2grid((11, 3), (10-indFreq, 2)) ax.hist(spikeRads, bins=50, color=colors[indFreq], histtype='step')
labelHeightFactor = 0.8 indCriterion = 0 for indExample in range(nExamples): indRow, dbRow = celldatabase.find_cell(database, **examples[indExample]) cell = ephyscore.Cell(dbRow) ### -- Pre -- ### sessiontype = 'laserpulse_pre' axPSTH = plt.subplot(examplesAllCriteria[indCriterion][indExample][0]) ephysData, bdata = cell.load(sessiontype) eventOnsetTimes = ephysData['events']['stimOn'] eventOnsetTimes = spikesanalysis.minimum_event_onset_diff( eventOnsetTimes, minEventOnsetDiff=0.5) if not indCriterion == 2: timeRange = [-0.3, 1.0] else: timeRange = [-0.01, 0.05] (spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial) = spikesanalysis.eventlocked_spiketimes( ephysData['spikeTimes'], eventOnsetTimes, timeRange) smoothPSTH = True smoothWinSize = 3 binsize = 10 #in milliseconds binEdges = np.around(np.arange(timeRange[0] - (binsize / 1000.0), timeRange[1] + 2 * (binsize / 1000.0),
def get_sound_onset_times(ephysData, sessionType): eventOnsetTimes = ephysData['events']['soundDetectorOn'] if len(eventOnsetTimes)==0: #some cells recorded before sound detector installed eventOnsetTimes = ephysData['events']['stimOn'] + AVERAGE_JITTER[sessionType] #correction for onset times, determined by comparing sound detector onset to stim event onset eventOnsetTimes = spikesanalysis.minimum_event_onset_diff(eventOnsetTimes, minEventOnsetDiff=0.2) return eventOnsetTimes
#Laser train ratio of pulse 2 to pulse 1 trainRatio = np.empty(len(pinp016db)) for indCell, cell in pinp016db.iterrows(): loader = dataloader.DataLoader(cell['subject']) trainSession = cell['ephys'][cell['sessiontype'].index('lasertrain')] eventData = loader.get_session_events(trainSession) try: spikeData = loader.get_session_spikes(trainSession, int(cell['tetrode']), cluster=int(cell['cluster'])) except AttributeError: trainRatio[indCell] = 0 continue eventOnsetTimes = loader.get_event_onset_times(eventData) eventOnsetTimes = spikesanalysis.minimum_event_onset_diff(eventOnsetTimes, 0.1) timeRange = [-0.1, 1] (spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial) = spikesanalysis.eventlocked_spiketimes(spikeData.timestamps, eventOnsetTimes, timeRange) # plt.clf() # plt.plot(spikeTimesFromEventOnset, trialIndexForEachSpike, '.') # plt.show() # plt.waitforbuttonpress() baseRange = [0, 0.05] responseRange = [0.2, 0.25] avgSpikesBase = spikesanalysis.spiketimes_to_spikecounts(spikeTimesFromEventOnset,indexLimitsEachTrial,baseRange).mean()
try: zStat, pVal = stats.mannwhitneyu(nspkResp, nspkBase) except ValueError: #All numbers identical will cause mann whitney to fail zStat, pVal = [0, 1] # if pVal<0.05 and zStat>0: #This does not work because MW still gives positive Z if response goes down if (pVal < 0.05) and (nspkResp.ravel().mean() > nspkBase.ravel().mean()): passPulse = True else: passPulse = False #Lasertrain analysis #There should be a significant response to all of the pulses spikeTimes = trainData['spikeTimes'] trainPulseOnsetTimes = trainData['events']['stimOn'] eventOnsetTimes = spikesanalysis.minimum_event_onset_diff( trainPulseOnsetTimes, 0.5) baseRange = [-0.050, -0.04] # Baseline range (in seconds) pulseTimes = [0, 0.2, 0.4, 0.6, 0.8] # baseRange = [-0.05, -0.03] binTime = baseRange[1] - baseRange[0] # Time-bin size alignmentRange = [baseRange[0], pulseTimes[-1] + binTime] (spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial) = spikesanalysis.eventlocked_spiketimes( spikeTimes, eventOnsetTimes, alignmentRange) nspkBase = spikesanalysis.spiketimes_to_spikecounts( spikeTimesFromEventOnset, indexLimitsEachTrial, baseRange) zStats = np.empty(len(pulseTimes)) pVals = np.empty(len(pulseTimes))
def calculate_base_stats(db, filename=''): """ Calculate parameters to be used to filter cells in calculate_indices """ sessionMulti = [ 'tuningCurve', 'tuningCurve(tc)' ] # sessions with multivariate stimulus 'shortTuningCurve','am' sessionSingle = ['noiseburst', 'laserpulse'] # sessions with single variable stimulus # FILTERING DATAFRAME firstCells = db.query(studyparams.FIRST_FLTRD_CELLS ) # isiViolations<0.02 and spikeShapeQuality>2 for indIter, (indRow, dbRow) in enumerate(firstCells.iterrows()): dbRow = firstCells.loc[indRow] sessions = dbRow['sessionType'] oneCell = ephyscore.Cell(dbRow, useModifiedClusters=False) print("Now processing ", dbRow['subject'], dbRow['date'], dbRow['depth'], dbRow['tetrode'], dbRow['cluster'], indRow) print("Sessions tested in this cell are(is) ", sessions) for session in sessions: ephysData, bdata = oneCell.load(session) spikeTimes = ephysData['spikeTimes'] if session == ('laserpulse' or 'lasertrain'): eventOnsetTimes = ephysData['events']['laserOn'] print(u"\U0001F4A9") else: eventOnsetTimes = ephysData['events']['soundDetectorOn'] eventOnsetTimes = spikesanalysis.minimum_event_onset_diff( eventOnsetTimes, minEventOnsetDiff=0.2) # SOUND RESPONSES AND LASER RESPONSES if session in sessionSingle: # single stimulus baseRange = [-0.1, 0 ] # if session != 'laserpulse' else [-0.05,-0.04] nspkBase, nspkResp = funcs.calculate_firing_rate( ephysData, baseRange, session) respSpikeMean = nspkResp.ravel().mean() try: zStats, pVals = stats.mannwhitneyu(nspkResp, nspkBase) except ValueError: # All numbers identical will cause mann-whitney to fail zStats, pVals = [0, 1] firstCells.loc[indRow, '{}_pVal'.format( session )] = pVals # changed from at to loc via recommendation from pandas firstCells.loc[indRow, '{}_FR'.format( session)] = respSpikeMean # mean firing rate # Frequency tuning responses and AM elif session in sessionMulti: # multivariate stimulus, such as am and tuning curve baseRange = [-0.1, 0] if session != 'am' else [-0.5, -0.1] currentFreq = bdata['currentFreq'] currentIntensity = bdata['currentIntensity'] # trialsEachType = behavioranalysis.find_trials_each_type(currentFreq, np.unique(currentFreq)) uniqFreq = np.unique(currentFreq) uniqueIntensity = np.unique(currentIntensity) allIntenBase = np.array([]) respSpikeMean = np.empty( (len(uniqueIntensity), len(uniqFreq))) # same as allIntenResp allIntenRespMedian = np.empty( (len(uniqueIntensity), len(uniqFreq))) Rsquareds = np.empty((len(uniqueIntensity), len(uniqFreq))) # TODO: Identify if this fix will need to be used in multiple functions. # Maybe include where eventOnsetTimes is first calculated if len(eventOnsetTimes) == len(currentFreq) + 1: eventOnsetTimes = eventOnsetTimes[:-1] respLatency = funcs.calculate_latency( eventOnsetTimes, currentFreq, uniqFreq, currentIntensity, uniqueIntensity, spikeTimes, indRow) elif len(eventOnsetTimes) < len(currentFreq): print( "Wrong number of events, probably caused by the original sound detector problems" ) respLatency = np.nan else: print("Something else is wrong with the number of events") respLatency = np.nan for indInten, intensity in enumerate(uniqueIntensity): spks = np.array([]) freqs = np.array([]) popts = [] pcovs = [] ind10AboveButNone = [] for indFreq, freq in enumerate(uniqFreq): selectinds = np.flatnonzero((currentFreq == freq) & ( currentIntensity == intensity)).tolist() nspkBase, nspkResp = funcs.calculate_firing_rate( ephysData, baseRange, session, selectinds=selectinds) spks = np.concatenate([spks, nspkResp.ravel()]) freqs = np.concatenate( [freqs, np.ones(len(nspkResp.ravel())) * freq]) respSpikeMean[indInten, indFreq] = np.mean(nspkResp) allIntenBase = np.concatenate( [allIntenBase, nspkBase.ravel()]) Rsquared, popt = funcs.calculate_fit( uniqFreq, allIntenBase, freqs, spks) Rsquareds[indInten, indFreq] = Rsquared popts.append(popt) # The reason why we are calculating bw10 here, it is to save the calculation time responseThreshold = funcs.calculate_response_threshold( 0.2, allIntenBase, respSpikeMean) # [6] Find Frequency Response Area (FRA) unit: fra boolean set, yes or no, but it's originally a pair fra = respSpikeMean > responseThreshold # [6.5] get the intensity threshold intensityInd, freqInd = funcs.calculate_intensity_threshold_and_CF_indices( fra, respSpikeMean) if intensityInd is None: # None of the intensities had anything bw10 = None lowerFreq = None upperFreq = None cf = None intensityThreshold = None fit_midpoint = None else: intensityThreshold = uniqueIntensity[intensityInd] cf = uniqFreq[freqInd] # [8] getting BW10 value, Bandwidth at 10dB above the neuron's sound intensity Threshold(SIT) ind10Above = intensityInd + int( 10 / np.diff(uniqueIntensity)[0] ) # How many inds to go above the threshold intensity ind lowerFreq, upperFreq, Rsquared10AboveSIT = funcs.calculate_BW10_params( ind10Above, popts, Rsquareds, responseThreshold, intensityThreshold) # print('lf:{},uf:{},R2:{}'.format(lowerFreq,upperFreq,Rsquared10AboveSIT)) if (lowerFreq is not None) and (upperFreq is not None): fit_midpoint = np.sqrt(lowerFreq * upperFreq) bw10 = (upperFreq - lowerFreq) / cf else: fit_midpoint = None bw10 = None # ADD PARAMS TO DATAFRAME [9] store data in DB: intensity threshold, rsquaredFit, bw10, cf, fra firstCells.at[indRow, 'thresholdFRA'] = intensityThreshold firstCells.at[indRow, 'cf'] = cf firstCells.at[indRow, 'lowerFreq'] = lowerFreq firstCells.at[indRow, 'upperFreq'] = upperFreq firstCells.at[indRow, 'rsquaredFit'] = Rsquared10AboveSIT firstCells.at[indRow, 'bw10'] = bw10 firstCells.at[indRow, 'fit_midpoint'] = fit_midpoint firstCells.at[indRow, 'latency'] = respLatency else: print("session {} is ignored".format(session) ) # Lasertrain, shortTuningCurve and AM are ignored return firstCells
eventFn = 'all_channels.events' spikesFn = 'Tetrode2.spikes' eventFile = os.path.join(dataDir,eventFn) spikesFile = os.path.join(dataDir,spikesFn) eventOnsetTimes = Events(eventFile).get_event_onset_times() dataSpikes = DataSpikes(spikesFile) spikeTimestamps = dataSpikes.timestamps #convert to seconds spikeTimestamps = spikeTimestamps/30000.0 eventOnsetTimes = eventOnsetTimes/30000.0 timeRange = [-0.5, 1.0] #Remove events except from frist pulse in laser train eventOnsetTimes = spikesanalysis.minimum_event_onset_diff(eventOnsetTimes, 0.5) (spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial) = spikesanalysis.eventlocked_spiketimes(spikeTimestamps, eventOnsetTimes, timeRange) plot(spikeTimesFromEventOnset, trialIndexForEachSpike, '.') show() ''' One int64 timestamp (actually a sample number; this can be converted to seconds using the sampleRate variable in the header) One uint16 number (N) indicating the samples per record (always 1024, at least for now) 1024 int16 samples 10-byte record marker (0 1 2 3 4 5 6 7 8 255) If a file is opened or closed in the middle of a record, the leading or trailing samples are set to zero.
def plot_bandwidth_report(cell, type='normal', bandTimeRange=[0.2, 1.0], bandBaseRange=[-1.0, -0.2]): plt.clf() bandIndex = int(cell['bestBandSession']) if bandIndex is None: print 'No bandwidth session given' return #create cell object for loading data cellObj = ephyscore.Cell(cell) #change dimensions of report to add laser trials if they exist if len(cellObj.get_session_inds('laserPulse')) > 0: laser = True gs = gridspec.GridSpec(13, 6) else: laser = False gs = gridspec.GridSpec(9, 6) offset = 4 * laser gs.update(left=0.15, right=0.85, top=0.96, wspace=0.7, hspace=1.0) tetrode = int(cell['tetrode']) cluster = int(cell['cluster']) #load bandwidth ephys and behaviour data bandEphysData, bandBData = cellObj.load_by_index(bandIndex) bandEventOnsetTimes = ephysanalysis.get_sound_onset_times( bandEphysData, 'bandwidth') bandSpikeTimestamps = bandEphysData['spikeTimes'] timeRange = [-0.2, 1.5] bandEachTrial = bandBData['currentBand'] numBands = np.unique(bandEachTrial) #change the trial type that the bandwidth session is split by so we can use this report for Arch-inactivation experiments #also changes the colours to be more thematically appropriate! (in Anna's opinion) if type == 'laser': secondSort = bandBData['laserTrial'] secondSortLabels = ['no laser', 'laser'] colours = ['k', '#c4a000'] errorColours = ['0.5', '#fce94f'] gaussFitCol = 'gaussFit' tuningR2Col = 'tuningFitR2' elif type == 'normal': secondSort = bandBData['currentAmp'] secondSortLabels = [ '{} dB'.format(amp) for amp in np.unique(secondSort) ] colours = ['#4e9a06', '#5c3566'] errorColours = ['#8ae234', '#ad7fa8'] gaussFitCol = 'gaussFit' tuningR2Col = 'tuningFitR2' charfreq = str(np.unique(bandBData['charFreq'])[0] / 1000) modrate = str(np.unique(bandBData['modRate'])[0]) numBands = np.unique(bandEachTrial) # -- plot rasters of the bandwidth trials -- rasterColours = [ np.tile([colours[0], errorColours[0]], len(numBands) / 2 + 1), np.tile([colours[1], errorColours[1]], len(numBands) / 2 + 1) ] plot_separated_rasters(gs, [0, 3], 5 + offset, bandEachTrial, secondSort, bandSpikeTimestamps, bandEventOnsetTimes, colours=rasterColours, titles=secondSortLabels, plotHeight=2) # -- plot bandwidth tuning curves -- plt.subplot(gs[5 + offset:, 3:]) tuningDict = ephysanalysis.calculate_tuning_curve_inputs( bandSpikeTimestamps, bandEventOnsetTimes, bandEachTrial, secondSort, bandTimeRange, baseRange=bandBaseRange, info='plotting') plot_tuning_curve(tuningDict['responseArray'], tuningDict['errorArray'], numBands, tuningDict['baselineSpikeRate'], linecolours=colours, errorcolours=errorColours) # load tuning ephys and behaviour data tuningEphysData, tuningBData = cellObj.load('tuningCurve') tuningEventOnsetTimes = ephysanalysis.get_sound_onset_times( tuningEphysData, 'tuningCurve') tuningSpikeTimestamps = tuningEphysData['spikeTimes'] # -- plot frequency tuning at intensity used in bandwidth trial with gaussian fit -- # high amp bandwidth trials used to select appropriate frequency maxAmp = max(np.unique(bandBData['currentAmp'])) if maxAmp < 1: maxAmp = 66.0 #HARDCODED dB VALUE FOR SESSIONS DONE BEFORE NOISE CALIBRATION # find tone intensity that corresponds to tone sessions in bandwidth trial toneInt = maxAmp - 15.0 #HARDCODED DIFFERENCE IN TONE AND NOISE AMP BASED ON OSCILLOSCOPE READINGS FROM RIG 2 freqEachTrial = tuningBData['currentFreq'] plt.subplot(gs[2 + offset:4 + offset, 0:3]) plot_tuning_fitted_gaussian(tuningSpikeTimestamps, tuningEventOnsetTimes, tuningBData, toneInt, cell[gaussFitCol], cell[tuningR2Col], timeRange=cell['tuningTimeRange']) # -- plot frequency tuning raster -- plt.subplot(gs[0 + offset:2 + offset, 0:3]) freqLabels = ["%.1f" % freq for freq in np.unique(freqEachTrial) / 1000.0] plot_sorted_raster(tuningSpikeTimestamps, tuningEventOnsetTimes, freqEachTrial, timeRange=[-0.2, 0.6], labels=freqLabels) plt.title('Frequency Tuning Raster') # -- plot AM PSTH -- amEphysData, amBData = cellObj.load('AM') amEventOnsetTimes = ephysanalysis.get_sound_onset_times(amEphysData, 'AM') amSpikeTimestamps = amEphysData['spikeTimes'] rateEachTrial = amBData['currentFreq'] timeRange = [-0.2, 1.5] colourList = ['b', 'g', 'y', 'orange', 'r'] plt.subplot(gs[2 + offset:4 + offset, 3:]) plot_sorted_psth(amSpikeTimestamps, amEventOnsetTimes, rateEachTrial, timeRange=[-0.2, 0.8], binsize=25, colorEachCond=colourList) plt.xlabel('Time from sound onset (sec)') plt.ylabel('Firing rate (Hz)') plt.title('AM PSTH') # -- plot AM raster -- plt.subplot(gs[0 + offset:2 + offset, 3:]) rateLabels = ["%.0f" % rate for rate in np.unique(rateEachTrial)] plot_sorted_raster(amSpikeTimestamps, amEventOnsetTimes, rateEachTrial, timeRange=[-0.2, 0.8], labels=rateLabels, colorEachCond=colourList) plt.xlabel('Time from sound onset (sec)') plt.ylabel('Modulation Rate (Hz)') plt.title('AM Raster') # -- plot laser pulse and laser train data (if available) -- if laser: # -- plot laser pulse raster -- laserEphysData, noBehav = cellObj.load('laserPulse') laserEventOnsetTimes = laserEphysData['events']['laserOn'] laserSpikeTimestamps = laserEphysData['spikeTimes'] timeRange = [-0.1, 0.4] plt.subplot(gs[0:2, 0:3]) laserSpikeTimesFromEventOnset, trialIndexForEachSpike, laserIndexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes( laserSpikeTimestamps, laserEventOnsetTimes, timeRange) pRaster, hcond, zline = extraplots.raster_plot( laserSpikeTimesFromEventOnset, laserIndexLimitsEachTrial, timeRange) plt.xlabel('Time from laser onset (sec)') plt.title('Laser Pulse Raster') # -- plot laser pulse psth -- plt.subplot(gs[2:4, 0:3]) binsize = 10 / 1000.0 spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes( laserSpikeTimestamps, laserEventOnsetTimes, [timeRange[0] - binsize, timeRange[1]]) binEdges = np.around(np.arange(timeRange[0] - binsize, timeRange[1] + 2 * binsize, binsize), decimals=2) spikeCountMat = spikesanalysis.spiketimes_to_spikecounts( spikeTimesFromEventOnset, indexLimitsEachTrial, binEdges) pPSTH = extraplots.plot_psth(spikeCountMat / binsize, 1, binEdges[:-1]) plt.xlim(timeRange) plt.xlabel('Time from laser onset (sec)') plt.ylabel('Firing Rate (Hz)') plt.title('Laser Pulse PSTH') # -- didn't record laser trains for some earlier sessions -- if len(cellObj.get_session_inds('laserTrain')) > 0: # -- plot laser train raster -- laserTrainEphysData, noBehav = cellObj.load('laserTrain') laserTrainEventOnsetTimes = laserTrainEphysData['events'][ 'laserOn'] laserTrainSpikeTimestamps = laserTrainEphysData['spikeTimes'] laserTrainEventOnsetTimes = spikesanalysis.minimum_event_onset_diff( laserTrainEventOnsetTimes, 0.5) timeRange = [-0.2, 1.0] plt.subplot(gs[0:2, 3:]) spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes( laserTrainSpikeTimestamps, laserTrainEventOnsetTimes, timeRange) pRaster, hcond, zline = extraplots.raster_plot( spikeTimesFromEventOnset, indexLimitsEachTrial, timeRange) plt.xlabel('Time from laser onset (sec)') plt.title('Laser Train Raster') # -- plot laser train psth -- plt.subplot(gs[2:4, 3:]) binsize = 10 / 1000.0 spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes( laserTrainSpikeTimestamps, laserTrainEventOnsetTimes, [timeRange[0] - binsize, timeRange[1]]) binEdges = np.around(np.arange(timeRange[0] - binsize, timeRange[1] + 2 * binsize, binsize), decimals=2) spikeCountMat = spikesanalysis.spiketimes_to_spikecounts( spikeTimesFromEventOnset, indexLimitsEachTrial, binEdges) pPSTH = extraplots.plot_psth(spikeCountMat / binsize, 1, binEdges[:-1]) plt.xlim(timeRange) plt.xlabel('Time from laser onset (sec)') plt.ylabel('Firing Rate (Hz)') plt.title('Laser Train PSTH') # -- show cluster analysis -- #tsThisCluster, wavesThisCluster, recordingNumber = celldatabase.load_all_spikedata(cell) # -- Plot ISI histogram -- plt.subplot(gs[4 + offset, 0:2]) spikesorting.plot_isi_loghist(bandSpikeTimestamps) # -- Plot waveforms -- plt.subplot(gs[4 + offset, 2:4]) spikesorting.plot_waveforms(bandEphysData['samples']) # -- Plot events in time -- plt.subplot(gs[4 + offset, 4:6]) spikesorting.plot_events_in_time(bandSpikeTimestamps) title = '{0}, {1}, {2}um, Tetrode {3}, Cluster {4}, {5}kHz, {6}Hz modulation'.format( cell['subject'], cell['date'], cell['depth'], tetrode, cluster, charfreq, modrate) plt.suptitle(title) fig_path = '/home/jarauser/Pictures/cell reports' fig_name = '{0}_{1}_{2}um_TT{3}Cluster{4}.png'.format( cell['subject'], cell['date'], cell['depth'], tetrode, cluster) full_fig_path = os.path.join(fig_path, fig_name) fig = plt.gcf() fig.set_size_inches(20, 25) fig.savefig(full_fig_path, format='png', bbox_inches='tight')
baseRange = [-0.05,-0.04] # Baseline range (in seconds) binTime = baseRange[1]-baseRange[0] # Time-bin size responseRange = [0, 0+binTime] fullTimeRange = [baseRange[0], responseRange[1]] for indRow, (dbIndex, dbRow) in enumerate(db.iterrows()): cellObj = ephyscore.Cell(dbRow) try: laserTrainEphysData, noBehav = cellObj.load('laserTrain') except IndexError: print "No laser session for this cell" testStatistic = 0 pVal = 1 else: laserTrainEventOnsetTimes = laserTrainEphysData['events']['laserOn'] laserTrainEventOnsetTimes = spikesanalysis.minimum_event_onset_diff(laserTrainEventOnsetTimes, 0.5) laserTrainSpikeTimestamps = laserTrainEphysData['spikeTimes'] spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = \ spikesanalysis.eventlocked_spiketimes(laserTrainSpikeTimestamps, laserTrainEventOnsetTimes, fullTimeRange) baseSpikeCountMat = spikesanalysis.spiketimes_to_spikecounts(spikeTimesFromEventOnset, indexLimitsEachTrial, baseRange) laserSpikeCountMat = spikesanalysis.spiketimes_to_spikecounts(spikeTimesFromEventOnset, indexLimitsEachTrial, responseRange) [testStatistic, pVal] = stats.ranksums(laserSpikeCountMat, baseSpikeCountMat) laserTrainTestStatistic[indRow] = testStatistic laserTrainPVal[indRow] = pVal
df.at[indIter, "tuningTestBase"] = np.NaN df.at[indIter, "tuningTestResp"] = np.NaN else: ttBaseRange = [-0.1, 0] # Extracting information from ephys and behavior data to do calculations later with currentFreq = ttBehavData['currentFreq'] currentIntensity = ttBehavData['currentIntensity'] uniqFreq = np.unique(currentFreq) uniqueIntensity = np.unique(currentIntensity) ttTrialsEachCond = behavioranalysis.find_trials_each_combination( currentFreq, uniqFreq, currentIntensity, uniqueIntensity) ttSpikeTimes = ttEphysData['spikeTimes'] ttEventOnsetTimes = ttEphysData['events']['soundDetectorOn'] ttEventOnsetTimes = spikesanalysis.minimum_event_onset_diff( ttEventOnsetTimes, minEventOnsetDiff=0.2) if len(ttEventOnsetTimes) == (len(currentFreq) + 1): ttEventOnsetTimes = ttEventOnsetTimes[0:-1] print( "Correcting ephys data to be same length as behavior data") toCalculate = True elif len(ttEventOnsetTimes) == len(currentFreq): print("Data is already the same length") toCalculate = True else: print("Something is wrong with the length of these data") toCalculate = False # Instead of generating an error I made it just not calculate statistics. I should possibly have it log all mice # and sites where it failed to calculate so someone can review later if toCalculate:
def plot_blind_cell_quality(cell): plt.clf() gs = gridspec.GridSpec(5, 6) #create cell object for loading data cellObj = ephyscore.Cell(cell) # -- plot laser pulse raster -- laserEphysData, noBehav = cellObj.load('laserPulse') laserEventOnsetTimes = laserEphysData['events']['laserOn'] laserSpikeTimestamps = laserEphysData['spikeTimes'] timeRange = [-0.1, 0.4] plt.subplot(gs[0:2, 0:3]) laserSpikeTimesFromEventOnset, trialIndexForEachSpike, laserIndexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes( laserSpikeTimestamps, laserEventOnsetTimes, timeRange) pRaster, hcond, zline = extraplots.raster_plot( laserSpikeTimesFromEventOnset, laserIndexLimitsEachTrial, timeRange) plt.xlabel('Time from laser onset (sec)') plt.title('Laser Pulse Raster') # -- plot laser pulse psth -- plt.subplot(gs[2:4, 0:3]) binsize = 10 / 1000.0 spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes( laserSpikeTimestamps, laserEventOnsetTimes, [timeRange[0] - binsize, timeRange[1]]) binEdges = np.around(np.arange(timeRange[0] - binsize, timeRange[1] + 2 * binsize, binsize), decimals=2) spikeCountMat = spikesanalysis.spiketimes_to_spikecounts( spikeTimesFromEventOnset, indexLimitsEachTrial, binEdges) pPSTH = extraplots.plot_psth(spikeCountMat / binsize, 1, binEdges[:-1]) plt.xlim(timeRange) plt.xlabel('Time from laser onset (sec)') plt.ylabel('Firing Rate (Hz)') plt.title('Laser Pulse PSTH') # -- didn't record laser trains for some earlier sessions -- if len(cellObj.get_session_inds('laserTrain')) > 0: # -- plot laser train raster -- laserTrainEphysData, noBehav = cellObj.load('laserTrain') laserTrainEventOnsetTimes = laserTrainEphysData['events']['laserOn'] laserTrainSpikeTimestamps = laserTrainEphysData['spikeTimes'] laserTrainEventOnsetTimes = spikesanalysis.minimum_event_onset_diff( laserTrainEventOnsetTimes, 0.5) timeRange = [-0.2, 1.0] plt.subplot(gs[0:2, 3:]) spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes( laserTrainSpikeTimestamps, laserTrainEventOnsetTimes, timeRange) pRaster, hcond, zline = extraplots.raster_plot( spikeTimesFromEventOnset, indexLimitsEachTrial, timeRange) plt.xlabel('Time from laser onset (sec)') plt.title('Laser Train Raster') # -- plot laser train psth -- plt.subplot(gs[2:4, 3:]) binsize = 10 / 1000.0 spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes( laserTrainSpikeTimestamps, laserTrainEventOnsetTimes, [timeRange[0] - binsize, timeRange[1]]) binEdges = np.around(np.arange(timeRange[0] - binsize, timeRange[1] + 2 * binsize, binsize), decimals=2) spikeCountMat = spikesanalysis.spiketimes_to_spikecounts( spikeTimesFromEventOnset, indexLimitsEachTrial, binEdges) pPSTH = extraplots.plot_psth(spikeCountMat / binsize, 1, binEdges[:-1]) plt.xlim(timeRange) plt.xlabel('Time from laser onset (sec)') plt.ylabel('Firing Rate (Hz)') plt.title('Laser Train PSTH') # -- show cluster analysis -- #tsThisCluster, wavesThisCluster, recordingNumber = celldatabase.load_all_spikedata(cell) # -- Plot ISI histogram -- plt.subplot(gs[4, 0:2]) spikesorting.plot_isi_loghist(tsThisCluster) # -- Plot waveforms -- plt.subplot(gs[4, 2:4]) spikesorting.plot_waveforms(wavesThisCluster) # -- Plot events in time -- plt.subplot(gs[4, 4:6]) spikesorting.plot_events_in_time(tsThisCluster)
def plot_blind_cell_quality(cell): plt.clf() gs = gridspec.GridSpec(5, 6) #create cell object for loading data cellObj = ephyscore.Cell(cell) # -- plot laser pulse raster -- laserEphysData, noBehav = cellObj.load('laserPulse') laserEventOnsetTimes = laserEphysData['events']['laserOn'] laserSpikeTimestamps = laserEphysData['spikeTimes'] timeRange = [-0.1, 0.4] plt.subplot(gs[0:2, 0:3]) laserSpikeTimesFromEventOnset, trialIndexForEachSpike, laserIndexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes( laserSpikeTimestamps, laserEventOnsetTimes, timeRange) pRaster, hcond, zline = extraplots.raster_plot(laserSpikeTimesFromEventOnset,laserIndexLimitsEachTrial,timeRange) plt.xlabel('Time from laser onset (sec)') plt.title('Laser Pulse Raster') # -- plot laser pulse psth -- plt.subplot(gs[2:4, 0:3]) binsize = 10/1000.0 spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes(laserSpikeTimestamps, laserEventOnsetTimes, [timeRange[0]-binsize, timeRange[1]]) binEdges = np.around(np.arange(timeRange[0]-binsize, timeRange[1]+2*binsize, binsize), decimals=2) spikeCountMat = spikesanalysis.spiketimes_to_spikecounts(spikeTimesFromEventOnset, indexLimitsEachTrial, binEdges) pPSTH = extraplots.plot_psth(spikeCountMat/binsize, 1, binEdges[:-1]) plt.xlim(timeRange) plt.xlabel('Time from laser onset (sec)') plt.ylabel('Firing Rate (Hz)') plt.title('Laser Pulse PSTH') # -- didn't record laser trains for some earlier sessions -- if len(cellObj.get_session_inds('laserTrain')) > 0: # -- plot laser train raster -- laserTrainEphysData, noBehav = cellObj.load('laserTrain') laserTrainEventOnsetTimes = laserTrainEphysData['events']['laserOn'] laserTrainSpikeTimestamps = laserTrainEphysData['spikeTimes'] laserTrainEventOnsetTimes = spikesanalysis.minimum_event_onset_diff(laserTrainEventOnsetTimes, 0.5) timeRange = [-0.2, 1.0] plt.subplot(gs[0:2, 3:]) spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes(laserTrainSpikeTimestamps, laserTrainEventOnsetTimes, timeRange) pRaster, hcond, zline = extraplots.raster_plot(spikeTimesFromEventOnset,indexLimitsEachTrial,timeRange) plt.xlabel('Time from laser onset (sec)') plt.title('Laser Train Raster') # -- plot laser train psth -- plt.subplot(gs[2:4, 3:]) binsize = 10/1000.0 spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes(laserTrainSpikeTimestamps, laserTrainEventOnsetTimes, [timeRange[0]-binsize, timeRange[1]]) binEdges = np.around(np.arange(timeRange[0]-binsize, timeRange[1]+2*binsize, binsize), decimals=2) spikeCountMat = spikesanalysis.spiketimes_to_spikecounts(spikeTimesFromEventOnset, indexLimitsEachTrial, binEdges) pPSTH = extraplots.plot_psth(spikeCountMat/binsize, 1, binEdges[:-1]) plt.xlim(timeRange) plt.xlabel('Time from laser onset (sec)') plt.ylabel('Firing Rate (Hz)') plt.title('Laser Train PSTH') # -- show cluster analysis -- #tsThisCluster, wavesThisCluster, recordingNumber = celldatabase.load_all_spikedata(cell) # -- Plot ISI histogram -- plt.subplot(gs[4, 0:2]) spikesorting.plot_isi_loghist(tsThisCluster) # -- Plot waveforms -- plt.subplot(gs[4, 2:4]) spikesorting.plot_waveforms(wavesThisCluster) # -- Plot events in time -- plt.subplot(gs[4, 4:6]) spikesorting.plot_events_in_time(tsThisCluster)
def append_base_stats(cellDB, filename=''): """ Calculate parameters to be used to filter cells in calculate_indices """ # FILTERING DATAFRAME firstCells = cellDB.query(studyparams.FIRST_FLTRD_CELLS) # isiViolations<0.02 and spikeShapeQuality>2.5 for indIter, (indRow, dbRow) in enumerate(firstCells.iterrows()): sessions = dbRow['sessionType'] oneCell = ephyscore.Cell(dbRow, useModifiedClusters=False) print("Now processing ", dbRow['subject'], dbRow['date'], dbRow['depth'], dbRow['tetrode'], dbRow['cluster'], indRow) print("Sessions tested in this cell are(is) ", sessions) # -------------- Noiseburst data calculations ------------------------- session = 'noiseburst' try: noiseEphysData, noBData = oneCell.load(session) except IndexError: print('This cell does not contain a {} session'.format(session)) else: baseRange = [-0.1, 0] # if session != 'laserpulse' else [-0.05,-0.04] noiseEventOnsetTimes = noiseEphysData['events']['soundDetectorOn'] noiseSpikeTimes = noiseEphysData['spikeTimes'] nspkBaseNoise, nspkRespNoise = funcs.calculate_firing_rate(noiseEventOnsetTimes, noiseSpikeTimes, baseRange) respSpikeMean = np.mean(nspkRespNoise) # Significance calculations for the noiseburst try: zStats, pVals = stats.mannwhitneyu(nspkRespNoise, nspkBaseNoise, alternative='two-sided') except ValueError: # All numbers identical will cause mann-whitney to fail, therefore p-value should be 1 as there is no difference zStats, pVals = [0, 1] # Adding noiseburst values to the dataframe cellDB.at[ indRow, '{}_pVal'.format(session)] = pVals # changed from at to loc via recommendation from pandas cellDB.at[indRow, '{}_zStat'.format(session)] = zStats cellDB.at[indRow, '{}_FR'.format(session)] = respSpikeMean # mean firing rate # ------------ Laserpulse calculations -------------------------------- session = 'laserpulse' try: pulseEphysData, noBData = oneCell.load(session) except IndexError: print('This cell does not contain a {} session'.format(session)) else: baseRange = [-0.1, 0] # if session != 'laserpulse' else [-0.05,-0.04] laserEventOnsetTimes = pulseEphysData['events']['laserOn'] laserSpikeTimes = pulseEphysData['spikeTimes'] nspkBaseLaser, nspkRespLaser = funcs.calculate_firing_rate(laserEventOnsetTimes, laserSpikeTimes, baseRange) respSpikeMean = np.mean(nspkRespLaser) baseSpikeMean = np.mean(nspkBaseLaser) changeFiring = respSpikeMean - baseSpikeMean # Significance calculations for the laserpulse try: zStats, pVals = stats.mannwhitneyu(nspkRespLaser, nspkBaseLaser, alternative='two-sided') except ValueError: # All numbers identical will cause mann-whitney to fail zStats, pVals = [0, 1] # Adding laserpulse calculations to the dataframe cellDB.at[ indRow, '{}_pVal'.format(session)] = pVals # changed from at to loc via recommendation from pandas cellDB.at[indRow, '{}_zStat'.format(session)] = zStats cellDB.at[indRow, '{}_FR'.format(session)] = respSpikeMean # mean firing rate cellDB.at[indRow, '{}_dFR'.format(session)] = changeFiring # Difference between base and response firing rate # -------------- Tuning curve calculations ---------------------------- session = 'tuningCurve' try: tuningEphysData, tuningBehavData = oneCell.load(session) except IndexError: print('This cell does not contain a {} session'.format(session)) else: baseRange = [-0.1, 0] # Extracting information from ephys and behavior data to do calculations later with currentFreq = tuningBehavData['currentFreq'] currentIntensity = tuningBehavData['currentIntensity'] uniqFreq = np.unique(currentFreq) uniqueIntensity = np.unique(currentIntensity) tuningTrialsEachCond = behavioranalysis.find_trials_each_combination(currentFreq, uniqFreq, currentIntensity, uniqueIntensity) allIntenBase = np.array([]) respSpikeMean = np.empty((len(uniqueIntensity), len(uniqFreq))) # same as allIntenResp allIntenRespMedian = np.empty((len(uniqueIntensity), len(uniqFreq))) Rsquareds = [] popts = [] tuningSpikeTimes = tuningEphysData['spikeTimes'] tuningEventOnsetTimes = tuningEphysData['events']['soundDetectorOn'] tuningEventOnsetTimes = spikesanalysis.minimum_event_onset_diff(tuningEventOnsetTimes, minEventOnsetDiff=0.2) # Checking to see if the ephys data has one more trial than the behavior data and removing the last session if it does if len(tuningEventOnsetTimes) == (len(currentFreq) + 1): tuningEventOnsetTimes = tuningEventOnsetTimes[0:-1] print("Correcting ephys data to be same length as behavior data") toCalculate = True elif len(tuningEventOnsetTimes) == len(currentFreq): print("Data is already the same length") toCalculate = True else: print("Something is wrong with the length of these data") toCalculate = False # Instead of generating an error I made it just not calculate statistics. I should posisbly have it log all mice # and sites where it failed to calculate so someone can review later # -------------------- Start of calculations for the tuningCurve data ------------------------- # The latency of the cell from the onset of the stim if toCalculate: tuningZStat, tuningPVal = \ funcs.sound_response_any_stimulus(tuningEventOnsetTimes, tuningSpikeTimes, tuningTrialsEachCond[:, :, -1], timeRange=[0.0, 0.05], baseRange=baseRange) # All trials at all frequencies at the highest intensity respLatency = funcs.calculate_latency(tuningEventOnsetTimes, currentFreq, uniqFreq, currentIntensity, uniqueIntensity, tuningSpikeTimes, indRow) else: respLatency = np.nan tuningPVal = np.nan tuningZStat = np.nan for indInten, intensity in enumerate(uniqueIntensity): spks = np.array([]) freqs = np.array([]) pcovs = [] ind10AboveButNone = [] # ------------ start of frequency specific calculations ------------- for indFreq, freq in enumerate(uniqFreq): selectinds = np.flatnonzero((currentFreq == freq) & (currentIntensity == intensity))#.tolist() nspkBase, nspkResp = funcs.calculate_firing_rate(tuningEventOnsetTimes, tuningSpikeTimes, baseRange, selectinds=selectinds) spks = np.concatenate([spks, nspkResp.ravel()]) freqs = np.concatenate([freqs, np.ones(len(nspkResp.ravel())) * freq]) respSpikeMean[indInten, indFreq] = np.mean(nspkResp) allIntenBase = np.concatenate([allIntenBase, nspkBase.ravel()]) # ------------------- Significance and fit calculations for tuning ---------------- # TODO: Do we really need to calculate this for each frequency at each intensity? Rsquared, popt = funcs.calculate_fit(uniqFreq, allIntenBase, freqs, spks) Rsquareds.append(Rsquared) popts.append(popt) # ------------------------------ Intensity based calculations ------------------------- # The reason why we are calculating bw10 here, it is to save the calculation time responseThreshold = funcs.calculate_response_threshold(0.2, allIntenBase, respSpikeMean) # [6] Find Frequency Response Area (FRA) unit: fra boolean set, yes or no, but it's originally a pair fra = respSpikeMean > responseThreshold # [6.5] get the intensity threshold intensityInd, freqInd = funcs.calculate_intensity_threshold_and_CF_indices(fra, respSpikeMean) if intensityInd is None: # None of the intensities had anything bw10 = None lowerFreq = None upperFreq = None cf = None intensityThreshold = None fit_midpoint = None else: intensityThreshold = uniqueIntensity[intensityInd] cf = uniqFreq[freqInd] if toCalculate: monoIndex, overallMaxSpikes = funcs.calculate_monotonicity_index(tuningEventOnsetTimes, currentFreq, currentIntensity, uniqueIntensity, tuningSpikeTimes, cf ) onsetRate, sustainedRate, baseRate = funcs.calculate_onset_to_sustained_ratio(tuningEventOnsetTimes, tuningSpikeTimes, currentFreq, currentIntensity, cf, respLatency) else: monoIndex = np.nan overallMaxSpikes = np.nan onsetRate = np.nan sustainedRate = np.nan baseRate = np.nan # [8] getting BW10 value, Bandwidth at 10dB above the neuron's sound intensity threshold(SIT) ind10Above = intensityInd + int( 10 / np.diff(uniqueIntensity)[0]) # How many inds to go above the threshold intensity ind lowerFreq, upperFreq, Rsquared10AboveSIT = funcs.calculate_BW10_params(ind10Above, popts, Rsquareds, responseThreshold, intensityThreshold) # print('lf:{},uf:{},R2:{}'.format(lowerFreq,upperFreq,Rsquared10AboveSIT)) if (lowerFreq is not None) and (upperFreq is not None): fitMidpoint = np.sqrt(lowerFreq * upperFreq) bw10 = (upperFreq - lowerFreq) / cf else: fitMidpoint = None bw10 = None # Adding tuningCurve calculations to the dataframe to be saved later cellDB.at[indRow, 'thresholdFRA'] = intensityThreshold cellDB.at[indRow, 'cf'] = cf cellDB.at[indRow, 'lowerFreq'] = lowerFreq cellDB.at[indRow, 'upperFreq'] = upperFreq cellDB.at[indRow, 'rsquaredFit'] = Rsquared10AboveSIT cellDB.at[indRow, 'bw10'] = bw10 cellDB.at[indRow, 'fit_midpoint'] = fitMidpoint cellDB.at[indRow, 'latency'] = respLatency cellDB.at[indRow, 'monotonicityIndex'] = monoIndex cellDB.at[indRow, 'onsetRate'] = onsetRate cellDB.at[indRow, 'sustainedRate'] = sustainedRate cellDB.at[indRow, 'baseRate'] = baseRate cellDB.at[indRow, 'tuning_pVal'] = tuningPVal cellDB.at[indRow, 'tuning_ZStat'] = tuningZStat # -------------------- am calculations --------------------------- session = 'am' try: amEphysData, amBehavData = oneCell.load(session) except IndexError: print('This cell does not contain a {} session'.format(session)) else: significantFreqsArray = np.array([]) # General variables for am calculations/plotting from ephys and behavior data amSpikeTimes = amEphysData['spikeTimes'] amEventOnsetTimes = amEphysData['events']['soundDetectorOn'] amCurrentFreq = amBehavData['currentFreq'] amUniqFreq = np.unique(amCurrentFreq) amTimeRange = [-0.2, 0.7] amTrialsEachCond = behavioranalysis.find_trials_each_type(amCurrentFreq, amUniqFreq) if len(amCurrentFreq) != len(amEventOnsetTimes): amEventOnsetTimes = amEventOnsetTimes[:-1] if len(amCurrentFreq) != len(amEventOnsetTimes): print('Removing one does not align events and behavior. Skipping AM for cell') else: (amSpikeTimesFromEventOnset, amTrialIndexForEachSpike, amIndexLimitsEachTrial) = \ spikesanalysis.eventlocked_spiketimes(amSpikeTimes, amEventOnsetTimes, amTimeRange) amBaseTime = [-0.6, -0.1] amOnsetTime = [0, 0.1] amResponseTime = [0, 0.5] # TODO: Should do some kind of post-hoc/correction on these such as # taking the p-value and dividing by the total number of comparisons done and using that as a threshold zStat, amPValue = \ funcs.sound_response_any_stimulus(amEventOnsetTimes, amSpikeTimes, amTrialsEachCond, amResponseTime, amBaseTime) cellDB.at[indRow, 'am_response_pVal'] = amPValue cellDB.at[indRow, 'am_response_ZStat'] = zStat # TODO: test calculations below # TODO: Should do some kind of post-hoc/correction on the alpha such as # taking the alpha and dividing by the total number of comparisons done (11) and using that as a threshold correctedPval = 0.05 / len(amUniqFreq) # Decide whether to make the next calculations based on 0.05 or on corrected value if amPValue > correctedPval: # No response print("No significant AM response, no synchronization will be calculated") elif amPValue < correctedPval: amTimeRangeSync = [0.1, 0.5] # Use this to cut out onset responses (amSyncSpikeTimesFromEventOnset, amSyncTrialIndexForEachSpike, amSyncIndexLimitsEachTrial) = spikesanalysis.eventlocked_spiketimes(amSpikeTimes, amEventOnsetTimes, amTimeRangeSync) allFreqSyncPVal, allFreqSyncZScore, allFreqVectorStrength, allFreqRal = \ funcs.calculate_am_significance_synchronization(amSyncSpikeTimesFromEventOnset, amSyncTrialIndexForEachSpike, amCurrentFreq, amUniqFreq) amSyncPValue = np.min(allFreqSyncPVal) amSyncZStat = np.max(allFreqSyncZScore) cellDB.at[indRow, 'am_synchronization_pVal'] = amSyncPValue cellDB.at[indRow, 'am_synchronization_ZStat'] = amSyncZStat phaseDiscrimAccuracyDict = funcs.calculate_phase_discrim_accuracy(amSpikeTimes, amEventOnsetTimes, amCurrentFreq, amUniqFreq) for rate in amUniqFreq: cellDB.at[indRow, 'phaseDiscrimAccuracy_{}Hz'.format(int(rate))] = \ phaseDiscrimAccuracyDict[int(rate)] rateDiscrimAccuracy = funcs.calculate_rate_discrimination_accuracy(amSpikeTimes, amEventOnsetTimes, amBaseTime, amResponseTime, amCurrentFreq) cellDB.at[indRow, 'rateDiscrimAccuracy'] = rateDiscrimAccuracy if any(allFreqSyncPVal < 0.05): sigPvals = np.array(allFreqSyncPVal) < 0.05 highestSyncInd = funcs.index_all_true_before(sigPvals) cellDB.at[indRow, 'highestSync'] = amUniqFreq[allFreqSyncPVal < 0.05].max() cellDB.at[indRow, 'highestUSync'] = amUniqFreq[highestSyncInd] # print possibleFreq[pValThisCell<0.05].max() else: cellDB.at[indRow, 'highestSync'] = 0 if any(allFreqSyncPVal < correctedPval): cellDB.at[indRow, 'highestSyncCorrected'] = amUniqFreq[allFreqSyncPVal < correctedPval].max() highestSyncCorrected = amUniqFreq[allFreqSyncPVal < correctedPval].max() freqsBelowThresh = allFreqSyncPVal < correctedPval freqsBelowThresh = freqsBelowThresh.astype(int) if len(significantFreqsArray) == 0: significantFreqsArray = freqsBelowThresh else: # significantFreqsArray = np.concatenate([[significantFreqsArray], [freqsBelowThresh]]) significantFreqsArray = np.vstack((significantFreqsArray, freqsBelowThresh)) else: cellDB.at[indRow, 'highestSyncCorrected'] = 0 cellDB['cfOnsetivityIndex'] = \ (cellDB['onsetRate'] - cellDB['sustainedRate']) / \ (cellDB['sustainedRate'] + cellDB['onsetRate']) return cellDB
def plot_bandwidth_report(cell, bandIndex, type='normal'): plt.clf() if bandIndex is None: print 'No bandwidth session given' return #create cell object for loading data cellObj = ephyscore.Cell(cell) #change dimensions of report to add laser trials if they exist if len(cellObj.get_session_inds('laserPulse'))>0: laser = True gs = gridspec.GridSpec(13, 6) else: laser = False gs = gridspec.GridSpec(9, 6) offset = 4*laser gs.update(left=0.15, right=0.85, top = 0.96, wspace=0.7, hspace=1.0) tetrode=int(cell['tetrode']) cluster=int(cell['cluster']) #load bandwidth ephys and behaviour data bandEphysData, bandBData = cellObj.load_by_index(bandIndex) bandEventOnsetTimes = ephysanalysis.get_sound_onset_times(bandEphysData, 'bandwidth') bandSpikeTimestamps = bandEphysData['spikeTimes'] timeRange = [-0.2, 1.5] bandEachTrial = bandBData['currentBand'] numBands = np.unique(bandEachTrial) #change the trial type that the bandwidth session is split by so we can use this report for Arch-inactivation experiments #also changes the colours to be more thematically appropriate! (in Anna's opinion) if type=='laser': secondSort = bandBData['laserTrial'] secondSortLabels = ['no laser','laser'] colours = ['k', '#c4a000'] errorColours = ['0.5', '#fce94f'] gaussFitCol = 'gaussFit' tuningR2Col = 'tuningFitR2' elif type=='normal': secondSort = bandBData['currentAmp'] secondSortLabels = ['{} dB'.format(amp) for amp in np.unique(secondSort)] colours = ['#4e9a06','#5c3566'] errorColours = ['#8ae234','#ad7fa8'] gaussFitCol = 'gaussFit' tuningR2Col = 'tuningFitR2' charfreq = str(np.unique(bandBData['charFreq'])[0]/1000) modrate = str(np.unique(bandBData['modRate'])[0]) numBands = np.unique(bandEachTrial) # -- plot rasters of the bandwidth trials -- rasterColours = [np.tile([colours[0],errorColours[0]],len(numBands)/2+1), np.tile([colours[1],errorColours[1]],len(numBands)/2+1)] plot_separated_rasters(gs, [0,3], 5+offset, bandEachTrial, secondSort, bandSpikeTimestamps, bandEventOnsetTimes, colours=rasterColours, titles=secondSortLabels, plotHeight=2) # -- plot bandwidth tuning curves -- plt.subplot(gs[5+offset:, 3:]) timeRange = [0.2, 1.0]# if type=='normal' else [0.1, 1.1] baseRange = [-1.1, -0.3] tuningDict = ephysanalysis.calculate_tuning_curve_inputs(bandSpikeTimestamps, bandEventOnsetTimes, bandEachTrial, secondSort, timeRange, info='plotting') plot_tuning_curve(tuningDict['responseArray'], tuningDict['errorArray'], numBands, tuningDict['baselineSpikeRate'], linecolours=colours, errorcolours=errorColours) # load tuning ephys and behaviour data tuningEphysData, tuningBData = cellObj.load('tuningCurve') tuningEventOnsetTimes = ephysanalysis.get_sound_onset_times(tuningEphysData,'tuningCurve') tuningSpikeTimestamps = tuningEphysData['spikeTimes'] # -- plot frequency tuning at intensity used in bandwidth trial with gaussian fit -- # high amp bandwidth trials used to select appropriate frequency maxAmp = max(np.unique(bandBData['currentAmp'])) if maxAmp < 1: maxAmp = 66.0 #HARDCODED dB VALUE FOR SESSIONS DONE BEFORE NOISE CALIBRATION # find tone intensity that corresponds to tone sessions in bandwidth trial toneInt = maxAmp - 15.0 #HARDCODED DIFFERENCE IN TONE AND NOISE AMP BASED ON OSCILLOSCOPE READINGS FROM RIG 2 freqEachTrial = tuningBData['currentFreq'] plt.subplot(gs[2+offset:4+offset, 0:3]) plot_tuning_fitted_gaussian(tuningSpikeTimestamps, tuningEventOnsetTimes, tuningBData, toneInt, cell[gaussFitCol], cell[tuningR2Col], timeRange=cell['tuningTimeRange']) # -- plot frequency tuning raster -- plt.subplot(gs[0+offset:2+offset, 0:3]) freqLabels = ["%.1f" % freq for freq in np.unique(freqEachTrial)/1000.0] plot_sorted_raster(tuningSpikeTimestamps, tuningEventOnsetTimes, freqEachTrial, timeRange=[-0.2,0.6], labels=freqLabels) plt.title('Frequency Tuning Raster') # -- plot AM PSTH -- amEphysData, amBData = cellObj.load('AM') amEventOnsetTimes = ephysanalysis.get_sound_onset_times(amEphysData, 'AM') amSpikeTimestamps = amEphysData['spikeTimes'] rateEachTrial = amBData['currentFreq'] timeRange = [-0.2, 1.5] colourList = ['b', 'g', 'y', 'orange', 'r'] plt.subplot(gs[2+offset:4+offset, 3:]) plot_sorted_psth(amSpikeTimestamps, amEventOnsetTimes, rateEachTrial, timeRange = [-0.2, 0.8], binsize = 25, colorEachCond = colourList) plt.xlabel('Time from sound onset (sec)') plt.ylabel('Firing rate (Hz)') plt.title('AM PSTH') # -- plot AM raster -- plt.subplot(gs[0+offset:2+offset, 3:]) rateLabels = ["%.0f" % rate for rate in np.unique(rateEachTrial)] plot_sorted_raster(amSpikeTimestamps, amEventOnsetTimes, rateEachTrial, timeRange=[-0.2, 0.8], labels=rateLabels, colorEachCond=colourList) plt.xlabel('Time from sound onset (sec)') plt.ylabel('Modulation Rate (Hz)') plt.title('AM Raster') # -- plot laser pulse and laser train data (if available) -- if laser: # -- plot laser pulse raster -- laserEphysData, noBehav = cellObj.load('laserPulse') laserEventOnsetTimes = laserEphysData['events']['laserOn'] laserSpikeTimestamps = laserEphysData['spikeTimes'] timeRange = [-0.1, 0.4] plt.subplot(gs[0:2, 0:3]) laserSpikeTimesFromEventOnset, trialIndexForEachSpike, laserIndexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes( laserSpikeTimestamps, laserEventOnsetTimes, timeRange) pRaster, hcond, zline = extraplots.raster_plot(laserSpikeTimesFromEventOnset,laserIndexLimitsEachTrial,timeRange) plt.xlabel('Time from laser onset (sec)') plt.title('Laser Pulse Raster') # -- plot laser pulse psth -- plt.subplot(gs[2:4, 0:3]) binsize = 10/1000.0 spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes(laserSpikeTimestamps, laserEventOnsetTimes, [timeRange[0]-binsize, timeRange[1]]) binEdges = np.around(np.arange(timeRange[0]-binsize, timeRange[1]+2*binsize, binsize), decimals=2) spikeCountMat = spikesanalysis.spiketimes_to_spikecounts(spikeTimesFromEventOnset, indexLimitsEachTrial, binEdges) pPSTH = extraplots.plot_psth(spikeCountMat/binsize, 1, binEdges[:-1]) plt.xlim(timeRange) plt.xlabel('Time from laser onset (sec)') plt.ylabel('Firing Rate (Hz)') plt.title('Laser Pulse PSTH') # -- didn't record laser trains for some earlier sessions -- if len(cellObj.get_session_inds('laserTrain')) > 0: # -- plot laser train raster -- laserTrainEphysData, noBehav = cellObj.load('laserTrain') laserTrainEventOnsetTimes = laserTrainEphysData['events']['laserOn'] laserTrainSpikeTimestamps = laserTrainEphysData['spikeTimes'] laserTrainEventOnsetTimes = spikesanalysis.minimum_event_onset_diff(laserTrainEventOnsetTimes, 0.5) timeRange = [-0.2, 1.0] plt.subplot(gs[0:2, 3:]) spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes(laserTrainSpikeTimestamps, laserTrainEventOnsetTimes, timeRange) pRaster, hcond, zline = extraplots.raster_plot(spikeTimesFromEventOnset,indexLimitsEachTrial,timeRange) plt.xlabel('Time from laser onset (sec)') plt.title('Laser Train Raster') # -- plot laser train psth -- plt.subplot(gs[2:4, 3:]) binsize = 10/1000.0 spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes(laserTrainSpikeTimestamps, laserTrainEventOnsetTimes, [timeRange[0]-binsize, timeRange[1]]) binEdges = np.around(np.arange(timeRange[0]-binsize, timeRange[1]+2*binsize, binsize), decimals=2) spikeCountMat = spikesanalysis.spiketimes_to_spikecounts(spikeTimesFromEventOnset, indexLimitsEachTrial, binEdges) pPSTH = extraplots.plot_psth(spikeCountMat/binsize, 1, binEdges[:-1]) plt.xlim(timeRange) plt.xlabel('Time from laser onset (sec)') plt.ylabel('Firing Rate (Hz)') plt.title('Laser Train PSTH') # -- show cluster analysis -- #tsThisCluster, wavesThisCluster, recordingNumber = celldatabase.load_all_spikedata(cell) # -- Plot ISI histogram -- plt.subplot(gs[4+offset, 0:2]) spikesorting.plot_isi_loghist(bandSpikeTimestamps) # -- Plot waveforms -- plt.subplot(gs[4+offset, 2:4]) spikesorting.plot_waveforms(bandEphysData['samples']) # -- Plot events in time -- plt.subplot(gs[4+offset, 4:6]) spikesorting.plot_events_in_time(bandSpikeTimestamps) title = '{0}, {1}, {2}um, Tetrode {3}, Cluster {4}, {5}kHz, {6}Hz modulation'.format(cell['subject'], cell['date'], cell['depth'], tetrode, cluster, charfreq, modrate) plt.suptitle(title) fig_path = '/home/jarauser/Pictures/cell reports' fig_name = '{0}_{1}_{2}um_TT{3}Cluster{4}.png'.format(cell['subject'], cell['date'], cell['depth'], tetrode, cluster) full_fig_path = os.path.join(fig_path, fig_name) fig = plt.gcf() fig.set_size_inches(20, 25) fig.savefig(full_fig_path, format = 'png', bbox_inches='tight')
'tetrode': 4, 'cluster': 4 } #suppressed cell in SOM-ArchT mouse ] cellTypes = ['PV', 'SOM'] for indCell, oneCell in enumerate(cellList): # -- find the cell we want based on dictionary -- cellInd, dbRow = celldatabase.find_cell(db, **oneCell) cell = ephyscore.Cell(dbRow) bandEphysData, bandBData = cell.load_by_index(int( dbRow['bestBandSession'])) bandEventOnsetTimes = bandEphysData['events']['soundDetectorOn'] bandEventOnsetTimes = spikesanalysis.minimum_event_onset_diff( bandEventOnsetTimes, minEventOnsetDiff=0.2) bandSpikeTimestamps = bandEphysData['spikeTimes'] bandEachTrial = bandBData['currentBand'] numBands = np.unique(bandEachTrial) LaserEachTrial = bandBData['laserTrial'] numLaser = np.unique(LaserEachTrial) bandTrialsEachCond = behavioranalysis.find_trials_each_combination( bandEachTrial, numBands, LaserEachTrial, numLaser) bandTimeRange = [-0.5, 1.5] binsize = 50 #in milliseconds bandSpikeTimesFromEventOnset, trialIndexForEachSpike, bandIndexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes( bandSpikeTimestamps, bandEventOnsetTimes,
def plot_pinp_report(dbRow, saveDir=None, useModifiedClusters=True): #Init cell object cell = ephyscore.Cell(dbRow, useModifiedClusters=useModifiedClusters) plt.clf() gs = gridspec.GridSpec(11, 6) gs.update(left=0.15, right=0.95, bottom=0.15, wspace=1, hspace=1) if 'noiseburst' in dbRow['sessionType']: #DONE ax0 = plt.subplot(gs[0:2, 0:3]) ephysData, bdata = cell.load('noiseburst') eventOnsetTimes = ephysData['events']['stimOn'] timeRange = [-0.3, 0.5] (spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial) = spikesanalysis.eventlocked_spiketimes( ephysData['spikeTimes'], eventOnsetTimes, timeRange) pRaster, hCond, zLine = extraplots.raster_plot( spikeTimesFromEventOnset, indexLimitsEachTrial, timeRange) plt.setp(pRaster, ms=1) ax0.set_xlim(timeRange) ax0.set_xticks([]) #Laser pulse psth ax1 = plt.subplot(gs[4:6, 0:3]) win = np.array([0, 0.25, 0.75, 1, 0.75, 0.25, 0]) # scipy.signal.hanning(7) win = win / np.sum(win) binEdges = np.arange(timeRange[0], timeRange[-1], 0.001) timeVec = binEdges[ 1:] # FIXME: is this the best way to define the time axis? spikeCountMat = spikesanalysis.spiketimes_to_spikecounts( spikeTimesFromEventOnset, indexLimitsEachTrial, binEdges) avResp = np.mean(spikeCountMat, axis=0) smoothPSTH = np.convolve(avResp, win, mode='same') plt.plot(timeVec, smoothPSTH, 'k-', mec='none', lw=2) ax1.set_xlim(timeRange) ax1.set_xlabel('Time from noise onset (s)') if 'laserpulse' in dbRow['sessionType']: #DONE #Laser pulse raster ax0 = plt.subplot(gs[2:4, 0:3]) ephysData, bdata = cell.load('laserpulse') eventOnsetTimes = ephysData['events']['stimOn'] timeRange = [-0.3, 0.5] (spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial) = spikesanalysis.eventlocked_spiketimes( ephysData['spikeTimes'], eventOnsetTimes, timeRange) pRaster, hCond, zLine = extraplots.raster_plot( spikeTimesFromEventOnset, indexLimitsEachTrial, timeRange) plt.setp(pRaster, ms=1) ax0.set_xlim(timeRange) ax0.set_xticks([]) #Laser pulse psth ax1 = plt.subplot(gs[4:6, 0:3]) win = np.array([0, 0.25, 0.75, 1, 0.75, 0.25, 0]) # scipy.signal.hanning(7) win = win / np.sum(win) binEdges = np.arange(timeRange[0], timeRange[-1], 0.001) timeVec = binEdges[ 1:] # FIXME: is this the best way to define the time axis? spikeCountMat = spikesanalysis.spiketimes_to_spikecounts( spikeTimesFromEventOnset, indexLimitsEachTrial, binEdges) avResp = np.mean(spikeCountMat, axis=0) smoothPSTH = np.convolve(avResp, win, mode='same') plt.plot(timeVec, smoothPSTH, 'k-', mec='none', lw=2) ax1.set_xlim(timeRange) ax1.set_xlabel('Time from laser pulse onset (s)') if 'lasertrain' in dbRow['sessionType']: #DONE #Laser train raster ax2 = plt.subplot(gs[2:4, 3:6]) ephysData, bdata = cell.load('lasertrain') eventOnsetTimes = ephysData['events']['stimOn'] eventOnsetTimes = spikesanalysis.minimum_event_onset_diff( eventOnsetTimes, 0.5) timeRange = [-0.5, 1] pulseTimes = [0, 0.2, 0.4, 0.6, 0.8] (spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial) = spikesanalysis.eventlocked_spiketimes( ephysData['spikeTimes'], eventOnsetTimes, timeRange) pRaster, hCond, zLine = extraplots.raster_plot( spikeTimesFromEventOnset, indexLimitsEachTrial, timeRange) plt.setp(pRaster, ms=1) ax2.set_xlim(timeRange) ax2.set_xticks(pulseTimes) #Laser train psth ax3 = plt.subplot(gs[4:6, 3:6]) win = np.array([0, 0.25, 0.75, 1, 0.75, 0.25, 0]) # scipy.signal.hanning(7) win = win / np.sum(win) binEdges = np.arange(timeRange[0], timeRange[-1], 0.001) timeVec = binEdges[ 1:] # FIXME: is this the best way to define the time axis? spikeCountMat = spikesanalysis.spiketimes_to_spikecounts( spikeTimesFromEventOnset, indexLimitsEachTrial, binEdges) avResp = np.mean(spikeCountMat, axis=0) smoothPSTH = np.convolve(avResp, win, mode='same') plt.plot(timeVec, smoothPSTH, 'k-', mec='none', lw=2) ax3.set_xlim(timeRange) ax3.set_xticks(pulseTimes) ax3.set_xlabel('Time from first pulse onset (s)') #Sorted tuning raster if 'tc' in dbRow['sessionType']: #DONE ax4 = plt.subplot(gs[6:8, 0:3]) ephysData, bdata = cell.load('tc') eventOnsetTimes = ephysData['events']['stimOn'] timeRange = [-0.5, 1] (spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial) = spikesanalysis.eventlocked_spiketimes( ephysData['spikeTimes'], eventOnsetTimes, timeRange) freqEachTrial = bdata['currentFreq'] possibleFreq = np.unique(freqEachTrial) freqLabels = ['{0:.1f}'.format(freq / 1000.0) for freq in possibleFreq] trialsEachCondition = behavioranalysis.find_trials_each_type( freqEachTrial, possibleFreq) pRaster, hCond, zLine = extraplots.raster_plot( spikeTimesFromEventOnset, indexLimitsEachTrial, timeRange, trialsEachCond=trialsEachCondition, labels=freqLabels) plt.setp(pRaster, ms=1) ax4.set_ylabel('Frequency (kHz)') #TC heatmap ax5 = plt.subplot(gs[8:10, 0:3]) baseRange = [-0.1, 0] responseRange = [0, 0.1] alignmentRange = [baseRange[0], responseRange[1]] freqEachTrial = bdata['currentFreq'] possibleFreq = np.unique(freqEachTrial) intensityEachTrial = bdata['currentIntensity'] possibleIntensity = np.unique(intensityEachTrial) #Init arrays to hold the baseline and response spike counts per condition allIntenBase = np.array([]) allIntenResp = np.empty((len(possibleIntensity), len(possibleFreq))) spikeTimes = ephysData['spikeTimes'] for indinten, inten in enumerate(possibleIntensity): spks = np.array([]) freqs = np.array([]) base = np.array([]) for indfreq, freq in enumerate(possibleFreq): selectinds = np.flatnonzero((freqEachTrial == freq) & (intensityEachTrial == inten)) selectedOnsetTimes = eventOnsetTimes[selectinds] (spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial) = spikesanalysis.eventlocked_spiketimes( spikeTimes, selectedOnsetTimes, alignmentRange) nspkBase = spikesanalysis.spiketimes_to_spikecounts( spikeTimesFromEventOnset, indexLimitsEachTrial, baseRange) nspkResp = spikesanalysis.spiketimes_to_spikecounts( spikeTimesFromEventOnset, indexLimitsEachTrial, responseRange) base = np.concatenate([base, nspkBase.ravel()]) spks = np.concatenate([spks, nspkResp.ravel()]) # inds = np.concatenate([inds, np.ones(len(nspkResp.ravel()))*indfreq]) freqs = np.concatenate( [freqs, np.ones(len(nspkResp.ravel())) * freq]) allIntenBase = np.concatenate([allIntenBase, nspkBase.ravel()]) allIntenResp[indinten, indfreq] = np.mean(nspkResp) lowFreq = possibleFreq.min() highFreq = possibleFreq.max() nFreqLabels = 3 freqTickLocations = np.linspace(0, len(possibleFreq), nFreqLabels) freqs = np.logspace(np.log10(lowFreq), np.log10(highFreq), nFreqLabels) freqs = np.round(freqs, decimals=1) nIntenLabels = 3 intensities = np.linspace(possibleIntensity.min(), possibleIntensity.max(), nIntenLabels) intenTickLocations = np.linspace(0, len(possibleIntensity) - 1, nIntenLabels) plt.imshow(np.flipud(allIntenResp), interpolation='nearest', cmap='Blues') ax5.set_yticks(intenTickLocations) ax5.set_yticklabels(intensities[::-1]) ax5.set_xticks(freqTickLocations) freqLabels = ['{0:.1f}'.format(freq) for freq in freqs] # ax.set_xticklabels(freqLabels, rotation='vertical') ax5.set_xticklabels(freqLabels) ax5.set_xlabel('Frequency (kHz)') plt.ylabel('Intensity (db SPL)') if not pd.isnull(dbRow['threshold']): plt.hold(1) indThresh = (len(possibleIntensity) - 1) - np.where( dbRow['threshold'] == possibleIntensity)[0] indCF = np.where(dbRow['cf'] == possibleFreq)[0] # import ipdb; ipdb.set_trace() ax5.plot(indCF, indThresh, 'r*') plt.suptitle('Threshold: {}'.format(dbRow['threshold'])) if not pd.isnull(dbRow['upperFreq']): plt.hold(1) threshPlus10 = indThresh - (10 / np.diff(possibleIntensity)[0]) upperFraction = (np.log2(dbRow['upperFreq']) - np.log2( possibleFreq[0])) / (np.log2(possibleFreq[-1]) - np.log2(possibleFreq[0])) indUpper = upperFraction * (len(possibleFreq) - 1) lowerFraction = (np.log2(dbRow['lowerFreq']) - np.log2( possibleFreq[0])) / (np.log2(possibleFreq[-1]) - np.log2(possibleFreq[0])) indLower = lowerFraction * (len(possibleFreq) - 1) # import ipdb; ipdb.set_trace() ax5.plot(indUpper, threshPlus10, 'b*') ax5.plot(indLower, threshPlus10, 'b*') if 'am' in dbRow['sessionType']: #DONE #Sorted am raster # ax6 = plt.subplot(gs[4:6, 3:6]) ax6spec = gs[6:8, 3:6] ephysData, bdata = cell.load('am') eventOnsetTimes = ephysData['events']['stimOn'] colors = get_colors(len(np.unique(bdata['currentFreq']))) timeRange = [-0.5, 1] (spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial) = spikesanalysis.eventlocked_spiketimes( ephysData['spikeTimes'], eventOnsetTimes, timeRange) # extraplots.raster_plot(spikeTimesFromEventOnset, # indexLimitsEachTrial, # timeRange, # trialsEachCond=bdata['currentFreq'], # colorsEachCond=colors) plot_example_with_rate(ax6spec, spikeTimesFromEventOnset, indexLimitsEachTrial, bdata['currentFreq'], colorEachCond=colors, maxSyncRate=cell.dbRow['highestSyncCorrected']) #AM cycle average hist psthLineWidth = 2 ax7 = plt.subplot(gs[8:10, 3:6]) colorEachCond = colors plt.hold(True) sortArray = bdata['currentFreq'] for indFreq, (freq, spikeTimesThisFreq, trialIndicesThisFreq) in enumerate( spiketimes_each_frequency(spikeTimesFromEventOnset, trialIndexForEachSpike, sortArray)): radsPerSec = freq * 2 * np.pi spikeRads = (spikeTimesThisFreq * radsPerSec) % (2 * np.pi) ax7.hist(spikeRads, bins=20, color=colors[indFreq], histtype='step') #AM psth # psthLineWidth = 2 # ax7 = plt.subplot(gs[6:8, 3:6]) # colorEachCond = colors # binsize = 50 # sortArray = bdata['currentFreq'] # binsize = binsize/1000.0 # # If a sort array is supplied, find the trials that correspond to each value of the array # trialsEachCond = behavioranalysis.find_trials_each_type(sortArray, np.unique(sortArray)) # (spikeTimesFromEventOnset, # trialIndexForEachSpike, # indexLimitsEachTrial) = spikesanalysis.eventlocked_spiketimes(ephysData['spikeTimes'], # eventOnsetTimes, # [timeRange[0]-binsize, # timeRange[1]]) # binEdges = np.around(np.arange(timeRange[0]-binsize, timeRange[1]+2*binsize, binsize), decimals=2) # spikeCountMat = spikesanalysis.spiketimes_to_spikecounts(spikeTimesFromEventOnset, indexLimitsEachTrial, binEdges) # pPSTH = extraplots.plot_psth(spikeCountMat/binsize, 1, binEdges[:-1], trialsEachCond, colorEachCond=colors) # plt.setp(pPSTH, lw=psthLineWidth) # plt.hold(True) # zline = plt.axvline(0,color='0.75',zorder=-10) # plt.xlim(timeRange) (timestamps, samples, recordingNumber) = cell.load_all_spikedata() #ISI loghist ax8 = plt.subplot(gs[10, 0:2]) if timestamps is not None: try: spikesorting.plot_isi_loghist(timestamps) except: # raise AttributeError print "problem with isi vals" #Waveforms ax9 = plt.subplot(gs[10, 2:4]) if len(samples) > 0: spikesorting.plot_waveforms(samples) #Events in time ax10 = plt.subplot(gs[10, 4:6]) if timestamps is not None: try: spikesorting.plot_events_in_time(timestamps) except: print "problem with isi vals" fig = plt.gcf() fig.set_size_inches(8.5 * 2, 11 * 2) figName = '{}_{}_{}um_TT{}c{}.png'.format(dbRow['subject'], dbRow['date'], int(dbRow['depth']), int(dbRow['tetrode']), int(dbRow['cluster'])) plt.suptitle(figName[:-4]) if saveDir is not None: figPath = os.path.join(saveDir, figName) plt.savefig(figPath)