def marginalized_analysis(): sys.stdout = tee.tee(STDOUT, open(OUTDIR+'eg-appendix1c.out', 'w')) x, y = make_data() prior = gv.gvar(91 * ['0(1)']) # prior for the fit ymod = y - (f(x, prior) - f(x, prior[:1])) priormod = prior[:1] fit = lsqfit.nonlinear_fit(data=(x, ymod), prior=priormod, fcn=f) print fit.format(maxline=True) sys.stdout = STDOUT print lsqfit.wavg(list(ymod) + list(priormod)) make_plot(x, ymod, fit, 'ymod(x)') inputs = dict(prior=prior, y0=y[0], y1=y[1], y2=y[2], y3=y[3], y4=y[4]) outputs = dict(p0=fit.p[0]) print gv.fmt_errorbudget(inputs=inputs, outputs=outputs) return fit
def marginalized_analysis(): sys.stdout = tee.tee(STDOUT, open(OUTDIR + 'eg-appendix1c.out', 'w')) x, y = make_data() prior = gv.gvar(91 * ['0(1)']) # prior for the fit ymod = y - (f(x, prior) - f(x, prior[:1])) priormod = prior[:1] fit = lsqfit.nonlinear_fit(data=(x, ymod), prior=priormod, fcn=f) print fit.format(maxline=True) sys.stdout = STDOUT print lsqfit.wavg(list(ymod) + list(priormod)) make_plot(x, ymod, fit, 'ymod(x)', name='eg-appendix1c') inputs = dict(prior=prior, y0=y[0], y1=y[1], y2=y[2], y3=y[3], y4=y[4]) outputs = dict(p0=fit.p[0]) print gv.fmt_errorbudget(inputs=inputs, outputs=outputs) return fit
def _fit_plateau(self, svdcut): """Fits the marginalized data to a constant""" if self.tfit is not None: tfit = self.tfit else: tfit = np.arange(self.t_snk) # Average over the remaining plateau yfit = self.marginalized_data[tfit] return lsqfit.wavg(yfit, prior=self.r_guess, svdcut=svdcut)
def main(): gv.ranseed([2009,2010,2011,2012]) # initialize random numbers (opt.) x,y = make_data() # make fit data p0 = None # make larger fits go faster (opt.) sys_stdout = sys.stdout sys.stdout = tee.tee(sys.stdout, open("eg1.out","w")) for nexp in range(3,20): prior = make_prior(nexp) fit = lsqfit.nonlinear_fit(data=(x,y),fcn=f,prior=prior,p0=p0) #, svdcut=SVDCUT) if fit.chi2/fit.dof<1.: p0 = fit.pmean # starting point for next fit (opt.) if nexp in [8, 9, 10]: print(".".center(73)) if nexp > 7 and nexp < 19: continue elif nexp not in [3]: print("") print '************************************* nexp =',nexp print fit.format() # print the fit results E = fit.p['E'] # best-fit parameters a = fit.p['a'] print 'E1/E0 =',E[1]/E[0],' E2/E0 =',E[2]/E[0] print 'a1/a0 =',a[1]/a[0],' a2/a0 =',a[2]/a[0] # extra data 1 print '\n--------------------- fit with extra information' sys.stdout = tee.tee(sys_stdout, open("eg1a.out", "w")) def ratio(p): return p['a'][1] / p['a'][0] newfit = lsqfit.nonlinear_fit(data=gv.gvar(1,1e-5), fcn=ratio, prior=fit.p) print (newfit) # print(newfit.p['a'][1] / newfit.p['a'][0]) # print(fit.p['a'][1] / fit.p['a'][0]) # alternate method for extra data sys.stdout = tee.tee(sys_stdout, open("eg1b.out", "w")) fit.p['a1/a0'] = fit.p['a'][1] / fit.p['a'][0] new_data = {'a1/a0' : gv.gvar(1,1e-5)} new_p = lsqfit.wavg([fit.p, new_data]) print 'chi2/dof = %.2f\n' % (new_p.chi2 / new_p.dof) print 'E:', new_p['E'][:4] print 'a:', new_p['a'][:4] print 'a1/a0:', new_p['a1/a0'] # # extra data 2 # sys.stdout = tee.tee(sys_stdout, open("eg1b.out", "w")) # newfit = fit # for i in range(1): # print '\n--------------------- fit with %d extra data sets' % (i+1) # x, ynew = make_data() # prior = newfit.p # newfit = lsqfit.nonlinear_fit(data=(x,ynew), fcn=f, prior=prior) # , svdcut=SVDCUT) # print newfit sys.stdout = sys_stdout # def fcn(x, p): # return f(x, p), f(x, p) # prior = make_prior(nexp) # fit = lsqfit.nonlinear_fit(data=(x, [y, ynew]), fcn=fcn, prior=prior, p0=newfit.pmean) # , svdcut=SVDCUT) # print(fit) if DO_BOOTSTRAP: Nbs = 40 # number of bootstrap copies outputs = {'E1/E0':[], 'E2/E0':[], 'a1/a0':[],'a2/a0':[],'E1':[],'a1':[]} # results for bsfit in fit.bootstrap_iter(n=Nbs): E = bsfit.pmean['E'] # best-fit parameters a = bsfit.pmean['a'] outputs['E1/E0'].append(E[1]/E[0]) # accumulate results outputs['E2/E0'].append(E[2]/E[0]) outputs['a1/a0'].append(a[1]/a[0]) outputs['a2/a0'].append(a[2]/a[0]) outputs['E1'].append(E[1]) outputs['a1'].append(a[1]) # print E[:2] # print a[:2] # print bsfit.chi2/bsfit.dof # extract means and standard deviations from the bootstrap output for k in outputs: outputs[k] = gv.gvar(np.mean(outputs[k]),np.std(outputs[k])) print 'Bootstrap results:' print 'E1/E0 =',outputs['E1/E0'],' E2/E1 =',outputs['E2/E0'] print 'a1/a0 =',outputs['a1/a0'],' a2/a0 =',outputs['a2/a0'] print 'E1 =',outputs['E1'],' a1 =',outputs['a1'] if DO_PLOT: import pylab as plt ratio = y/fit.fcn(x,fit.pmean) plt.xlim(0,21) plt.xlabel('x') plt.ylabel('y/f(x,p)') plt.errorbar(x=x,y=gv.mean(ratio),yerr=gv.sdev(ratio),fmt='ob') plt.plot([0.0,21.0],[1.0,1.0]) plt.show()
def plot_corr_effective_mass(models,data,fit=None,req=[list(),list()],**kwargs): """ Get all data ready so that it can be plotted on command Allows for dynamic cycling through plots """ _emNMod = len(models) _emIdx = [0] ## -- index of plotted function, in array so it can be modified in functions ## -- objects to hold all plot data ## - Dat/Fit refers to the correlator data or the fit function ## - Central/Error are the central value and errors _emLogRatio = [] _emLogRatioCentral = [] _emLogRatioError = [] _emLogRatioFit = [] _emFoldRatio = [] _emFoldRatioCentral= [] _emFoldRatioError = [] _emFoldRatioFit = [] _emRatioFit = [] _emRatioFitNonZero = [] _emFitCentral = [] _emFitError = [] ## -- timeslice objects _emTPosRatio = [] _emTPosFit = [] _emTPosFold = [] _emTPosFoldFit = [] # ## -- fitting options _emFitMin = 0 _emFitMax = 0 _emSep = 0 fig,ax = plt.subplots(1,figsize=(10,8)) # ## -- setup plot function def do_plot_corr_effective_mass(idx,fig=fig): fig.clear() #fig.set_size_inches(10,10) #doesn't work ax = fig.add_subplot(111) if print_quality: plt.subplots_adjust(bottom=0.15,left=0.18,right=0.97,top=0.95) else: #plt.subplots_adjust(bottom=0.15,left=0.15,right=0.97,top=0.95) pass #fig.set_figheight(20) #doesn't work #fig.set_figwidth(20) key = models[idx[0]].datatag ax.set_xlim([-1,df.cor_len/2]) ax.set_ylim(utp.get_option("y_limit",[0.0,1.4],**kwargs[key])) # # -- plot correlator data if utp.get_option("meff_do_fold",False,**kwargs[key]): ## -- plot fit ax.plot([t for t in _emTPosFit[idx[0]] if t < len(_emTData)/2],_emFitCentral[idx[0]], color=utp.get_option("color3",'b',**kwargs[key])) ax.plot([t for t in _emTPosFit[idx[0]] if t < len(_emTData)/2],_emFitError[idx[0]][0], color=utp.get_option("color3",'b',**kwargs[key]), ls=utp.get_option("linestyle2",'--',**kwargs[key])) ax.plot([t for t in _emTPosFit[idx[0]] if t < len(_emTData)/2],_emFitError[idx[0]][1], color=utp.get_option("color3",'b',**kwargs[key]), ls=utp.get_option("linestyle2",'--',**kwargs[key])) ## -- _emTPosRatio not necessarily symmetric, get times correct ax.errorbar(_emTPosFold[idx[0]],_emFoldRatioCentral[idx[0]],yerr=_emFoldRatioError[idx[0]], mfc=utp.get_option("markerfacecolor1",'None',**kwargs[key]), mec=utp.get_option("markeredgecolor1",'k',**kwargs[key]), color=utp.get_option("markeredgecolor1",'k',**kwargs[key]), ls=utp.get_option("linestyle1",'None',**kwargs[key]), marker=utp.get_option("marker1",'o',**kwargs[key]), ms=utp.get_option("markersize",10,**kwargs[key])) ax.scatter(_emTPosFoldFit[idx[0]],gv.mean(_emFoldRatioFit[idx[0]]), color=utp.get_option("color1",'r',**kwargs[key]), marker=utp.get_option("marker",'o',**kwargs[key]), s=utp.get_option("markersize",100,**kwargs[key])) else: ## -- plot fit ax.plot(_emTPosFit[idx[0]],_emFitCentral[idx[0]], color=utp.get_option("color3",'b',**kwargs[key])) ax.plot(_emTPosFit[idx[0]],_emFitError[idx[0]][0], color=utp.get_option("color3",'b',**kwargs[key]), ls=utp.get_option("linestyle2",'--',**kwargs[key])) ax.plot(_emTPosFit[idx[0]],_emFitError[idx[0]][1], color=utp.get_option("color3",'b',**kwargs[key]), ls=utp.get_option("linestyle2",'--',**kwargs[key])) ## -- ax.errorbar(_emTPosRatio[idx[0]],_emLogRatioCentral[idx[0]],yerr=_emLogRatioError[idx[0]], mfc=utp.get_option("markerfacecolor1",'None',**kwargs[key]), mec=utp.get_option("markeredgecolor1",'k',**kwargs[key]), color=utp.get_option("markeredgecolor1",'k',**kwargs[key]), ls=utp.get_option("linestyle1",'None',**kwargs[key]), marker=utp.get_option("marker1",'o',**kwargs[key]), ms=utp.get_option("markersize",8,**kwargs[key])) ax.scatter(_emTPosFit[idx[0]],gv.mean(_emLogRatioFit[idx[0]]), color=utp.get_option("color1",'r',**kwargs[key]), marker=utp.get_option("marker",'o',**kwargs[key]), s=utp.get_option("markersize",64,**kwargs[key])) fig.suptitle(utp.get_option("plottitleem",str(idx[0])+" default title "+str(key),**kwargs[key]), fontsize=utp.get_option("titlesize",20,**kwargs[key])) # -- modify some options if print_quality: ax.set_xlabel(r'$t$',fontsize=40) if sn_ratio: ax.set_ylabel(utp.get_option("yaxistitle", r"$-\frac{1}{"+str(_emSep)+r"}v_{i}^{T}\,log\frac{C_{ij}(t+"+str(_emSep)+r")}{C_{ij}(t)}w_{j}$", **kwargs[key]),fontsize=40) else: ax.set_ylabel(utp.get_option("yaxistitle", r"$-\frac{1}{"+str(_emSep)+r"}\,log\frac{C_{ij}(t+"+str(_emSep)+r")}{C_{ij}(t)}$", **kwargs[key]),fontsize=40) plt.xticks(plt.xticks()[0],fontsize=24) plt.yticks(plt.yticks()[0],fontsize=24) else: ax.set_xlabel(r'$t$') ax.set_ylabel(utp.get_option("yaxistitle", r"$-\frac{1}{"+str(_emSep)+r"}\,log\frac{C(t+"+str(_emSep)+r")}{C(t)}$",**kwargs[key])) for item in ([ax.xaxis.label,ax.yaxis.label]): # must be after setting label content (LaTeX ruins it) item.set_fontsize(fontsize=utp.get_option("fontsize",20,**kwargs[key])) rect =fig.patch rect.set_facecolor('white') if utp.get_option("to_file",False,**kwargs[key]): save_dir = utp.get_option("em_save_dir","./plotdump",**kwargs[key]) save_name = utp.get_option("em_save_name","emplot-"+key+".pdf",**kwargs[key]) plt.savefig(save_dir+'/'+save_name) if utp.get_option("to_terminal",True,**kwargs[key]): plt.draw() pass # ## -- setup button press action function def press_effective_mass(event,idx=_emIdx): #print('press_effective_mass', event.key) try: ## -- manually indicate index idx[0] = int(event.key) + (idx[0])*10 except ValueError: if event.key==' ': ## -- space ## -- allows for replotting when changing index by typing number keys idx[0] = idx[0] % _emNMod do_plot_corr_effective_mass(idx) elif event.key=='left': idx[0] = (idx[0] - 1) % _emNMod do_plot_corr_effective_mass(idx) elif event.key=='right': idx[0] = (idx[0] + 1) % _emNMod do_plot_corr_effective_mass(idx) elif event.key=='backspace': ## -- reset index so can manually flip through using number keys idx[0] = 0 elif event.key=='d': ## -- dump plots into ./plotdump directory for ix,model in zip(range(len(models)),models): key = model.datatag save_dir = utp.get_option("em_save_dir","./plotdump",**kwargs[key]) save_name = utp.get_option("em_save_name","emplot-"+key+".png",**kwargs[key]) do_plot_corr_effective_mass([ix]) plt.savefig(save_dir+'/'+save_name) do_plot_corr_effective_mass(idx) # ## -- fig.canvas.mpl_connect('key_press_event',press_effective_mass) ## -- save plot data for idx,model in zip(range(len(models)),models): key = model.datatag ## -- parameters used in fitting ## default = 2 _emSep = utp.get_option("meff_sep",2,**kwargs[key]) ## default = smallest t not included in fit _emFitMin = utp.get_option("meff_fit_min",model.tfit[-1]+1,**kwargs[key]) ## default = midpoint - sep _emFitMax = utp.get_option("meff_fit_max", model.tdata[-1]/2-_emSep-int(model.tdata[-1]/12),**kwargs[key]) _emTData = model.tdata _emTFit = range(_emFitMin,_emFitMax) _emTFit = np.append(_emTFit,list(sorted([len(_emTData) - t for t in _emTFit]))) if not(fit is None) and (len(req[0]) > 0 or len(req[1]) > 0): _emSubFcn = utp.mask_fit_fcn(model,fit,req,invert=False) _emSub = np.array(_emSubFcn(np.array(_emTData))) else: _emSub = 0 _emDataFold = utf.fold_data(data[key]-_emSub,(model.tp < 0)) #_emTDataNonZero = [t for t in _emTData if np.abs(gv.mean(data[key])[t]) > 1e-20] #_emTDataNonZero = [t for t in range(len(_emDataFold)) if np.mean(_emDataFold[t]) > 1e-20] # ## -- data _emRatio = np.array(_emDataFold[_emSep:])/np.array(_emDataFold[:-_emSep]) _emTDataRatio = np.array(range(len(_emRatio))) _emTDataNonZero = np.array([t for t in range(len(_emRatio)) if _emRatio[t] > 1e-20]) #_emRatio = np.array([-gv.log(x)/_emSep for x in _emRatio if x > 1e-20]) #_emTDataRatio =\ # [t for t in _emTData # if (t in _emTDataNonZero) and (t <= _emTData[-1]/2 +1 - _emSep) ] # first half #_emTDataRatio = np.append(_emTDataRatio, # [t for t in _emTData # if (t in _emTDataNonZero) and (t >= _emTData[-1]/2 +1 + _emSep) ] ) # second half #_emRatio =\ # [data[key][t+_emSep]/data[key][t] for t in _emTData # if (t in _emTDataNonZero) and (t <= _emTData[-1]/2 +1 - _emSep) ] # first half #_emRatio = np.append(_emRatio, # [data[key][t-_emSep]/data[key][t] for t in _emTData # if (t in _emTDataNonZero) and (t >= _emTData[-1]/2 +1 + _emSep) ] ) # second half ## -- times _emTPosRatio.append( [_emTDataRatio[t] for t in range(len(_emTDataRatio)) if _emRatio[t] > 0] ) _emTPosFit.append( [_emTDataRatio[t] for t in range(len(_emTDataRatio)) if _emRatio[t] > 0 and _emTDataRatio[t] in _emTFit] ) ## -- ratios _emLogRatio.append( [-gv.log(_emRatio[t])/_emSep for t in range(len(_emTDataRatio)) if _emRatio[t] > 0] ) _emLogRatioFit.append( [-gv.log(_emRatio[t])/_emSep for t in range(len(_emTDataRatio)) if (gv.mean(_emRatio[t]) > 0) and (_emTDataRatio[t] in _emTPosFit[-1])] ) _emFoldRatio.append(_emLogRatio[-1]) _emFoldRatioFit.append(_emLogRatioFit[-1]) _emTPosFold.append(_emTPosRatio[-1]) _emTPosFoldFit.append(_emTPosFit[-1]) ## -- folding #_emFoldRatio.append(list()) #_emFoldRatioFit.append(list()) #_emTPosFold.append(list()) #_emTPosFoldFit.append(list()) #for t in range(1,len(_emTData)/2): # if not(t in _emTPosRatio[-1]) or not(len(_emTData)-t in _emTPosRatio[-1]): # continue # _emFoldRatio[-1].append((_emLogRatio[-1][list(_emTPosRatio[-1]).index(t)] # +_emLogRatio[-1][list(_emTPosRatio[-1]).index(len(_emTData)-t)])/2) # _emTPosFold[-1].append(t) # if not(t in _emTPosFit[-1]) or not(len(_emTData)-t in _emTPosFit[-1]): # continue # _emFoldRatioFit[-1].append((_emLogRatio[-1][list(_emTPosRatio[-1]).index(t)] # +_emLogRatio[-1][list(_emTPosRatio[-1]).index(len(_emTData)-t)])/2) # _emTPosFoldFit[-1].append(t) #for t in range(len(_emTPosFold[-1])): # print t,_emTPosFold[-1][t],_emFoldRatio[-1][t] #for t in range(len(_emTPosFoldFit[-1])): # print t,_emTPosFoldFit[-1][t],_emFoldRatioFit[-1][t] _emLogRatioCentral.append(gv.mean(_emLogRatio[-1])) _emLogRatioError.append([ list(gv.sdev(_emLogRatio[-1])), list(gv.sdev(_emLogRatio[-1])) ]) _emFoldRatioCentral.append(gv.mean(_emFoldRatio[-1])) _emFoldRatioError.append([ list(gv.sdev(_emFoldRatio[-1])), list(gv.sdev(_emFoldRatio[-1])) ]) ## -- fit _emRatioFit.append(lsq.wavg(_emLogRatioFit[-1])) if utp.get_option("meff_do_fold",False,**kwargs[key]): _emFitCentral.append([gv.mean(_emRatioFit[-1]) for t in _emTPosFit[-1] if t < len(_emTData)/2]) _emFitError.append( [list(np.array(_emFitCentral[-1])-np.array([gv.sdev(_emRatioFit[-1]) for t in _emTPosFit[-1] if t < len(_emTData)/2])), list(np.array(_emFitCentral[-1])+np.array([gv.sdev(_emRatioFit[-1]) for t in _emTPosFit[-1] if t < len(_emTData)/2]))]) else: _emFitCentral.append([gv.mean(_emRatioFit[-1]) for t in _emTPosFit[-1]]) _emFitError.append( [list(np.array(_emFitCentral[-1])-np.array([gv.sdev(_emRatioFit[-1]) for t in _emTPosFit[-1]])), list(np.array(_emFitCentral[-1])+np.array([gv.sdev(_emRatioFit[-1]) for t in _emTPosFit[-1]]))]) print "Best plateau fits: " for key,rfit in zip([model.datatag for model in models],_emRatioFit): print " ",key," : ",rfit print " ----------------- " _emRatioFitNonZero = [x for x in _emRatioFit if not(x is None)] print " avg : ",lsq.wavg(_emRatioFitNonZero) ## -- done saving data if not(utp.get_option("to_terminal",True,**kwargs[key])) and\ utp.get_option("to_file",False,**kwargs[key]): for ix in range(len(models)): ## -- loops and saves all without creating window do_plot_corr_effective_mass([ix]) else: do_plot_corr_effective_mass(_emIdx)
def main(): x, y = make_data() # make fit data # y = gv.gvar(gv.mean(y), 0.75**2 * gv.evalcov(y)) p0 = None # make larger fits go faster (opt.) sys_stdout = sys.stdout sys.stdout = tee.tee(sys.stdout, open("eg1.out", "w")) for nexp in range(1, 7): prior = make_prior(nexp) fit = lsqfit.nonlinear_fit(data=(x, y), fcn=fcn, prior=prior, p0=p0) if fit.chi2 / fit.dof < 1.: p0 = fit.pmean # starting point for next fit (opt.) print '************************************* nexp =', nexp print fit.format() # print the fit results E = fit.p['E'] # best-fit parameters a = fit.p['a'] if nexp > 2: print 'E1/E0 =', E[1] / E[0], ' E2/E0 =', E[2] / E[0] print 'a1/a0 =', a[1] / a[0], ' a2/a0 =', a[2] / a[0] print # error budget outputs = { 'E1/E0': E[1] / E[0], 'E2/E0': E[2] / E[0], 'a1/a0': a[1] / a[0], 'a2/a0': a[2] / a[0] } inputs = {'E': fit.prior['E'], 'a': fit.prior['a'], 'y': y} inputs = collections.OrderedDict() inputs['a'] = fit.prior['a'] inputs['E'] = fit.prior['E'] inputs['y'] = fit.data[1] print '================= Error Budget Analysis' print fit.fmt_values(outputs) print fit.fmt_errorbudget(outputs, inputs) sys.stdout = sys_stdout # print(gv.gvar(str(a[1])) / gv.gvar(str(a[0])) ) # print(gv.evalcorr([fit.p['a'][1], fit.p['E'][1]])) # print(fit.format(True)) # redo fit with 4 parameters since that is enough prior = make_prior(4) fit = lsqfit.nonlinear_fit(data=(x, y), fcn=fcn, prior=prior, p0=fit.pmean) sys.stdout = tee.tee(sys_stdout, open("eg1a.out", "w")) print '--------------------- original fit' print fit.format() E = fit.p['E'] # best-fit parameters a = fit.p['a'] print 'E1/E0 =', E[1] / E[0], ' E2/E0 =', E[2] / E[0] print 'a1/a0 =', a[1] / a[0], ' a2/a0 =', a[2] / a[0] print # extra data 1 print '\n--------------------- new fit to extra information' def ratio(p): return p['a'][1] / p['a'][0] newfit = lsqfit.nonlinear_fit(data=gv.gvar(1, 1e-5), fcn=ratio, prior=fit.p) print(newfit.format()) E = newfit.p['E'] a = newfit.p['a'] print 'E1/E0 =', E[1] / E[0], ' E2/E0 =', E[2] / E[0] print 'a1/a0 =', a[1] / a[0], ' a2/a0 =', a[2] / a[0] if DO_PLOT: import matplotlib.pyplot as plt ratio = y / fit.fcn(x, fit.pmean) plt.xlim(4, 15) plt.ylim(0.95, 1.05) plt.xlabel('x') plt.ylabel('y / f(x,p)') plt.yticks([0.96, 0.98, 1.00, 1.02, 1.04], ['0.96', '0.98', '1.00', '1.02', '1.04']) plt.errorbar(x=x, y=gv.mean(ratio), yerr=gv.sdev(ratio), fmt='ob') plt.plot([4.0, 21.0], [1.0, 1.0], 'b:') plt.savefig('eg1.png', bbox_inches='tight') plt.show() # alternate method for extra data sys.stdout = tee.tee(sys_stdout, open("eg1b.out", "w")) fit.p['a1/a0'] = fit.p['a'][1] / fit.p['a'][0] new_data = {'a1/a0': gv.gvar(1, 1e-5)} new_p = lsqfit.wavg([fit.p, new_data]) print 'chi2/dof = %.2f\n' % (new_p.chi2 / new_p.dof) print 'E:', new_p['E'][:4] print 'a:', new_p['a'][:4] print 'a1/a0:', new_p['a1/a0'] if DO_BAYES: # Bayesian Fit gv.ranseed([123]) prior = make_prior(4) fit = lsqfit.nonlinear_fit(data=(x, y), fcn=f, prior=prior, p0=fit.pmean) sys.stdout = tee.tee(sys_stdout, open("eg1c.out", "w")) # print fit expval = lsqfit.BayesIntegrator(fit, limit=10.) # adapt integrator to PDF expval(neval=40000, nitn=10) # calculate expectation value of function g(p) fit_hist = gv.PDFHistogram(fit.p['E'][0]) def g(p): parameters = [p['a'][0], p['E'][0]] return dict( mean=parameters, outer=np.outer(parameters, parameters), hist=fit_hist.count(p['E'][0]), ) r = expval(g, neval=40000, nitn=10, adapt=False) # print results print r.summary() means = r['mean'] cov = r['outer'] - np.outer(r['mean'], r['mean']) print 'Results from Bayesian Integration:' print 'a0: mean =', means[0], ' sdev =', cov[0, 0]**0.5 print 'E0: mean =', means[1], ' sdev =', cov[1, 1]**0.5 print 'covariance from Bayesian integral =', np.array2string( cov, prefix=36 * ' ') print print 'Results from Least-Squares Fit:' print 'a0: mean =', fit.p['a'][0].mean, ' sdev =', fit.p['a'][0].sdev print 'E0: mean =', fit.p['E'][0].mean, ' sdev =', fit.p['E'][0].sdev print 'covariance from least-squares fit =', np.array2string( gv.evalcov([fit.p['a'][0], fit.p['E'][0]]), prefix=36 * ' ', precision=3) sys.stdout = sys_stdout # make histogram of E[0] probabilty plt = fit_hist.make_plot(r['hist']) plt.xlabel('$E_0$') plt.ylabel('probability') plt.savefig('eg1c.png', bbox_inches='tight') # plt.show() if DO_BOOTSTRAP: Nbs = 40 # number of bootstrap copies outputs = { 'E1/E0': [], 'E2/E0': [], 'a1/a0': [], 'a2/a0': [], 'E1': [], 'a1': [] } # results for bsfit in fit.bootstrap_iter(n=Nbs): E = bsfit.pmean['E'] # best-fit parameters a = bsfit.pmean['a'] outputs['E1/E0'].append(E[1] / E[0]) # accumulate results outputs['E2/E0'].append(E[2] / E[0]) outputs['a1/a0'].append(a[1] / a[0]) outputs['a2/a0'].append(a[2] / a[0]) outputs['E1'].append(E[1]) outputs['a1'].append(a[1]) # print E[:2] # print a[:2] # print bsfit.chi2/bsfit.dof # extract means and standard deviations from the bootstrap output for k in outputs: outputs[k] = gv.gvar(np.mean(outputs[k]), np.std(outputs[k])) print 'Bootstrap results:' print 'E1/E0 =', outputs['E1/E0'], ' E2/E1 =', outputs['E2/E0'] print 'a1/a0 =', outputs['a1/a0'], ' a2/a0 =', outputs['a2/a0'] print 'E1 =', outputs['E1'], ' a1 =', outputs['a1']
def __init__(self, data, ampl='0(1)', dE='1(1)', E=None, s=(1, -1), tp=None, tmin=6, svdcut=1e-6, osc=False, nterm=10): """ Args: data: list / array of correlator data ampl: str, the prior for the amplitude. Default is '0(1)' dE: str, the prior for the energy splitting. Default is '1(1)' E0: str, the prior for the ground state energy. Default is None, which corresponds to taking the value for dE for the ground state as well s: tuple (s, so) with the signs for the towers of decay and oscillating states, repsectively. Default is (1, -1) tp: int, the periodicity of the data. Negative tp denotes antiperiodic "sinh-like" data. Default is None, corresponding to exponential decay tmin: int, the smallest tmin to include in the "averaging" svdcut: float, the desired svd cut for the "averaging" osc: bool, whether to estimate the lowest-lying oscillating state instead of the decay state nterms: the number of terms to include in the towers of decaying and oscillating states. Raises: RuntimeError: Can't estimate energy when cosh(E) < 1. """ self.osc = osc self.nterm = nterm s = self._to_tuple(s) a, ao = self._build(ampl) dE, dEo = self._build(dE, E) s, so = s tmax = None if tp is None: # Data is not periodic # Model data with exponential decay def g(E, t): return gv.exp(-E * t) elif tp > 0: # Data is periodic # Model with a cosh def g(E, t): return gv.exp(-E * t) + gv.exp(-E * (tp - t)) if tmin > 1: tmax = -tmin + 1 else: tmax = None elif tp < 0: # Data is antiperiodic # Model with a sinh def g(E, t): return gv.exp(-E * t) - gv.exp(-E * (-tp - t)) # Reflect and fold the data around the midpoint tmid = int((-tp + 1) // 2) data_rest = lsqfit.wavg( [data[1:tmid], -data[-1:-tmid:-1]], svdcut=svdcut) data = np.array([data[0]] + list(data_rest)) else: raise ValueError('FastFit: bad tp') t = np.arange(len(data))[tmin:tmax] data = data[tmin:tmax] if not t.size: raise ValueError( 'FastFit: tmin too large? No t values left. ' f'(tmin, tmax, tp)=({tmin}, {tmax}, {tp}).' ) self.tmin = tmin self.tmax = tmax if osc: data *= (-1) ** t * so a, ao = ao, a dE, dEo = dEo, dE s, so = so, s d_data = 0. E = np.cumsum(dE) # Sum the tower of decaying states, excluding the ground state for aj, Ej in list(zip(a, E))[1:]: d_data += s * aj * g(Ej, t) # Sum the full tower of oscillating states if ao is not None and dEo is not None: Eo = np.cumsum(dEo) for aj, Ej in zip(ao, Eo): d_data += so * aj * g(Ej, t) * (-1) ** t # Marginalize over the exicted states data = data - d_data self.marginalized_data = data # Average over the remaining plateau meff = 0.5 * (data[2:] + data[:-2]) / data[1:-1] ratio = lsqfit.wavg(meff, prior=gv.cosh(E[0]), svdcut=svdcut) if ratio >= 1: self.E = type(ratio)(gv.arccosh(ratio), ratio.fit) self.ampl = lsqfit.wavg(data / g(self.E, t) / s, svdcut=svdcut, prior=a[0]) else: LOGGER.warn( 'Cannot estiamte energy in FastFit: cosh(E) = %s', str(ratio) ) self.E = None self.ampl = None
def main(): gv.ranseed([2009,2010,2011,2012]) # initialize random numbers (opt.) x,y = make_data() # make fit data p0 = None # make larger fits go faster (opt.) sys_stdout = sys.stdout sys.stdout = tee.tee(sys.stdout, open("eg1.out","w")) for nexp in range(1, 11): prior = make_prior(nexp) fit = lsqfit.nonlinear_fit(data=(x,y),fcn=f,prior=prior,p0=p0) #, svdcut=SVDCUT) if fit.chi2/fit.dof<1.: p0 = fit.pmean # starting point for next fit (opt.) if nexp > 5 and nexp < 10: print(".".center(73)) continue elif nexp not in [1]: print("") print '************************************* nexp =',nexp print fit.format() # print the fit results E = fit.p['E'] # best-fit parameters a = fit.p['a'] if nexp > 2: print 'E1/E0 =',E[1]/E[0],' E2/E0 =',E[2]/E[0] print 'a1/a0 =',a[1]/a[0],' a2/a0 =',a[2]/a[0] # redo fit with 4 parameters since that is enough prior = make_prior(4) fit = lsqfit.nonlinear_fit(data=(x,y), fcn=f, prior=prior, p0=fit.pmean) sys.stdout = sys_stdout print fit # extra data 1 print '\n--------------------- fit with extra information' sys.stdout = tee.tee(sys_stdout, open("eg1a.out", "w")) def ratio(p): return p['a'][1] / p['a'][0] newfit = lsqfit.nonlinear_fit(data=gv.gvar(1,1e-5), fcn=ratio, prior=fit.p) print (newfit) E = newfit.p['E'] a = newfit.p['a'] print 'E1/E0 =',E[1]/E[0],' E2/E0 =',E[2]/E[0] print 'a1/a0 =',a[1]/a[0],' a2/a0 =',a[2]/a[0] # alternate method for extra data sys.stdout = tee.tee(sys_stdout, open("eg1b.out", "w")) fit.p['a1/a0'] = fit.p['a'][1] / fit.p['a'][0] new_data = {'a1/a0' : gv.gvar(1,1e-5)} new_p = lsqfit.wavg([fit.p, new_data]) print 'chi2/dof = %.2f\n' % (new_p.chi2 / new_p.dof) print 'E:', new_p['E'][:4] print 'a:', new_p['a'][:4] print 'a1/a0:', new_p['a1/a0'] if DO_BAYES: # Bayesian Fit gv.ranseed([123]) prior = make_prior(4) fit = lsqfit.nonlinear_fit(data=(x,y), fcn=f, prior=prior, p0=fit.pmean) sys.stdout = tee.tee(sys_stdout, open("eg1c.out", "w")) # print fit expval = lsqfit.BayesIntegrator(fit, limit=10.) # adapt integrator to PDF expval(neval=10000, nitn=10) # calculate expectation value of function g(p) fit_hist = gv.PDFHistogram(fit.p['E'][0]) def g(p): parameters = [p['a'][0], p['E'][0]] return dict( mean=parameters, outer=np.outer(parameters, parameters), hist=fit_hist.count(p['E'][0]), ) r = expval(g, neval=10000, nitn=10, adapt=False) # print results print r.summary() means = r['mean'] cov = r['outer'] - np.outer(r['mean'], r['mean']) print 'Results from Bayesian Integration:' print 'a0: mean =', means[0], ' sdev =', cov[0,0]**0.5 print 'E0: mean =', means[1], ' sdev =', cov[1,1]**0.5 print 'covariance from Bayesian integral =', np.array2string(cov, prefix=36 * ' ') print print 'Results from Least-Squares Fit:' print 'a0: mean =', fit.p['a'][0].mean, ' sdev =', fit.p['a'][0].sdev print 'E0: mean =', fit.p['E'][0].mean, ' sdev =', fit.p['E'][0].sdev print 'covariance from least-squares fit =', np.array2string(gv.evalcov([fit.p['a'][0], fit.p['E'][0]]), prefix=36*' ',precision=3) sys.stdout = sys_stdout # make histogram of E[0] probabilty plt = fit_hist.make_plot(r['hist']) plt.xlabel('$E_0$') plt.ylabel('probability') plt.savefig('eg1c.png', bbox_inches='tight') # plt.show() # # extra data 2 # sys.stdout = tee.tee(sys_stdout, open("eg1b.out", "w")) # newfit = fit # for i in range(1): # print '\n--------------------- fit with %d extra data sets' % (i+1) # x, ynew = make_data() # prior = newfit.p # newfit = lsqfit.nonlinear_fit(data=(x,ynew), fcn=f, prior=prior) # , svdcut=SVDCUT) # print newfit sys.stdout = sys_stdout # def fcn(x, p): # return f(x, p), f(x, p) # prior = make_prior(nexp) # fit = lsqfit.nonlinear_fit(data=(x, [y, ynew]), fcn=fcn, prior=prior, p0=newfit.pmean) # , svdcut=SVDCUT) # print(fit) if DO_BOOTSTRAP: Nbs = 40 # number of bootstrap copies outputs = {'E1/E0':[], 'E2/E0':[], 'a1/a0':[],'a2/a0':[],'E1':[],'a1':[]} # results for bsfit in fit.bootstrap_iter(n=Nbs): E = bsfit.pmean['E'] # best-fit parameters a = bsfit.pmean['a'] outputs['E1/E0'].append(E[1]/E[0]) # accumulate results outputs['E2/E0'].append(E[2]/E[0]) outputs['a1/a0'].append(a[1]/a[0]) outputs['a2/a0'].append(a[2]/a[0]) outputs['E1'].append(E[1]) outputs['a1'].append(a[1]) # print E[:2] # print a[:2] # print bsfit.chi2/bsfit.dof # extract means and standard deviations from the bootstrap output for k in outputs: outputs[k] = gv.gvar(np.mean(outputs[k]),np.std(outputs[k])) print 'Bootstrap results:' print 'E1/E0 =',outputs['E1/E0'],' E2/E1 =',outputs['E2/E0'] print 'a1/a0 =',outputs['a1/a0'],' a2/a0 =',outputs['a2/a0'] print 'E1 =',outputs['E1'],' a1 =',outputs['a1'] if DO_PLOT: import matplotlib.pyplot as plt ratio = y / fit.fcn(x,fit.pmean) plt.xlim(4, 21) plt.xlabel('x') plt.ylabel('y / f(x,p)') plt.errorbar(x=x,y=gv.mean(ratio),yerr=gv.sdev(ratio),fmt='ob') plt.plot([4.0, 21.0], [1.0, 1.0], 'b:') plt.savefig('eg1.png', bbox_inches='tight') plt.show()
def plot_corr_effective_mass_check(models,data,fit=None,**kwargs): """ Get all data ready so that it can be plotted on command Allows for dynamic cycling through plots """ _emNMod = len(models) _emIdx = [0] ## -- index of plotted function, in array so it can be modified in functions ## -- objects to hold all plot data ## - Dat/Fit refers to the correlator data or the fit function ## - Central/Error are the central value and errors _emLogRatio = [] _emLogRatioCentral = [] _emLogRatioError = [] _emLogRatioFit = [] _emRatioFit = [] _emRatioFitNonZero = [] _emFitCentral = [] _emFitError = [] ## -- timeslice objects _emTPosRatio = [] _emTPosFit = [] # ## -- fitting options _emFitMin = 0 _emFitMax = 0 _emSep = 0 fig,ax = plt.subplots(1) # ## -- setup plot function def do_plot_corr_effective_mass_check(idx,fig=fig): fig.clear() ax = fig.add_subplot(111) key = models[idx[0]].datatag ax.set_ylim(utp.get_option("y_limit",[0.0,1.2],**kwargs[key])) # ## -- plot fit ax.plot(_emTPosFit[idx[0]],_emFitCentral[idx[0]], color=utp.get_option("color3",'b',**kwargs[key])) ax.plot(_emTPosFit[idx[0]],_emFitError[idx[0]][0], color=utp.get_option("color3",'b',**kwargs[key]), ls=utp.get_option("linestyle2",'--',**kwargs[key])) ax.plot(_emTPosFit[idx[0]],_emFitError[idx[0]][1], color=utp.get_option("color3",'b',**kwargs[key]), ls=utp.get_option("linestyle2",'--',**kwargs[key])) ## -- plot reference for val in df.ec_reference_lines: vt = [val for t in _emTPosFit[idx[0]]] ax.plot(_emTPosFit[idx[0]],vt, color=utp.get_option("color2",'g',**kwargs[key])) # -- plot correlator data ax.errorbar(_emTPosRatio[idx[0]],_emLogRatioCentral[idx[0]],yerr=_emLogRatioError[idx[0]], mfc=utp.get_option("markerfacecolor1",'None',**kwargs[key]), mec=utp.get_option("markeredgecolor1",'k',**kwargs[key]), color=utp.get_option("markeredgecolor1",'k',**kwargs[key]), ls=utp.get_option("linestyle1",'None',**kwargs[key]), marker=utp.get_option("marker1",'o',**kwargs[key]), ms=utp.get_option("markersize",6,**kwargs[key])) ax.scatter(_emTPosFit[idx[0]],gv.mean(_emLogRatioFit[idx[0]]), color=utp.get_option("color1",'r',**kwargs[key]), marker=utp.get_option("marker",'o',**kwargs[key]), s=utp.get_option("markersize",36,**kwargs[key])) fig.suptitle(utp.get_option("plottitle",str(idx[0])+" default title "+str(key),**kwargs[key]), fontsize=utp.get_option("titlesize",20,**kwargs[key])) # -- modify some options ax.set_xlabel(r'$t$ slice') ax.set_ylabel(utp.get_option("yaxistitle", r"$-\frac{1}{"+str(_emSep)+r"}\,log\frac{C(t+"+str(_emSep)+r")}{C(t)}$",**kwargs[key])) for item in ([ax.xaxis.label,ax.yaxis.label]): # must be after setting label content (LaTeX ruins it) item.set_fontsize(fontsize=utp.get_option("fontsize",20,**kwargs[key])) rect =fig.patch rect.set_facecolor('white') if utp.get_option("to_file",False,**kwargs[key]): save_dir = utp.get_option("ec_save_dir","./plotdump",**kwargs[key]) save_name = utp.get_option("ec_save_name","ecplot-"+key+".pdf",**kwargs[key]) plt.savefig(save_dir+'/'+save_name) if utp.get_option("to_terminal",True,**kwargs[key]): plt.draw() pass # ## -- setup button press action function def press_effective_mass(event,idx=_emIdx): #print('press_effective_mass', event.key) try: ## -- manually indicate index idx[0] = int(event.key) + (idx[0])*10 except ValueError: if event.key==' ': ## -- space ## -- allows for replotting when changing index by typing number keys idx[0] = idx[0] % _emNMod do_plot_corr_effective_mass_check(idx) elif event.key=='left': idx[0] = (idx[0] - 1) % _emNMod do_plot_corr_effective_mass_check(idx) elif event.key=='right': idx[0] = (idx[0] + 1) % _emNMod do_plot_corr_effective_mass_check(idx) elif event.key=='backspace': ## -- reset index so can manually flip through using number keys idx[0] = 0 elif event.key=='d': ## -- dump plots into ./plotdump directory for ix,model in zip(range(len(models)),models): key = model.datatag save_dir = utp.get_option("ec_save_dir","./plotdump",**kwargs[key]) save_name = utp.get_option("ec_save_name","ecplot-"+key+".png",**kwargs[key]) do_plot_corr_effective_mass_check([ix]) plt.savefig(save_dir+'/'+save_name) do_plot_corr_effective_mass_check(idx) # ## -- fig.canvas.mpl_connect('key_press_event',press_effective_mass) ## -- save plot data for idx,model in zip(range(len(models)),models): key = model.datatag ## -- parameters used in fitting ## default = 2 _emSep = utp.get_option("meff_sep",2,**kwargs[key]) ## default = smallest t not included in fit _emFitMin = utp.get_option("meff_fit_min",model.tfit[-1]+1,**kwargs[key]) ## default = midpoint - sep _emFitMax = utp.get_option("meff_fit_max", model.tdata[-1]/2-_emSep-int(model.tdata[-1]/12),**kwargs[key]) _emTData = model.tdata _emTFit = range(_emFitMin,_emFitMax) _emTFit = np.append(_emTFit,list(sorted([len(_emTData) - t for t in _emTFit]))) _emTDataNonZero = [t for t in _emTData if np.abs(gv.mean(data[key])[t]) > 1e-20] # ## -- data _emTDataRatio =\ [t for t in _emTData if (t in _emTDataNonZero) and (t <= _emTData[-1]/2 +1 - _emSep) ] # first half _emTDataRatio = np.append(_emTDataRatio, [t for t in _emTData if (t in _emTDataNonZero) and (t >= _emTData[-1]/2 +1 + _emSep) ] ) # second half _emRatio =\ [data[key][t+_emSep]/data[key][t] for t in _emTData if (t in _emTDataNonZero) and (t <= _emTData[-1]/2 +1 - _emSep) ] # first half _emRatio = np.append(_emRatio, [data[key][t-_emSep]/data[key][t] for t in _emTData if (t in _emTDataNonZero) and (t >= _emTData[-1]/2 +1 + _emSep) ] ) # second half _emTPosRatio.append( [_emTDataRatio[t] for t in range(len(_emTDataRatio)) if _emRatio[t] > 0] ) _emTPosFit.append( [_emTDataRatio[t] for t in range(len(_emTDataRatio)) if _emRatio[t] > 0 and _emTDataRatio[t] in _emTFit] ) _emLogRatio.append( [-gv.log(_emRatio[t])/_emSep for t in range(len(_emTDataRatio)) if _emRatio[t] > 0] ) _emLogRatioFit.append( [-gv.log(_emRatio[t])/_emSep for t in range(len(_emTDataRatio)) if (gv.mean(_emRatio[t]) > 0) and (_emTDataRatio[t] in _emTPosFit[-1])] ) _emLogRatioCentral.append(gv.mean(_emLogRatio[-1])) _emLogRatioError.append([ list(gv.sdev(_emLogRatio[-1])), list(gv.sdev(_emLogRatio[-1])) ]) ## -- fit _emRatioFit.append(lsq.wavg(_emLogRatioFit[-1])) _emFitCentral.append([gv.mean(_emRatioFit[-1]) for t in _emTPosFit[-1]]) _emFitError.append( [list(np.array(_emFitCentral[-1])-np.array([gv.sdev(_emRatioFit[-1]) for t in _emTPosFit[-1]])), list(np.array(_emFitCentral[-1])+np.array([gv.sdev(_emRatioFit[-1]) for t in _emTPosFit[-1]]))] ) print "Best plateau fits: " for key,rfit in zip([model.datatag for model in models],_emRatioFit): print " ",key," : ",rfit print " ----------------- " _emRatioFitNonZero = [x for x in _emRatioFit if not(x is None)] print " avg : ",lsq.wavg(_emRatioFitNonZero) ## -- done saving data if not(utp.get_option("to_terminal",True,**kwargs[key])) and\ utp.get_option("to_file",False,**kwargs[key]): for ix in range(len(models)): ## -- loops and saves all without creating window do_plot_corr_effective_mass_check([ix]) else: do_plot_corr_effective_mass_check(_emIdx)