def __call__(self, fitted_model): # We want to use the fitted model self.hf0 = fitted_model.hf0 self.w = fitted_model.w self.nu = fitted_model.nu self.pi = fitted_model.pi X_ = fitted_model.X.copy() for j in fitted_model.applythreshold: X_[:, j] = threshold.u_v(X_[:, j], self.nu) self.history_evaluation(X_, fitted_model.r, (0.75, .55)) out = [Likelihood_and_Slope_Collector(fitted_model)] #0,1,2 out.append([self.vdifficult]) # 3 out.append([self.veasy]) # 4 out.append([self.phist]) # 5 out.append([self.pstim]) # 6 out.append([self.pSH]) # 7 out.append([self.peasy]) # 8 out.append(fitted_model.pi) # 9,10,11 # out.append ( fitted_model.w[1:self.hf0] ) # 12,...,12+hf0 out.append( self.get_thres(fitted_model.w[:self.hf0], fitted_model.nu, fitted_model.pi, .75)) # 12,...,12+hf0 out.append( self.get_thres(fitted_model.w[:self.hf0], fitted_model.nu, fitted_model.pi, .85)) # 12+hf0,...,12+2*hf0 out.append(fitted_model.nu) # out.append(fitted_model.w) # out.append(np.ravel(self.stimuli)) out.append(np.ravel(self.conditions)) out.append(np.ravel(self.variance_explained)) return np.concatenate(out)
def pmfplot(d, results, infodict, ax, errors=True): """Generate the pmf plot""" for i, c in enumerate(infodict['conditions']): c = int(c) d_ = d.getsummary(c) x = pl.mgrid[infodict['xmin']:infodict['xmax']:100j] if len(d.th_features) > 0: # d_[:,0] = u_v ( d_[:,0], results['model_w_hist'].nu ) # x = u_v ( x, results['model_w_hist'].nu ) d_[:, 0] = u_v(d_[:, 0], results['model_nohist'].nu) x = u_v(x, results['model_nohist'].nu) if errors: graphics.plot_data_summary(d_, ax, infodict['colors'][i], infodict['labels'][i]) else: # AEU: change the marker to make datapoints small. What goes wrong in the plot here? ax.plot(d_[:, 0], d_[:, 1] / d_[:, 2], '.', color=infodict['colors'][i], label=infodict['labels'][i]) # wfit = results['model_w_hist'].w[infodict['indices'][c]] wfit = results['model_nohist'].w[infodict['indices'][i]] w0fit = results['model_w_hist'].w0[infodict['indices'][i]] pfit = results['model_w_hist'].pi p0fit = results['model_nohist'].pi if not d.ground_truth is None: wgfit = d.ground_truth['w'][infodict['indices'][i]] pgfit = d.ground_truth['pi'] gt = graphics.plot_pmf(pgfit, wgfit, x, ax, (np.array([255, 240, 240], 'd') / 255 + infodict['colors'][i]) / 2.) pl.setp(gt, linestyle='--') # graphics.plot_pmf ( pfit, w0fit, x, ax, [.9,.9,.9], alpha=0.1 ) graphics.plot_pmf(p0fit, wfit, x, ax, infodict['colors'][i]) graphics.label_axes(title="(A) psychometric function", xlabel=r"transduced stimulus $u_\nu(s\tilde{z})$", ylabel=r"probability for $r=1$", nxticks=5, ax=ax)
def plot_nonlinearity(nu, x=None, ax=None, color='k'): """Plot a threshold nonlinearity""" from threshold import u_v if ax is None: ax = pl.gca() ax = prepare_axes(ax) if x is None: xmin, xmax = ax.get_xlim() x = pl.mgrid[xmin:xmax:100j] return ax.plot(x, u_v(x, nu), color=color)
def pcorrect(self, x, pleft=0.5, pright=0.5, ind=[0, 1]): """Get probability of a correct response rather than probability of left/right response :Parameters: *x* stimulus intensities *pleft* probability that the stimulus is on the left (or number of stimuli on the left) *pright* probability that the stimulus is on the right """ Z = pleft + pright if Z > 1: pleft /= Z pright /= Z s = threshold.u_v(x, self.nu) psi_p = self.pi[1] + self.pi[2] * logistic(self.w[ind[0]] + self.w[ind[1]] * s) psi_m = self.pi[0] + self.pi[2] * ( 1 - logistic(self.w[ind[0]] - self.w[ind[1]] * s)) return pleft * psi_m + pright * psi_p, s
def e(x): p1 = pi[1] + pi[2] * model.logistic(w[0] + w[i] * threshold.u_v(x, nu)) p2 = 1 - (pi[1] + pi[2] * model.logistic(w[0] + w[i] * threshold.u_v(-x, nu))) return abs(.5 * p1 + .5 * p2 - p)
def history_evaluation(self, X, r, p): """Determine variance explained by history :Parameters: *X* design matrix *r* responses *p* probability correct that is considered the border between easy and difficult """ difficult, easy = performance_filter(r, X, p, hf0=self.hf0) assert np.shape( np.shape(difficult))[0] == 1, 'difficult is not a vectors' assert np.shape(np.shape(easy))[0] == 1, 'easy is not a vectors' # AEU: get both output args from performance_filter #easy = np.logical_not ( difficult ) X_ = X.copy() for j in self.applythreshold: X_[:, j] = threshold.u_v(X[:, j], self.nu) current_stimulus = np.dot(X_[:, 1:self.hf0], self.w[1:self.hf0]) history_features = np.dot(X_[:, self.hf0:], self.w[self.hf0:]) self.vdifficult = np.var ( history_features[difficult] ) / \ (np.var (history_features[difficult]) + np.var(current_stimulus[difficult])) self.veasy = np.var ( history_features[easy] ) / \ (np.var (history_features[easy]) + np.var(current_stimulus[easy])) S = [] V = [] C = [] for condition in xrange(1, self.hf0): stimuli = np.unique(abs(X_[:, condition])) S_ = [] V_ = [] for s in stimuli: if abs(s) < 1e-10: continue i = abs(X_[:, condition]) == s S_.append(s) V_.append( np.var(history_features[i]) / (np.var(history_features[i]) + np.var(current_stimulus[i]))) S.append(S_) V.append(V_) C.append([condition] * len(S_)) self.stimuli = np.concatenate(S) self.conditions = np.concatenate(C) self.variance_explained = np.concatenate(V) # c = -self.w[0] c = 0. self.phist = np.mean((history_features[difficult] > c) == r[difficult]) self.pstim = np.mean((current_stimulus[difficult] > c) == r[difficult]) self.pSH = np.mean(((history_features[difficult] + current_stimulus[difficult]) > c) == r) self.peasy = np.mean((history_features[easy] > c) == r[easy]) return np.var(current_stimulus), np.var(history_features), (S, V)
def __em(self, X, r): """Optimize parameters using expectation maximation :Parameters: *X* design matrix *r* response vector """ w = self.w p = self.pi nu = self.nu # w = np.array ( [.01,.8,-.8,.5] ) if self.verbose: print "Starting values:" print "nu:", nu print "w: ", w print "p: ", p X_ = X.copy() for j in self.applythreshold: X_[:, j] = threshold.u_v(X[:, j], nu) # Expectation gwx = history_model.__combine_features(X_, w) q = history_model.__determine_single_trial_lapses(r, gwx, p) p = history_model.__optimize_p(q, self.pprior) l = history_model.__likelihood(gwx, r, p) for i in xrange(self.emiter): # Maximization nu_ = nu nu = threshold.optimize_nu(X, r, q[:, -1], w, nu, self.applythreshold, niter=self.nuiter, stop=self.nustop) if np.isnan(nu): sys.exit(2) for j in self.applythreshold: X_[:, j] = threshold.u_v(X[:, j], nu) # if len ( self.applythreshold ) == 1: # nu = threshold.optimize_nu ( X, r, q[:,-1], w, nu, niter=self.nuiter, stop=self.nustop ) # if np.isnan(nu): # sys.exit ( 2 ) # for j in self.applythreshold: # X_[:,j] = threshold.u_v ( X[:,j], nu ) # elif len ( self.applythreshold ) > 1: # raise NotImplementedError, "optimization of the threshold nu is not implemented for this case" w_ = w p_ = p w = glm.optimize_w(X_, r, q[:, -1], w, niter=self.glmiter, stop=self.glmstop, lm=self.lmprior) p = history_model.__optimize_p(q, self.pprior) if np.isnan(p).any(): print i, p sys.exit(1) # Expectation gwx = history_model.__combine_features(X_, w) q = history_model.__determine_single_trial_lapses(r, gwx, p) l_ = history_model.__likelihood(gwx, r, p) # Stop? rel_e = np.abs((l_ - l) / l) abs_e = max(max(np.abs(w - w_).max(), np.abs(p - p_).max()), abs(nu - nu_)) if i > self.miniter: if rel_e < self.emstop and abs_e < self.emabs: if self.verbose: sys.stderr.write( "Converged after %d iterations\n relative error: %g\n absolute error: %g\n" % (i, rel_e, abs_e)) break if self.storeopt: self.opt.append([l_, rel_e, abs_e] + [pp for pp in p] + [ww for ww in w] + [float(nu)]) if self.verbose: print l_, rel_e, abs_e l = l_ else: if self.verbose: sys.stderr.write( "No convergence after %d iterations\nrelative error: %g\n" % (i, rel_e)) return w, p, q, l, nu
def figure3 ( ): w,h = 25,8.5 fig = pl.figure ( figsize=(fullwidth,h*fullwidth/w) ) # a,b,c,d = place_axes ( fig, 1.5,2, [9,9,5,5],[6]*4, # [True]*2+[False]*2, [1.8,1.8,.5,.5], (w,h) ) a,b,c = place_axes ( fig, 1.5,2, [9,9,5],[6]*3, [True]*2+[False], [1.8,1.8,.5], (w,h) ) d = fig.add_axes ( [10,10,1,1] ) a.text ( .05, laby, r"\textbf{a}", transform=a.transAxes ) b.text ( .05, laby, r"\textbf{b}", transform=b.transAxes ) c.text ( .05, laby, r"\textbf{c}", transform=c.transAxes ) d.text ( .05, laby, r"\textbf{d}", transform=d.transAxes ) M = results['model_w_hist'] # Figures 3 A,B for condition in plotinfo['conditions']: condition = int ( condition ) print "c",condition d_ = data.getsummary ( condition ) # x = pl.mgrid[0:plotinfo['xmax']:100j] x = pl.mgrid[0:30:100j] # if len(data.th_features)>0: # x = threshold.u_v ( x, results['model_w_hist'].nu ) wfit = results['model_w_hist'].w[plotinfo['indices'][condition]] w0fit = results['model_nohist'].w[plotinfo['indices'][condition]] pfit = results['model_w_hist'].pi p0fit = results['model_nohist'].pi x_ = threshold.u_v ( x, results['model_w_hist'].nu ) x0 = threshold.u_v ( x, results['model_nohist'].nu ) col = plotinfo['colors'][condition] pmf = 0.5*(pfit[1]+pfit[2]*model.logistic ( wfit[0]+wfit[1]*x_ )) + \ 0.5*(1-(pfit[1]+pfit[2]*model.logistic ( wfit[0]-wfit[1]*x_ ))) p0f = 0.5*(p0fit[1]+p0fit[2]*model.logistic ( w0fit[0]+w0fit[1]*x0 )) + \ 0.5*(1-(p0fit[1]+p0fit[2]*model.logistic ( w0fit[0]-w0fit[1]*x0 ))) print p0fit perror = (1-p0f-(1-pmf))/(1-p0f) a.plot ( x, pmf, color = col ) a.plot ( x, p0f, color = col, linestyle='--' ) b.plot ( x, pl.clip(perror,0,1e5), color = col ) a.yaxis.set_major_formatter ( prcformatter ) a.xaxis.set_major_formatter ( myformatter ) a.set_xticks ( (0,10,20,30) ) pl.setp ( (a,b), xlabel='Stimulus intensity' ) a.set_ylabel ( 'Probability correct [\%]' ) b.set_ylabel ( 'Error rate exp. [\%]' ) b.set_xticks ( (0,10,20,30) ) b.yaxis.set_major_locator ( tckr ( density=2, figure=fig, which=1 ) ) b.yaxis.set_major_formatter ( prcformatter ) b.xaxis.set_major_formatter ( myformatter ) if observer in ['KP','sim_KP','sim_KP_nh']: b.set_ylim ( 0, .35 ) if observer in ['pk']: pl.setp ( (a,b), xlim=(-.1,30.1) ) # figure 3 C textfile.write ( "Figure 3C:\n" ) z0 = 0 C = statistics.EvaluationCollector ( M ) ewh = C(results['model_w_hist']) enh = C(results['model_nohist']) hf0 = M.hf0 # perm = results['permutation_wh'] # # TODO: These indices have to be adapted to the revised collector # thresholds_wh = pl.array([C.get_thres ( perm[i,13+hf0:13+2*hf0], perm[i,12+hf0], perm[i,9:12], p=0.75 ) \ # for i in xrange ( 2000 )]) # perm = results['permutation_nh'] # thresholds_nh = pl.array([C.get_thres ( perm[i,13+hf0:13+2*hf0], perm[i,12+hf0], perm[i,9:12], p=0.75 ) \ # for i in xrange ( 2000 )]) if thlev == .75: thind = 11 elif thlev == .85: thind = 10+hf0 else: raise ValueError for condition in xrange ( 1, M.hf0 ): s_wh = results['permutation_wh'][:,thind+condition] s_nh = results['permutation_nh'][:,thind+condition] # s_wh = thresholds_wh[:,condition] # s_nh = thresholds_nh[:,condition] s_ratio = s_wh/s_nh s_ratio_obs = ewh[thind+condition]/enh[thind+condition] # s_ratio_obs = results['model_w_hist'].w[condition]/results['model_nohist'].w[condition] z = (s_ratio_obs-pl.mean(s_ratio))/pl.std(s_ratio) cpe = pl.mean ( s_ratio < s_ratio_obs ) ci = pl.prctile ( s_ratio, (2.5,97.5) ) if z < z0 and ci[1]-ci[0] > 0: c0 = condition s_ratio_ = s_ratio s_ratio_obs_ = s_ratio_obs ci_ = ci textfile.write ( "Condition %d\n th75_ratio = %g\n cpe = %g\n percentiles of Null-Distribution: %g, %g\n" % \ (condition,s_ratio_obs,cpe,ci[0],ci[1]) ) try: print "Using condition %d for figure 3C" % (c0,) except: c0 = 1 s_ratio_ = s_ratio s_ratio_obs_ = s_ratio_obs ci_ = ci hist,bins = pl.histogram ( s_ratio_ ) c.bar ( bins[:-1], hist, pl.diff ( bins ), edgecolor=graphics.histogram_color, facecolor=graphics.histogram_color ) yrange = c.get_ylim () # c.plot ( [1]*2, yrange, 'k:' ) if s_ratio_obs<ci_[0]: c.plot ( [s_ratio_obs_]*2, (yrange[0],yrange[0]+0.85*(yrange[1]-yrange[0])), linewidth=2, color=graphics.observed_color ) c.plot ( [s_ratio_obs_], [yrange[0]+0.95*(yrange[1]-yrange[0])], '*', color=graphics.observed_color ) else: c.plot ( [s_ratio_obs_]*2, yrange, linewidth=2, color=graphics.observed_color ) c.plot ( [ci_[0]]*2, yrange, color=graphics.C95_color ) c.plot ( [ci_[1]]*2, yrange, color=graphics.C95_color ) c.set_ylim ( *yrange ) c.set_xlabel ( r'Threshold ratio' ) c.xaxis.set_major_formatter ( myformatter ) c.xaxis.set_major_formatter ( myformatter ) # c.text ( .7, 0.7, r"$\frac{\theta_\mathrm{h}}{\theta_0}$", # transform=c.transAxes ) # c.set_xlim ( trimmed_hlim ( s_ratio_, s_ratio_obs_ ) ) # c.xaxis.set_major_locator ( tckr ( density=0.4, figure=fig, which=0 ) ) c.set_xlim ( .99, 1.01 ) # c.xaxis.set_ticks ( (.95,1) ) # c.set_xlim ( .85, 1.05 ) c.xaxis.set_ticks ( (.99,1.,1.01) ) # figure 3 D l_wh = 0.5*results['permutation_wh'][:,[9,10]].sum(1) l_nh = 0.5*results['permutation_nh'][:,[9,10]].sum(1) l_ratio = l_wh-l_nh l_ratio_obs = results['model_w_hist'].pi[[0,1]].sum()-results['model_nohist'].pi[[0,1]].sum() cpe = pl.mean ( l_ratio < l_ratio_obs ) ci = pl.prctile ( l_ratio, (2.5,97.5) ) textfile.write ( "Figure 3D:\n lapse_ratio = %g\n cpe = %g\n percentiles of Null-distribution: %g, %g\n lapse_rate (w hist) = %g\n lapse_rate (no hist) = %g\n" % \ (l_ratio_obs,cpe,ci[0],ci[1],results['model_w_hist'].pi[[0,1]].sum(),results['model_nohist'].pi[[0,1]].sum()) ) d = graphics.prepare_axes ( d, haveon=('bottom',) ) # hist,bins = pl.histogram ( l_ratio ) hist,bins = pl.histogram ( l_ratio, bins=good_lapse_bins ( l_ratio ) ) # hist,bins = pl.histogram ( l_ratio, bins=pl.mgrid[-.0001:.0001:20j] ) d.bar ( bins[:-1], hist, pl.diff(bins), edgecolor=graphics.histogram_color, facecolor=graphics.histogram_color, zorder=0 ) yrange = d.get_ylim () # d.plot ( [1]*2, yrange, 'k:' ) if l_ratio_obs < ci[0] or l_ratio_obs > ci[1]: d.plot ( [l_ratio_obs]*2, [yrange[0], yrange[0]+0.85*(yrange[1]-yrange[0])], linewidth=2, color=graphics.observed_color) d.plot ( [l_ratio_obs], [yrange[0]+0.95*(yrange[1]-yrange[0])], '*', color=graphics.observed_color) else: print "lrobs",l_ratio_obs d.plot ( [l_ratio_obs]*2, yrange, color=graphics.observed_color, zorder=2) d.plot ([ci[0]]*2, yrange, color=graphics.C95_color, zorder=1 ) d.plot ([ci[1]]*2, yrange, color=graphics.C95_color, zorder=1 ) d.set_ylim ( yrange ) d.set_xlabel ( r'Asymptote difference' ) # d.text ( .7, 0.7, r"$\frac{\lambda_\mathrm{h}}{\lambda_0}$", # transform=d.transAxes ) # d.set_xlim ( trimmed_hlim ( l_ratio, l_ratio_obs, (0,5) ) ) d.set_xlim ( -.003, .001 ) d.xaxis.set_major_locator ( tckr ( density=0.4, figure=fig, which=0 ) ) d.xaxis.set_ticks ( (-.002,0) ) # d.set_xlim ( (.75, 1.25) ) d.xaxis.set_major_formatter ( myformatter ) a.set_ylim ( .49, 1.01 ) pl.savefig ( "figures/%s3.pdf" % ( figname, ) ) pl.savefig ( "figures/%s3.eps" % ( figname, ) )