ax.plot(np.unique(targetLengths), num[0] / denom[0], 'bo-') ax.plot(np.unique(targetLengths), num[1] / denom[1], 'ro-') ax.plot(0, no_goNum / no_goDen, 'ko') if no_goNum == no_goMove: ax.plot(0, no_goR / no_goMove, 'ro') ax.plot(0, no_goL / no_goMove, 'bo') #ax.annotate(denom, (np.unique(targetLengths), denom)) '''chanceRates = [[[i/n for i in scipy.stats.binom.interval(0.95,n,0.5)] for n in h] for h in denom] chanceRates = np.array(chanceRates) for val, chanceR, chanceL in zip(np.unique(targetLengths), chanceRates[0], chanceRates[1]): plt.plot([val, val], chanceR, color='red', alpha=.5) # 0 and 1 = R and L, respectively plt.plot([val+.2, val+.2], chanceL, color='blue', alpha=.5)''' formatFigure(fig, ax, xLabel='Target Length (frames)', yLabel='percent trials', title=title + " : " + '-'.join(f.split('_')[-3:-1])) ax.set_xlim([-2, trialTargetFrames[0] + 2]) ax.set_ylim([0, 1.01]) ax.set_xticks(np.unique(trialTargetFrames)) ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) ax.tick_params(direction='out', top=False, right=False) if 0 in trialTargetFrames: a = ax.get_xticks().tolist() a = [int(i) for i in a] a[0] = 'no-go' ax.set_xticklabels(a)
def plot_opto_masking(d, ignoreNoRespAfter=None): matplotlib.rcParams['pdf.fonttype'] = 42 # create dataframe of session df = create_df(d) mouse = df.mouse framerate = df.framerate date = get_dates(df.date) if ignoreNoRespAfter is not None: end = ignore_after(d, ignoreNoRespAfter)[0] df = df[:end] df['respDir'] = d['trialResponseDir'][:len(df)] # separate out the target only, mask only, catch only, and masking trials # (we are using the averages of these, not left/right) # remove the ignore trials # NO OPTO TRIALS maskOnly = df[(df['trialType'] == 'maskOnly') & (df['ignoreTrial'] == False)] targetOnly = df[(df['trialType'] == 'targetOnly') & (df['ignoreTrial'] == False)] masking = df[(df['trialType'] == 'mask') & (df['ignoreTrial'] == False)] catch = df[(df['trialType'] == 'catch') & (df['ignoreTrial'] == False)] hitsNoOpto = [[] for i in range(4)] # list for each df above respsNoOpto = [[] for i in range(4)] totalsNoOpto = [[] for i in range(4)] for i, frame in enumerate([maskOnly, targetOnly, masking, catch]): hitsNoOpto[i].append(np.sum((frame['resp'] == 1))) respsNoOpto[i].append(np.sum((np.isfinite(frame['respDir'])))) totalsNoOpto[i].append(len(frame)) totalTrialsNoOpto = np.array( [len(frame) for frame in [maskOnly, targetOnly, masking, catch]]) hitsNoOpto = np.squeeze(np.array(hitsNoOpto)) respsNoOpto = np.squeeze(np.array(respsNoOpto)) totalsNoOpto = np.squeeze(np.array(totalsNoOpto)) # OPTO TRIALS maskOnlyOpto = df[(df['trialType'] == 'maskOnlyOpto') & (df['ignoreTrial'] == False)] targetOnlyOpto = df[(df['trialType'] == 'targetOnlyOpto') & (df['ignoreTrial'] == False)] maskingOpto = df[(df['trialType'] == 'maskOpto') & (df['ignoreTrial'] == False)] catchOpto = df[(df['trialType'] == 'catchOpto') & (df['ignoreTrial'] == False)] # separate out by onset and count correct by onset optoOnset = d['optoOnset'][:] hits = [[] for i in range(4)] # list for each df above resps = [[] for i in range(4)] totals = [[] for i in range(4)] for i, frame in enumerate( [maskOnlyOpto, targetOnlyOpto, maskingOpto, catchOpto]): for on in optoOnset: hits[i].append( np.sum((frame['optoOnset'] == on) & (frame['resp'] == 1))) resps[i].append( np.sum((frame['optoOnset'] == on) & (np.isfinite(frame['respDir'])))) totals[i].append(np.sum(frame['optoOnset'] == on)) totalTrialsOpto = np.array([ len(frame) for frame in [maskOnlyOpto, targetOnlyOpto, maskingOpto, catchOpto] ]) hits = np.squeeze(np.array(hits)) resps = np.squeeze(np.array(resps)) totals = np.squeeze(np.array(totals)) # plot the percent correct against the opto onset on the xaxis xNoOpto = max(optoOnset) + 1 yText = [1.2, 1.15, 1.1, 1.05] colors = ['k', 'c', 'k', 'm'] alphas = [.3, .5, .8, 1] for num, denom, title in zip( [resps, hits], [totals, resps], ['Response Rate', 'Fraction Correct Given Response']): fig, ax = plt.subplots() for i, (al, c, text, lbl, noOptoResp, noOptoCorr) in enumerate( zip(alphas, colors, yText, ['Mask only', 'Target only', 'Masked trials', 'Catch'], list(respsNoOpto / totalsNoOpto), list(hitsNoOpto / respsNoOpto)) ): # this needs to be resps over totals for no opto #for fraction correct there should only be target and masked plotted # or the plot needs to be different, like the ones sam made if title == 'Response Rate': ax.plot(optoOnset, num[i] / denom[i], 'o-', color=c, lw=3, alpha=al, label=lbl) ax.plot(xNoOpto, noOptoResp, 'o', color=c, alpha=al) for x, n in zip(optoOnset, np.transpose(denom[i])): fig.text(x, text, str(n), transform=ax.transData, color=c, alpha=al, fontsize=10, ha='center', va='bottom') else: if lbl == 'Mask only' or lbl == 'Catch': pass else: ax.plot(optoOnset, num[i] / denom[i], 'o-', color=c, lw=3, alpha=al, label=lbl) ax.plot(xNoOpto, noOptoCorr, 'o', color=c, alpha=al) for x, n in zip(optoOnset, np.transpose(denom[i])): fig.text(x, text, str(n), transform=ax.transData, color=c, alpha=al, fontsize=10, ha='center', va='bottom') # for r in respsNoOpto[1:3]: # fig.text(xNoOpto, text, str(r), transform=ax.transData, color=c, alpha=al, fontsize=10, ha='center', va='bottom') # if title == 'Response Rate': for t, y, cl, alp in zip(totalsNoOpto, yText, colors, alphas): fig.text(xNoOpto, y, str(t), transform=ax.transData, color=cl, alpha=alp, fontsize=10, ha='center', va='bottom') elif title == 'Fraction Correct Given Response': for r, y, cl, alp in zip(respsNoOpto[1:3], yText[1:3], colors[1:3], alphas[1:3]): fig.text(xNoOpto, y, str(r), transform=ax.transData, color=cl, alpha=alp, fontsize=10, ha='center', va='bottom') ## format the plots formatFigure(fig, ax, xLabel='Opto onset from target onset (ms)', yLabel=title) fig.suptitle((mouse + ', ' + date + ' ' + 'Masking with optogenetic silencing of V1'), fontsize=13) xticks = list(optoOnset) xticklabels = [ int(np.round((tick / framerate) * 1000)) - 17 for tick in optoOnset ] # remove 17 ms of latency x, lbl = ([xNoOpto], ['no\nopto']) xticks = np.concatenate((xticks, x)) xticklabels = xticklabels + lbl ax.set_xticks(xticks) ax.set_xticklabels(xticklabels) ax.set_xlim([min(optoOnset) - 1, max(xticks) + 1]) ax.set_ylim([0, 1.05]) ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) ax.tick_params(direction='out', top=False, right=False) plt.subplots_adjust(top=0.815, bottom=0.135, left=0.1, right=0.92, hspace=0.2, wspace=0.2) plt.legend(loc='best', fontsize='small', numpoints=1)
# else: if rewardDirection>0 and mask>0: if soa==2: ax.plot(trialTime[:trialWheel.size], trialWheel, 'b', alpha=0.2) #plotting right turning if rewardFrame is not None: ax.plot(trialTime[rewardFrame], trialWheel[rewardFrame], 'bo') rightMask[0].append(trialWheel) elif soa==6: ax.plot(trialTime[:trialWheel.size], trialWheel, 'g', alpha=0.2) #plotting right turning if rewardFrame is not None: ax.plot(trialTime[rewardFrame], trialWheel[rewardFrame], 'go') elif rewardDirection<0 and mask>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') leftMask.append(trialWheel) rightMask = pd.DataFrame(rightMask).fillna(np.nan).values leftMask = pd.DataFrame(leftMask).fillna(np.nan).values nogoMask = pd.DataFrame(nogoMask).fillna(np.nan).values ax.plot(trialTime[:rightMask.shape[1]], np.nanmean(rightMask,0), 'r', linewidth=3) ax.plot(trialTime[:leftMask.shape[1]], np.nanmean(leftMask, 0), 'b', linewidth=3) ax.plot(trialTime[:nogoMask.shape[1]], np.nanmean(nogoMask,0), 'k', linewidth=3) ax.plot([trialTime[framesToShowBeforeStart+openLoopFrames]]*2, ax.get_ylim(), 'k--') formatFigure(fig, ax, xLabel='Time from stimulus onset (s)', yLabel='Wheel Position (pix)', title=name_date[-3:-1] + [ 'Mask Trials']) plt.tight_layout()
hits = np.squeeze(np.array(hits)) misses = np.squeeze(np.array(misses)) noResps = np.squeeze(np.array(noResps)) totalTrials = hits + misses + noResps avg_hits.append(hits) avg_total.append(totalTrials) for length, num, denom, title in zip([np.unique(targetLengths)], [hits], [totalTrials], ['Averaged success rate']): ax = plt.subplot() ax.plot(length, num / denom, 'k-o', alpha=.5) formatFigure(fig, ax, xLabel='Target Length (ms)', yLabel='percent trials', title=title + ' 6/04/2019') ax.set_xlim([0, targetLengths[-1] + 2]) ax.set_ylim([0, 1.01]) ax.set_xticks(np.unique(targetLengths)) ax.set_xticklabels(np.round(targetLengths * 8.3).astype(int)) ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) ax.tick_params(direction='out', top=False, right=False) avg_hits = np.mean(avg_hits, axis=0) avg_total = np.mean(avg_total, axis=0) average = avg_hits / avg_total
fig = plt.figure(facecolor='w', figsize=(10, 10), tight_layout=True) #title='-'.join(f.split('_')[-3:-1])) for i, (num, denom, title) in enumerate( zip([hitsR, hitsR, hitsR + missesR], [totalTrialsR, hitsR + missesR, totalTrialsR], [ 'Right Side, Total hit rate', 'Right Side, Response hit rate', 'Right Side, Total response rate' ])): ax = fig.add_subplot(2, 3, i + 1) for i, ct in enumerate(contrast): ax.plot(np.unique(maskOnset), num[i] / denom[i], marker='o', label=ct) ax.set_xticks(np.unique(maskOnset)) formatFigure(fig, ax, xLabel='Mask SOA', yLabel='percent trials', title=title + " : " + '-'.join(f.split('_')[-3:-1])) ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) ax.tick_params(direction='out', top=False, right=False) ax.set_ylim([0, 1.01]) ax.set_xlim([-1, max(maskOnset) + 5]) for i, (num, denom, title) in enumerate( zip([hitsL, hitsL, hitsL + missesL], [totalTrialsL, hitsL + missesL, totalTrialsL], [ 'Left Side, Total hit rate', 'Left Side, Response hit rate', 'Left Side, Total response rate' ])): ax = fig.add_subplot(2, 3, i + 4)
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)
fig = plt.figure(facecolor='w', figsize=(10, 10), tight_layout=True) #title='-'.join(f.split('_')[-3:-1])) #fig.text(0.5, 0.9, '-'.join(f.split('_')[-3:-1]), ha='center', va='center') for i, (num, denom, title) in enumerate( zip([hitsR, hitsR, hitsR + missesR], [totalTrialsR, hitsR + missesR, totalTrialsR], [ 'Right Side, Total hit rate', 'Right Side, Response hit rate', 'Right Side, Total response rate' ])): ax = fig.add_subplot(3, 3, i + 1) for i, ct in enumerate(contrast): ax.plot(np.unique(maskOnset), num[i] / denom[i], marker='o', label=ct) ax.set_xticks(np.unique(maskOnset)) formatFigure(fig, ax, yLabel='percent trials', title=title + " : " + '-'.join(f.split('_')[-3:-1])) ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) ax.tick_params(direction='out', top=False, right=False) ax.set_ylim([0, 1.01]) ax.set_xlim([-1, max(maskOnset) + 5]) L = plt.legend(loc='lower right', title='Mask Contrast') for i, m in enumerate(contrast): L.get_texts()[i].set_text(m) for i, (num, denom, title) in enumerate( zip([hitsL, hitsL, hitsL + missesL], [totalTrialsL, hitsL + missesL, totalTrialsL], [ 'Left Side, Total hit rate', 'Left Side, Response hit rate',
def plot_soa(data, showTrialN=True, showNogo=True): matplotlib.rcParams['pdf.fonttype'] = 42 d = data trialResponse = d['trialResponse'][:] trialRewardDirection = d['trialRewardDir'][:len(trialResponse)] trialTargetFrames = d['trialTargetFrames'][:len(trialResponse)] trialMaskContrast = d['trialMaskContrast'][:len(trialResponse)] framerate = 120 #round(d['frameRate'][()]) maskOnset = d['maskOnset'][()] * 1000 / framerate trialMaskOnset = d['trialMaskOnset'][:len(trialResponse )] * 1000 / framerate noMaskVal = maskOnset[-1] + round( np.mean(np.diff(maskOnset) )) # assigns noMask condition an evenly-spaced value from soas maskOnset = np.append(maskOnset, noMaskVal) # makes final value the no-mask condition for i, (mask, trial) in enumerate(zip( trialMaskOnset, trialTargetFrames)): # filters target-Only trials if trial > 0 and mask == 0: trialMaskOnset[i] = noMaskVal # [turn R] , [turn L] hits = [[], []] misses = [[], []] noResps = [[], []] for i, direction in enumerate([1, -1]): directionResponses = [ trialResponse[(trialRewardDirection == direction) & (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 turns, ind = nogo_turn( d, returnArray=True) # returns arrays with turning direction as 1/-1 nogoTurnTrial = ind[0] # list of indices of trials where turning occured maskTurnTrial = ind[1] nogoTotal = len(trialResponse[(trialTargetFrames == 0) & (trialMaskContrast == 0)]) #nogoCorrect = len(trialResponse[(trialResponse==1) & (trialTargetFrames==0) & (trialMaskContrast==0)]) sanity check nogoMove = len(nogoTurnTrial) nogoR = turns[0].count(1) nogoL = turns[0].count(-1) #maskTotal = len(trialResponse[(trialMaskContrast>0)]) sanity check maskOnlyTotal = len( trialResponse[(trialMaskContrast > 0) & (trialTargetFrames == 0)] ) # rotation task 'mask only' trials can't be 'correct' maskOnlyCorr = len( trialResponse[(trialMaskContrast > 0) & (trialResponse == 1) & (trialTargetFrames == 0)]) maskOnlyR = turns[1].count(1) maskOnlyL = turns[1].count(-1) for num, denom, title in zip( [hits, hits, respOnly], [totalTrials, respOnly, totalTrials], [ 'Fraction Correct', 'Fraction Correct Given Response', 'Response Rate' ]): fig, ax = plt.subplots() ax.plot(maskOnset, num[0] / denom[0], 'ro-', lw=3, alpha=.7 ) #here [0] is right turning trials and [1] is left turning ax.plot(maskOnset, num[1] / denom[1], 'bo-', lw=3, alpha=.7) if title == 'Response Rate': ax.plot( 0, (maskOnlyR / maskOnlyTotal), 'r>', ms=8 ) #plot the side that was turned in no-go with an arrow in that direction ax.plot(0, (maskOnlyL / maskOnlyTotal), 'b<', ms=8) ax.plot(0, ((maskOnlyTotal - maskOnlyCorr) / maskOnlyTotal), 'ko') if showTrialN: ax.annotate(str(maskOnlyTotal), xy=(1, (maskOnlyTotal - maskOnlyCorr) / maskOnlyTotal), xytext=(0, 0), textcoords='offset points') ax.annotate(str(maskOnlyR), xy=(1, maskOnlyR / maskOnlyTotal), xytext=(0, 0), textcoords='offset points') ax.annotate(str(maskOnlyL), xy=(1, maskOnlyL / maskOnlyTotal), xytext=(0, 0), textcoords='offset points') if showNogo: if len(turns[0]) > 0: ax.plot(-15, nogoMove / nogoTotal, 'ko') ax.plot( -15, nogoR / nogoMove, 'r>', ms=8 ) #plot the side that was turned in no-go with an arrow in that direction ax.plot(-15, nogoL / nogoMove, 'b<', ms=8) if showTrialN: ax.annotate(str(nogoMove), xy=(-14, nogoMove / nogoTotal), xytext=(0, 0), textcoords='offset points') ax.annotate(str(nogoR), xy=(-14, nogoR / nogoMove), xytext=(0, 0), textcoords='offset points') ax.annotate(str(nogoL), xy=(-14, nogoL / nogoMove), xytext=(0, 0), textcoords='offset points') else: ax.plot(-15, 0, 'go') formatFigure(fig, ax, xLabel='Stimulus Onset Asynchrony (ms)', yLabel=title, title=str(d).split('_')[-3:-1]) xticks = maskOnset xticklabels = list(np.round(xticks).astype(int)) xticklabels[-1] = 'no mask' if title == 'Response Rate': x, lbl = ([-15, 0], ['no\ngo', 'mask\nonly' ]) if showNogo else ([0], ['mask\nonly']) xticks = np.concatenate((x, xticks)) xticklabels = lbl + xticklabels ax.set_xticks(xticks) ax.set_xticklabels(xticklabels) ax.set_xlim([-20, xticks[-1] + 10]) 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)
def performance_data(mouse, ignoreRepeats=True): def count(resp, direction): return len(trialResponse[(trialResponse==resp) & (trialRewardDirection==direction) & (trialTargetFrames!=0)]) rightCorr = [] leftCorr = [] rightNoResp = [] leftNoResp = [] totalTrials = [] no_goCorr = [] no_goMoveL = [] no_goMoveR = [] files = get_files(mouse, 'training_') for i,f in enumerate(files): d = h5py.File(f) trialResponse = d['trialResponse'][:] trialRewardDirection = d['trialRewardDir'][:len(trialResponse)] trialTargetFrames = d['trialTargetFrames'][:len(trialResponse)] if ignoreRepeats== True and d['incorrectTrialRepeats'][()] > 0: 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] print('Repeats: ' + (str((len(trialResponseOG) - len(trialResponse)))) + '/' + str(len(trialResponseOG))) elif ignoreRepeats == False or d['incorrectTrialRepeats'][()]==0: pass rightTurnTotal = sum((trialRewardDirection==1) & (trialTargetFrames!=0)) leftTurnTotal = sum((trialRewardDirection==-1) & (trialTargetFrames!=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) respTotal = (leftTurnTotal + rightTurnTotal) - (rightNoResp + leftNoResp) total = (leftTurnTotal + rightTurnTotal) leftCorr.append(leftTurnCorr/leftTurnTotal) rightCorr.append(rightTurnCorr/rightTurnTotal) totalTrials.append(total) # make this a function? # if 0 not in trialTargetFrames: # pass # elif 0 in trialTargetFrames: # no_goTotal = len(trialTargetFrames[trialTargetFrames==0]) # no_goCorrect = len(trialResponse[(trialTargetFrames==0) & (trialResponse==1)]) # print('No-go Correct: ' + str(round(no_goCorrect/no_goTotal, 2)) + ' of ' + str(no_goTotal)) # # #returns an array of values that show the direction turned for ALL no-go trials, then returns % per direction # no_goTurnDir = [] # # stimStart= d['trialStimStartFrame'][:len(trialResponse)] # trialRespFrames = d['trialResponseFrame'][:len(trialResponse)] # trialOpenLoop = d['trialOpenLoopFrames'][:len(trialResponse)] # deltaWheel = d['deltaWheelPos'].value # # # if ignoreRepeats== True: # stimStart = stimStart[prevTrialIncorrect==False] # trialRespFrames = trialRespFrames[prevTrialIncorrect==False] # trialOpenLoop = trialOpenLoop[prevTrialIncorrect==False] # # stimStart = stimStart[trialTargetFrames==0] # trialRespFrames = trialRespFrames[trialTargetFrames==0] # trialOpenLoop = trialOpenLoop[trialTargetFrames==0] # deltaWheel = d['deltaWheelPos'].value # no_goResp = trialResponse[trialTargetFrames==0] # # stimStart += trialOpenLoop # # startWheelPos = [] # endWheelPos = [] # # for (start, end, resp) in zip(stimStart, trialRespFrames, no_goResp): # if resp==-1: # endWheelPos.append(deltaWheel[end]) # startWheelPos.append(deltaWheel[start]) # # endWheelPos = np.array(endWheelPos) # startWheelPos = np.array(startWheelPos) # wheelPos = endWheelPos - startWheelPos # # for i in wheelPos: # if i >0: # no_goTurnDir.append(1) # else: # no_goTurnDir.append(-1) # # no_goTurnDir = np.array(no_goTurnDir) # print('no-go turn R: ' + str(sum(no_goTurnDir==1))) # print('no-go turn L: ' + str(sum(no_goTurnDir==-1))) # d.close() fig, ax = plt.subplots() xaxis = range(len(files)) ax.plot(xaxis, rightCorr, 'ro-') ax.plot(xaxis, leftCorr, 'bo-') # ax.plot(xaxis, np.mean(rightCorr+leftCorr), 'k--') formatFigure(fig, ax, xLabel='Session number', yLabel='Percent Correct', title='Performance over time, ' + mouse, xTickLabels=range(len(files)))
def plot_targetDuration(data, ignoreRepeats=True): d = data trialResponse = d['trialResponse'][:] trialRewardDirection = d['trialRewardDir'][:len(trialResponse)] targetLengths = d['targetFrames'][:] # does not include no-gos trialTargetFrames = d['trialTargetFrames'][:len(trialResponse)] # [R stim] , [L stim] hits = [[], []] misses = [[], []] noResps = [[], []] for i, direction in enumerate([-1, 1]): directionResponses = [ trialResponse[(trialRewardDirection == direction) & (trialTargetFrames == tf)] for tf in targetLengths ] 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 # here call no_go movement function? if 0 in trialTargetFrames: no_goTotal = len(trialTargetFrames[trialTargetFrames == 0]) no_goCorrect = len(trialResponse[(trialResponse == 1) & (trialTargetFrames == 0)]) no_goMove = no_goTotal - no_goCorrect no_goTurnDir = [] stimStart = d['trialStimStartFrame'][:len(trialResponse)][ trialTargetFrames == 0] trialRespFrames = d['trialResponseFrame'][:len(trialResponse)][ trialTargetFrames == 0] trialOpenLoop = d['trialOpenLoopFrames'][:len(trialResponse)][ trialTargetFrames == 0] deltaWheel = d['deltaWheelPos'][:] no_goResp = trialResponse[trialTargetFrames == 0] stimStart += trialOpenLoop startWheelPos = [] endWheelPos = [] # we want to see which direction they moved the wheel on an incorrect no-go for (start, end, resp) in zip(stimStart, trialRespFrames, no_goResp): if resp == -1: endWheelPos.append(deltaWheel[end]) startWheelPos.append(deltaWheel[start]) endWheelPos = np.array(endWheelPos) startWheelPos = np.array(startWheelPos) wheelPos = endWheelPos - startWheelPos for i in wheelPos: if i > 0: no_goTurnDir.append(1) else: no_goTurnDir.append(-1) no_goTurnDir = np.array(no_goTurnDir) no_goR = sum(no_goTurnDir[no_goTurnDir == 1]) no_goL = sum(no_goTurnDir[no_goTurnDir == -1]) * -1 for no_goNum, no_goDen, num, denom, title in zip( [no_goCorrect, no_goCorrect, no_goMove], [no_goTotal, no_goTotal, no_goTotal], [hits, hits, hits + misses], [totalTrials, hits + misses, totalTrials], [ 'Percent Correct', 'Percent Correct Given Response', 'Total response rate' ]): fig, ax = plt.subplots() ax.plot(np.unique(targetLengths), num[0] / denom[0], 'bo-') ax.plot(np.unique(targetLengths), num[1] / denom[1], 'ro-') ax.plot(0, no_goNum / no_goDen, 'go') if no_goNum == no_goMove: ax.axhline(no_goR / no_goMove, xmin=0, xmax=1, linestyle='--', color='r') ax.plot(0, no_goL / no_goMove, 'bo') # chanceRates = [[[i/n for i in scipy.stats.binom.interval(0.95,n,0.5)] for n in h] for h in denom] # chanceRates = np.array(chanceRates) # for val, chanceR, chanceL in zip(np.unique(targetLengths), chanceRates[0], chanceRates[1]): # plt.plot([val, val], chanceR, color='red', alpha=.5) # 0 and 1 = R and L, respectively # plt.plot([val+.2, val+.2], chanceL, color='blue', alpha=.5)''' formatFigure(fig, ax, xLabel='Target Length (frames)', yLabel='percent trials', title=title + " : " + '-'.join(str(data).split('_')[-3:-1])) ax.set_xlim([-2, trialTargetFrames[0] + 2]) ax.set_ylim([0, 1.01]) ax.set_xticks(np.unique(trialTargetFrames)) ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) ax.tick_params(direction='out', top=False, right=False) ax.text(np.unique(targetLengths), (num[0] / denom[0]), str(denom)) if 0 in trialTargetFrames: a = ax.get_xticks().tolist() a = [int(i) for i in a] a[0] = 'no-go' ax.set_xticklabels(a)