trialStimStartFrames = d['trialStimStartFrame'][:trialEndFrames.size]
trialRewardDirection = d['trialRewardDir'][:trialEndFrames.size]
trialResponse = d['trialResponse'][:trialEndFrames.size]
deltaWheel = d['deltaWheelPos'][:]
trialOpenLoopFrames = d['trialOpenLoopFrames'][:]
trialResponseFrames = d['trialResponseFrame'][:]
trialMaskOnset = d['trialMaskOnset'][:]
maskContrast = d['trialMaskContrast'][:]

preStimFrames = trialStimStartFrames-trialStartFrames if 'trialStimStartFrame' in d else np.array([d['preStimFrames'][:]]*trialStartFrames.size)

trialStartFrames += preStimFrames    
    
nogo = d['trialTargetFrames'][:-1]==0

ignoreTrials = ignore_trials(d)

postTrialFrames = 0 if d['postRewardTargetFrames'][()]>0 else 1 #make sure we have at least one frame after the reward

data = list(zip(trialRewardDirection, trialResponse, trialStartFrames, 
                trialStimStartFrame, trialResponseFrame, trialEndFrames,
                trialMaskOnset, maskContrast))
index = range(len(trialResponse))

df = pd.DataFrame(data, index=index, columns=['rewDir', 'resp', 'trialStart', 'stimStart', 'respFrame', 'endFrame', 'soa', 'mask'])


fig, ax = plt.subplots()

# turnRightTrials == stim presented on L, turn right - viceversa for turnLeftTrials - or for orientation, turn right
nogoTrials = []
Пример #2
0
def session(data, ignoreRepeats=True, printValues=True):

    d = data

    def count(resp, direction):
        return len(trialResponse[(trialResponse == resp)
                                 & (trialRewardDirection == direction) &
                                 (trialTargetFrames != 0)])

    trialResponse = d['trialResponse'][:]
    trialRewardDirection = d['trialRewardDir'][:len(trialResponse)]
    trialTargetFrames = d['trialTargetFrames'][:len(trialResponse)]
    trialMaskContrast = d['trialMaskContrast'][:len(trialResponse)]

    trialRewards = 0

    for trial in trialResponse:
        if trial == 1:
            trialRewards += 1

    if ignoreRepeats == True:

        trialResponseOG = trialResponse
        if 'trialRepeat' in d.keys():
            prevTrialIncorrect = d['trialRepeat'][:len(trialResponse)]
        else:
            prevTrialIncorrect = np.concatenate(
                ([False], trialResponseOG[:-1] < 1))
        trialResponse = trialResponseOG[prevTrialIncorrect == False]
        trialRewardDirection = trialRewardDirection[prevTrialIncorrect ==
                                                    False]
        trialTargetFrames = trialTargetFrames[prevTrialIncorrect == False]
        trialMaskContrast = trialMaskContrast[prevTrialIncorrect == False]
        print('Repeats: ' +
              (str((len(trialResponseOG) - len(trialResponse)))) + '/' +
              str(len(trialResponseOG)))
        print((round(len(trialResponseOG) - len(trialResponse)) /
               len(trialResponseOG)))

    elif ignoreRepeats == False:
        trialResponse = d['trialResponse'][:]
        #nogo_turn(d, ignoreRepeats=False, returnArray=False)[0]
        print('Trials: ' + (str(len(trialResponse))))
    else:
        pass

    ignoreTrials = ignore_trials(d)

    ignoreBooleanMask = np.zeros(len(trialResponse), dtype=bool)
    for i, m in enumerate(ignoreBooleanMask):
        if i in ignoreTrials:
            ignoreBooleanMask[i] = True

    trialResponse = trialResponse[
        ignoreBooleanMask ==
        False]  # potentially poor wording, but this is using the boolean mask
    trialRewardDirection = trialRewardDirection[ignoreBooleanMask == False]
    trialTargetFrames = trialTargetFrames[ignoreBooleanMask == False]
    trialMaskContrast = trialMaskContrast[ignoreBooleanMask == False]
    #how to use this indexing

    rightTurnTotal = sum(
        (trialRewardDirection == 1) & (trialTargetFrames != 0))  #left stim
    leftTurnTotal = sum(
        (trialRewardDirection == -1) & (trialTargetFrames != 0))  #right stim
    nogoTotal = sum((trialTargetFrames == 0) & (trialMaskContrast == 0))

    # count(response, reward direction) where -1 is turn left
    rightTurnCorr, leftTurnCorr = count(1, 1), count(1, -1)
    rightTurnIncorrect, leftTurnIncorrect = count(-1, 1), count(-1, -1)
    rightNoResp, leftNoResp = count(0, 1), count(0, -1)

    nogoCorr = len(
        trialResponse[(trialResponse == 1) & (trialTargetFrames == 0) &
                      (trialMaskContrast == 0)])
    nogoMove = len(
        trialResponse[(trialResponse == -1) & (trialTargetFrames == 0) &
                      (trialMaskContrast == 0)])
    respTotal = len(
        trialResponse[(trialResponse != 0)
                      & (trialTargetFrames > 0)])  # response of GO trials
    totalCorrect = len(
        trialResponse[trialResponse == 1])  # this includes nogos
    total = len(trialResponse)

    trialRewards2 = 0

    for trial in trialResponse:
        if trial == 1:
            trialRewards2 += 1
    print('Counted rewards: ' + str(trialRewards2))
    print("Rewards this session:  " + str(trialRewards))

    cell_texts = dict()
    for i, (num, denom, title) in enumerate(
            zip([
                rightTurnCorr, rightTurnIncorrect, rightNoResp, leftTurnCorr,
                leftTurnIncorrect, leftNoResp, nogoCorr,
                (leftTurnCorr + rightTurnCorr), totalCorrect
            ], [
                rightTurnTotal, rightTurnTotal, rightTurnTotal, leftTurnTotal,
                leftTurnTotal, leftTurnTotal, nogoTotal, respTotal, total
            ], [
                'Turn R % Correct:', 'Turn R % Incorre:', 'Turn R % No Resp:',
                'L % Correct:', 'L % Incorre:', 'L % No Resp:', 'NoGo Corr:',
                'Total Correct, given Response:', 'Total Correct (incl nogos):'
            ])):

        if printValues == True:
            print(str(title) + '   ' + str(round(num / denom, 2)))
        else:
            val = (round(num / denom, 2))
            cell_texts.update({title: val})
    return cell_texts
Пример #3
0
def plot_soa(data, ignoreNoRespAfter=None, showNogo=True):

    matplotlib.rcParams['pdf.fonttype'] = 42

    d = data

    end = ignore_after(
        d, ignoreNoRespAfter)[0] if ignoreNoRespAfter is not None else len(
            d['trialResponse'][:])

    ignore = ignore_trials(d)  # ignore trials with early movement
    ignoring = np.full(end, 0)

    for i, _ in enumerate(ignoring):
        if i in ignore:
            ignoring[i] = 1

    # bring in and clean relevant variables
    trialResponse = d['trialResponse'][:end][ignoring == 0]
    trialRewardDirection = d['trialRewardDir'][:end][ignoring == 0]
    trialTargetFrames = d['trialTargetFrames'][:end][ignoring == 0]
    trialMaskContrast = d['trialMaskContrast'][:end][ignoring == 0]
    trialMaskPosition = d['trialMaskPos'][:end][ignoring == 0]
    trialType = d['trialType'][:end][ignoring == 0]
    trialStimStart = d['trialStimStartFrame'][:end][ignoring == 0]
    trialRespFrame = d['trialResponseFrame'][:end][ignoring == 0]
    deltaWheel = d['deltaWheelPos'][:]

    framerate = int(np.round(1 / np.median(d['frameIntervals'][:])))
    maskOnset = d['maskOnset'][()] * 1000 / framerate
    trialMaskOnset = d['trialMaskOnset'][:end][ignoring == 0] * (1000 /
                                                                 framerate)

    # create new, simpler array for mask position
    trialMaskArray = np.full(len(trialMaskPosition),
                             0)  # used later to filter trials

    for i, t in enumerate(trialMaskPosition):
        if 480 in t:
            trialMaskArray[i] = 1  # mask lateral (overlapping target)
        elif 270 in t:
            trialMaskArray[i] = 2  # mask center
        else:
            trialMaskArray[i] = 0

# filter and count target only trials (no mask)
# these are independent from mask postition and thus outside of loop below

    targetOnlyVal = maskOnset[-1] + round(np.mean(
        np.diff(maskOnset)))  # assigns evenly-spaced value from soas

    for i, (mask, trial) in enumerate(zip(
            trialMaskOnset, trialTargetFrames)):  # filters target-Only trials
        if trial > 0 and mask == 0:
            trialMaskOnset[i] = targetOnlyVal

    targetOnlyHit = [[], []]  # [left turning], [right turning]
    targetOnlyResp = [[], []]
    targetOnlyTotals = [[], []]

    for i, side in enumerate([-1, 1]):  # [L turning], [R turning]
        for (typ, rew, resp) in zip(trialType, trialRewardDirection,
                                    trialResponse):
            if typ == 'targetOnly':
                if rew == side:
                    targetOnlyTotals[i].append(1)
                    if resp == 1:
                        targetOnlyHit[i].append(1)
                    if resp != 0:
                        targetOnlyResp[i].append(1)

    def total(var):
        return list(map(sum, var))

    targetOnlyHit = total(targetOnlyHit)
    targetOnlyResp = total(targetOnlyResp)
    targetOnlyTotals = total(targetOnlyTotals)

    ### PLOTTING

    for mask, j in zip(['mask lateral', 'mask center'], [1, 2]):

        # depending on mask position, filter and count trial resps
        # [turn L] , [turn R]
        hits = [[], []]
        misses = [[], []]
        noResps = [[], []]

        for i, direction in enumerate([-1, 1]):
            directionResponses = [
                trialResponse[(trialRewardDirection == direction)
                              & (trialMaskArray == j) &
                              (trialMaskOnset == soa)]
                for soa in np.unique(maskOnset)
            ]
            hits[i].append([np.sum(drs == 1) for drs in directionResponses])
            misses[i].append([np.sum(drs == -1) for drs in directionResponses])
            noResps[i].append([np.sum(drs == 0) for drs in directionResponses])

        hits = np.squeeze(np.array(hits))
        misses = np.squeeze(np.array(misses))
        noResps = np.squeeze(np.array(noResps))
        totalTrials = hits + misses + noResps
        respOnly = hits + misses

        # mask only -- mask only center and side
        maskOnlyTurns = [[], []]  # 1st is indices, 2nd is turning dir

        for i, (t, pos, start, end) in enumerate(
                zip(trialType, trialMaskArray, trialStimStart,
                    trialRespFrame)):
            if t == 'maskOnly' and pos == j:
                wheel = (np.cumsum(deltaWheel[start:end])[-1])
                maskOnlyTurns[0].append(i)
                maskOnlyTurns[1].append((wheel / abs(wheel)).astype(int))

        ## add catch?  after this loop?

        maskOnlyTotal = len(trialResponse[(trialMaskContrast > 0)
                                          & (trialTargetFrames == 0)])
        maskOnlyR = maskOnlyTurns[1].count(1)
        maskOnlyL = maskOnlyTurns[1].count(-1)
        maskOnlyMove = len(maskOnlyTurns)

        for title in (['Response Rate', 'Fraction Correct Given Response']):

            fig, ax = plt.subplots()

            if mask == 'mask lateral':
                plt.suptitle('Mask Overlaps target')
            elif mask == 'mask center':
                plt.suptitle('Mask Center Screen (non-overlapping)')

            if title == 'Response Rate':
                ax.plot(maskOnset,
                        respOnly[0] / totalTrials[0],
                        'bo-',
                        lw=3,
                        alpha=.7)  # left turning
                ax.plot(maskOnset,
                        respOnly[1] / totalTrials[1],
                        'ro-',
                        lw=3,
                        alpha=.7)  # right turning

                #plot mask only for given mask position
                ax.plot(5, (maskOnlyR / maskOnlyTotal), 'ro')
                ax.plot(5, (maskOnlyL / maskOnlyTotal), 'bo')
                ax.plot(5, ((maskOnlyTotal - maskOnlyCorr) / maskOnlyTotal),
                        'ko')

                ax.plot(targetOnlyVal, targetOnlyResp[0] / targetOnlyTotals[0],
                        'bo')
                ax.plot(targetOnlyVal, targetOnlyResp[1] / targetOnlyTotals[1],
                        'ro')

                ### add catch trials to resp rate??
                ### add catch counts as text at top

                denom = totalTrials

            elif title == 'Fraction Correct Given Response':
                ax.plot(maskOnset,
                        hits[0] / respOnly[0],
                        'bo-',
                        lw=3,
                        alpha=.7)  # left turning
                ax.plot(maskOnset,
                        hits[1] / respOnly[1],
                        'ro-',
                        lw=3,
                        alpha=.7)  # right turning

                ax.plot(targetOnlyVal, targetOnlyHit[0] / targetOnlyResp[0],
                        'bo')
                ax.plot(targetOnlyVal, targetOnlyHit[1] / targetOnlyResp[1],
                        'ro')

                denom = respOnly

            for x, Ltrials, Rtrials in zip(
                    maskOnset, denom[0], denom[1]):  #denom[0]==L, denom[1]==R
                for y, n, clr in zip((1.03, 1.08), [Rtrials, Ltrials], 'rb'):
                    fig.text(x,
                             y,
                             str(n),
                             transform=ax.transData,
                             color=clr,
                             fontsize=10,
                             ha='center',
                             va='bottom')

            formatFigure(fig,
                         ax,
                         xLabel='Mask Onset From Target Onset (ms)',
                         yLabel=title)

            ax.set_title(str(d).split('_')[-3:-1],
                         fontdict={'fontsize': 10},
                         pad=10)

            xticks = np.append(maskOnset, targetOnlyVal)
            xticks = np.insert(xticks, 0, 5)
            xticklabels = list(np.round(xticks).astype(int))
            xticklabels[0] = 'Mask Only'
            xticklabels[-1] = 'Target Only'
            #        if title=='Response Rate':
            #            # add catch label to plot
            #               x = 0
            #            xticks = np.concatenate((x,xticks))
            #            xticklabels = lbl+xticklabels
            ax.set_xticks(xticks)
            ax.set_xticklabels(xticklabels)
            ax.set_xlim([0, xticks[-1] + 5])
            ax.set_ylim([0, 1.1])
            ax.spines['right'].set_visible(False)
            ax.spines['top'].set_visible(False)
            ax.tick_params(direction='out', top=False, right=False)

            if title == 'Response Rate':
                ax.xaxis.set_label_coords(0.5, -0.08)
Пример #4
0
def makeWheelPlot(data, returnData=False, responseFilter=[-1,0,1], ignoreRepeats=True, 
                  framesToShowBeforeStart=60, mask=False, maskOnly=False):


    #Clean up inputs if needed    
    #if response filter is an int, make it a list
    if type(responseFilter) is int:
        responseFilter = [responseFilter]
    
    d = data
    frameRate = d['frameRate'][()]
    trialEndFrames = d['trialEndFrame'][:]
    trialStartFrames = d['trialStartFrame'][:trialEndFrames.size]
    trialRewardDirection = d['trialRewardDir'][:trialEndFrames.size]
    trialResponse = d['trialResponse'][:trialEndFrames.size]
    deltaWheel = d['deltaWheelPos'][:]
    
    preStimFrames = d['trialStimStartFrame'][:trialEndFrames.size]-trialStartFrames if 'trialStimStartFrame' in d else np.array([d['preStimFrames'][:]]*trialStartFrames.size)
    
    trialStartFrames += preStimFrames    
    
    if 'trialOpenLoopFrames' in d.keys():
        openLoopFrames = d['trialOpenLoopFrames'][:]
    elif 'openLoopFrames' in d.keys():
        openLoopFrames = d['openLoopFrames'][:]
    else:
        raise ValueError 
    
    
    if 'rewardFrames' in d.keys():
        rewardFrames = d['rewardFrames'][:]
    elif 'responseFrames' in d.keys():
        responseTrials = np.where(trialResponse!= 0)[0]
        rewardFrames = d['responseFrames'][:][trialResponse[responseTrials]>0]
    else:
        rewardFrames = d['trialResponseFrame'][:len(trialResponse)]
        rewardFrames = rewardFrames[trialResponse>0]  
        
    nogo = d['trialTargetFrames'][:-1]==0
    
        
    # alters the necessary variables to exclude any trials that are an incorrect repeat 
    #(i.e, a repeated trial after an incorrect choice).  If there are no repeats, it passes
    if ignoreRepeats == True:
        if 'trialRepeat' in d.keys():
            prevTrialIncorrect = d['trialRepeat'][:len(trialResponse)]
            subtitle = ['repeats ignored']
        elif 'incorrectTrialRepeats' in d and d['incorrectTrialRepeats'][()] > 0:
            prevTrialIncorrect = np.concatenate(([False],trialResponse[:-1]<1))
            trialResponse = trialResponse[prevTrialIncorrect==False]
            trialStartFrames = trialStartFrames[prevTrialIncorrect==False]
            trialEndFrames = trialEndFrames[prevTrialIncorrect==False]
            trialRewardDirection = trialRewardDirection[prevTrialIncorrect==False]
            nogo = nogo[prevTrialIncorrect==False]
            subtitle = ['repeats ignored']
        elif 'incorrectTrialRepeats' in d and d['incorrectTrialRepeats'][()] == 0:
            subtitle= ['no repeated trials']
    else:
        subtitle = ['repeats incl']

    
    ignoreTrials = ignore_trials(d)
    
    postTrialFrames = 0 if d['postRewardTargetFrames'][()]>0 else 1 #make sure we have at least one frame after the reward

    fig, ax = plt.subplots()
    
    # turnRightTrials == stim presented on L, turn right - viceversa for turnLeftTrials - or for orientation, turn right
    nogoTrials = []
    turnRightTrials = []
    turnLeftTrials = []
    maxTrialFrames = max(trialEndFrames-trialStartFrames+framesToShowBeforeStart+postTrialFrames)  #??? why  
    trialTime = (np.arange(maxTrialFrames)-framesToShowBeforeStart)/frameRate  # evenly-spaced array of times for x-axis
    for i, (trialStart, trialEnd, rewardDirection, resp) in enumerate(zip(
            trialStartFrames, trialEndFrames, trialRewardDirection, trialResponse)):
        if i>0 and i<len(trialStartFrames):
            if i in ignoreTrials:
                pass
            else:
                if resp in responseFilter:
                    #get wheel position trace for this trial!
                    trialWheel = np.cumsum(deltaWheel[
                            trialStart-framesToShowBeforeStart:trialStart-framesToShowBeforeStart + maxTrialFrames
                            ])
                    trialWheel -= trialWheel[0]
                    trialreward = np.where((rewardFrames>trialStart)&(rewardFrames<=trialEnd))[0]
                    rewardFrame = rewardFrames[trialreward[0]]-trialStart+framesToShowBeforeStart if len(trialreward)>0 else None
                    if nogo[i]:
                        ax.plot(trialTime[:trialWheel.size], trialWheel, 'g', alpha=0.2)   # plotting no-go trials
                        if rewardFrame is not None:
                            ax.plot(trialTime[rewardFrame], trialWheel[rewardFrame], 'go')
                        nogoTrials.append(trialWheel)
                    elif rewardDirection>0:
                        ax.plot(trialTime[:trialWheel.size], trialWheel, 'r', alpha=0.2)  #plotting right turning 
                        if rewardFrame is not None:
                            ax.plot(trialTime[rewardFrame], trialWheel[rewardFrame], 'ro')
                        turnRightTrials.append(trialWheel)
                    elif rewardDirection<0:
                        ax.plot(trialTime[:trialWheel.size], trialWheel, 'b', alpha=0.2)   # plotting left turning 
                        if rewardFrame is not None:
                            ax.plot(trialTime[rewardFrame], trialWheel[rewardFrame], 'bo')
                        turnLeftTrials.append(trialWheel)
    
    turnRightTrials = pd.DataFrame(turnRightTrials).fillna(np.nan).values
    turnLeftTrials = pd.DataFrame(turnLeftTrials).fillna(np.nan).values
    nogoTrials = pd.DataFrame(nogoTrials).fillna(np.nan).values
    ax.plot(trialTime[:turnRightTrials.shape[1]], np.nanmean(turnRightTrials,0), 'r', linewidth=3)
    ax.plot(trialTime[:turnLeftTrials.shape[1]], np.nanmean(turnLeftTrials, 0), 'b', linewidth=3)
    ax.plot(trialTime[:nogoTrials.shape[1]], np.nanmean(nogoTrials,0), 'k', linewidth=3)
    ax.plot([trialTime[framesToShowBeforeStart+openLoopFrames]]*2, ax.get_ylim(), 'k--')
    
    name_date = str(data).split('_')    

    
    formatFigure(fig, ax, xLabel='Time from stimulus onset (s)', 
                 yLabel='Wheel Position (pix)', title=name_date[-3:-1] + subtitle)
    plt.tight_layout()