예제 #1
0
def inactivation_base_stats(db, filename=''):
    laserTestStatistic = np.empty(len(db))
    laserPVal = np.empty(len(db))

    soundResponseTestStatistic = np.empty(len(db))
    soundResponsePVal = np.empty(len(db))
    onsetSoundResponseTestStatistic = np.empty(len(db))
    onsetSoundResponsePVal = np.empty(len(db))
    sustainedSoundResponseTestStatistic = np.empty(len(db))
    sustainedSoundResponsePVal = np.empty(len(db))

    gaussFit = []
    tuningTimeRange = []
    Rsquared = np.empty(len(db))
    prefFreq = np.empty(len(db))
    octavesFromPrefFreq = np.empty(len(db))
    bestBandSession = np.empty(len(db))

    for indRow, (dbIndex, dbRow) in enumerate(db.iterrows()):
        cellObj = ephyscore.Cell(dbRow)
        print "Now processing", dbRow['subject'], dbRow['date'], dbRow[
            'depth'], dbRow['tetrode'], dbRow['cluster']

        # --- Determine laser responsiveness of each cell (using first 100 ms of noise-in-laser trials) ---
        try:
            laserEphysData, noBehav = cellObj.load('lasernoisebursts')
        except IndexError:
            print "No laser pulse session for this cell"
            testStatistic = np.nan
            pVal = np.nan
            changeFR = np.nan
        else:
            testStatistic, pVal, changeFR = funcs.laser_response(
                laserEphysData,
                baseRange=[-0.3, -0.2],
                responseRange=[0.0, 0.1])
        laserTestStatistic[indRow] = testStatistic
        laserPVal[indRow] = pVal

        # --- Determine sound responsiveness during bandwidth sessions and calculate baseline firing rates with and without laser---
        #done in a kind of stupid way because regular and control sessions are handled the same way
        if any(session in dbRow['sessionType']
               for session in ['laserBandwidth', 'laserBandwidthControl']):
            if 'laserBandwidth' in dbRow['sessionType']:
                bandEphysData, bandBehavData = cellObj.load('laserBandwidth')
                behavSession = 'laserBandwidth'
                db.at[dbIndex, 'controlSession'] = 0
            elif 'laserBandwidthControl' in dbRow['sessionType']:
                bandEphysData, bandBehavData = cellObj.load(
                    'laserBandwidthControl')
                behavSession = 'laserBandwidthControl'
                db.at[dbIndex, 'controlSession'] = 1
            bandEventOnsetTimes = funcs.get_sound_onset_times(
                bandEphysData, 'bandwidth')
            bandSpikeTimestamps = bandEphysData['spikeTimes']
            bandEachTrial = bandBehavData['currentBand']
            secondSort = bandBehavData['laserTrial']
            numBands = np.unique(bandEachTrial)
            numSec = np.unique(secondSort)

            trialsEachComb = behavioranalysis.find_trials_each_combination(
                bandEachTrial, numBands, secondSort, numSec)
            trialsEachBaseCond = trialsEachComb[:, :,
                                                0]  #using no laser trials to determine sound responsiveness
            testStatistic, pVal = funcs.sound_response_any_stimulus(
                bandEventOnsetTimes, bandSpikeTimestamps, trialsEachBaseCond,
                [0.0, 1.0], [-1.2, -0.2])
            onsetTestStatistic, onsetpVal = funcs.sound_response_any_stimulus(
                bandEventOnsetTimes, bandSpikeTimestamps, trialsEachBaseCond,
                [0.0, 0.05], [-0.25, 0.2])
            sustainedTestStatistic, sustainedpVal = funcs.sound_response_any_stimulus(
                bandEventOnsetTimes, bandSpikeTimestamps, trialsEachBaseCond,
                [0.2, 1.0], [-1.0, 0.2])
            pVal *= len(numBands)  #correction for multiple comparisons
            onsetpVal *= len(numBands)
            sustainedpVal *= len(numBands)
            #pdb.set_trace()

            #find baselines with and without laser
            baselineRange = [-0.05, 0.0]
            baselineRates, baselineSEMs = funcs.inactivated_cells_baselines(
                bandSpikeTimestamps, bandEventOnsetTimes, secondSort,
                baselineRange)
            db.at[dbIndex, 'baselineFRnoLaser'] = baselineRates[0]
            db.at[dbIndex, 'baselineFRLaser'] = baselineRates[1]
            db.at[dbIndex, 'baselineFRnoLaserSEM'] = baselineSEMs[0]
            db.at[dbIndex, 'baselineFRLaserSEM'] = baselineSEMs[1]
            db.at[dbIndex,
                  'baselineChangeFR'] = baselineRates[1] - baselineRates[0]
        else:
            print "No bandwidth session for this cell"
            testStatistic = np.nan
            pVal = np.nan
            onsetTestStatistic = np.nan
            onsetpVal = np.nan
            sustainedTestStatistic = np.nan
            sustainedpVal = np.nan
            #pdb.set_trace()

        soundResponseTestStatistic[indRow] = testStatistic
        soundResponsePVal[indRow] = pVal
        onsetSoundResponseTestStatistic[indRow] = onsetTestStatistic
        onsetSoundResponsePVal[indRow] = onsetpVal
        sustainedSoundResponseTestStatistic[indRow] = sustainedTestStatistic
        sustainedSoundResponsePVal[indRow] = sustainedpVal

        # --- Determine frequency tuning of cells ---
        try:
            tuningEphysData, tuningBehavData = cellObj.load('tuningCurve')
        except IndexError:
            print "No tuning session for this cell"
            freqFit = np.full(4, np.nan)
            thisRsquared = np.nan
            bestFreq = np.nan
            tuningWindow = np.full(2, np.nan)
            octavesFromBest = np.nan
            bandIndex = np.nan
        else:
            tuningEventOnsetTimes = funcs.get_sound_onset_times(
                tuningEphysData, 'tuningCurve')
            tuningSpikeTimestamps = tuningEphysData['spikeTimes']
            freqEachTrial = tuningBehavData['currentFreq']
            intensityEachTrial = tuningBehavData['currentIntensity']
            numFreqs = np.unique(freqEachTrial)
            numIntensities = np.unique(intensityEachTrial)
            timeRange = [-0.2, 0.2]
            spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes(
                tuningSpikeTimestamps, tuningEventOnsetTimes, timeRange)
            trialsEachType = behavioranalysis.find_trials_each_type(
                intensityEachTrial, numIntensities)
            trialsHighInt = trialsEachType[:, -1]
            trialsEachComb = behavioranalysis.find_trials_each_combination(
                freqEachTrial, numFreqs, intensityEachTrial, numIntensities)
            trialsEachFreqHighInt = trialsEachComb[:, :, -1]
            tuningWindow = funcs.best_window_freq_tuning(
                spikeTimesFromEventOnset, indexLimitsEachTrial,
                trialsEachFreqHighInt)
            tuningWindow = np.array(tuningWindow)
            spikeCountMat = spikesanalysis.spiketimes_to_spikecounts(
                spikeTimesFromEventOnset, indexLimitsEachTrial, tuningWindow)
            tuningSpikeRates = (spikeCountMat[trialsHighInt].flatten()) / (
                tuningWindow[1] - tuningWindow[0])
            freqsThisIntensity = freqEachTrial[trialsHighInt]
            freqFit, thisRsquared = funcs.gaussian_tuning_fit(
                np.log2(freqsThisIntensity), tuningSpikeRates)
            if freqFit is not None:
                bestFreq = 2**freqFit[0]
                bandIndex, octavesFromBest = funcs.best_index(
                    cellObj, bestFreq, behavSession)
            else:
                freqFit = np.full(4, np.nan)
                bestFreq = np.nan
                bandIndex = np.nan
                octavesFromBest = np.nan
        gaussFit.append(freqFit)
        tuningTimeRange.append(tuningWindow)
        Rsquared[indRow] = thisRsquared
        prefFreq[indRow] = bestFreq
        octavesFromPrefFreq[indRow] = octavesFromBest
        bestBandSession[indRow] = bandIndex

    db['laserPVal'] = laserPVal
    db['laserUStat'] = laserTestStatistic

    db['soundResponseUStat'] = soundResponseTestStatistic
    db['soundResponsePVal'] = soundResponsePVal
    db['onsetSoundResponseUStat'] = onsetSoundResponseTestStatistic
    db['onsetSoundResponsePVal'] = onsetSoundResponsePVal
    db['sustainedSoundResponseUStat'] = sustainedSoundResponseTestStatistic
    db['sustainedSoundResponsePVal'] = sustainedSoundResponsePVal

    db['gaussFit'] = gaussFit
    db['tuningTimeRange'] = tuningTimeRange
    db['tuningFitR2'] = Rsquared
    db['prefFreq'] = prefFreq
    db['octavesFromPrefFreq'] = octavesFromPrefFreq
    db['bestBandSession'] = bestBandSession

    if len(filename) != 0:
        celldatabase.save_hdf(db, filename)
        print filename + " saved"

    return db
def photoID_base_stats(db, filename=''):
    '''
    This function takes as argument a pandas DataFrame and adds new columns.
    The filename should be the full path to where the database will be saved. If a filename is not specified, the database will not be saved.
    
    This function computed basic statistics for all clusters (e.g. laser responsiveness, sound responsiveness, preferred frequency).
    '''
    soundLoc = []
    NaKpeakLatency = np.empty(len(db))

    laserTestStatistic = np.empty(len(db))
    laserPVal = np.empty(len(db))
    laserTrainTestStatistic = np.empty(len(db))
    laserTrainPVal = np.empty(len(db))
    laserChangeFR = np.empty(len(db))

    soundResponseTestStatistic = np.empty(len(db))
    soundResponsePVal = np.empty(len(db))
    onsetSoundResponseTestStatistic = np.empty(len(db))
    onsetSoundResponsePVal = np.empty(len(db))
    sustainedSoundResponseTestStatistic = np.empty(len(db))
    sustainedSoundResponsePVal = np.empty(len(db))
    AMRate = np.empty(len(db))

    gaussFit = []
    tuningTimeRange = []
    Rsquared = np.empty(len(db))
    prefFreq = np.empty(len(db))
    octavesFromPrefFreq = np.empty(len(db))
    bestBandSession = np.empty(len(db))

    for indRow, (dbIndex, dbRow) in enumerate(db.iterrows()):
        cellObj = ephyscore.Cell(dbRow, useModifiedClusters=True)
        print "Now processing", dbRow['subject'], dbRow['date'], dbRow[
            'depth'], dbRow['tetrode'], dbRow['cluster']

        # --- Determine if sound presentation was ipsi or contra to recording location ---
        soundSide = dbRow['info'][2]
        recordingSide = dbRow['brainArea']

        if (soundSide == 'sound_left' and recordingSide == 'left_AC') or (
                soundSide == 'sound_right' and recordingSide == 'right_AC'):
            soundLoc.append('ipsi')
        else:
            soundLoc.append('contra')

        # --- Determine time difference between Na and K peak (spike width) ---
        peakTimes = dbRow['spikePeakTimes']
        latency = peakTimes[2] - peakTimes[1]
        NaKpeakLatency[indRow] = latency

        # --- Determine laser responsiveness of each cell (using laser pulse) ---
        try:
            laserEphysData, noBehav = cellObj.load('laserPulse')
        except IndexError:
            print "No laser pulse session for this cell"
            testStatistic = np.nan
            pVal = np.nan
            changeFR = np.nan
        else:
            testStatistic, pVal, changeFR = funcs.laser_response(
                laserEphysData)
        laserTestStatistic[indRow] = testStatistic
        laserPVal[indRow] = pVal
        laserChangeFR[indRow] = changeFR

        # --- Determine laser responsiveness of each cell (using laser train) ---
        try:
            laserTrainEphysData, noBehav = cellObj.load('laserTrain')
        except IndexError:
            print "No laser train session for this cell"
            testStatistic = np.nan
            pVal = np.nan
        else:
            testStatistic, pVal, changeFR = funcs.laser_response(
                laserTrainEphysData)
        laserTrainTestStatistic[indRow] = testStatistic
        laserTrainPVal[indRow] = pVal

        # --- Determine sound responsiveness during bandwidth sessions and other statistics about bandwidth session---
        try:
            bandEphysData, bandBehavData = cellObj.load('bandwidth')
        except IndexError:
            print "No bandwidth session for this cell"
            testStatistic = np.nan
            pVal = np.nan
            onsetTestStatistic = np.nan
            onsetpVal = np.nan
            sustainedTestStatistic = np.nan
            sustainedpVal = np.nan
            AM = np.nan
        else:
            bandEventOnsetTimes = funcs.get_sound_onset_times(
                bandEphysData, 'bandwidth')
            bandSpikeTimestamps = bandEphysData['spikeTimes']
            bandEachTrial = bandBehavData['currentBand']
            secondSort = bandBehavData['currentAmp']
            numBands = np.unique(bandEachTrial)
            numSec = np.unique(secondSort)
            AM = np.unique(bandBehavData['modRate'])

            trialsEachComb = behavioranalysis.find_trials_each_combination(
                bandEachTrial, numBands, secondSort, numSec)
            trialsEachBaseCond = trialsEachComb[:, :,
                                                -1]  #using high amp trials for photoidentified, no laser for inactivation
            testStatistic, pVal = funcs.sound_response_any_stimulus(
                bandEventOnsetTimes, bandSpikeTimestamps, trialsEachBaseCond,
                [0.0, 1.0], [-1.2, -0.2])
            onsetTestStatistic, onsetpVal = funcs.sound_response_any_stimulus(
                bandEventOnsetTimes, bandSpikeTimestamps, trialsEachBaseCond,
                [0.0, 0.05], [-0.25, 0.2])
            sustainedTestStatistic, sustainedpVal = funcs.sound_response_any_stimulus(
                bandEventOnsetTimes, bandSpikeTimestamps, trialsEachBaseCond,
                [0.2, 1.0], [-1.0, 0.2])
            pVal *= len(numSec)  #correction for multiple comparisons
            onsetpVal *= len(numSec)
            sustainedpVal *= len(numSec)

        soundResponseTestStatistic[indRow] = testStatistic
        soundResponsePVal[indRow] = pVal
        onsetSoundResponseTestStatistic[indRow] = onsetTestStatistic
        onsetSoundResponsePVal[indRow] = onsetpVal
        sustainedSoundResponseTestStatistic[indRow] = sustainedTestStatistic
        sustainedSoundResponsePVal[indRow] = sustainedpVal
        AMRate[indRow] = AM

        # --- Determine frequency tuning of cells ---
        try:
            tuningEphysData, tuningBehavData = cellObj.load('tuningCurve')
        except IndexError:
            print "No tuning session for this cell"
            freqFit = np.full(4, np.nan)
            thisRsquared = np.nan
            bestFreq = np.nan
            tuningWindow = [np.nan, np.nan]
            octavesFromBest = np.nan
            bandIndex = np.nan
        else:
            tuningEventOnsetTimes = funcs.get_sound_onset_times(
                tuningEphysData, 'tuningCurve')
            tuningSpikeTimestamps = tuningEphysData['spikeTimes']
            freqEachTrial = tuningBehavData['currentFreq']
            intensityEachTrial = tuningBehavData['currentIntensity']
            numFreqs = np.unique(freqEachTrial)
            numIntensities = np.unique(intensityEachTrial)
            timeRange = [-0.2, 0.2]
            spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes(
                tuningSpikeTimestamps, tuningEventOnsetTimes, timeRange)
            trialsEachType = behavioranalysis.find_trials_each_type(
                intensityEachTrial, numIntensities)
            trialsHighInt = trialsEachType[:, -1]
            trialsEachComb = behavioranalysis.find_trials_each_combination(
                freqEachTrial, numFreqs, intensityEachTrial, numIntensities)
            trialsEachFreqHighInt = trialsEachComb[:, :, -1]
            tuningWindow = funcs.best_window_freq_tuning(
                spikeTimesFromEventOnset, indexLimitsEachTrial,
                trialsEachFreqHighInt)
            spikeCountMat = spikesanalysis.spiketimes_to_spikecounts(
                spikeTimesFromEventOnset, indexLimitsEachTrial, tuningWindow)
            tuningSpikeRates = (spikeCountMat[trialsHighInt].flatten()) / (
                tuningWindow[1] - tuningWindow[0])
            freqsThisIntensity = freqEachTrial[trialsHighInt]
            freqFit, thisRsquared = funcs.gaussian_tuning_fit(
                np.log2(freqsThisIntensity), tuningSpikeRates)
            if freqFit is not None:
                bestFreq = 2**freqFit[0]
                bandIndex, octavesFromBest = funcs.best_index(
                    cellObj, bestFreq, 'bandwidth')
            else:
                freqFit = np.full(4, np.nan)
                bestFreq = np.nan
                bandIndex = np.nan
                octavesFromBest = np.nan
        gaussFit.append(freqFit)
        tuningTimeRange.append(tuningWindow)
        Rsquared[indRow] = thisRsquared
        prefFreq[indRow] = bestFreq
        octavesFromPrefFreq[indRow] = octavesFromBest
        bestBandSession[indRow] = bandIndex

    db['soundLocation'] = soundLoc
    db['spikeWidth'] = NaKpeakLatency
    db['AMRate'] = AMRate

    db['laserPVal'] = laserPVal
    db['laserUStat'] = laserTestStatistic
    db['laserTrainPVal'] = laserTrainPVal
    db['laserTrainUStat'] = laserTrainTestStatistic
    db['laserChangeFR'] = laserChangeFR

    db['soundResponseUStat'] = soundResponseTestStatistic
    db['soundResponsePVal'] = soundResponsePVal
    db['onsetSoundResponseUStat'] = onsetSoundResponseTestStatistic
    db['onsetSoundResponsePVal'] = onsetSoundResponsePVal
    db['sustainedSoundResponseUStat'] = sustainedSoundResponseTestStatistic
    db['sustainedSoundResponsePVal'] = sustainedSoundResponsePVal

    db['gaussFit'] = gaussFit
    db['tuningTimeRange'] = tuningTimeRange
    db['tuningFitR2'] = Rsquared
    db['prefFreq'] = prefFreq
    db['octavesFromPrefFreq'] = octavesFromPrefFreq
    db['bestBandSession'] = bestBandSession

    if len(filename) != 0:
        celldatabase.save_hdf(db, filename)
        print filename + " saved"

    return db
예제 #3
0
def inactivation_database(db,
                          baseStats=False,
                          computeIndices=True,
                          filename='inactivation_cells.h5'):
    if type(db) == str:
        dbPath = os.path.join(settings.DATABASE_PATH, db)
        db = celldatabase.load_hdf(dbPath)

    if baseStats:
        soundResponseTestStatistic = np.empty(len(db))
        soundResponsePVal = np.empty(len(db))
        onsetSoundResponseTestStatistic = np.empty(len(db))
        onsetSoundResponsePVal = np.empty(len(db))
        sustainedSoundResponseTestStatistic = np.empty(len(db))
        sustainedSoundResponsePVal = np.empty(len(db))

        gaussFit = []
        tuningTimeRange = []
        Rsquared = np.empty(len(db))
        prefFreq = np.empty(len(db))
        octavesFromPrefFreq = np.empty(len(db))
        bestBandSession = np.empty(len(db))

        for indRow, (dbIndex, dbRow) in enumerate(db.iterrows()):
            cellObj = ephyscore.Cell(dbRow)
            print "Now processing", dbRow['subject'], dbRow['date'], dbRow[
                'depth'], dbRow['tetrode'], dbRow['cluster']

            # --- Determine sound responsiveness during bandwidth sessions and calculate baseline firing rates with and without laser---
            #done in a kind of stupid way because regular and control sessions are handled the same way
            if any(session in dbRow['sessionType']
                   for session in ['laserBandwidth', 'laserBandwidthControl']):
                if 'laserBandwidth' in dbRow['sessionType']:
                    bandEphysData, bandBehavData = cellObj.load(
                        'laserBandwidth')
                    behavSession = 'laserBandwidth'
                    db.at[dbIndex, 'controlSession'] = 0
                elif 'laserBandwidthControl' in dbRow['sessionType']:
                    bandEphysData, bandBehavData = cellObj.load(
                        'laserBandwidthControl')
                    behavSession = 'laserBandwidthControl'
                    db.at[dbIndex, 'controlSession'] = 1
                bandEventOnsetTimes = funcs.get_sound_onset_times(
                    bandEphysData, 'bandwidth')
                bandSpikeTimestamps = bandEphysData['spikeTimes']
                bandEachTrial = bandBehavData['currentBand']
                secondSort = bandBehavData['laserTrial']
                numBands = np.unique(bandEachTrial)
                numSec = np.unique(secondSort)

                trialsEachComb = behavioranalysis.find_trials_each_combination(
                    bandEachTrial, numBands, secondSort, numSec)
                trialsEachBaseCond = trialsEachComb[:, :,
                                                    0]  #using no laser trials to determine sound responsiveness
                testStatistic, pVal = funcs.sound_response_any_stimulus(
                    bandEventOnsetTimes, bandSpikeTimestamps,
                    trialsEachBaseCond, [0.0, 1.0], [-1.2, -0.2])
                onsetTestStatistic, onsetpVal = funcs.sound_response_any_stimulus(
                    bandEventOnsetTimes, bandSpikeTimestamps,
                    trialsEachBaseCond, [0.0, 0.05], [-0.25, 0.2])
                sustainedTestStatistic, sustainedpVal = funcs.sound_response_any_stimulus(
                    bandEventOnsetTimes, bandSpikeTimestamps,
                    trialsEachBaseCond, [0.2, 1.0], [-1.0, 0.2])
                pVal *= len(numBands)  #correction for multiple comparisons
                onsetpVal *= len(numBands)
                sustainedpVal *= len(numBands)
                #pdb.set_trace()

                #find baselines with and without laser
                baselineRange = [-0.05, 0.0]
                baselineRates, baselineSEMs = funcs.inactivated_cells_baselines(
                    bandSpikeTimestamps, bandEventOnsetTimes, secondSort,
                    baselineRange)
                db.at[dbIndex, 'baselineFRnoLaser'] = baselineRates[0]
                db.at[dbIndex, 'baselineFRLaser'] = baselineRates[1]
                db.at[dbIndex, 'baselineFRnoLaserSEM'] = baselineSEMs[0]
                db.at[dbIndex, 'baselineFRLaserSEM'] = baselineSEMs[1]
                db.at[dbIndex,
                      'baselineChangeFR'] = baselineRates[1] - baselineRates[0]
            else:
                print "No bandwidth session for this cell"
                testStatistic = np.nan
                pVal = np.nan
                onsetTestStatistic = np.nan
                onsetpVal = np.nan
                sustainedTestStatistic = np.nan
                sustainedpVal = np.nan
                #pdb.set_trace()

            soundResponseTestStatistic[indRow] = testStatistic
            soundResponsePVal[indRow] = pVal
            onsetSoundResponseTestStatistic[indRow] = onsetTestStatistic
            onsetSoundResponsePVal[indRow] = onsetpVal
            sustainedSoundResponseTestStatistic[
                indRow] = sustainedTestStatistic
            sustainedSoundResponsePVal[indRow] = sustainedpVal

            # --- Determine frequency tuning of cells ---
            try:
                tuningEphysData, tuningBehavData = cellObj.load('tuningCurve')
            except IndexError:
                print "No tuning session for this cell"
                freqFit = np.full(4, np.nan)
                thisRsquared = np.nan
                bestFreq = np.nan
                tuningWindow = np.full(2, np.nan)
                octavesFromBest = np.nan
                bandIndex = np.nan
            else:
                tuningEventOnsetTimes = funcs.get_sound_onset_times(
                    tuningEphysData, 'tuningCurve')
                tuningSpikeTimestamps = tuningEphysData['spikeTimes']
                freqEachTrial = tuningBehavData['currentFreq']
                intensityEachTrial = tuningBehavData['currentIntensity']
                numFreqs = np.unique(freqEachTrial)
                numIntensities = np.unique(intensityEachTrial)
                timeRange = [-0.2, 0.2]
                spikeTimesFromEventOnset, trialIndexForEachSpike, indexLimitsEachTrial = spikesanalysis.eventlocked_spiketimes(
                    tuningSpikeTimestamps, tuningEventOnsetTimes, timeRange)
                trialsEachType = behavioranalysis.find_trials_each_type(
                    intensityEachTrial, numIntensities)
                trialsHighInt = trialsEachType[:, -1]
                trialsEachComb = behavioranalysis.find_trials_each_combination(
                    freqEachTrial, numFreqs, intensityEachTrial,
                    numIntensities)
                trialsEachFreqHighInt = trialsEachComb[:, :, -1]
                tuningWindow = funcs.best_window_freq_tuning(
                    spikeTimesFromEventOnset, indexLimitsEachTrial,
                    trialsEachFreqHighInt)
                tuningWindow = np.array(tuningWindow)
                spikeCountMat = spikesanalysis.spiketimes_to_spikecounts(
                    spikeTimesFromEventOnset, indexLimitsEachTrial,
                    tuningWindow)
                tuningSpikeRates = (spikeCountMat[trialsHighInt].flatten()) / (
                    tuningWindow[1] - tuningWindow[0])
                freqsThisIntensity = freqEachTrial[trialsHighInt]
                freqFit, thisRsquared = funcs.gaussian_tuning_fit(
                    np.log2(freqsThisIntensity), tuningSpikeRates)
                if freqFit is not None:
                    bestFreq = 2**freqFit[0]
                    bandIndex, octavesFromBest = funcs.best_index(
                        cellObj, bestFreq, behavSession)
                else:
                    freqFit = np.full(4, np.nan)
                    bestFreq = np.nan
                    bandIndex = np.nan
                    octavesFromBest = np.nan
            gaussFit.append(freqFit)
            tuningTimeRange.append(tuningWindow)
            Rsquared[indRow] = thisRsquared
            prefFreq[indRow] = bestFreq
            octavesFromPrefFreq[indRow] = octavesFromBest
            bestBandSession[indRow] = bandIndex

        db['soundResponseUStat'] = soundResponseTestStatistic
        db['soundResponsePVal'] = soundResponsePVal
        db['onsetSoundResponseUStat'] = onsetSoundResponseTestStatistic
        db['onsetSoundResponsePVal'] = onsetSoundResponsePVal
        db['sustainedSoundResponseUStat'] = sustainedSoundResponseTestStatistic
        db['sustainedSoundResponsePVal'] = sustainedSoundResponsePVal

        db['gaussFit'] = gaussFit
        db['tuningTimeRange'] = tuningTimeRange
        db['tuningFitR2'] = Rsquared
        db['prefFreq'] = prefFreq
        db['octavesFromPrefFreq'] = octavesFromPrefFreq
        db['bestBandSession'] = bestBandSession

    if computeIndices:
        bestCells = db.query("isiViolations<0.02")  # or modifiedISI<0.02")
        bestCells = bestCells.loc[bestCells['spikeShapeQuality'] > 2]
        bestCells = bestCells.query(
            'soundResponsePVal<0.05 or onsetSoundResponsePVal<0.05 or sustainedSoundResponsePVal<0.05'
        )
        bestCells = bestCells.loc[bestCells['tuningFitR2'] > R2CUTOFF]
        bestCells = bestCells.loc[
            bestCells['octavesFromPrefFreq'] < OCTAVESCUTOFF]

        for dbIndex, dbRow in bestCells.iterrows():

            cell = ephyscore.Cell(dbRow)

            bandEphysData, bandBehavData = cell.load_by_index(
                int(dbRow['bestBandSession']))
            bandEventOnsetTimes = funcs.get_sound_onset_times(
                bandEphysData, 'bandwidth')
            bandSpikeTimestamps = bandEphysData['spikeTimes']

            bandEachTrial = bandBehavData['currentBand']
            secondSort = bandBehavData['laserTrial']

            propOnset, propSustained = funcs.onset_sustained_spike_proportion(
                bandSpikeTimestamps, bandEventOnsetTimes)

            db.at[dbIndex, 'proportionSpikesOnset'] = propOnset
            db.at[dbIndex, 'proportionSpikesSustained'] = propSustained

            #by default: not subtracting baseline, but are replacing pure tone response with baseline for 0 bw condition
            onsetSupInds, onsetSupIndpVals, onsetFacInds, onsetFacIndpVals, onsetPeakInds, onsetSpikeArray = funcs.bandwidth_suppression_from_peak(
                bandSpikeTimestamps,
                bandEventOnsetTimes,
                bandEachTrial,
                secondSort,
                timeRange=[0.0, 0.05],
                baseRange=[-0.05, 0.0])
            db.at[dbIndex, 'onsetSuppressionIndexLaser'] = onsetSupInds[-1]
            db.at[dbIndex, 'onsetSuppressionpValLaser'] = onsetSupIndpVals[-1]
            db.at[dbIndex, 'onsetFacilitationIndexLaser'] = onsetFacInds[-1]
            db.at[dbIndex, 'onsetFacilitationpValLaser'] = onsetFacIndpVals[-1]
            db.at[dbIndex,
                  'onsetPrefBandwidthLaser'] = bandEachTrial[onsetPeakInds[-1]]

            db.at[dbIndex, 'onsetSuppressionIndexNoLaser'] = onsetSupInds[0]
            db.at[dbIndex, 'onsetSuppressionpValNoLaser'] = onsetSupIndpVals[0]
            db.at[dbIndex, 'onsetFacilitationIndexNoLaser'] = onsetFacInds[0]
            db.at[dbIndex,
                  'onsetFacilitationpValNoLaser'] = onsetFacIndpVals[0]
            db.at[dbIndex, 'onsetPrefBandwidthNoLaser'] = bandEachTrial[
                onsetPeakInds[0]]

            #base range is right before sound onset so we get estimate for laser baseline
            sustainedSupInds, sustainedSupIndpVals, sustainedFacInds, sustainedFacIndpVals, sustainedPeakInds, sustainedSpikeArray = funcs.bandwidth_suppression_from_peak(
                bandSpikeTimestamps,
                bandEventOnsetTimes,
                bandEachTrial,
                secondSort,
                timeRange=[0.2, 1.0],
                baseRange=[-0.05, 0.0])
            db.at[dbIndex,
                  'sustainedSuppressionIndexLaser'] = sustainedSupInds[-1]
            db.at[dbIndex,
                  'sustainedSuppressionpValLaser'] = sustainedSupIndpVals[-1]
            db.at[dbIndex,
                  'sustainedFacilitationIndexLaser'] = sustainedFacInds[-1]
            db.at[dbIndex,
                  'sustainedFacilitationpValLaser'] = sustainedFacIndpVals[-1]
            db.at[dbIndex, 'sustainedPrefBandwidthLaser'] = bandEachTrial[
                sustainedPeakInds[-1]]

            db.at[dbIndex,
                  'sustainedSuppressionIndexNoLaser'] = sustainedSupInds[0]
            db.at[dbIndex,
                  'sustainedSuppressionpValNoLaser'] = sustainedSupIndpVals[0]
            db.at[dbIndex,
                  'sustainedFacilitationIndexNoLaser'] = sustainedFacInds[0]
            db.at[dbIndex,
                  'sustainedFacilitationpValNoLaser'] = sustainedFacIndpVals[0]
            db.at[dbIndex, 'sustainedPrefBandwidthNoLaser'] = bandEachTrial[
                sustainedPeakInds[0]]

            #no laser fit
            sustainedResponseNoLaser = sustainedSpikeArray[:, 0]

            bandsForFit = np.unique(bandEachTrial)
            bandsForFit[-1] = 6
            mFixed = 1

            fitParams, R2 = fitfuncs.diff_of_gauss_fit(
                bandsForFit, sustainedResponseNoLaser, mFixed=mFixed)

            #fit params
            db.at[dbIndex, 'R0noLaser'] = fitParams[0]
            db.at[dbIndex, 'RDnoLaser'] = fitParams[3]
            db.at[dbIndex, 'RSnoLaser'] = fitParams[4]
            db.at[dbIndex, 'mnoLaser'] = mFixed
            db.at[dbIndex, 'sigmaDnoLaser'] = fitParams[1]
            db.at[dbIndex, 'sigmaSnoLaser'] = fitParams[2]
            db.at[dbIndex, 'bandwidthTuningR2noLaser'] = R2

            testBands = np.linspace(bandsForFit[0], bandsForFit[-1], 500)
            allFitParams = [mFixed]
            allFitParams.extend(fitParams)
            suppInd, prefBW = fitfuncs.extract_stats_from_fit(
                allFitParams, testBands)

            db.at[dbIndex, 'fitSustainedSuppressionIndexNoLaser'] = suppInd
            db.at[dbIndex, 'fitSustainedPrefBandwidthNoLaser'] = prefBW

            #laser fit
            sustainedResponseLaser = sustainedSpikeArray[:, 1]

            fitParamsLaser, R2Laser = fitfuncs.diff_of_gauss_fit(
                bandsForFit, sustainedResponseLaser, mFixed=mFixed)

            #fit params
            db.at[dbIndex, 'R0laser'] = fitParamsLaser[0]
            db.at[dbIndex, 'RDlaser'] = fitParamsLaser[3]
            db.at[dbIndex, 'RSlaser'] = fitParamsLaser[4]
            db.at[dbIndex, 'mlaser'] = mFixed
            db.at[dbIndex, 'sigmaDlaser'] = fitParamsLaser[1]
            db.at[dbIndex, 'sigmaSlaser'] = fitParamsLaser[2]
            db.at[dbIndex, 'bandwidthTuningR2laser'] = R2Laser

            allFitParamsLaser = [mFixed]
            allFitParamsLaser.extend(fitParamsLaser)
            suppIndLaser, prefBWLaser = fitfuncs.extract_stats_from_fit(
                allFitParamsLaser, testBands)

            db.at[dbIndex, 'fitSustainedSuppressionIndexLaser'] = suppIndLaser
            db.at[dbIndex, 'fitSustainedPrefBandwidthLaser'] = prefBWLaser

            meanLaserDiff = np.mean(sustainedResponseLaser -
                                    sustainedResponseNoLaser)
            db.at[dbIndex, 'laserChangeResponse'] = meanLaserDiff

            laserDiff = sustainedResponseLaser - sustainedResponseNoLaser
            peakInd = np.argmax(sustainedResponseNoLaser)

            db.at[dbIndex, 'peakChangeFR'] = laserDiff[peakInd]
            db.at[dbIndex, 'WNChangeFR'] = laserDiff[-1]

            testRespsNoLaser = fitfuncs.diff_gauss_form(
                testBands, *allFitParams)
            testRespsLaser = fitfuncs.diff_gauss_form(testBands,
                                                      *allFitParamsLaser)

            laserDiffModel = testRespsLaser - testRespsNoLaser
            peakIndModel = np.argmax(testRespsNoLaser)

            db.at[dbIndex, 'fitPeakChangeFR'] = laserDiffModel[peakIndModel]
            db.at[dbIndex, 'fitWNChangeFR'] = laserDiffModel[-1]

            #also calculating fits and suppression with pure tone being 0 bw condition
            toneSustainedSupInds, toneSustainedSupIndpVals, toneSustainedFacInds, toneSustainedFacIndpVals, toneSustainedPeakInds, toneSustainedSpikeArray = funcs.bandwidth_suppression_from_peak(
                bandSpikeTimestamps,
                bandEventOnsetTimes,
                bandEachTrial,
                secondSort,
                timeRange=[0.2, 1.0],
                baseRange=[-0.05, 0.0],
                zeroBWBaseline=False)
            db.at[
                dbIndex,
                'sustainedSuppressionIndexNoLaserPureTone'] = toneSustainedSupInds[
                    0]
            db.at[
                dbIndex,
                'sustainedSuppressionpValNoLaserPureTone'] = toneSustainedSupIndpVals[
                    0]
            db.at[
                dbIndex,
                'sustainedFacilitationIndexNoLaserPureTone'] = toneSustainedFacInds[
                    0]
            db.at[
                dbIndex,
                'sustainedFacilitationpValNoLaserPureTone'] = toneSustainedFacIndpVals[
                    0]
            db.at[dbIndex,
                  'sustainedPrefBandwidthNoLaserPureTone'] = bandEachTrial[
                      toneSustainedPeakInds[0]]

            db.at[
                dbIndex,
                'sustainedSuppressionIndexLaserPureTone'] = toneSustainedSupInds[
                    -1]
            db.at[
                dbIndex,
                'sustainedSuppressionpValLaserPureTone'] = toneSustainedSupIndpVals[
                    -1]
            db.at[
                dbIndex,
                'sustainedFacilitationIndexLaserPureTone'] = toneSustainedFacInds[
                    -1]
            db.at[
                dbIndex,
                'sustainedFacilitationpValLaserPureTone'] = toneSustainedFacIndpVals[
                    -1]
            db.at[dbIndex,
                  'sustainedPrefBandwidthLaserPureTone'] = bandEachTrial[
                      toneSustainedPeakInds[-1]]

            toneSustainedResponseNoLaser = toneSustainedSpikeArray[:, 0]

            toneFitParamsNoLaser, toneR2 = fitfuncs.diff_of_gauss_fit(
                bandsForFit, toneSustainedResponseNoLaser, mFixed=mFixed)

            #fit params
            db.at[dbIndex, 'R0PureToneNoLaser'] = toneFitParamsNoLaser[0]
            db.at[dbIndex, 'RDPureToneNoLaser'] = toneFitParamsNoLaser[3]
            db.at[dbIndex, 'RSPureToneNoLaser'] = toneFitParamsNoLaser[4]
            db.at[dbIndex, 'mPureToneNoLaser'] = mFixed
            db.at[dbIndex, 'sigmaDPureToneNoLaser'] = toneFitParamsNoLaser[1]
            db.at[dbIndex, 'sigmaSPureToneNoLaser'] = toneFitParamsNoLaser[2]
            db.at[dbIndex, 'bandwidthTuningR2PureToneNoLaser'] = toneR2

            allFitParamsToneNoLaser = [mFixed]
            allFitParamsToneNoLaser.extend(toneFitParamsNoLaser)
            suppIndTone, prefBWTone = fitfuncs.extract_stats_from_fit(
                allFitParamsToneNoLaser, testBands)

            db.at[dbIndex,
                  'fitSustainedSuppressionIndexPureToneNoLaser'] = suppIndTone
            db.at[dbIndex,
                  'fitSustainedPrefBandwidthPureToneNoLaser'] = prefBWTone

            toneSustainedResponseLaser = toneSustainedSpikeArray[:, 1]

            toneFitParamsLaser, toneR2Laser = fitfuncs.diff_of_gauss_fit(
                bandsForFit, toneSustainedResponseLaser, mFixed=mFixed)

            #fit params
            db.at[dbIndex, 'R0PureToneLaser'] = toneFitParamsLaser[0]
            db.at[dbIndex, 'RDPureToneLaser'] = toneFitParamsLaser[3]
            db.at[dbIndex, 'RSPureToneLaser'] = toneFitParamsLaser[4]
            db.at[dbIndex, 'mPureToneLaser'] = mFixed
            db.at[dbIndex, 'sigmaDPureToneLaser'] = toneFitParamsLaser[1]
            db.at[dbIndex, 'sigmaSPureToneLaser'] = toneFitParamsLaser[2]
            db.at[dbIndex, 'bandwidthTuningR2PureToneLaser'] = toneR2Laser

            allFitParamsToneLaser = [mFixed]
            allFitParamsToneLaser.extend(toneFitParamsLaser)
            suppIndToneLaser, prefBWToneLaser = fitfuncs.extract_stats_from_fit(
                allFitParamsToneLaser, testBands)

            db.at[
                dbIndex,
                'fitSustainedSuppressionIndexPureToneLaser'] = suppIndToneLaser
            db.at[dbIndex,
                  'fitSustainedPrefBandwidthPureToneLaser'] = prefBWToneLaser

            testRespsNoLaser = fitfuncs.diff_gauss_form(
                testBands, *allFitParamsToneNoLaser)
            testRespsLaser = fitfuncs.diff_gauss_form(testBands,
                                                      *allFitParamsToneLaser)

            laserDiffModel = testRespsLaser - testRespsNoLaser
            peakIndModel = np.argmax(testRespsNoLaser)

            db.at[dbIndex,
                  'fitPeakChangeFRPureTone'] = laserDiffModel[peakIndModel]
            db.at[dbIndex, 'fitWNChangeFRPureTone'] = laserDiffModel[-1]

            #also calculating fits and suppression with nothing being fit for bw 0
            noZeroSustainedResponseNoLaser = sustainedSpikeArray[1:, 0]
            bandsForFitNoZero = bandsForFit[1:]

            noZeroFitParamsNoLaser, noZeroR2 = fitfuncs.diff_of_gauss_fit(
                bandsForFitNoZero,
                noZeroSustainedResponseNoLaser,
                mFixed=mFixed)

            #fit params
            db.at[dbIndex, 'R0noZeroNoLaser'] = noZeroFitParamsNoLaser[0]
            db.at[dbIndex, 'RDnoZeroNoLaser'] = noZeroFitParamsNoLaser[3]
            db.at[dbIndex, 'RSnoZeroNoLaser'] = noZeroFitParamsNoLaser[4]
            db.at[dbIndex, 'mnoZeroNoLaser'] = mFixed
            db.at[dbIndex, 'sigmaDnoZeroNoLaser'] = noZeroFitParamsNoLaser[1]
            db.at[dbIndex, 'sigmaSnoZeroNoLaser'] = noZeroFitParamsNoLaser[2]
            db.at[dbIndex, 'bandwidthTuningR2noZeroNoLaser'] = noZeroR2

            allFitParamsNoZero = [mFixed]
            allFitParamsNoZero.extend(noZeroFitParamsNoLaser)
            testBandsNoZero = np.linspace(bandsForFitNoZero[0],
                                          bandsForFitNoZero[-1], 500)
            suppIndNoZero, prefBWNoZero = fitfuncs.extract_stats_from_fit(
                allFitParamsNoZero, testBandsNoZero)

            db.at[dbIndex,
                  'fitSustainedSuppressionIndexNoZeroNoLaser'] = suppIndNoZero
            db.at[dbIndex,
                  'fitSustainedPrefBandwidthNoZeroNoLaser'] = prefBWNoZero

            noZeroSustainedResponseLaser = sustainedSpikeArray[1:, 1]
            bandsForFitNoZero = bandsForFit[1:]

            noZeroFitParamsLaser, noZeroR2Laser = fitfuncs.diff_of_gauss_fit(
                bandsForFitNoZero, noZeroSustainedResponseLaser, mFixed=mFixed)

            #fit params
            db.at[dbIndex, 'R0noZeroLaser'] = noZeroFitParamsLaser[0]
            db.at[dbIndex, 'RDnoZeroLaser'] = noZeroFitParamsLaser[3]
            db.at[dbIndex, 'RSnoZeroLaser'] = noZeroFitParamsLaser[4]
            db.at[dbIndex, 'mnoZeroLaser'] = mFixed
            db.at[dbIndex, 'sigmaDnoZeroLaser'] = noZeroFitParamsLaser[1]
            db.at[dbIndex, 'sigmaSnoZeroLaser'] = noZeroFitParamsLaser[2]
            db.at[dbIndex, 'bandwidthTuningR2noZeroLaser'] = noZeroR2Laser

            allFitParamsNoZeroLaser = [mFixed]
            allFitParamsNoZeroLaser.extend(noZeroFitParamsLaser)
            suppIndNoZeroLaser, prefBWNoZeroLaser = fitfuncs.extract_stats_from_fit(
                allFitParamsNoZeroLaser, testBandsNoZero)

            db.at[
                dbIndex,
                'fitSustainedSuppressionIndexNoZeroLaser'] = suppIndNoZeroLaser
            db.at[dbIndex,
                  'fitSustainedPrefBandwidthNoZeroLaser'] = prefBWNoZeroLaser

            testRespsNoLaser = fitfuncs.diff_gauss_form(
                testBandsNoZero, *allFitParamsNoZero)
            testRespsLaser = fitfuncs.diff_gauss_form(testBandsNoZero,
                                                      *allFitParamsNoZeroLaser)

            laserDiffModel = testRespsLaser - testRespsNoLaser
            peakIndModel = np.argmax(testRespsNoLaser)

            db.at[dbIndex,
                  'fitPeakChangeFRNoZero'] = laserDiffModel[peakIndModel]
            db.at[dbIndex, 'fitWNChangeFRNoZero'] = laserDiffModel[-1]

    if len(filename) != 0:
        celldatabase.save_hdf(db, dbFilename)
        # 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(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

        if toCalculate:
            ttZStat, ttPVal = \
                funcs.sound_response_any_stimulus(ttEventOnsetTimes, ttSpikeTimes, tuningTrialsEachCond[:, :, -1],
                                                  timeRange=[0.0, 0.05], baseRange=baseRange)

            for indInten, intensity in enumerate(uniqueIntensity):
                spks = np.array([])
                freqs = np.array([])
                popts = []
                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(
                        ttEventOnsetTimes,
                        ttSpikeTimes,
예제 #5
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