def sure_stimulus_duration(trialsfile, plot, saved=None, **kwargs): if saved is not None: psure_by_duration_by_coh = saved else: trials, A, R, M, perf = utils.load(trialsfile) # Sort trials_by_cond = {} for n, trial in enumerate(trials): if not trial['wager']: continue cond = trial['coh'] if perf.choices[n] is not None: trials_by_cond.setdefault(cond, {'durations': [], 'sures': []}) duration = np.ptp(trial['durations']['stimulus']) trials_by_cond[cond]['durations'].append(duration) trials_by_cond[cond]['sures'].append(perf.choices[n] == 'S') # Number of bins nbins = kwargs.get('nbins', 10) # Average psure_by_duration_by_coh = {} for coh, v in trials_by_cond.items(): (xbins, ybins, xedges, binsizes) = datatools.partition(v['durations'], v['sures'], nbins=nbins) duration = [np.mean(xbin) for xbin in xbins] psure = [utils.divide(np.sum(ybin > 0), len(ybin)) for ybin in ybins] psure_by_duration_by_coh[coh] = (duration, psure) #===================================================================================== # Plot #===================================================================================== lineprop = {'lw': kwargs.get('lw', 1)} dataprop = {'ms': kwargs.get('ms', 7), 'mew': kwargs.get('mew', 0)} colors = kwargs.get('colors', kiani2009_colors) cohs = sorted(psure_by_duration_by_coh) for coh in cohs: duration, psure = psure_by_duration_by_coh[coh] plot.plot(duration, psure, color=colors[coh], label='{}\%'.format(coh), **lineprop) plot.plot(duration, psure, 'o', mfc=colors[coh], **dataprop) plot.xlim(100, 800) plot.ylim(0, 1) #===================================================================================== return psure_by_duration_by_coh
def choice_pattern(trialsfile, offers, plot, **kwargs): # Load trials trials, A, R, M, perf = utils.load(trialsfile) B_by_offer = {} n_nondecision = 0 for n, trial in enumerate(trials): if perf.choices[n] is None: n_nondecision += 1 continue juice_L, juice_R = trial['juice'] offer = trial['offer'] if perf.choices[n] == 'B': B = 1 elif perf.choices[n] == 'A': B = 0 else: raise ValueError("invalid choice") B_by_offer.setdefault(offer, []).append(B) print("Non-decision trials: {}/{}".format(n_nondecision, len(trials))) pB_by_offer = {} for offer in B_by_offer: Bs = B_by_offer[offer] pB_by_offer[offer] = utils.divide(sum(Bs), len(Bs)) #print(offer, pB_by_offer[offer]) #------------------------------------------------------------------------------------- # Plot #------------------------------------------------------------------------------------- if plot is None: return ms = kwargs.get('ms', 7) rotation = kwargs.get('rotation', 60) for i, offer in enumerate(offers): plot.plot(i, 100 * pB_by_offer[offer], 'o', color='k', ms=ms) plot.xticks(range(len(offers))) plot.xticklabels(['{}B:{}A'.format(*offer) for offer in offers], rotation=rotation) plot.xlim(0, len(offers) - 1) plot.ylim(0, 100)
def performance(trialsfile, plot, **kwargs): # Load trials trials, A, R, M, perf = utils.load(trialsfile) correct_by_cond = {} for n, trial in enumerate(trials): if not perf.decisions[n]: continue gt_lt = trial['gt_lt'] fpair = trial['fpair'] if gt_lt == '>': f1, f2 = fpair else: f2, f1 = fpair cond = (f1, f2) correct_by_cond.setdefault(cond, []).append(perf.corrects[n]) pcorrect_by_cond = {} for c in correct_by_cond: corrects = correct_by_cond[c] pcorrect_by_cond[c] = utils.divide(sum(corrects), len(corrects)) #------------------------------------------------------------------------------------- # Plot #------------------------------------------------------------------------------------- plot.equal() lw = kwargs.get('lw', 1) fontsize = kwargs.get('fontsize', 10) _min, _max = kwargs.get('lims', (10 - 4, 34 + 4)) r = kwargs.get('r', 1.5) for (f1, f2), pcorrect in pcorrect_by_cond.items(): plot.circle((f1, f2), r, ec='none', fc=smap.to_rgba(f1)) plot.text(f1, f2, '{}'.format(int(100 * pcorrect)), color='w', fontsize=fontsize, ha='center', va='center') plot.xlim(_min, _max) plot.ylim(_min, _max) plot.plot([_min, _max], [_min, _max], color='k', lw=lw)
def choice_pattern(trialsfile, offers, plot, **kwargs): # Load trials trials, A, R, M, perf = utils.load(trialsfile) B_by_offer = {} n_nondecision = 0 for n, trial in enumerate(trials): if perf.choices[n] is None: n_nondecision += 1 continue juice_L, juice_R = trial['juice'] offer = trial['offer'] if perf.choices[n] == 'B': B = 1 elif perf.choices[n] == 'A': B = 0 else: raise ValueError("invalid choice") B_by_offer.setdefault(offer, []).append(B) print("Non-decision trials: {}/{}".format(n_nondecision, len(trials))) pB_by_offer = {} for offer in B_by_offer: Bs = B_by_offer[offer] pB_by_offer[offer] = utils.divide(sum(Bs), len(Bs)) #print(offer, pB_by_offer[offer]) #------------------------------------------------------------------------------------- # Plot #------------------------------------------------------------------------------------- if plot is None: return ms = kwargs.get('ms', 7) rotation = kwargs.get('rotation', 60) for i, offer in enumerate(offers): plot.plot(i, 100*pB_by_offer[offer], 'o', color='k', ms=ms) plot.xticks(range(len(offers))) plot.xticklabels(['{}B:{}A'.format(*offer) for offer in offers], rotation=rotation) plot.xlim(0, len(offers)-1) plot.ylim(0, 100)
def correct_stimulus_duration(trialsfile, plot, saved=None, **kwargs): if saved is not None: pcorrect_by_duration_by_coh, pcorrect_by_duration_by_coh_wager = saved else: trials, A, R, M, perf = utils.load(trialsfile) # Sort trials_by_cond = {} trials_by_cond_wager = {} for n, trial in enumerate(trials): coh = trial['coh'] if coh == 0 or perf.choices[n] not in ['L', 'R']: continue cond = coh duration = np.ptp(trial['durations']['stimulus']) if trial['wager']: trials_by_cond_wager.setdefault(cond, {'durations': [], 'corrects': []}) trials_by_cond_wager[cond]['durations'].append(duration) trials_by_cond_wager[cond]['corrects'].append(perf.corrects[n]) else: trials_by_cond.setdefault(cond, {'durations': [], 'corrects': []}) trials_by_cond[cond]['durations'].append(duration) trials_by_cond[cond]['corrects'].append(perf.corrects[n]) # Number of bins nbins = kwargs.get('nbins', 10) # Average no-wager trials pcorrect_by_duration_by_coh = {} for coh, v in trials_by_cond.items(): (xbins, ybins, xedges, binsizes) = datatools.partition(v['durations'], v['corrects'], nbins=nbins) duration = [np.mean(xbin) for xbin in xbins] pcorrect = [utils.divide(np.sum(ybin > 0), len(ybin)) for ybin in ybins] pcorrect_by_duration_by_coh[coh] = (duration, pcorrect) # Average wager trials pcorrect_by_duration_by_coh_wager = {} for coh, v in trials_by_cond_wager.items(): (xbins, ybins, xedges, binsizes) = datatools.partition(v['durations'], v['corrects'], nbins=nbins) duration = [np.mean(xbin) for xbin in xbins] pcorrect = [utils.divide(np.sum(ybin > 0), len(ybin)) for ybin in ybins] pcorrect_by_duration_by_coh_wager[coh] = (duration, pcorrect) #===================================================================================== # Plot #===================================================================================== lineprop = {'ls': '--', 'lw': kwargs.get('lw', 1), 'dashes': kwargs.get('dashes', [9, 4])} dataprop = {'mew': kwargs.get('mew', 1)} dataprop['ms'] = kwargs.get('ms', 6) + dataprop['mew']/2 lineprop_wager = {'lw': kwargs.get('lw', 1)} dataprop_wager = {'ms': kwargs.get('ms', 7), 'mew': kwargs.get('mew', 0)} colors = kwargs.get('colors', kiani2009_colors) # No-wager trials cohs = sorted(pcorrect_by_duration_by_coh) for coh in cohs: duration, pcorrect = pcorrect_by_duration_by_coh[coh] plot.plot(duration, pcorrect, color=colors[coh], zorder=10, **lineprop) plot.plot(duration, pcorrect, 'o', mfc='w', mec=colors[coh], zorder=10, **dataprop) # Wager trials cohs = sorted(pcorrect_by_duration_by_coh_wager) for coh in cohs: duration, pcorrect = pcorrect_by_duration_by_coh_wager[coh] plot.plot(duration, pcorrect, color=colors[coh], zorder=5, **lineprop_wager) plot.plot(duration, pcorrect, 'o', mfc=colors[coh], mec=colors[coh], zorder=5, **dataprop_wager) plot.xlim(100, 800) plot.ylim(0.5, 1) #===================================================================================== return pcorrect_by_duration_by_coh, pcorrect_by_duration_by_coh_wager
def psychometric(trialsfile, plot, **kwargs): # Load trials trials, A, R, M, perf = utils.load(trialsfile) decision_by_freq = {} high_by_freq = {} for n, trial in enumerate(trials): mod = trial['mod'] freq = trial['freq'] decision_by_freq.setdefault(mod, {}) high_by_freq.setdefault(mod, {}) decision_by_freq[mod].setdefault(freq, []) high_by_freq[mod].setdefault(freq, []) if perf.decisions[n]: decision_by_freq[mod][freq].append(True) if perf.choices[n] == 'H': high = 1 else: high = 0 high_by_freq[mod][freq].append(high) else: decision_by_freq[mod][freq].append(False) freqs = {} p_decision = {} p_high = {} for mod in decision_by_freq: freqs[mod] = np.sort(high_by_freq[mod].keys()) p_decision[mod] = np.zeros(len(freqs[mod])) p_high[mod] = np.zeros(len(freqs[mod])) for i, freq in enumerate(freqs[mod]): p_decision[mod][i] = sum(decision_by_freq[mod][freq]) / len( decision_by_freq[mod][freq]) p_high[mod][i] = utils.divide(sum(high_by_freq[mod][freq]), len(high_by_freq[mod][freq])) #------------------------------------------------------------------------------------- # Plot #------------------------------------------------------------------------------------- lw = kwargs.get('lw', 1.5) ms = kwargs.get('ms', 6) all_x = [] all_y = [] sigmas = {} for mod in ['v', 'a', 'va']: if mod == 'v': label = 'Visual' elif mod == 'a': label = 'Auditory' elif mod == 'va': label = 'Multisensory' else: raise ValueError x = freqs[mod] y = p_high[mod] # Fit psychometric curve props = dict(lw=lw, color=colors[mod], label=label) try: popt, func = fittools.fit_psychometric(x, y) sigmas[mod] = popt['sigma'] fit_x = np.linspace(min(x), max(x), 201) fit_y = func(fit_x, **popt) plot.plot(fit_x, 100 * fit_y, **props) except RuntimeError: print("Unable to fit, drawing a line through the points.") plot.plot(x, 100 * y, **props) plot.plot(x, 100 * y, 'o', ms=ms, mew=0, mfc=props['color']) all_x.append(x) # Is it optimal? print("") print(" Optimality test") print(" ---------------") print("") for mod in ['v', 'a', 'va']: print(" sigma_{:<2} = {:.6f}".format(mod, sigmas[mod])) print(" 1/sigma_v**2 + 1/sigma_a**2 = {:.6f}".format(1 / sigmas['v']**2 + 1 / sigmas['a']**2)) print(" 1/sigma_va**2 = {:.6f}".format(1 / sigmas['va']**2)) plot.xlim(np.min(all_x), np.max(all_x)) plot.ylim(0, 100) plot.yticks([0, 50, 100]) plot.xlabel('Frequency (events/sec)') plot.ylabel('Percent high') return [sigmas[k] for k in ['v', 'a', 'va']]
def indifference_point(trialsfile, offers, plot=None, **kwargs): # Load trials trials, A, R, M, perf = utils.load(trialsfile) B_by_offer = {} n_nondecision = 0 for n, trial in enumerate(trials): if perf.choices[n] is None: n_nondecision += 1 continue juice_L, juice_R = trial['juice'] offer = trial['offer'] if perf.choices[n] == 'B': B = 1 elif perf.choices[n] == 'A': B = 0 else: raise ValueError("invalid choice") B_by_offer.setdefault(offer, []).append(B) print("Non-decision trials: {}/{}".format(n_nondecision, len(trials))) pB_by_offer = {} for offer in B_by_offer: Bs = B_by_offer[offer] pB_by_offer[offer] = utils.divide(sum(Bs), len(Bs)) #print(offer, pB_by_offer[offer]) X = [] Y = [] for i, offer in enumerate(offers): B, A = offer X.append((B - A) / (B + A)) Y.append(pB_by_offer[offer]) X = np.asarray(X) Y = np.asarray(Y) idx = np.argsort(X) X = X[idx] Y = Y[idx] #------------------------------------------------------------------------------------- # Fit #------------------------------------------------------------------------------------- try: popt, func = fittools.fit_psychometric(X, Y) mu = popt['mu'] idpt = (1 + mu) / (1 - mu) print("Indifference point = {}".format(idpt)) fit_x = np.linspace(min(X), max(X), 201) fit_y = func(fit_x, **popt) fit = fit_x, fit_y except RuntimeError: print("Unable to fit, drawing a line through the points.") mu = None idpt = None fit = X, Y #------------------------------------------------------------------------------------- # Plot #------------------------------------------------------------------------------------- if plot is None: return idpt lw = kwargs.get('lw', 1.5) ms = kwargs.get('ms', 7) rotation = kwargs.get('rotation', 60) plot.plot(fit_x, 100 * fit_y, '-', color='k', lw=lw) plot.plot(X, 100 * Y, 'o', color='k', ms=ms) plot.hline(50, color='0.5', zorder=2) if mu is not None: plot.text_upper_left('1A = {:.1f}B'.format(idpt), fontsize=10) plot.vline(mu, color='0.5', zorder=2) #plot.xticks(range(len(offers))) #plot.xticklabels(['{}B:{}A'.format(*offer) for offer in offers], rotation=rotation) #plot.xlim(0, len(offers)-1) plot.ylim(0, 100) return idpt
#------------------------------------------------------------------------------------- # Reward #------------------------------------------------------------------------------------- plot = fig['reward'] ntrials = [] rewards = [] pcorrects = [] for record in training_history: ntrials.append(record['n_trials']) rewards.append(record['mean_reward']) perf = record['perf'] pcorrects.append(utils.divide(perf.n_correct, perf.n_decision)) ntrials = np.asarray(ntrials) / T rewards = np.asarray(rewards) pcorrects = np.asarray(pcorrects) print(rewards) w1 = list(np.where(rewards == -1)[0]) w2 = list(np.where(rewards > 0)[0]) try: w1.append(w2[0]) except IndexError: pass dashes = [5, 3] #plot.plot(ntrials[w1], rewards[w1], '--', color=color, lw=lw, dashes=dashes)
#------------------------------------------------------------------------------------- # Reward #------------------------------------------------------------------------------------- plot = fig['reward'] ntrials = [] rewards = [] pcorrects = [] for record in training_history: ntrials.append(record['n_trials']) rewards.append(record['mean_reward']) perf = record['perf'] pcorrects.append(utils.divide(perf.n_correct, perf.n_decision)) ntrials = np.asarray(ntrials)/T rewards = np.asarray(rewards) pcorrects = np.asarray(pcorrects) print(rewards) w1 = list(np.where(rewards == -1)[0]) w2 = list(np.where(rewards > 0)[0]) try: w1.append(w2[0]) except IndexError: pass dashes = [5, 3] #plot.plot(ntrials[w1], rewards[w1], '--', color=color, lw=lw, dashes=dashes)
def indifference_point(trialsfile, offers, plot=None, **kwargs): # Load trials trials, A, R, M, perf = utils.load(trialsfile) B_by_offer = {} n_nondecision = 0 for n, trial in enumerate(trials): if perf.choices[n] is None: n_nondecision += 1 continue juice_L, juice_R = trial['juice'] offer = trial['offer'] if perf.choices[n] == 'B': B = 1 elif perf.choices[n] == 'A': B = 0 else: raise ValueError("invalid choice") B_by_offer.setdefault(offer, []).append(B) print("Non-decision trials: {}/{}".format(n_nondecision, len(trials))) pB_by_offer = {} for offer in B_by_offer: Bs = B_by_offer[offer] pB_by_offer[offer] = utils.divide(sum(Bs), len(Bs)) #print(offer, pB_by_offer[offer]) X = [] Y = [] for i, offer in enumerate(offers): B, A = offer X.append((B - A)/(B + A)) Y.append(pB_by_offer[offer]) X = np.asarray(X) Y = np.asarray(Y) idx = np.argsort(X) X = X[idx] Y = Y[idx] #------------------------------------------------------------------------------------- # Fit #------------------------------------------------------------------------------------- try: popt, func = fittools.fit_psychometric(X, Y) mu = popt['mu'] idpt = (1+mu)/(1-mu) print("Indifference point = {}".format(idpt)) fit_x = np.linspace(min(X), max(X), 201) fit_y = func(fit_x, **popt) fit = fit_x, fit_y except RuntimeError: print("Unable to fit, drawing a line through the points.") mu = None idpt = None fit = X, Y #------------------------------------------------------------------------------------- # Plot #------------------------------------------------------------------------------------- if plot is None: return idpt lw = kwargs.get('lw', 1.5) ms = kwargs.get('ms', 7) rotation = kwargs.get('rotation', 60) plot.plot(fit_x, 100*fit_y, '-', color='k', lw=lw) plot.plot(X, 100*Y, 'o', color='k', ms=ms) plot.hline(50, color='0.5', zorder=2) if mu is not None: plot.text_upper_left('1A = {:.1f}B'.format(idpt), fontsize=10) plot.vline(mu, color='0.5', zorder=2) #plot.xticks(range(len(offers))) #plot.xticklabels(['{}B:{}A'.format(*offer) for offer in offers], rotation=rotation) #plot.xlim(0, len(offers)-1) plot.ylim(0, 100) return idpt
def psychometric(trialsfile, plot, **kwargs): # Load trials trials, A, R, M, perf = utils.load(trialsfile) decision_by_freq = {} high_by_freq = {} for n, trial in enumerate(trials): mod = trial['mod'] freq = trial['freq'] decision_by_freq.setdefault(mod, {}) high_by_freq.setdefault(mod, {}) decision_by_freq[mod].setdefault(freq, []) high_by_freq[mod].setdefault(freq, []) if perf.decisions[n]: decision_by_freq[mod][freq].append(True) if perf.choices[n] == 'H': high = 1 else: high = 0 high_by_freq[mod][freq].append(high) else: decision_by_freq[mod][freq].append(False) freqs = {} p_decision = {} p_high = {} for mod in decision_by_freq: freqs[mod] = np.sort(high_by_freq[mod].keys()) p_decision[mod] = np.zeros(len(freqs[mod])) p_high[mod] = np.zeros(len(freqs[mod])) for i, freq in enumerate(freqs[mod]): p_decision[mod][i] = sum(decision_by_freq[mod][freq])/len(decision_by_freq[mod][freq]) p_high[mod][i] = utils.divide(sum(high_by_freq[mod][freq]), len(high_by_freq[mod][freq])) #------------------------------------------------------------------------------------- # Plot #------------------------------------------------------------------------------------- lw = kwargs.get('lw', 1.5) ms = kwargs.get('ms', 6) all_x = [] all_y = [] sigmas = {} for mod in ['v', 'a', 'va']: if mod == 'v': label = 'Visual' elif mod == 'a': label = 'Auditory' elif mod == 'va': label = 'Multisensory' else: raise ValueError x = freqs[mod] y = p_high[mod] # Fit psychometric curve props = dict(lw=lw, color=colors[mod], label=label) try: popt, func = fittools.fit_psychometric(x, y) sigmas[mod] = popt['sigma'] fit_x = np.linspace(min(x), max(x), 201) fit_y = func(fit_x, **popt) plot.plot(fit_x, 100*fit_y, **props) except RuntimeError: print("Unable to fit, drawing a line through the points.") plot.plot(x, 100*y, **props) plot.plot(x, 100*y, 'o', ms=ms, mew=0, mfc=props['color']) all_x.append(x) # Is it optimal? print("") print(" Optimality test") print(" ---------------") print("") for mod in ['v', 'a', 'va']: print(" sigma_{:<2} = {:.6f}".format(mod, sigmas[mod])) print(" 1/sigma_v**2 + 1/sigma_a**2 = {:.6f}" .format(1/sigmas['v']**2 + 1/sigmas['a']**2)) print(" 1/sigma_va**2 = {:.6f}".format(1/sigmas['va']**2)) plot.xlim(np.min(all_x), np.max(all_x)) plot.ylim(0, 100) plot.yticks([0, 50, 100]) plot.xlabel('Frequency (events/sec)') plot.ylabel('Percent high') return [sigmas[k] for k in ['v', 'a', 'va']]