예제 #1
0
    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, '.')
예제 #2
0
    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, '.')
예제 #3
0
    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
예제 #5
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
예제 #6
0
    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')
예제 #7
0
    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')
예제 #10
0
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),
예제 #11
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
예제 #12
0
#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()
예제 #13
0
    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))
예제 #14
0
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
예제 #15
0
        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.
예제 #16
0
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')
예제 #17
0
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:
예제 #19
0
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)
예제 #20
0
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)
예제 #21
0
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
예제 #22
0
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')
예제 #23
0
        '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,
예제 #24
0
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)