def test_explicit(self): explicit_mod = Model( self.explicit_fcn, fjacb=self.explicit_fjb, fjacd=self.explicit_fjd, meta=dict(name='Sample Explicit Model', ref='ODRPACK UG, pg. 39'), ) explicit_dat = Data([0.,0.,5.,7.,7.5,10.,16.,26.,30.,34.,34.5,100.], [1265.,1263.6,1258.,1254.,1253.,1249.8,1237.,1218.,1220.6, 1213.8,1215.5,1212.]) explicit_odr = ODR(explicit_dat, explicit_mod, beta0=[1500.0, -50.0, -0.1], ifixx=[0,0,1,1,1,1,1,1,1,1,1,0]) explicit_odr.set_job(deriv=2) explicit_odr.set_iprint(init=0, iter=0, final=0) out = explicit_odr.run() assert_array_almost_equal( out.beta, np.array([1.2646548050648876e+03, -5.4018409956678255e+01, -8.7849712165253724e-02]), ) assert_array_almost_equal( out.sd_beta, np.array([1.0349270280543437, 1.583997785262061, 0.0063321988657267]), ) assert_array_almost_equal( out.cov_beta, np.array([[4.4949592379003039e-01, -3.7421976890364739e-01, -8.0978217468468912e-04], [-3.7421976890364739e-01, 1.0529686462751804e+00, -1.9453521827942002e-03], [-8.0978217468468912e-04, -1.9453521827942002e-03, 1.6827336938454476e-05]]), )
def do_the_fit(obs, **kwargs): global print_output, beta0 func = kwargs.get('function') yerr = kwargs.get('yerr') length = len(yerr) xerr = kwargs.get('xerr') if length == len(obs): assert 'x_constants' in kwargs data = RealData(kwargs.get('x_constants'), obs, sy=yerr) fit_type = 2 elif length == len(obs) // 2: data = RealData(obs[:length], obs[length:], sx=xerr, sy=yerr) fit_type = 0 else: raise Exception('x and y do not fit together.') model = Model(func) odr = ODR(data, model, beta0, partol=np.finfo(np.float64).eps) odr.set_job(fit_type=fit_type, deriv=1) output = odr.run() if print_output and not silent: print(*output.stopreason) print('chisquare/d.o.f.:', output.res_var) print_output = 0 beta0 = output.beta return output.beta[kwargs.get('n')]
def graph(a,toc): #a:odr with xerrors or curvefit without? toc: number of the figure plt.figure(toc,figsize=(15,10)) for tickLabel in plt.gca().get_xticklabels()+plt.gca().get_yticklabels(): tickLabel.set_fontsize(15) plt.title("Number of coincidence counts in the peak of $Na^{22}$ wrt angle",fontsize=17) plt.xlabel(r'Angle $\theta$ (°)',fontsize=17) plt.ylabel('# coincidence events',fontsize=17) plt.scatter(Ld,res,label='\n Data with parameters'+\ ' \n $16$ $cm$ source-detectors'+\ ' \n $150$ $s/points$') if a==False: par, par_va = curve_fit(simplegaussian, Ld, res, p0=[70000, 180, 10,1000],sigma=err_res,absolute_sigma=True) chi2=round(sum(((res - simplegaussian(Ld,*par) )/ err_res) ** 2)/(len(Ld)-3),2) plt.plot(Lc,simplegaussian(Lc, *par),color='gold',label='Fit with '+r'$A\exp\{\frac{-(\theta-\mu)^2}{2\sigma^2}\}+Cst$'+\ ' \n $A =$%s'%int(par[0])+' $ \pm$ %s'%int(np.sqrt(np.diag(par_va)[0]))+' #'+\ ' \n $\mu =$ %s'%round(par[1],1)+' $\pm$ %s'%round(np.sqrt(np.diag(par_va)[1]),1)+'°'+\ ' \n $\sigma =$ %s'%round(par[2],1)+ '$\pm$ %s'%round(np.sqrt(np.diag(par_va)[2]),1)+'°'+\ ' \n $Cst=$ %s'%int(par[3])+' $\pm$ %s'%int(np.sqrt(np.diag(par_va)[3]))+' #'+\ ' \n $\chi^2/dof = $ %s'%chi2) plt.errorbar(Ld, res, err_res,fmt='.',label=r'$y=\sqrt{counts}$ '+\ '\n $x=0°$', color='black',ecolor='lightgray', elinewidth=3, capsize=0) else: data = RealData(Ld,res,err_resx,err_res) model = Model(simplegaussianl) odr = ODR(data, model, [73021, 183, 11,1208]) odr.set_job(fit_type=2) output = odr.run() xn = Lc yn = simplegaussianl(output.beta, xn) #pl.hold(True) #plot(Ld,res,'ro') #print(x,y) plt.plot(xn,yn,'k-',label=' ODR leastsq fit'+\ ' \n $\chi^2/dof = $ %s'%round(output.sum_square/(len(Ld)-3),2)+'\n') odr.set_job(fit_type=0) output = odr.run() par,par_va=output.beta,output.cov_beta yn = simplegaussianl(output.beta, xn) plt.plot(xn,yn,color='gold',label='ODR fit '+r'$A\exp\{\frac{-(\theta-\mu)^2}{2\sigma^2}\}+Cst$'+\ ' \n $A =$%s'%int(par[0])+' $ \pm$ %s'%int(np.sqrt(np.diag(par_va)[0]))+' #'+\ ' \n $\mu =$ %s'%round(par[1],1)+' $\pm$ %s'%round(np.sqrt(np.diag(par_va)[1]),1)+'°'+\ ' \n $\sigma =$ %s'%round(par[2],1)+ '$\pm$ %s'%round(np.sqrt(np.diag(par_va)[2]),1)+'°'+\ ' \n $Cst=$ %s'%int(par[3])+' $\pm$ %s'%int(np.sqrt(np.diag(par_va)[3]))+' #'+\ ' \n Sum of squares/dof $= $ %s'%round(output.sum_square/(len(Ld)-3),2)) plt.legend(loc=0) plt.errorbar(Ld, res, err_res,err_resx,label=r'$y=\sqrt{counts}$ '+\ '\n $x=$%s'%errx+'°',fmt='.', color='black',ecolor='lightgray', elinewidth=3, capsize=0) plt.gca().set_xlim(140,220) plt.legend(bbox_to_anchor=(0.68, 0.58), loc=1, borderaxespad=0.,prop={'size':14}) plt.yscale('log') plt.ylim(1e2,1e5)
def ODR_fitting(xdata, ydata, fitfunction, beta, fix): bpl_all = Model(fitfunction) data_all = RealData(xdata, ydata, sx=np.cov([xdata, ydata])[0][1], sy=np.cov([xdata, ydata])[0][1]) odr_all = ODR(data_all, bpl_all, beta0=beta, ifixb=fix) odr_all.set_job(fit_type=0) output_all = odr_all.run() #output_all.pprint() return (output_all.beta, output_all.sd_beta)
def odr_fit(func, dom, mrng, srng, pg): ''' performs orthogonal distance regression ''' dat = RealData(dom, mrng, EPS * np.ones(len(dom)), srng + EPS) mod = ODRModel(func) odr = ODR(dat, mod, pg) odr.set_job(fit_type=0) fit = odr.run() popt = fit.beta perr = fit.sd_beta ndom = 128 fdom = np.linspace(np.min(dom), np.max(dom), ndom) fval = func(popt, fdom) return popt, perr, fdom, fval
def scipyODR(recipe, *args, **kwargs): from scipy.odr import Data, Model, ODR, RealData, odr_stop # FIXME # temporarily change _weights to _weights**2 to fit the ODR fits a = [w ** 2 for w in recipe._weights] recipe._weights = a model = Model(recipe.evaluateODR, # implicit=1, meta=dict(name='ODR fit'), ) x = [recipe._contributions.values()[0].profile.x] y = [recipe._contributions.values()[0].profile.y] dy = [recipe._contributions.values()[0].profile.dy] cont = recipe._contributions.values() for i in range(1, len(cont)): xplus = x[-1][-1] - x[-1][-2] + x[-1][-1] x.append(cont[i].profile.x + x[-1][-1] + xplus) y.append(cont[i].profile.y) dy.append(cont[i].profile.dy) x.append(np.arange(len(recipe._restraintlist)) * (x[-1][-1] - x[-1][-2]) + x[-1][-1]) y.append(np.zeros_like(recipe._restraintlist)) dy = np.concatenate(dy) dy = np.concatenate( [dy, np.ones_like(recipe._restraintlist) + np.average(dy)]) data = RealData(x=np.concatenate(x), y=np.concatenate(y), sy=dy) odr_kwargs = {} if kwargs.has_key('maxiter'): odr_kwargs['maxit'] = kwargs['maxiter'] odr = ODR(data, model, beta0=recipe.getValues(), **odr_kwargs) odr.set_job(deriv=1) out = odr.run() # out.pprint() # FIXME # revert back a = [np.sqrt(w) for w in recipe._weights] recipe._weights = a return {'x': out.beta, 'esd': out.sd_beta, 'cov': out.cov_beta, 'raw': out, }
def regression(func: Callable, num_params: int, data: Data, estimation: Callable = estimation, ) -> Tuple[np.ndarray, np.ndarray, float, float]: """Do an ODR Computes the Regression of func, given values and optional standard deviations and a function model. Parameters ---------- func: Callable Function to use for estimation. Must be func(beta ,x) -> y. num_params: int Number of parameters used in func. Length for beta0. data: Data Regression data. Returns ------- beta, sbeta, chi2_red, r2: Tuple[np.ndarray, np.ndarray, float, float] beta is the optimal valeu for beta in func, sbeta the standard deviation. chi2_red is the reduced $\chi^2$ for the regression, r2 is $R^2$ for the regression. """ realdata = RealData(data.x, data.y, sx=data.sx, sy=data.sy) model = Model(func) odr = ODR(realdata, model, beta0 = estimation(data.x,data.y, num_params)) # If sx is given do odr, else just do least-squares fit_type = 0 if isinstance(data.sx, np.ndarray) else 2 odr.set_job(fit_type=fit_type) output = odr.run() chi2_red = 0 r2 = 0 if isinstance(data.sy, np.ndarray): residuals = data.y - func(output.beta, data.x) chi_arr = residuals / data.sy chi2_red = np.sum(chi_arr**2) / (len(data.x)-len(output.beta)) ybar = np.sum(data.y/(data.sy**2))/np.sum(1/data.sy**2) r2 = 1 - np.sum(chi_arr**2)/np.sum(((data.y-ybar)/data.sy)**2) return output.beta, output.sd_beta*np.sqrt(len(data.x)), chi2_red, r2
def gerar_qui_quadrado(self,vetor,funcao,funcao2):#gera o qui quadrado if self.x_erro.all() != 0 and self.y_erro.all() != 0: odr = ODR(self.data,self.model,vetor)#cria classe do tipo "Ortogonal Distance Regression" odr.set_job(fit_type = 2)#No tipo 2 a classe odr faz qui quadrado resultado = odr.run() #gera o qui quadrado, retorna um tipo retorna uma classe output esperado = funcao(resultado.beta, self.xdata) #recebe os valores esperados pela aproximação qui_quadrado = chisquare(self.ydata,esperado) #gera o qui quadrado return resultado.beta,resultado.sd_beta,qui_quadrado[1] #retorna os valores da aproximação e seus erros else: if self.y_erro.any() != 0: resultado, erro = curve_fit(funcao2,self.xdata,self.ydata,vetor,self.y_erro,absolute_sigma = False)#chamada de função com erro em y else: resultado, erro = curve_fit(funcao2,self.xdata,self.ydata)#chamada de função seme erro erro = (diagonal(erro))**0.5#a raiz quadrada da diagonal principal da matriz de covariancia é o erro de cada variavel esperado = funcao(resultado, self.xdata) #recebe os valores esperados pela aproximação qui_quadrado = chisquare(self.ydata,esperado) #gera o qui quadrado, que retorna um vetor com 2 casas return resultado,erro,qui_quadrado[1] #retorna o resultado do qui quadrado, os erros das variáveis e a confiabilidade
def Normal_calc(t, nn): pc_0 = NN(t, nn) x = pc_0.x y = pc_0.y z = pc_0.z def func(beta, data): x, y = data a, b, c = beta return a * x + b * y + c data = Data([x, y], z) model = Model(func) odr = ODR(data, model, beta0=[0.0, 0.0, 0.0]) odr.set_job(fit_type=0) res = odr.run() """Extend plot with plt.Quiver (vectors) later on...?""" # Calculate xyz coordinates for corner vertices of the plane Y, X = np.mgrid[y.min():y.max():2j, x.min():x.max():2j] Z = func(res.beta, [X, Y]) f = plt.figure() pl = f.add_subplot(111, projection='3d') pl.scatter3D(x, y, z) pl.plot_surface(X, Y, Z, alpha=0.4) plt.show() # Define 3 points on plane for cross product calculation (from previous calculation) P = [X[0][0], Y[0][0], Z[0][0]] Q = [X[0][1], Y[0][1], Z[0][1]] R = [X[1][0], Y[1][0], Z[1][0]] print('PQR:', P, Q, R) # Calculate vectors on plane PQ = [Q[0] - P[0], Q[1] - P[1], Q[2] - P[2]] PR = [R[0] - P[0], R[1] - P[1], R[2] - P[2]] print(PQ, PR) # Calculate cross product of vectors + normalize to 1 = sqrt(x**2+y**2+z**2) N1 = np.cross(PQ, PR) print('N1:', N1) N1_array = np.array([[N1[0], N1[1], N1[2]]], dtype=np.float) N1_normalized = preprocessing.normalize(N1_array, norm='l2') return N1_normalized[0]
def test_odr_fit(n): dim = 10 + int(30 * np.random.rand()) x = np.arange(dim) + np.random.normal(0.0, 0.15, dim) xerr = 0.1 + 0.1 * np.random.rand(dim) y = 2 * np.exp(-0.06 * x) + np.random.normal(0.0, 0.15, dim) yerr = 0.1 + 0.1 * np.random.rand(dim) ox = [] for i, item in enumerate(x): ox.append(pe.pseudo_Obs(x[i], xerr[i], str(i))) oy = [] for i, item in enumerate(x): oy.append(pe.pseudo_Obs(y[i], yerr[i], str(i))) def f(x, a, b): return a * np.exp(-b * x) def func(a, x): y = a[0] * np.exp(-a[1] * x) return y data = RealData([o.value for o in ox], [o.value for o in oy], sx=[o.dvalue for o in ox], sy=[o.dvalue for o in oy]) model = Model(func) odr = ODR(data, model, [0, 0], partol=np.finfo(np.float).eps) odr.set_job(fit_type=0, deriv=1) output = odr.run() beta = pe.fits.odr_fit(ox, oy, func) pe.Obs.e_tag_global = 5 for i in range(2): beta[i].gamma_method(e_tag=5, S=1.0) assert math.isclose(beta[i].value, output.beta[i], rel_tol=1e-5) assert math.isclose( output.cov_beta[i, i], beta[i].dvalue**2, rel_tol=2.5e-1), str( output.cov_beta[i, i]) + ' ' + str(beta[i].dvalue**2) assert math.isclose(pe.covariance(beta[0], beta[1]), output.cov_beta[0, 1], rel_tol=2.5e-1) pe.Obs.e_tag_global = 0
def test_work_ind(self): def func(par, x): b0, b1 = par return b0 + b1 * x # generate some data n_data = 4 x = np.arange(n_data) y = np.where(x % 2, x + 0.1, x - 0.1) x_err = np.full(n_data, 0.1) y_err = np.full(n_data, 0.1) # do the fitting linear_model = Model(func) real_data = RealData(x, y, sx=x_err, sy=y_err) odr_obj = ODR(real_data, linear_model, beta0=[0.4, 0.4]) odr_obj.set_job(fit_type=0) out = odr_obj.run() sd_ind = out.work_ind['sd'] assert_array_almost_equal(out.sd_beta, out.work[sd_ind:sd_ind + len(out.sd_beta)])
GCover6.append(i) if datatype[i] == 3: notGC.append(i) LxM = np.log10(lx_m[index]) err = lx_m[index] + lx_m_err[index] LxMerr = np.log10(err) - LxM A = age[index] Aerr = age_err[index] data = RealData(A, LxM, sx=Aerr, sy=LxMerr) xn = np.linspace(2, 13.5, 100) modelLA = Model(funcLin) odrLA = ODR(data, modelLA, [28, -2]) odrLA.set_job(fit_type=0) outLA = odrLA.run() ynLA = funcLin(outLA.beta, xn) Res = funcLin(outLA.beta, A) - LxM StDev = Res / LxMerr ChiSq = np.sum(((funcLin(outLA.beta, A) - LxM) / LxMerr)**2) RedChiSq = ChiSq / (len(A) - len(outLA.beta)) fig1 = plt.figure(1) plt.clf() #frame1 = fig1.add_axes((0.1,0.3,0.8,0.6)) plt.errorbar(A, LxM, yerr=LxMerr, xerr=Aerr, ecolor='k',
return y def linear_beta(x, beta_0, beta_1): return beta_0 + beta_1 * x intensity = np.array(As).reshape(9, 5).T[[0, 3, 4, 1, 2]].T # move peak 2 & 3 to the correct position A_lambda = intensity[:-1].T # entries of each peak put together peaks = ['558.3', '563.5', '564.7', '570.8', '576.7'] intersects = [] x = np.array(concentration[:-1]) sx = 4 for i, peak, A in enum(peaks, A_lambda): y = un.nominal_values(A) sy = un.std_devs(A) data = RealData(x, y, sx=sx, sy=sy) model = Model(func) odr = ODR(data, model, [6, 0]) odr.set_job(fit_type=0) output = odr.run() beta = uc.correlated_values(output.beta, output.cov_beta) fit = linear_beta(x_fit, *beta) #Intersects y0 = intensity[-1][i] # peak intensities of the original sample x0 = (y0 - beta[0]) / beta[1] intersects.append(x0) lamb_all = np.array(x0s).reshape(9, 5) d_lin = np.load(npy_dir + 'ccd_calibration.npy') lamb_all = linear(lamb_all, *d_lin) # Integrate error on wavelength of CCD lamb_mean = np.mean(lamb_all, 0) lamb_laser = np.load(npy_dir + 'ccd_lamb_laser.npy')[0] dnu = (1 / lamb_mean - 1 / lamb_laser) * 10**7 lamb_mean = np.sort(lamb_mean) lits = np.array([888, 1028, 1091, 1274, 1464])
def test_ticket_11800(self): # parameters beta_true = np.array([1.0, 2.3, 1.1, -1.0, 1.3, 0.5]) nr_measurements = 10 std_dev_x = 0.01 x_error = np.array([[ 0.00063445, 0.00515731, 0.00162719, 0.01022866, -0.01624845, 0.00482652, 0.00275988, -0.00714734, -0.00929201, -0.00687301 ], [ -0.00831623, -0.00821211, -0.00203459, 0.00938266, -0.00701829, 0.0032169, 0.00259194, -0.00581017, -0.0030283, 0.01014164 ]]) std_dev_y = 0.05 y_error = np.array([[ 0.05275304, 0.04519563, -0.07524086, 0.03575642, 0.04745194, 0.03806645, 0.07061601, -0.00753604, -0.02592543, -0.02394929 ], [ 0.03632366, 0.06642266, 0.08373122, 0.03988822, -0.0092536, -0.03750469, -0.03198903, 0.01642066, 0.01293648, -0.05627085 ]]) beta_solution = np.array([ 2.62920235756665876536e+00, -1.26608484996299608838e+02, 1.29703572775403074502e+02, -1.88560985401185465804e+00, 7.83834160771274923718e+01, -7.64124076838087091801e+01 ]) # model's function and Jacobians def func(beta, x): y0 = beta[0] + beta[1] * x[0, :] + beta[2] * x[1, :] y1 = beta[3] + beta[4] * x[0, :] + beta[5] * x[1, :] return np.vstack((y0, y1)) def df_dbeta_odr(beta, x): nr_meas = np.shape(x)[1] zeros = np.zeros(nr_meas) ones = np.ones(nr_meas) dy0 = np.array([ones, x[0, :], x[1, :], zeros, zeros, zeros]) dy1 = np.array([zeros, zeros, zeros, ones, x[0, :], x[1, :]]) return np.stack((dy0, dy1)) def df_dx_odr(beta, x): nr_meas = np.shape(x)[1] ones = np.ones(nr_meas) dy0 = np.array([beta[1] * ones, beta[2] * ones]) dy1 = np.array([beta[4] * ones, beta[5] * ones]) return np.stack((dy0, dy1)) # do measurements with errors in independent and dependent variables x0_true = np.linspace(1, 10, nr_measurements) x1_true = np.linspace(1, 10, nr_measurements) x_true = np.array([x0_true, x1_true]) y_true = func(beta_true, x_true) x_meas = x_true + x_error y_meas = y_true + y_error # estimate model's parameters model_f = Model(func, fjacb=df_dbeta_odr, fjacd=df_dx_odr) data = RealData(x_meas, y_meas, sx=std_dev_x, sy=std_dev_y) odr_obj = ODR(data, model_f, beta0=0.9 * beta_true, maxit=100) #odr_obj.set_iprint(init=2, iter=0, iter_step=1, final=1) odr_obj.set_job(deriv=3) odr_out = odr_obj.run() # check results assert_equal(odr_out.info, 1) assert_array_almost_equal(odr_out.beta, beta_solution)
def show(): data_filename = 'number.txt' data = np.loadtxt(data_filename,skiprows=0) number = np.reshape(data,(41,3)) #emperical error xerr = np.sqrt(number[:,0])/3 yerr = number[:,2] data = Data(number[:,0].T, number[:,1].T, we = 1/(np.power(xerr.T,2)+np.spacing(1)), wd = 1/(np.power(yerr.T,2)+np.spacing(1))) model = Model(ord_function) odr = ODR(data, model, beta0=[0, 0]) odr.set_job(fit_type=2) output = odr.run() popt = output.beta perr = output.sd_beta output.pprint() fitting_error = np.mean(np.sqrt(np.power(popt[0]*number[:,0]+popt[1] - number[:,1],2))) labels = np.array([[1,1,1,1,1,1,\ 2,2,2,2,2,2,\ 3,3,3,3,3,3,\ 4,4,4,4,4,4,\ 5,5,5,5,5,5,\ 6,6,6,6,6,\ 7,7,7,7,7,7], [0,1,2,3,4,5,\ 0,1,2,3,4,5,\ 0,1,2,3,4,5,\ 0,1,2,3,4,5,\ 0,1,2,3,4,5,\ 0,1,2,3,4, 0,1,2,3,4,5]]) fig, ax = plt.subplots(ncols = 1) ax.errorbar(number[:,0], number[:,1], xerr = xerr, yerr = yerr, fmt='o') ax.plot(number[:,0], popt[0]*number[:,0]+popt[1], '-r') bbox_props = dict(boxstyle="square,pad=0.3", fc="white", ec="black", lw=2) annotation_text = "function: y = kx + b \n" \ "k = %.2f" % popt[0] + " +/- %.2f" % perr[0] + '\n' \ "b = %.2f" % popt[1] + " +/- %.2f" % perr[1] + '\n' \ "Error: %.2f" % fitting_error ax.text(10, np.amax(number[:,1])+10, annotation_text, ha="left", va="top", rotation=0, size=15, bbox=bbox_props) for i in range(0, len(number[:,0])): # <-- ax.annotate('(%s, %s)' % (labels[0,i], labels[1,i]),\ (number[i,0]+1, number[i,1]-1)) # ax.set_title('Algorithom Performance') ax.set_xlabel('Bubble Number Counted Manually') ax.set_ylabel('Bubbble Number Counted by Algorithom') plt.grid() plt.xlim((np.amin(number[:,0])-5,np.amax(number[:,0])+5)) plt.ylim((0,np.amax(number[:,1])+20)) plt.show()
def test_total_least_squares(): dim = 10 + int(30 * np.random.rand()) x = np.arange(dim) + np.random.normal(0.0, 0.15, dim) xerr = 0.1 + 0.1 * np.random.rand(dim) y = 2 * np.exp(-0.06 * x) + np.random.normal(0.0, 0.15, dim) yerr = 0.1 + 0.1 * np.random.rand(dim) ox = [] for i, item in enumerate(x): ox.append(pe.pseudo_Obs(x[i], xerr[i], str(i))) oy = [] for i, item in enumerate(x): oy.append(pe.pseudo_Obs(y[i], yerr[i], str(i))) def f(x, a, b): return a * np.exp(-b * x) def func(a, x): y = a[0] * np.exp(-a[1] * x) return y data = RealData([o.value for o in ox], [o.value for o in oy], sx=[o.dvalue for o in ox], sy=[o.dvalue for o in oy]) model = Model(func) odr = ODR(data, model, [0, 0], partol=np.finfo(np.float64).eps) odr.set_job(fit_type=0, deriv=1) output = odr.run() out = pe.total_least_squares(ox, oy, func, expected_chisquare=True) beta = out.fit_parameters str(out) repr(out) len(out) for i in range(2): beta[i].gamma_method(S=1.0) assert math.isclose(beta[i].value, output.beta[i], rel_tol=1e-5) assert math.isclose( output.cov_beta[i, i], beta[i].dvalue**2, rel_tol=2.5e-1), str( output.cov_beta[i, i]) + ' ' + str(beta[i].dvalue**2) assert math.isclose(pe.covariance(beta[0], beta[1]), output.cov_beta[0, 1], rel_tol=2.5e-1) out = pe.total_least_squares(ox, oy, func, const_par=[beta[1]]) diff = out.fit_parameters[0] - beta[0] assert (diff / beta[0] < 1e-3 * beta[0].dvalue) assert ((out.fit_parameters[1] - beta[1]).is_zero()) oxc = [] for i, item in enumerate(x): oxc.append(pe.cov_Obs(x[i], xerr[i]**2, 'covx' + str(i))) oyc = [] for i, item in enumerate(x): oyc.append(pe.cov_Obs(y[i], yerr[i]**2, 'covy' + str(i))) outc = pe.total_least_squares(oxc, oyc, func) betac = outc.fit_parameters for i in range(2): betac[i].gamma_method(S=1.0) assert math.isclose(betac[i].value, output.beta[i], rel_tol=1e-3) assert math.isclose( output.cov_beta[i, i], betac[i].dvalue**2, rel_tol=2.5e-1), str( output.cov_beta[i, i]) + ' ' + str(betac[i].dvalue**2) assert math.isclose(pe.covariance(betac[0], betac[1]), output.cov_beta[0, 1], rel_tol=2.5e-1) outc = pe.total_least_squares(oxc, oyc, func, const_par=[betac[1]]) diffc = outc.fit_parameters[0] - betac[0] assert (diffc / betac[0] < 1e-3 * betac[0].dvalue) assert ((outc.fit_parameters[1] - betac[1]).is_zero()) outc = pe.total_least_squares(oxc, oy, func) betac = outc.fit_parameters for i in range(2): betac[i].gamma_method(S=1.0) assert math.isclose(betac[i].value, output.beta[i], rel_tol=1e-3) assert math.isclose( output.cov_beta[i, i], betac[i].dvalue**2, rel_tol=2.5e-1), str( output.cov_beta[i, i]) + ' ' + str(betac[i].dvalue**2) assert math.isclose(pe.covariance(betac[0], betac[1]), output.cov_beta[0, 1], rel_tol=2.5e-1) outc = pe.total_least_squares(oxc, oy, func, const_par=[betac[1]]) diffc = outc.fit_parameters[0] - betac[0] assert (diffc / betac[0] < 1e-3 * betac[0].dvalue) assert ((outc.fit_parameters[1] - betac[1]).is_zero())
def test_multi(self): multi_mod = Model( self.multi_fcn, meta=dict(name='Sample Multi-Response Model', ref='ODRPACK UG, pg. 56'), ) multi_x = np.array([30.0, 50.0, 70.0, 100.0, 150.0, 200.0, 300.0, 500.0, 700.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0, 7000.0, 10000.0, 15000.0, 20000.0, 30000.0, 50000.0, 70000.0, 100000.0, 150000.0]) multi_y = np.array([ [4.22, 4.167, 4.132, 4.038, 4.019, 3.956, 3.884, 3.784, 3.713, 3.633, 3.54, 3.433, 3.358, 3.258, 3.193, 3.128, 3.059, 2.984, 2.934, 2.876, 2.838, 2.798, 2.759], [0.136, 0.167, 0.188, 0.212, 0.236, 0.257, 0.276, 0.297, 0.309, 0.311, 0.314, 0.311, 0.305, 0.289, 0.277, 0.255, 0.24, 0.218, 0.202, 0.182, 0.168, 0.153, 0.139], ]) n = len(multi_x) multi_we = np.zeros((2, 2, n), dtype=float) multi_ifixx = np.ones(n, dtype=int) multi_delta = np.zeros(n, dtype=float) multi_we[0,0,:] = 559.6 multi_we[1,0,:] = multi_we[0,1,:] = -1634.0 multi_we[1,1,:] = 8397.0 for i in range(n): if multi_x[i] < 100.0: multi_ifixx[i] = 0 elif multi_x[i] <= 150.0: pass # defaults are fine elif multi_x[i] <= 1000.0: multi_delta[i] = 25.0 elif multi_x[i] <= 10000.0: multi_delta[i] = 560.0 elif multi_x[i] <= 100000.0: multi_delta[i] = 9500.0 else: multi_delta[i] = 144000.0 if multi_x[i] == 100.0 or multi_x[i] == 150.0: multi_we[:,:,i] = 0.0 multi_dat = Data(multi_x, multi_y, wd=1e-4/np.power(multi_x, 2), we=multi_we) multi_odr = ODR(multi_dat, multi_mod, beta0=[4.,2.,7.,.4,.5], delta0=multi_delta, ifixx=multi_ifixx) multi_odr.set_job(deriv=1, del_init=1) out = multi_odr.run() assert_array_almost_equal( out.beta, np.array([4.3799880305938963, 2.4333057577497703, 8.0028845899503978, 0.5101147161764654, 0.5173902330489161]), ) assert_array_almost_equal( out.sd_beta, np.array([0.0130625231081944, 0.0130499785273277, 0.1167085962217757, 0.0132642749596149, 0.0288529201353984]), ) assert_array_almost_equal( out.cov_beta, np.array([[0.0064918418231375, 0.0036159705923791, 0.0438637051470406, -0.0058700836512467, 0.011281212888768], [0.0036159705923791, 0.0064793789429006, 0.0517610978353126, -0.0051181304940204, 0.0130726943624117], [0.0438637051470406, 0.0517610978353126, 0.5182263323095322, -0.0563083340093696, 0.1269490939468611], [-0.0058700836512467, -0.0051181304940204, -0.0563083340093696, 0.0066939246261263, -0.0140184391377962], [0.011281212888768, 0.0130726943624117, 0.1269490939468611, -0.0140184391377962, 0.0316733013820852]]), )
def test_multi(self): multi_mod = Model( self.multi_fcn, meta=dict(name='Sample Multi-Response Model', ref='ODRPACK UG, pg. 56'), ) multi_x = np.array([ 30.0, 50.0, 70.0, 100.0, 150.0, 200.0, 300.0, 500.0, 700.0, 1000.0, 1500.0, 2000.0, 3000.0, 5000.0, 7000.0, 10000.0, 15000.0, 20000.0, 30000.0, 50000.0, 70000.0, 100000.0, 150000.0 ]) multi_y = np.array([ [ 4.22, 4.167, 4.132, 4.038, 4.019, 3.956, 3.884, 3.784, 3.713, 3.633, 3.54, 3.433, 3.358, 3.258, 3.193, 3.128, 3.059, 2.984, 2.934, 2.876, 2.838, 2.798, 2.759 ], [ 0.136, 0.167, 0.188, 0.212, 0.236, 0.257, 0.276, 0.297, 0.309, 0.311, 0.314, 0.311, 0.305, 0.289, 0.277, 0.255, 0.24, 0.218, 0.202, 0.182, 0.168, 0.153, 0.139 ], ]) n = len(multi_x) multi_we = np.zeros((2, 2, n), dtype=float) multi_ifixx = np.ones(n, dtype=int) multi_delta = np.zeros(n, dtype=float) multi_we[0, 0, :] = 559.6 multi_we[1, 0, :] = multi_we[0, 1, :] = -1634.0 multi_we[1, 1, :] = 8397.0 for i in range(n): if multi_x[i] < 100.0: multi_ifixx[i] = 0 elif multi_x[i] <= 150.0: pass # defaults are fine elif multi_x[i] <= 1000.0: multi_delta[i] = 25.0 elif multi_x[i] <= 10000.0: multi_delta[i] = 560.0 elif multi_x[i] <= 100000.0: multi_delta[i] = 9500.0 else: multi_delta[i] = 144000.0 if multi_x[i] == 100.0 or multi_x[i] == 150.0: multi_we[:, :, i] = 0.0 multi_dat = Data(multi_x, multi_y, wd=1e-4 / np.power(multi_x, 2), we=multi_we) multi_odr = ODR(multi_dat, multi_mod, beta0=[4., 2., 7., .4, .5], delta0=multi_delta, ifixx=multi_ifixx) multi_odr.set_job(deriv=1, del_init=1) out = multi_odr.run() assert_array_almost_equal( out.beta, np.array([ 4.3799880305938963, 2.4333057577497703, 8.0028845899503978, 0.5101147161764654, 0.5173902330489161 ]), ) assert_array_almost_equal( out.sd_beta, np.array([ 0.0130625231081944, 0.0130499785273277, 0.1167085962217757, 0.0132642749596149, 0.0288529201353984 ]), ) assert_array_almost_equal( out.cov_beta, np.array([[ 0.0064918418231375, 0.0036159705923791, 0.0438637051470406, -0.0058700836512467, 0.011281212888768 ], [ 0.0036159705923791, 0.0064793789429006, 0.0517610978353126, -0.0051181304940204, 0.0130726943624117 ], [ 0.0438637051470406, 0.0517610978353126, 0.5182263323095322, -0.0563083340093696, 0.1269490939468611 ], [ -0.0058700836512467, -0.0051181304940204, -0.0563083340093696, 0.0066939246261263, -0.0140184391377962 ], [ 0.011281212888768, 0.0130726943624117, 0.1269490939468611, -0.0140184391377962, 0.0316733013820852 ]]), )
def zeroth_fit_2var(Nml,Eth,nu_des_ini,t_start,t_stop): deca=0 sizeOfFont = 16 fontProperties = {'family':'sans-serif', 'weight' : 'normal', 'size' : sizeOfFont} #rc('text', usetex=True) rc('font',**fontProperties) ticks_font = font_manager.FontProperties(family='cm', style='normal', size=sizeOfFont, weight='normal', stretch='normal') filenm='12CO_13CO_1_1_fit.txt' #if molec =='n2': # m_mol=30.0e-3 # xtex=0.042 #if molec =='co': m_mol=28.0e-3 xtex=0.0375 #if molec =='co2': # m_mol=44.0e-3 #if molec =='h2o': # m_mol=18.0e-3 errort=0.1 T_tot, N_tot,N_13co = np.loadtxt(filenm,unpack=True,skiprows=1) N_tot=N_13co T_ini=T_tot T_tot=T_tot T_tot_err=T_tot*0.0+errort N_tot=np.clip(N_tot,1e-12,1e30) N_tot_err=1e12+N_tot*0 h_rate=1/60.0 #Kmin-1 T=T_tot[np.where((T_tot>t_start) & (T_tot<t_stop))] N=N_tot[np.where((T_tot>t_start) & (T_tot<t_stop))] N_err=1e10+N*0 T_err=T*0.0+errort x=1.0/T x_err=T_err/(T**2) #print x_err y=np.log(N/(1e15)) y_err=N_err/N #y=np.log(N) p=[0.,0.] #nu_des_ini=7e11#np.sqrt(2.0*1e19*8.31*Eth/(np.pi*np.pi*m_mol)) #slope, intercept, r_value, p_value, std_err=scipy.stats.linregress(x, y) def func(p, t): return p[1] +t*p[0] #def func (p,t): # return np.log(1e12/h_rate)+t*p[0] #def func(p, t): # return np.log(np.sqrt(2.0*1e19*8.31*-1*p[0]/(np.pi*np.pi*m_mol))/h_rate) +t*p[0] #p[1]=np.log(1e12/h_rate) #p,pcov=curve_fit(func, x, y) #err = np.sqrt(np.diag(pcov)) data = RealData(x, y, sx=x_err,sy=y_err)#, sy=np.log(0.001)) model = Model(func) #odr = ODR(data, model, beta0=[-800,1e12]) odr = ODR(data, model, beta0=[-750,7e11]) odr.set_job(fit_type=2) output = odr.run() p=output.beta err=output.sd_beta E_des=-p[0] nu_des=h_rate*np.exp(p[1]) nu_theo=h_rate*np.exp(np.log(np.sqrt(2.0*1e19*8.31*-1*p[0]/(np.pi*np.pi*m_mol))/h_rate)) #p[1]=np.log(np.sqrt(2.0*1e19*8.31*-1*p[0]/(np.pi*np.pi*m_mol))/h_rate) #err[1]=0.0 #nu_theo=np.sqrt(2.0*1e19*8.31*Eth/(np.pi*np.pi*m_mol)) print 'E_des fit', p[0]*-1, '+-',err[0] print 'E_des litt', Eth print 'nu fit e12', 1e-12*h_rate*np.exp(p[1]), '+-',err[1]*1e-12*h_rate*np.exp(p[1]) print 'nu litt e12', 1e-12*nu_des_ini print 'nu theo e12', 1e-12*nu_theo #nu_des=2e11 #print "nu e12n", nu_des*1e-12 # def funct(x,t): # if x[0]>0.0: # f_ml = -(nu_des/h_rate)*np.exp(-E_des/t) # f_g= f_ml-x[1] # if x[0]<0.0: # f_ml=0 # f_g= f_ml-x[1] # return [f_ml,f_g] # F_pure = odeint(funct,[Nml,0.00],T_tot) # N_ml = np.clip(F_pure[:,0],0.0,10) # N_g = -F_pure[:,1] # k_d_ml = (nu_des/h_rate)*np.exp(-E_des/T_tot) # k_d_mode=(nu_des_ini/h_rate)*np.exp(-Eth/T_tot) #print "Ns",N_ml #if order==0: # k_d_ml[np.where(k_d_ml>np.max(N))]=0.0 #A[:,i] = k_d_ml #A[:,i] = np.clip(k_d_ml,-1e15,1e15) #x,resid = optimize.nnls(A,b) #slope, intercept, r_value, p_value, std_err=scipy.stats.linregress(x, y) plot_tpd='12CO_reglinfit_2var.pdf' plt.errorbar(x,y,xerr=x_err,yerr=y_err,color='k') #plt.errorbar(a,b,yerr=c, linestyle="None") plt.plot(x,p[1]+p[0]*x,color='r',linestyle='--',linewidth=3.0) #plt.plot(x,p[1]+p[0]*x,color='r',linestyle='--',linewidth=3.0) plt.text(xtex,0.0,'-Slope: '+str(round(E_des))+' +- '+str(round(err[0]))) plt.text(xtex,-0.5,'exp(Intercept)*h_rate: '+ str(round(1e-12*h_rate*np.exp(p[1]),2))+ '+/-'+str(round(err[1]*1e-12*h_rate*np.exp(p[1]),2))+ 'e12') #plt.plot(x,p[0]+(p[1]-err[1])*x,color='r',linestyle='--',linewidth=3.0) #plt.plot(x,p[0]+(p[1]+err[1])*x,color='r',linestyle='--',linewidth=3.0) #plt.plot(x,np.log(1e12/h_rate)-Eth*x,color='b',linestyle='--',linewidth=3.0) #plt.xlim(1/(t_stop+5),1/(t_start-5)) plt.savefig(plot_tpd) plt.close('all') #ind=np.where(N_tot<np.max(N_tot)) #plot_tpd='12CO_tpdfit_2var.pdf' #plt.errorbar(T_tot[ind],N_tot[ind]/(1e15),xerr=T_tot_err[ind],yerr=N_tot_err[ind]/1e15,color='k') #plt.plot([t_start-deca,t_start-deca],[0,np.max(N_tot)/1e15],linestyle='--',color='g') #plt.plot([t_stop-deca,t_stop-deca],[0,np.max(N_tot)/1e15],linestyle='--',color='g') #plt.plot(T,-np.exp(intercept)*np.exp(-1*slope/T),color='r',linestyle='--',linewidth=3.0) #plt.plot(T,(60*1.5e12/5.3e15)*np.exp(-950.0/T),color='b',linestyle='--',linewidth=3.0) #plt.plot(T_tot,np.clip(k_d_ml,0,2*np.max(N_tot/1e15)),color='r') #plt.plot(T_tot,np.clip(k_d_mode,0,2*np.max(N_tot/1e15)),color='r') #plt.xlim(15,50) #plt.ylim(-0.005,np.max(N_tot)/1e15+0.1) #plt.savefig(plot_tpd) plt.close('all')
def main(): try: data_filename = 'number.txt' data = np.loadtxt(data_filename, skiprows=0) cur = np.reshape(data, (41, 3)) data_filename = 'curvature.txt' data = np.loadtxt(data_filename, skiprows=0) hough = np.reshape(data, (41, 3)) #emperical error xerr = np.sqrt(hough[:, 0]) / 3 yerr_h = hough[:, 2] yerr_c = cur[:, 2] data_h = Data(hough[:, 0].T, hough[:, 1].T, we=1 / (np.power(xerr.T, 2) + np.spacing(1)), wd=1 / (np.power(yerr_h.T, 2) + np.spacing(1))) data_c = Data(cur[:, 0].T, cur[:, 1].T, we=1 / (np.power(xerr.T, 2) + np.spacing(1)), wd=1 / (np.power(yerr_c.T, 2) + np.spacing(1))) model = Model(ord_function) odr_h = ODR(data_h, model, beta0=[0, 0]) odr_c = ODR(data_c, model, beta0=[0, 0]) odr_h.set_job(fit_type=2) odr_c.set_job(fit_type=2) output_h = odr_h.run() output_c = odr_c.run() popt_h = output_h.beta perr_h = output_h.sd_beta popt_c = output_c.beta perr_c = output_c.sd_beta popt_h, pcov_h = curve_fit(linear_fit_function, hough[:, 0], hough[:, 1], [1, 0], hough[:, 2]) perr_h = np.sqrt(np.diag(pcov_h)) # popt_c, pcov_c = curve_fit(linear_fit_function, cur[:,0], cur[:,1], [1, 0], cur[:, 2]) # perr_c = np.sqrt(np.diag(pcov_c)) A = popt_h[0] / np.sqrt(popt_h[0] * popt_h[0] + 1) B = -1 / np.sqrt(popt_h[0] * popt_h[0] + 1) C = popt_h[1] / np.sqrt(popt_h[0] * popt_h[0] + 1) fitting_error_h = np.mean(np.abs(A * hough[:, 0] + B * hough[:, 1] + C)) A = popt_c[0] / np.sqrt(popt_c[0] * popt_c[0] + 1) B = -1 / np.sqrt(popt_c[0] * popt_c[0] + 1) C = popt_c[1] / np.sqrt(popt_c[0] * popt_c[0] + 1) fitting_error_c = np.mean(np.abs(A * cur[:, 0] + B * cur[:, 1] + C)) fig, ax = plt.subplots(ncols=1) ax.errorbar(hough[:, 0], hough[:, 1], xerr=xerr, yerr=yerr_h, fmt='o', color='blue') ax.errorbar(cur[:, 0], cur[:, 1], xerr=xerr, yerr=yerr_c, fmt='o', color='red') ax.plot(hough[:, 0], popt_h[0] * hough[:, 0] + popt_h[1], '-b', linewidth=2) ax.plot(cur[:, 0], popt_c[0] * cur[:, 0] + popt_c[1], '-r', linewidth=2) bbox_props = dict(boxstyle="square,pad=0.3", fc="white", ec="black", lw=2) annotation_text = "function: y = kx + b \n" \ "Hough Transfrom (blue)\n"\ "k = %.2f b = %.2f Error = %.2f" % (popt_h[0], popt_h[1], fitting_error_h) + '\n'\ "Curvature Method (red)\n"\ "k = %.2f b = %.2f Error = %.2f" % (popt_c[0], popt_c[1], fitting_error_c) ax.text(10, max(np.amax(hough[:, 1]), np.amax(cur[:, 1])) + 10, annotation_text, ha="left", va="top", rotation=0, size=15, bbox=bbox_props) ax.set_title('Algorithom Performance') ax.set_xlabel('Bubble Number Counted Manually') ax.set_ylabel('Bubbble Number Counted by Algorithom') plt.grid() plt.xlim((np.amin(hough[:, 0]) - 5, np.amax(hough[:, 0]) + 5)) plt.ylim((0, max(np.amax(hough[:, 1]), np.amax(cur[:, 1])) + 20)) plt.show() except KeyboardInterrupt: print "Shutdown requested... exiting" except Exception: traceback.print_exc(file=sys.stdout) sys.exit(0)
def main(): try: legend = ['curvature', 'neural-network', 'hough transform', 'SVM-Preliminary'] data_filename = ['number.txt', 'skflow.txt', 'curvature.txt', 'SVM.txt'] colors = ['blue', 'red', 'black', 'green'] annotation_text = "function: y = kx + b"; fig, ax = plt.subplots(ncols = 1) for i in range(len(data_filename)): temp = np.loadtxt(data_filename[i],skiprows=0) data = np.reshape(temp,(41,len(temp)/41)) #print data data[:,1:3] = np.true_divide(data[:,1:3], np.amax(data[:,1])) data[:,1] = data[:,1]+i #print data #emperical error xerr = np.sqrt(data[:,0])/3 yerr = data[:,2] data_fit = Data(data[:,0].T, data[:,1].T, \ we = 1/(np.power(xerr.T,2)+np.spacing(1)),\ wd = 1/(np.power(yerr.T,2)+np.spacing(1))) model = Model(ord_function) odr = ODR(data_fit, model, beta0=[0, 0]) odr.set_job(fit_type=2) output = odr.run() popt = output.beta perr= output.sd_beta popt, pcov = curve_fit(linear_fit_function, data[:,0], data[:,1], [1, 0], data[:, 2]) perr = np.sqrt(np.diag(pcov)) A = popt[0]/np.sqrt(popt[0]*popt[0]+1) B = -1/np.sqrt(popt[0]*popt[0]+1) C = popt[1]/np.sqrt(popt[0]*popt[0]+1) fitting_error= np.mean(np.abs(A*data[:,0]+B*data[:,1]+C)) ax.errorbar(data[:,0], data[:,1], xerr = xerr,\ yerr = yerr, fmt='o',color=colors[i]) ### not using error bar in fitting ######### popt[0],popt[1] = np.polyfit(data[:,0], data[:,1], 1) ### ax.plot(data[:,0], popt[0]*data[:,0]+popt[1], colors[i], linewidth = 2) annotation_text = annotation_text + "\n" +\ legend[i] + "(" + \ colors[i] + ") \n" + \ "k = %.2f b = %.2f Error = %.2f"%( \ popt[0], popt[1], fitting_error) bbox_props = dict(boxstyle="square,pad=0.3", fc="white", ec="black", lw=2) #ax.text(0, 4.15, annotation_text, ha="left", va="top", \ # rotation=0, size=14, bbox=bbox_props) ax.set_title('Algorithom Performance') ax.set_xlabel('Bubble Number Counted Manually') ax.set_ylabel('Normalized Bubbble Number Counted by Algorithom') plt.grid() plt.xlim((np.amin(data[:,0])-5,np.amax(data[:,0])+5)) plt.ylim((0,np.amax(data[:,1])+0.2)) plt.show() except KeyboardInterrupt: print "Shutdown requested... exiting" except Exception: traceback.print_exc(file=sys.stdout) sys.exit(0)
def main(): try: if (len(sys.argv) > 1 and sys.argv[1] == '1'): data_filename = 'number.txt' start_time = time.time() number = np.zeros((41,3)) index = -1 for det in range(1,8): if (det!=6): num_n = 6 else: num_n = 5 for n in range(0,num_n): index = index + 1 temp = np.zeros(3) for angle in range(1,4): filename = 'detector_' + str(det) + '_no_' + str(n) \ + '_angle_' + str(angle) + '.jpg' refname = 'detector_' + str(det) + '_no_' + str(n) \ + '_background.jpg' elapse_time = (time.time()-start_time) if(elapse_time >= 1): remain_time = elapse_time/(index*3+angle-1)*41*3-elapse_time print 'Processing .. ' + filename \ + time.strftime(" %H:%M:%S", time.gmtime(elapse_time)) \ + ' has past. ' + 'Remaining time: ' \ + time.strftime(" %H:%M:%S", time.gmtime(remain_time)) else: print 'Processing .. ' + filename \ + time.strftime(" %H:%M:%S", time.gmtime(elapse_time)) \ + ' has past' image = rgb2gray(io.imread(filename)) ref = rgb2gray(io.imread(refname)) temp[angle-1] = ellipse.count_bubble(image,ref) #temp[angle-1] = ellipse.count_bubble(image) number[index,1] = np.mean(temp) number[index,2] = np.std(temp) manual_count = np.array([1,27,40,79,122,160,1,18,28,42,121,223,0,11,24,46,\ 142,173,3,19,23,76,191,197,0,15,24,45,91,152,0,\ 16,27,34,88,0,9,12,69,104,123]) number[:,0] = manual_count.T number.tofile(data_filename,sep=" ") elif(len(sys.argv) > 1): data_filename = sys.argv[1] data = np.loadtxt(data_filename,skiprows=0) number = np.reshape(data,(41,3)) else: data_filename = 'number.txt' data = np.loadtxt(data_filename,skiprows=0) number = np.reshape(data,(41,3)) #emperical error xerr = np.sqrt(number[:,0])/3 yerr = number[:,2] data = Data(number[:,0].T, number[:,1].T, we = 1/(np.power(xerr.T,2)+np.spacing(1)), wd = 1/(np.power(yerr.T,2)+np.spacing(1))) model = Model(ord_function) odr = ODR(data, model, beta0=[0, 0]) odr.set_job(fit_type=2) output = odr.run() popt = output.beta perr = output.sd_beta output.pprint() # popt, pcov = curve_fit(linear_fit_function, number[:,0], number[:,1], [0, 0], number[:, 2]) # perr = np.sqrt(np.diag(pcov)) fitting_error = np.mean(np.sqrt(np.power(popt[0]*number[:,0]+popt[1] - number[:,1],2))) labels = np.array([[1,1,1,1,1,1,\ 2,2,2,2,2,2,\ 3,3,3,3,3,3,\ 4,4,4,4,4,4,\ 5,5,5,5,5,5,\ 6,6,6,6,6,\ 7,7,7,7,7,7], [0,1,2,3,4,5,\ 0,1,2,3,4,5,\ 0,1,2,3,4,5,\ 0,1,2,3,4,5,\ 0,1,2,3,4,5,\ 0,1,2,3,4, 0,1,2,3,4,5]]) fig, ax = plt.subplots(ncols = 1) ax.errorbar(number[:,0], number[:,1], xerr = xerr, yerr = yerr, fmt='o') ax.plot(number[:,0], popt[0]*number[:,0]+popt[1], '-r') bbox_props = dict(boxstyle="square,pad=0.3", fc="white", ec="black", lw=2) annotation_text = "function: y = kx + b \n" \ "k = %.2f" % popt[0] + " +/- %.2f" % perr[0] + '\n' \ "b = %.2f" % popt[1] + " +/- %.2f" % perr[1] + '\n' \ "Error: %.2f" % fitting_error ax.text(10, np.amax(number[:,1])+10, annotation_text, ha="left", va="top", rotation=0, size=15, bbox=bbox_props) for i in range(0, len(number[:,0])): # <-- ax.annotate('(%s, %s)' % (labels[0,i], labels[1,i]),\ (number[i,0]+1, number[i,1]-1)) # ax.set_title('Algorithom Performance') ax.set_xlabel('Bubble Number Counted Manually') ax.set_ylabel('Bubbble Number Counted by Algorithom') plt.grid() plt.xlim((np.amin(number[:,0])-5,np.amax(number[:,0])+5)) plt.ylim((0,np.amax(number[:,1])+20)) plt.show() except KeyboardInterrupt: print "Shutdown requested... exiting" except Exception: traceback.print_exc(file=sys.stdout) sys.exit(0)
def odr_fit(x, y, func, silent=False, **kwargs): """Performs a non-linear fit to y = func(x) and returns a list of Obs corresponding to the fit parameters. x has to be a list of Obs, or a tuple of lists of Obs y has to be a list of Obs the dvalues of the Obs are used as x- and yerror for the fit. func has to be of the form def func(a, x): y = a[0] + a[1] * x + a[2] * anp.sinh(x) return y For multiple x values func can be of the form def func(a, x): (x1, x2) = x return a[0] * x1 ** 2 + a[1] * x2 It is important that all numpy functions refer to autograd.numpy, otherwise the differentiation will not work. Based on the orthogonal distance regression module of scipy Keyword arguments ----------------- dict_output -- If true, the output is a dictionary containing all relevant data instead of just a list of the fit parameters. silent -- If true all output to the console is omitted (default False). initial_guess -- can provide an initial guess for the input parameters. Relevant for non-linear fits with many parameters. expected_chisquare -- If true prints the expected chisquare which is corrected by effects caused by correlated input data. This can take a while as the full correlation matrix has to be calculated (default False). """ result_dict = {} result_dict['fit_function'] = func x = np.array(x) x_shape = x.shape if not callable(func): raise TypeError('func has to be a function.') for i in range(25): try: func(np.arange(i), x.T[0]) except: pass else: break n_parms = i if not silent: print('Fit with', n_parms, 'parameters') x_f = np.vectorize(lambda o: o.value)(x) dx_f = np.vectorize(lambda o: o.dvalue)(x) y_f = np.array([o.value for o in y]) dy_f = np.array([o.dvalue for o in y]) if np.any(np.asarray(dx_f) <= 0.0): raise Exception('No x errors available, run the gamma method first.') if np.any(np.asarray(dy_f) <= 0.0): raise Exception('No y errors available, run the gamma method first.') if 'initial_guess' in kwargs: x0 = kwargs.get('initial_guess') if len(x0) != n_parms: raise Exception('Initial guess does not have the correct length.') else: x0 = [1] * n_parms data = RealData(x_f, y_f, sx=dx_f, sy=dy_f) model = Model(func) odr = ODR(data, model, x0, partol=np.finfo(np.float).eps) odr.set_job(fit_type=0, deriv=1) output = odr.run() result_dict['residual_variance'] = output.res_var result_dict['method'] = 'ODR' result_dict['xplus'] = output.xplus if not silent: print('Method: ODR') print(*output.stopreason) print('Residual variance:', result_dict['residual_variance']) if output.info > 3: raise Exception('The minimization procedure did not converge.') m = x_f.size def odr_chisquare(p): model = func(p[:n_parms], p[n_parms:].reshape(x_shape)) chisq = anp.sum(((y_f - model) / dy_f)**2) + anp.sum( ((x_f - p[n_parms:].reshape(x_shape)) / dx_f)**2) return chisq if kwargs.get('expected_chisquare') is True: W = np.diag(1 / np.asarray(np.concatenate( (dy_f.ravel(), dx_f.ravel())))) if kwargs.get('covariance') is not None: cov = kwargs.get('covariance') else: cov = covariance_matrix(np.concatenate((y, x.ravel()))) number_of_x_parameters = int(m / x_f.shape[-1]) old_jac = jacobian(func)(output.beta, output.xplus) fused_row1 = np.concatenate( (old_jac, np.concatenate( (number_of_x_parameters * [np.zeros(old_jac.shape)]), axis=0))) fused_row2 = np.concatenate( (jacobian(lambda x, y: func(y, x))( output.xplus, output.beta).reshape(x_f.shape[-1], x_f.shape[-1] * number_of_x_parameters), np.identity(number_of_x_parameters * old_jac.shape[0]))) new_jac = np.concatenate((fused_row1, fused_row2), axis=1) A = W @ new_jac P_phi = A @ np.linalg.inv(A.T @ A) @ A.T expected_chisquare = np.trace( (np.identity(P_phi.shape[0]) - P_phi) @ W @ cov @ W) if expected_chisquare <= 0.0: print('Warning, negative expected_chisquare.') expected_chisquare = np.abs(expected_chisquare) result_dict['chisquare/expected_chisquare'] = odr_chisquare( np.concatenate( (output.beta, output.xplus.ravel()))) / expected_chisquare if not silent: print('chisquare/expected_chisquare:', result_dict['chisquare/expected_chisquare']) hess_inv = np.linalg.pinv( jacobian(jacobian(odr_chisquare))(np.concatenate( (output.beta, output.xplus.ravel())))) def odr_chisquare_compact_x(d): model = func(d[:n_parms], d[n_parms:n_parms + m].reshape(x_shape)) chisq = anp.sum(((y_f - model) / dy_f)**2) + anp.sum( ((d[n_parms + m:].reshape(x_shape) - d[n_parms:n_parms + m].reshape(x_shape)) / dx_f)**2) return chisq jac_jac_x = jacobian(jacobian(odr_chisquare_compact_x))(np.concatenate( (output.beta, output.xplus.ravel(), x_f.ravel()))) deriv_x = -hess_inv @ jac_jac_x[:n_parms + m, n_parms + m:] def odr_chisquare_compact_y(d): model = func(d[:n_parms], d[n_parms:n_parms + m].reshape(x_shape)) chisq = anp.sum(((d[n_parms + m:] - model) / dy_f)**2) + anp.sum( ((x_f - d[n_parms:n_parms + m].reshape(x_shape)) / dx_f)**2) return chisq jac_jac_y = jacobian(jacobian(odr_chisquare_compact_y))(np.concatenate( (output.beta, output.xplus.ravel(), y_f))) deriv_y = -hess_inv @ jac_jac_y[:n_parms + m, n_parms + m:] result = [] for i in range(n_parms): result.append( derived_observable( lambda x, **kwargs: x[0], [ pseudo_Obs(output.beta[i], 0.0, y[0].names[0], y[0].shape[y[0].names[0]]) ] + list(x.ravel()) + list(y), man_grad=[0] + list(deriv_x[i]) + list(deriv_y[i]))) result_dict['fit_parameters'] = result result_dict['odr_chisquare'] = odr_chisquare( np.concatenate((output.beta, output.xplus.ravel()))) result_dict['d.o.f.'] = x.shape[-1] - n_parms return result_dict if kwargs.get('dict_output') else result
def total_least_squares(x, y, func, silent=False, **kwargs): r'''Performs a non-linear fit to y = func(x) and returns a list of Obs corresponding to the fit parameters. Parameters ---------- x : list list of Obs, or a tuple of lists of Obs y : list list of Obs. The dvalues of the Obs are used as x- and yerror for the fit. func : object func has to be of the form ```python import autograd.numpy as anp def func(a, x): return a[0] + a[1] * x + a[2] * anp.sinh(x) ``` For multiple x values func can be of the form ```python def func(a, x): (x1, x2) = x return a[0] * x1 ** 2 + a[1] * x2 ``` It is important that all numpy functions refer to autograd.numpy, otherwise the differentiation will not work. silent : bool, optional If true all output to the console is omitted (default False). initial_guess : list can provide an initial guess for the input parameters. Relevant for non-linear fits with many parameters. expected_chisquare : bool If true prints the expected chisquare which is corrected by effects caused by correlated input data. This can take a while as the full correlation matrix has to be calculated (default False). Based on the orthogonal distance regression module of scipy ''' output = Fit_result() output.fit_function = func x = np.array(x) x_shape = x.shape if not callable(func): raise TypeError('func has to be a function.') for i in range(25): try: func(np.arange(i), x.T[0]) except Exception: pass else: break n_parms = i if not silent: print('Fit with', n_parms, 'parameter' + 's' * (n_parms > 1)) x_f = np.vectorize(lambda o: o.value)(x) dx_f = np.vectorize(lambda o: o.dvalue)(x) y_f = np.array([o.value for o in y]) dy_f = np.array([o.dvalue for o in y]) if np.any(np.asarray(dx_f) <= 0.0): raise Exception('No x errors available, run the gamma method first.') if np.any(np.asarray(dy_f) <= 0.0): raise Exception('No y errors available, run the gamma method first.') if 'initial_guess' in kwargs: x0 = kwargs.get('initial_guess') if len(x0) != n_parms: raise Exception( 'Initial guess does not have the correct length: %d vs. %d' % (len(x0), n_parms)) else: x0 = [1] * n_parms data = RealData(x_f, y_f, sx=dx_f, sy=dy_f) model = Model(func) odr = ODR(data, model, x0, partol=np.finfo(np.float64).eps) odr.set_job(fit_type=0, deriv=1) out = odr.run() output.residual_variance = out.res_var output.method = 'ODR' output.message = out.stopreason output.xplus = out.xplus if not silent: print('Method: ODR') print(*out.stopreason) print('Residual variance:', output.residual_variance) if out.info > 3: raise Exception('The minimization procedure did not converge.') m = x_f.size def odr_chisquare(p): model = func(p[:n_parms], p[n_parms:].reshape(x_shape)) chisq = anp.sum(((y_f - model) / dy_f)**2) + anp.sum( ((x_f - p[n_parms:].reshape(x_shape)) / dx_f)**2) return chisq if kwargs.get('expected_chisquare') is True: W = np.diag(1 / np.asarray(np.concatenate( (dy_f.ravel(), dx_f.ravel())))) if kwargs.get('covariance') is not None: cov = kwargs.get('covariance') else: cov = covariance_matrix(np.concatenate((y, x.ravel()))) number_of_x_parameters = int(m / x_f.shape[-1]) old_jac = jacobian(func)(out.beta, out.xplus) fused_row1 = np.concatenate( (old_jac, np.concatenate( (number_of_x_parameters * [np.zeros(old_jac.shape)]), axis=0))) fused_row2 = np.concatenate( (jacobian(lambda x, y: func(y, x))(out.xplus, out.beta).reshape( x_f.shape[-1], x_f.shape[-1] * number_of_x_parameters), np.identity(number_of_x_parameters * old_jac.shape[0]))) new_jac = np.concatenate((fused_row1, fused_row2), axis=1) A = W @ new_jac P_phi = A @ np.linalg.inv(A.T @ A) @ A.T expected_chisquare = np.trace( (np.identity(P_phi.shape[0]) - P_phi) @ W @ cov @ W) if expected_chisquare <= 0.0: warnings.warn("Negative expected_chisquare.", RuntimeWarning) expected_chisquare = np.abs(expected_chisquare) output.chisquare_by_expected_chisquare = odr_chisquare( np.concatenate((out.beta, out.xplus.ravel()))) / expected_chisquare if not silent: print('chisquare/expected_chisquare:', output.chisquare_by_expected_chisquare) fitp = out.beta hess_inv = np.linalg.pinv( jacobian(jacobian(odr_chisquare))(np.concatenate( (fitp, out.xplus.ravel())))) def odr_chisquare_compact_x(d): model = func(d[:n_parms], d[n_parms:n_parms + m].reshape(x_shape)) chisq = anp.sum(((y_f - model) / dy_f)**2) + anp.sum( ((d[n_parms + m:].reshape(x_shape) - d[n_parms:n_parms + m].reshape(x_shape)) / dx_f)**2) return chisq jac_jac_x = jacobian(jacobian(odr_chisquare_compact_x))(np.concatenate( (fitp, out.xplus.ravel(), x_f.ravel()))) deriv_x = -hess_inv @ jac_jac_x[:n_parms + m, n_parms + m:] def odr_chisquare_compact_y(d): model = func(d[:n_parms], d[n_parms:n_parms + m].reshape(x_shape)) chisq = anp.sum(((d[n_parms + m:] - model) / dy_f)**2) + anp.sum( ((x_f - d[n_parms:n_parms + m].reshape(x_shape)) / dx_f)**2) return chisq jac_jac_y = jacobian(jacobian(odr_chisquare_compact_y))(np.concatenate( (fitp, out.xplus.ravel(), y_f))) deriv_y = -hess_inv @ jac_jac_y[:n_parms + m, n_parms + m:] result = [] for i in range(n_parms): result.append( derived_observable( lambda my_var, **kwargs: (my_var[0] + np.finfo(np.float64).eps) / (x.ravel()[0].value + np.finfo(np.float64).eps) * out.beta[i], list(x.ravel()) + list(y), man_grad=list(deriv_x[i]) + list(deriv_y[i]))) output.fit_parameters = result output.odr_chisquare = odr_chisquare( np.concatenate((out.beta, out.xplus.ravel()))) output.dof = x.shape[-1] - n_parms output.p_value = 1 - chi2.cdf(output.odr_chisquare, output.dof) return output
def fitDoubleGaussians(charges, charge_err, data, data_err): # some simple peakfinding to find the first and second peaks peak1_value = np.max(data) peak1_bin = [x for x in range(len(data)) if data[x] == peak1_value][0] peak1_charge = charges[peak1_bin] # Preliminary fits to get better estimates of parameters... first_peak_data = RealData( charges[peak1_bin - 30:peak1_bin + 30], data[peak1_bin - 30:peak1_bin + 30], charge_err[peak1_bin - 30:peak1_bin + 30], data_err[peak1_bin - 30:peak1_bin + 30], ) first_peak_model = Model(gauss_fit) first_peak_odr = ODR(first_peak_data, first_peak_model, [peak1_value, peak1_charge, 0.1 * peak1_charge]) first_peak_odr.set_job(fit_type=2) first_peak_output = first_peak_odr.run() first_peak_params = first_peak_output.beta #second_peak_params, covariance = curve_fit(gauss_fit2, # data[peak1_bin-30:peak1_bin+30], # data[peak1_bin-30:peak1_bin+30], # p0 = [peak1_value, peak1_charge, 0.1*peak1_charge]) # subtract the largest peak so we can search for the other one updated_data = data - gauss_fit(first_peak_params, charges) #updated_data = data[:int(len(data)*2.0/3.0)] peak2_value = np.max(updated_data) peak2_bin = [ x for x in range(len(updated_data)) if updated_data[x] == peak2_value ][0] peak2_charge = charges[peak2_bin] #first_peak_params, covariance = curve_fit(gauss_fit2, # updated_data[peak2_bin-30:peak2_bin+30], # updated_data[peak2_bin-30:peak2_bin+30], # p0 = [peak2_value, peak2_charge, 0.1*peak2_charge]) # and the second peak... second_peak_data = RealData( charges[peak2_bin - 30:peak2_bin + 30], data[peak2_bin - 30:peak2_bin + 30], charge_err[peak2_bin - 30:peak2_bin + 30], data_err[peak2_bin - 30:peak2_bin + 30], ) second_peak_model = Model(gauss_fit) second_peak_odr = ODR(second_peak_data, second_peak_model, [peak2_value, peak2_charge, first_peak_params[2]]) second_peak_odr.set_job(fit_type=2) second_peak_output = second_peak_odr.run() second_peak_params = second_peak_output.beta # Now fit both gaussians simultaneously double_peak_data = RealData(charges, data, charge_err, data_err) double_peak_model = Model(double_gauss_fit) double_peak_odr = ODR(double_peak_data, double_peak_model, [ first_peak_params[0], first_peak_params[1], first_peak_params[2], second_peak_params[0], second_peak_params[1], second_peak_params[2] ]) double_peak_odr.set_job(fit_type=0) double_peak_output = double_peak_odr.run() double_peak_params = double_peak_output.beta double_peak_sigmas = double_peak_output.sd_beta #double_peak_params = [first_peak_params[0], first_peak_params[1], first_peak_params[2], # second_peak_params[0], second_peak_params[1], second_peak_params[2]] return double_peak_params, double_peak_sigmas
# now do ODR # Define a function (quadratic in our case) to fit the data with. def linear_func(p, x): m, c = p return m * x + c # Create a model for fitting. linear_model = Model(linear_func) # Create a RealData object using our initiated data from above. data = RealData(data[:, 2], data[:, 3]) # Set up ODR with the model and data. odr = ODR(data, linear_model, beta0=[1., 0.]) odr.set_job(fit_type=0) #if set fit_type=2, returns the same as leastsq # Run the regression. out = odr.run() # Use the in-built pprint method to give us results. out.pprint() modr = out.beta[0] codr = out.beta[1] yplt_odr = modr * xplt + codr plt.plot(xplt, yplt_odr, 'b-', lw=2, label='ODR') plt.xlim([1.8, 6.5]) plt.ylim([1.8, 6.5]) plt.legend(numpoints=1, loc=2) plt.grid(which='both') plt.xlabel('Original $\mathregular{M_L}$ $\mathregular{(M_{LH})}$',
def fitDoubleGaussians(charges, charge_err, data, data_err): # some simple peakfinding to find the first and second peaks peak1_value = np.max(data) peak1_bin = [x for x in range(len(data)) if data[x]==peak1_value][0] peak1_charge = charges[peak1_bin] # Preliminary fits to get better estimates of parameters... first_peak_data = RealData(charges[peak1_bin-30:peak1_bin+30], data[peak1_bin-30:peak1_bin+30], charge_err[peak1_bin-30:peak1_bin+30], data_err[peak1_bin-30:peak1_bin+30],) first_peak_model = Model(gauss_fit) first_peak_odr = ODR(first_peak_data, first_peak_model, [peak1_value, peak1_charge, 0.1*peak1_charge]) first_peak_odr.set_job(fit_type=2) first_peak_output = first_peak_odr.run() first_peak_params = first_peak_output.beta #second_peak_params, covariance = curve_fit(gauss_fit2, # data[peak1_bin-30:peak1_bin+30], # data[peak1_bin-30:peak1_bin+30], # p0 = [peak1_value, peak1_charge, 0.1*peak1_charge]) # subtract the largest peak so we can search for the other one updated_data = data-gauss_fit(first_peak_params, charges) #updated_data = data[:int(len(data)*2.0/3.0)] peak2_value = np.max(updated_data) peak2_bin = [x for x in range(len(updated_data)) if updated_data[x]==peak2_value][0] peak2_charge = charges[peak2_bin] #first_peak_params, covariance = curve_fit(gauss_fit2, # updated_data[peak2_bin-30:peak2_bin+30], # updated_data[peak2_bin-30:peak2_bin+30], # p0 = [peak2_value, peak2_charge, 0.1*peak2_charge]) # and the second peak... second_peak_data = RealData(charges[peak2_bin-30:peak2_bin+30], data[peak2_bin-30:peak2_bin+30], charge_err[peak2_bin-30:peak2_bin+30], data_err[peak2_bin-30:peak2_bin+30],) second_peak_model = Model(gauss_fit) second_peak_odr = ODR(second_peak_data, second_peak_model, [peak2_value, peak2_charge, first_peak_params[2]]) second_peak_odr.set_job(fit_type=2) second_peak_output = second_peak_odr.run() second_peak_params = second_peak_output.beta # Now fit both gaussians simultaneously double_peak_data = RealData(charges, data, charge_err, data_err) double_peak_model = Model(double_gauss_fit) double_peak_odr = ODR(double_peak_data, double_peak_model, [first_peak_params[0], first_peak_params[1], first_peak_params[2], second_peak_params[0], second_peak_params[1], second_peak_params[2]]) double_peak_odr.set_job(fit_type=0) double_peak_output = double_peak_odr.run() double_peak_params = double_peak_output.beta double_peak_sigmas = double_peak_output.sd_beta #double_peak_params = [first_peak_params[0], first_peak_params[1], first_peak_params[2], # second_peak_params[0], second_peak_params[1], second_peak_params[2]] return double_peak_params, double_peak_sigmas