def lebensdauer(p, x, x_error, y, y_error): model = odr.Model(exp) data = odr.RealData(x, y, sx=x_error, sy=y_error) out = odr.ODR(data, model, beta0=p).run() popt = out.beta perr = out.sd_beta x_fit = np.linspace(min(x), max(x), 1000) y_fit = exp(popt, x_fit) print("Exponential Funciton\n", popt, perr) plt.plot( x_fit, y_fit, label= "$N(t)=N_0\cdot \exp(-\\frac{t}{\\tau})+c$\n$N_0=(%.3f\pm%.3f)$\n$\\tau=(%.3f\pm%.3f)ns$\n$c=(%.3f\pm%.3f)$" % (popt[0], perr[0], popt[2], perr[2], popt[1], perr[1]))
def fit_both(datax,datay,errx,erry,func,beta0,print_info=False): dat = so.RealData(datax,datay,sx=errx,sy=erry) mod = so.Model(func) odr = so.ODR(dat,mod,beta0=beta0) res = odr.run() # if print_info: res.pprint() # sd_beta = np.sqrt(np.diag(res.cov_beta)) beta = res.beta pull_x = res.xplus normed_residuals = np.sqrt((res.eps/erry)**2 + (res.delta/errx)**2) pull_y = -np.sign(res.eps)*normed_residuals return [ [beta,sd_beta], [pull_x,pull_y], [res.res_var,len(datax)-len(beta0)] ]
def anpassung_yerr(function, x, y, y_error, presets, plot): model = odr.Model(function) data = odr.RealData(x, y, sy=y_error) out = odr.ODR(data, model, beta0=presets).run() popt = out.beta perr = out.sd_beta if plot == True: x_fit = np.linspace(min(x), max(x), 10000) y_fit = function(popt, x_fit) plt.plot(x_fit, y_fit) return popt,perr
def fit_circle(arc_contour): """ Fit the circle with feeding points Algorithm from scipy-cookbook: http://scipy-cookbook.readthedocs.io/items/Least_Squares_Circle.html :param arc_contour: :return: (x, y, r) """ from scipy import odr x = np.array([i[0][0] for i in arc_contour]) y = np.array([i[0][1] for i in arc_contour]) def calc_R(c): """ calculate the distance of each 2D points from the center c=(xc, yc) """ return np.sqrt((x - c[0])**2 + (y - c[1])**2) def circlemodel(beta, x): """ implicit function of the circle """ xc, yc, r = beta return (x[0] - xc)**2 + (x[1] - yc)**2 - r**2 def calc_estimate(data): """ Return a first estimation on the parameter from the data """ xc0, yc0 = data.x.mean(axis=1) r0 = np.sqrt((data.x[0] - xc0)**2 + (data.x[1] - yc0)**2).mean() return xc0, yc0, r0 # for implicit function : # data.x contains both coordinates of the points # data.y is the dimensionality of the response lsc_data = odr.Data(np.row_stack([x, y]), y=1) lsc_model = odr.Model(circlemodel, implicit=True, estimate=calc_estimate) lsc_odr = odr.ODR(lsc_data, lsc_model) lsc_out = lsc_odr.run() xc_3, yc_3, R_3 = lsc_out.beta print('lsc_out.sum_square = ', lsc_out.sum_square) # Ri_3 = calc_R([xc_3, yc_3]) # residu_3 = sum((Ri_3 - R_3) ** 2) # residu2_3 = sum((Ri_3 ** 2 - R_3 ** 2) ** 2) # print('residu_3 :', residu_3 ) # print('residu2_3 :', residu2_3) return xc_3, yc_3, R_3
def linear_fit_odr(x, y, xerr=None, yerr=None): from scipy import odr def f(B, x): return B[0] * x + B[1] linear = odr.Model(f) if xerr == None: xerr = np.ones(len(x)) if yerr == None: yerr = np.ones(len(y)) for i, e in enumerate(yerr): if e == 0: yerr[i] = 1 mydata = odr.RealData(x, y, sx=xerr, sy=yerr) myodr = odr.ODR(mydata, linear, beta0=[-1., 0.]) myoutput = myodr.run() return (myoutput.beta[0], myoutput.beta[1], myoutput.sd_beta[0], myoutput.sd_beta[1])
def leastErrorsHedgeRatio(df, stock1, stock2, days_moving_avg): y = np.asarray(df[stock1].tolist()[-days_moving_avg:]) # stock 1 data x = np.asarray(df[stock2].tolist()[-days_moving_avg:]) # stock 2 data # First use polyfit to generate rough estimate of betas fit_np = np.polyfit(x, y, 1) # Fit the data using scipy.odr def f(B, x): return B[0] * x + B[1] linear = odr.Model(f) mydata = odr.RealData(x, y, sx=np.std(x), sy=np.std(y)) myodr = odr.ODR(mydata, linear, beta0=[fit_np[0], fit_np[1]]) myoutput = myodr.run() return (myoutput.beta[0], myoutput.beta[1] ) # return both slope and intercept
def fit_y(datax,datay,erry,func,beta0,print_info=False): dat = so.RealData(datax,datay,sy=erry) mod = so.Model(func) odr = so.ODR(dat,mod,beta0=beta0) odr.set_job(fit_type=2) res = odr.run() # if print_info: res.pprint() # sd_beta = np.sqrt(np.diag(res.cov_beta)) beta = res.beta res_x = res.xplus res_y = res.eps reserr = erry return [ [beta,sd_beta], [res_x,res_y,reserr], [res.res_var,len(datax)-len(beta0)] ]
def findCurvatureR(x, y): # for implicit function : # data.x contains both coordinates of the points # data.y is the dimensionality of the response lsc_data = odr.Data(np.row_stack([x, y]), y=1) lsc_model = odr.Model(f_3, implicit=True, estimate=calc_estimate) lsc_odr = odr.ODR(lsc_data, lsc_model) lsc_out = lsc_odr.run() xc_3, yc_3, R_3 = lsc_out.beta Ri_3 = calc_R([xc_3, yc_3], x, y) residu_3 = sum((Ri_3 - R_3)**2) residu2_3 = sum((Ri_3**2 - R_3**2)**2) #ncalls_3 = f_3.ncalls #print ('lsc_out.sum_square = ',lsc_out.sum_square) return ([xc_3, yc_3, R_3])
def OneDCornerDetection(x, y): """ More explaination about odr can be found here: https://docs.scipy.org/doc/scipy/reference/odr.html#id1 http://stackoverflow.com/questions/22670057/linear-fitting-in-python-with-uncertainty-in-both-x-and-y-coordinates """ # Create a RealData object using input data data = spyodr.RealData(x, y) # Create linear model for fitting. beta0 = [min(y), 0.5 * (min(x) + max(x)), 0.707] linear_model = spyodr.Model(OneDCornerFunction) # Set up ODR with the model and data. odr = spyodr.ODR(data, linear_model, beta0=beta0) out = odr.run() coef = out.beta return coef, out.res_var
def get_fit_parameters(x, y, x_error, y_error): global odr model_func = odr.Model(linear_func) data = odr.RealData(x, y, sx=x_error, sy=y_error) odr_object = odr.ODR(data, model_func, beta0=[40, 0.05], taufac=1E-5, partol=1E-5, maxit=10000000) out = odr_object.run() optimized_parameters = out.beta parameter_errors = out.sd_beta cov_matrix = out.cov_beta return (optimized_parameters, parameter_errors), cov_matrix
def anpassung_xerr(function, x, y, x_error, presets, plot,customlabel): model = odr.Model(function) data = odr.RealData(x, y, sx=x_error) out = odr.ODR(data, model, beta0=presets).run() popt = out.beta perr = out.sd_beta if plot == True: x_fit = np.linspace(min(x), max(x), 10000) y_fit = function(popt, x_fit) if customlabel == False: plt.plot(x_fit, y_fit) else: plt.plot(x_fit, y_fit,label=customlabel) return popt,perr
def gausanpassung(x1, y1, x1_error, y1_error): model = odr.Model(gauss) width = 0.7 height = 1. for i in range(0, int(eckdaten[0, 1])): # print(eckdaten[3+i*2,:]) x = x1[int(eckdaten[3 + i * 2, 0]):int(eckdaten[3 + i * 2, 2])] y = y1[int(eckdaten[3 + i * 2, 0]):int(eckdaten[3 + i * 2, 2])] x_error = x1_error[int(eckdaten[3 + i * 2, 0]):int(eckdaten[3 + i * 2, 2])] y_error = y1_error[int(eckdaten[3 + i * 2, 0]):int(eckdaten[3 + i * 2, 2])] # Create a RealData object data = odr.RealData(x, y, sx=x_error, sy=y_error) # Set up ODR with the model and data. presets = [ ecal.E(eckdaten[3 + i * 2, 1]), width, y1[int(eckdaten[3 + i * 2, 1])] * height, 0., 1. ] # presets=[eckdaten[3+i*2,1], width, y1[int(eckdaten[3+i*2,1])]*height, 0. ,1.] out = odr.ODR(data, model, beta0=presets).run() popt = out.beta perr = out.sd_beta # maxima[0,i]=popt[0]#a # maxima[1,i]=perr[0]#a_err # maxima[2,i]=popt[2]#d # maxima[3,i]=perr[2]#d_err # print(popt,min(x), max(x)) maxima[i] = np.vstack((popt, perr)) b = ufloat(popt[1], perr[1]) x_fit = np.linspace(min(x), max(x), 10000) y_fit = gauss(maxima[i, 0], x_fit) print(round(popt[2], 2), round(perr[2], 2)) # print(np.hstack(np.stack((popt,perr),axis=1))) plt.plot(x_fit, y_fit, label=str(i + 1) + '. Peak (' + str(round(popt[0], 2)) + '+/-' + str(round(perr[0], 2)) + ') keV') # plt.errorbar(x=popt[0], y=popt[2]+popt[3]*popt[0]+popt[4], yerr=perr[2] ,xerr=perr[0], marker='x',linestyle = 'None', color='red',zorder=3) # plt.plot(x_fit, gauss(presets, x_fit), color='grey', zorder=-3) return maxima
def gausanpassung(x1, y1, x1_error, y1_error): model = odr.Model(gauss) width = 3. height = 1. if detektortyp == 'H': width = 0.7 height = 1. for i in range(0, int(eckdaten[0, 1])): x = x1[int(eckdaten[3 + i * 2, 0]):int(eckdaten[3 + i * 2, 2])] y = y1[int(eckdaten[3 + i * 2, 0]):int(eckdaten[3 + i * 2, 2])] x_error = x1_error[int(eckdaten[3 + i * 2, 0]):int(eckdaten[3 + i * 2, 2])] y_error = y1_error[int(eckdaten[3 + i * 2, 0]):int(eckdaten[3 + i * 2, 2])] # Create a RealData object data = odr.RealData(x, y, sx=x_error, sy=y_error) # Set up ODR with the model and data. presets = [ ecal.E(eckdaten[3 + i * 2, 1]), width, y1[int(eckdaten[3 + i * 2, 1])] * height, 0., 1. ] out = odr.ODR(data, model, beta0=presets).run() popt = out.beta perr = out.sd_beta b = ufloat(popt[1], perr[1]) maxima[0, i] = popt[0] #a maxima[1, i] = perr[0] #a_err print(perr[0]) maxima[2, i] = popt[2] #d maxima[3, i] = perr[2] #d_err relint[i] = eckdaten[3 + i * 2, 4] FWHM = 2 * np.sqrt(2 * np.log(2)) * b # print(str(i+1)+'. Peak;'+str(round(popt[0],2))+'plusundminus'+str(round(perr[0],2))+';'+str(round(popt[2],2))+'plusundminus'+str(round(perr[2],2))) # print(datensatz+';'+str(i+1)+'. Peak;'+str(b)+';'+str(FWHM)) x_fit = np.linspace(min(x), max(x), 10000) y_fit = gauss(popt, x_fit) plt.plot(x_fit, y_fit, label=str(i + 1) + '. Peak (E=(' + str(round(popt[0], 2)) + '$\pm$' + str(round(perr[0], 2)) + ')keV)')
def perform_odr(add, dev, wadd, wdev): """ A wrapper to calculate an ODR regression. params: ------- add, dev - x and y axis of the regression wadd, wdev - standard deviations returns: an ODR object """ linear = odr.Model(f) # mydata = odr.Data(add, dev, wd=1./wadd, we=1./wdev) mydata = odr.RealData(add, dev, sx=wadd, sy=wdev) myodr = odr.ODR(mydata, linear, beta0=[0]) myoutput = myodr.run() return myoutput
def circle_3b(xs, ys): # for implicit function # data.x contains both coordinates of the points # data.y is the dimensionality of the response lsc_data = odr.Data(np.row_stack([xs, ys]), y=1) lsc_model = odr.Model(f_3b, implicit=True, estimate=calc_estimate, fjacd=jacd, fjacb=jacb) # beta0 has been replaced by an estimate function lsc_odr = odr.ODR(lsc_data, lsc_model) # use user derivatives function without checking lsc_odr.set_job(deriv=3) # print details for each iteration # lsc_odr.set_iprint(iter=1, iter_step=1) lsc_out = lsc_odr.run() xc_3b, yc_3b, R_3b = lsc_out.beta return (xc_3b, yc_3b), R_3b
def polyfit(x, y, xerr, yerr, deg): """ Perform a polynomial fit on data with 2 dimensional errors using the scipy.odr orthogonal distance regression pacage. @param x: x data @param y: y data @param xerr: errors on x data @param yerr: errors on y data @param deg: degree """ model = odr.Model(lambda B, x: _func(B, x, deg=deg)) data = odr.Data(x, y, wd=1. / pow(xerr, 1), we=1. / pow(yerr, 1)) beta0 = np.polyfit(x, y, deg) # np.polyfit w/o errors as estimate. odr_fit = odr.ODR(data, model, beta0=beta0) fit = odr_fit.run() return fit.beta
def circle_fit_jacobian(x, y): lsc_data = odr.Data(row_stack([x, y]), y=1) lsc_model = odr.Model(f_3b, implicit=True, estimate=calc_estimate, fjacd=jacd, fjacb=jacb) lsc_odr = odr.ODR( lsc_data, lsc_model) # beta0 has been replaced by an estimate function lsc_odr.set_job(deriv=3) # use user derivatives function without checking # lsc_odr.set_iprint(iter=1, iter_step=1) # print details for each iteration lsc_out = lsc_odr.run() xc_3b, yc_3b, R_3b = lsc_out.beta # Ri_3b = calc_R(xc_3b, yc_3b) # residu_3b = sum((Ri_3b - R_3b)**2) return xc_3b, yc_3b, R_3b
def fit(show=True): fit_func = lambda t, x: e ** (-1 * (x - t[1]) / t[0]) m = odr.Model(fit_func) d = odr.RealData(bins[:-1], n) t0 = [.5, 7] o = odr.ODR(d, m, beta0=t0) out = o.run() x_fit = bins fit = fit_func(out.beta, x_fit) if show: xlabel('Time [us]') ylabel('Number of Entries') title('Muon Life Time') plot(x_fit, fit, 'r', lw=2, label='fit: e^(-x/t0), t0={:1.3f} ({:1.3f}) \nchi2: {:1.2f}'.format(out.beta[0], out.sd_beta[0], out.res_var)) legend(loc='upper right', fontsize = 14) axis([0, 12, 0, 40]) pyplot.show() return out.beta, out.sd_beta
def fit_to_model(self): ellipsemodel = odr.Model(ellipsepolar) a = np.empty(self.number_of_full_turns()) ecc = np.empty(self.number_of_full_turns()) for i in np.arange(self.number_of_full_turns()): data_to_fit = odr.Data( self.phi_rotated()[self.periloc()[i]:self.periloc()[i + 1]], self.r[self.periloc()[i]:self.periloc()[i + 1]]) peri0 = self.r[self.periloc()[0]] apo0 = self.r[int(self.periloc()[0] + self.turn_length()[0] / 2)] a0 = (peri0 + apo0) / 2 ecc0 = (1 - peri0 / apo0) / (1 + peri0 / apo0) job = odr.ODR(data_to_fit, ellipsemodel, beta0=np.array([a0, ecc0])) results = job.run() a[i], ecc[i] = results.beta return a, ecc
def linRegressionXY(x, y, sx, sy): """ linear regression y(x) = ax + b with errors on x and y uses numerical "orthogonal distance regression" from package scipy.odr Args: * x: np-array, independent data * y: np-array, dependent data * sx: scalar or np-array, uncertainty(ies) on x * sy: scalar or np-array, uncertainty(ies) on y Returns: * float: a slope * float: b constant * float: sa sigma on slope * float: sb sigma on constant * float: cor correlation * float: chi2 \chi-square """ from scipy import odr def fitf(P, x): # the linear model (note order or parameters for odr !) return P[1]*x + P[0] # transform uncertainties to numpy-arrays, if necessary if not hasattr(sx,'__iter__'): sx=sx*np.ones(len(x)) if not hasattr(sy,'__iter__'): sy=sy*np.ones(len(y)) # get initial values for numerical optimisation from linear # regression with analytical formula, ignoring x errors a0, b0, sa0, sb0, cor0, chi20 = linRegression(x, y, sy) # set up odr package: mod = odr.Model(fitf) dat = odr.RealData(x, y, sx, sy) odrfit = odr.ODR(dat, mod, beta0=[b0, a0]) r = odr.ODR.run(odrfit) ndf = len(x)-2 a, b, sa, sb = r.beta[1], r.beta[0],\ np.sqrt(r.cov_beta[1,1]), np.sqrt(r.cov_beta[0,0]) cor = r.cov_beta[0,1]/(sa*sb) chi2 = r.res_var*ndf return a, b, sa, sb, cor, chi2
def scatter_plotter(y, pred): #Function used to fit the points thanks to scipy ODR. sxx = np.std(pred) syy = np.std(y) linear = odr.Model(f) mydata = odr.RealData(np.concatenate(pred), y, sx=sxx, sy=syy) myodr = odr.ODR(mydata, linear, beta0=[1, 0.5]) myoutput = myodr.run() mark = dict(marker='o', color="black", fillstyle="none", markersize=15, linewidth=0) #Plotting fig = plt.figure(figsize=(15, 8)) plt.plot(pred, y, **mark, label="Predicted") top = max(pred) bottom = min(pred) #Plot of the bisector, the line in which the poinst must be in the neighborhood plt.plot([bottom, top], [bottom, top], "r--", color="deepskyblue", label="Perfect NN") #Plot of the fit plt.plot(pred, f(myoutput.beta, pred), "r--", color="m", label="Linear inrterpolation, m=%.2f, bias=%.2f" % (myoutput.beta[0], myoutput.beta[1])) plt.xlabel('denseneural_prediction') plt.ylabel('True y values') plt.title("NN regression visualization, MSE: %.4f" % mean_squared_error(truth_train, pred), fontsize=20) plt.legend(loc="best", prop={'size': 15}) plt.show() plt.savefig('scatter_plot.png')
def detrend(method, data1, data2): """ Model and remove a mutiplicative offset between data1 and data2 by method :param method: Detrending method to use :type method: None or str :param numpy.array data1: Array of first measures :param numpy.array data2: Array of second measures """ slope = slopeErr = None if method is None: pass elif method.lower() == 'linear': reg = stats.linregress(data1, data2) slope = reg.slope slopeErr = reg.stderr data2 = data2 / slope elif method.lower() == 'odr': from scipy import odr def f(B, x): return B[0]*x + B[1] linear = odr.Model(f) odrData = odr.Data(data1, data2, wd=1./numpy.power(numpy.std(data1),2), we=1./numpy.power(numpy.std(data2),2)) odrModel = odr.ODR(odrData, linear, beta0=[1., 2.]) myoutput = odrModel.run() slope = myoutput.beta[0] slopeErr = myoutput.sd_beta[0] data2 = data2 / slope else: raise NotImplementedError(f"'{detrend}' is not a valid detrending method.") return data2, slope, slopeErr
def fit(instance): fit_options = instance.fit_options data = instance.data model = ODR.Model(fit_options.function) odr_data = ODR.RealData(data.x, data.y, sx=data.sx, sy=data.sy) odr = ODR.ODR(odr_data, model, beta0=fit_options.params) raw_output = odr.run() beta = raw_output.beta err = raw_output.sd_beta cov_mtr = raw_output.cov_beta chi2 = 0 degree_freedom = len(data.x) - len(fit_options.params) fit_result = FitResult(beta, err, cov_mtr, chi2, degree_freedom, raw_output) instance.result = fit_result return fit_result
def implement(self): lsc_data = odr.Data(row_stack([self.x1, self.y1]), y=1) lsc_model = odr.Model(self.f_3b, implicit=True, estimate=self.calc_estimate, fjacd=self.jacd, fjacb=self.jacb) lsc_odr = odr.ODR( lsc_data, lsc_model) # beta0 has been replaced by an estimate function lsc_odr.set_job( deriv=3) # use user derivatives function without checking # lsc_odr.set_iprint(iter=1, iter_step=1) # print details for each iteration lsc_out = lsc_odr.run() xc_3b, yc_3b, Radius = lsc_out.beta Ri_3b = self.calc_R(xc_3b, yc_3b) residu = sum((Ri_3b - Radius)**2) dce = [xc_3b, yc_3b] return dce, Radius, residu
def perform_arbitrary_regression( plot: plots.Plottable, function: str) -> Tuple[plots.Plottable, Dict[str, Value], np.ndarray]: pyFunc = mathsFunction(function) ODRModel = odr.Model(pyFunc.function) RealData = odr.RealData(plot.x, y=plot.y, sy=plot.yErr, sx=plot.xErr) coeffs = pyFunc.coefficients def next_val(l: List, b: List, best: odr.Output) -> odr.Output: if len(l) == 0: o = odr.ODR(RealData, ODRModel, beta0=b) output = o.run() if best is None: return output if best.sum_square > output.sum_square: return output return best for n in np.linspace(l[0].initial, l[0].final, l[0].number): new_b = b.copy() new_b.append(n) best = next_val(l[1:], new_b, best) return best coList: List[Union[None, mathsFunction.variables. coefficient]] = [None] * pyFunc.numberOfCoefficients for letter, coef in coeffs.items(): coList[pyFunc.letterToNumber[letter]] = coef output = next_val(coList, [], None) space = np.linspace(plot.x[0], plot.x[-1], 1000) f_x = pyFunc.function(output.beta, space) uncertainties = np.sqrt(np.diag(output.cov_beta)) coefficients = {} for letter, number in pyFunc.letterToNumber.items(): coefficients[letter] = Value(output.beta[number], uncertainties[number]) return ( plots.Plottable(x=space, y=f_x), coefficients, pyFunc.function(output.beta, plot.x), )
def odr_fit(n, data, func, params=None, fixed_params=None, nopeaks=4, **kw): """#n is the number of gaussians to fit params is an array of parameters for each gaussian (A, mu, sigma) for fixed params: 'A value of 0 fixes the parameter, a value > 0 makes the parameter free.' """ if params is None: params = find_peak_data(data, n) #set up odr module model = odr.Model(func) odr_data = odr.Data(range(len(data)), data) fit = odr.ODR(odr_data, model, params, ifixb=fixed_params, **kw) #run the fit output = fit.run() return output.beta, output.sd_beta
def gausanpassung(x1, y1, x1_error, y1_error): model = odr.Model(gauss) width = 0.7 height = 1. for i in range(0, int(eckdaten[0, 1])): # print(eckdaten[3+i*2,:]) x = x1[int(eckdaten[3 + i * 2, 0]):int(eckdaten[3 + i * 2, 2])] y = y1[int(eckdaten[3 + i * 2, 0]):int(eckdaten[3 + i * 2, 2])] x_error = x1_error[int(eckdaten[3 + i * 2, 0]):int(eckdaten[3 + i * 2, 2])] y_error = y1_error[int(eckdaten[3 + i * 2, 0]):int(eckdaten[3 + i * 2, 2])] # Create a RealData object data = odr.RealData(x, y, sx=x_error, sy=y_error) # Set up ODR with the model and data. presets = [ ecal.E(eckdaten[3 + i * 2, 1]), width, y1[int(eckdaten[3 + i * 2, 1])] * height, 0., 1. ] # presets=[eckdaten[3+i*2,1], width, y1[int(eckdaten[3+i*2,1])]*height, 0. ,1.] out = odr.ODR(data, model, beta0=presets).run() popt = out.beta perr = out.sd_beta maxima[0, i] = popt[0] #a maxima[1, i] = perr[0] #a_err maxima[2, i] = popt[2] #d maxima[3, i] = perr[2] #d_err # print(perr[2]) b = ufloat(popt[1], perr[1]) x_fit = np.linspace(min(x), max(x), 10000) y_fit = gauss(popt, x_fit) plt.plot(x_fit, y_fit, label=str(i + 1) + '. Peak (' + str(round(popt[0], 2)) + '+/-' + str(round(perr[0], 2)) + ') keV') # plt.plot(x_fit, gauss(presets, x_fit), color='grey', zorder=-3) return maxima
def _olsFit(): if yError is not None and _np.count_nonzero(yError) != len(yError): _warnings.warn( 'data.yError contains 0: executing OLS fitting without yError instead.' ) return Rdata = _odr.RealData(x, y, sy=yError) odrObj = _odr.ODR(Rdata, _odr.Model(self.fn), self.initialParams) odrObj.set_job(fit_type=2) self._fitObj = odrObj.run() self._fitParams = self.fitObj.beta self._fitParamsStdError = self.fitObj.sd_beta self._R2 = _gf.R2(x, y, self.fittedFn) #The following line raises warnings in pylint. The code is OK tough. self._reducedChi2 = self.fitObj.res_var #See http://mail.scipy.org/pipermail/scipy-user/2012-May/032207.html #For an OLS fit, ODR scales the covariance matrix by res_var=reducedChi2, so we need to get rid of that scaling: self._fitObj.cov_beta = self._fitObj.cov_beta * self._reducedChi2
def perform_linear_regression( plot: plots.Plottable ) -> Tuple[plots.Plottable, Dict[str, Value], np.ndarray]: slope, intercept, _, _, _ = stats.linregress(plot.x, plot.y) RealData = odr.RealData(plot.x, y=plot.y, sx=plot.xErr, sy=plot.yErr) o = odr.ODR(RealData, odr.Model(lambda B, x: B[0] * x + B[1]), beta0=[slope, intercept]) output = o.run() beta = output.beta f_x: np.ndarray = beta[0] * plot.x + beta[1] return ( plots.Plottable(x=plot.x, y=f_x), { "gradient": Value(beta[0], output.sd_beta[0]), "intercept": Value(beta[1], output.sd_beta[1]), }, f_x, )
def fit_ODR(y, x1, x2=None, beta0=None, func=None, err_x=None, err_y=None, ci=0.95, maxit=1000): if x2 is not None: x = np.row_stack((x1, x2)) # odr doesn't seem to work with column_stack else: x = x1 if beta0 is None: beta0 = [0.1, 1] if x2 is not None: beta0.append(1) data = odr.RealData(x, y, sx=err_x, sy=err_y) model = odr.Model(func) odrfit = odr.ODR(data, model, beta0, maxit=maxit) output = odrfit.run() # confidence intervals df_e = len(x1) - len(output.beta) # degrees of freedom, error conf = [] t_df = stats.t.ppf(ci, df_e) # 0.975 for i in range(len(output.beta)): conf.append([output.beta[i] - t_df * output.sd_beta[i], output.beta[i] + t_df * output.sd_beta[i]]) # chi sqr expected = func(output.beta, x) chisqr = output.sum_square # np.sum(((y - expected) ** 2) / expected) chisqr_nu = output.res_var # covariance matrix cov_beta = output.cov_beta * output.res_var print(' -> ODR RESULTS') print(' -> reason for halting:', output.stopreason) for ii, val in enumerate(output.beta): print(' -> beta', ii, ':', val, '+/-', output.sd_beta[ii], ' CI:', conf[ii][0], conf[ii][1]) print(' -> sum of squares error:', chisqr) print(' -> reduced chi sqr:', chisqr_nu) print(' -> covariance matrix:\n') printarr(cov_beta) # print(' -> eps', output.eps, len(output.eps), len(y)) print('\n') return output