def test_dabam_names(): """ Tests that the I/O methods work well for the list of input values :return: """ print( "------------------- test_dabam_names ------------------------------") dm = dabam() number_of_input_fields = len(dm.inputs) argsdict = dm.inputs names = [] values = [] for i, j in argsdict.items(): names.append(i) values.append(j) #change values and reinsert in object values2 = copy.copy(values) for i in range(number_of_input_fields): if values[i] != None: values2[i] = 2 * values[i] print("-----------------------------------------------------") print("--input_name value value2") for i in range(number_of_input_fields): print(i, names[i], values[i], values2[i]) dm.inputs[names[i]] = values2[i] print("-----------------------------------------------------") print("-----------------------------------------------------") print("--input_name input_name_short stored_value2, help") for i in range(number_of_input_fields): print( names[i], dm.get_input_value(names[i]), dm.get_input_value_short_name(names[i]), dm.inputs[names[i]], "\n", dm.get_input_value_help(names[i]), ) print("-----------------------------------------------------") #back to initial values dict2 = dm.get_inputs_as_dictionary() for i in range(number_of_input_fields): dict2[names[i]] = values[i] dm.inputs[names[i]] = values2[i] dm.set_inputs_from_dictionary(dict2) print("--back to initial value") if (dm.inputs == dabam().inputs): print("Back to initial value: OK") else: raise Exception( "Back to initial value: error returning to initial state")
def test_dabam_stdev_slopes(nmax=9): """ Tests the slope error value for the nmax first profiles (from remote server) :return: """ print( "------------------- test_dabam_slopes ------------------------------" ) stdev_ok = [ 4.8651846141972904e-07, 1.5096270252538352e-07, 1.7394444580303415e-07, 1.3427931903345248e-07, 8.4197811681221573e-07, 1.0097219914737401e-06, 5.74153915948042e-07, 5.7147678897188605e-07, 4.3527688789008779e-07, 2.3241765005153794e-07, 2.2883095949050537e-07, 3.1848792295534762e-07, 1.2899449478710491e-06, 1.1432193606225235e-06, 2.1297554130432642e-06, 1.8447156600570902e-06, 2.2715775271373941e-06, 1.1878208663183125e-07, 4.1777346923623561e-08, 4.0304426129060434e-07, 4.3430016136041185e-07, 5.3156037926371151e-06, 1.7725086287871762e-07, 2.0222947541222619e-07, 7.2140041229621698e-08 ] tmp_profile = [] tmp_psd = [] stdev_ok = [] for i in range(nmax): print(">> testing slopes stdev from profile number: ", i) dm = dabam() dm.set_input_silent(True) dm.set_input_entryNumber(i + 1) dm.load() stdev_profile = dm.stdev_profile_slopes() stdev_psd = dm.stdev_psd_slopes() tmp_profile.append(stdev_profile) tmp_psd.append(stdev_psd) try: tmp = float(dm.metadata["CALC_SLOPE_RMS"]) * float( dm.metadata["CALC_SLOPE_RMS_FACTOR"]) except: tmp = 0 stdev_ok.append(tmp) for i in range(nmax): print( "Entry, stdev from profile, stdev from psd, stdev OK (stored): %03d %8.3g %8.3g %8.3g" % (i + 1, tmp_profile[i], tmp_psd[i], stdev_ok[i])) for i in range(nmax): if stdev_ok[i] != 0.0: print("Checking correctness of dabam-entry: %d" % (1 + i)) print( " Check slopes profile urad: StDev=%f, FromPSD=%f, stored=%f " % (1e6 * tmp_profile[i], 1e6 * tmp_psd[i], 1e6 * stdev_ok[i])) assert abs(tmp_profile[i] - stdev_ok[i]) < 1e-6 assert abs(tmp_psd[i] - stdev_ok[i]) < 1e-6
import dabam import numpy import seaborn as sns import pandas as pd import json from io import StringIO do_plots = 1 #create DABAM objects to load experimental and two simulated profiles #dm = [dabam.dabam(),dabam.dabam(),dabam.dabam()] # # load input from DABAM # dm = dabam.dabam() #[dm[i-1].set_input_entryNumber(i) for i in range(1,57)] #[dm[i-1].load() for i in range(1,57)] #for i in range(1,57): #plane_entry=[i for i in range(1,57) if dm[i-1].metadata['SURFACE_SHAPE']=="plane"] #self.metadata['SURFACE_SHAPE'] plane_entry = [] cylindrical_entry = [] elliptical_entry = [] spherical_entry = [] toroidal_entry = [] surface_set = set() #df=pd.DataFrame() #for i in range(1,57): # dm.set_input_entryNumber(i) # fileaddress='../data/'+(dm.file_metadata())
from matplotlib import pylab as plt import dabam import numpy do_plots = 0 #create DABAM objects to load experimental and two simulated profiles dm = [dabam.dabam(), dabam.dabam(), dabam.dabam()] # # load input from DABAM # dabam_entry = 12 #dm = dabam.dabam() dm[0].set_input_entryNumber(dabam_entry) dm[0].load() if do_plots: dm[0].set_input_plot("psd_h") dm[0].plot() dm[0].set_input_plot("acov_h") dm[0].plot() # # define inputs for fractal and Gaussian simulated profiles # cl = 0.05 #dm.autocorrelation_heights() # 0.03 beta = 1.1 # 0.9 #(-dm.powerlaw["hgt_pendent"])
# text = dabam.dabam_summary() print(text) out = dabam.dabam_summary_dictionary() for i in range(len(out)): print("i=:%d, entry:%d"%(i,(out[i])["entry"])) print(out[13]) # # load a given entry (=14) # dm = dabam.dabam() dm.set_input_silent(True) dm.load(14) info = dm.info_profiles() print(info) # # make a bunh of plots # dm.set_input_plot("heights slopes psd_h csd_h acf_h histo_h") dm.plot() # you can do plots by accessing data, ex: plt.plot(1e3*dm.y,1e6*dm.zHeights) # dm.metadata # metadata
def convert_antoine(): from srxraylib.plot.gol import plot directory = "/home/manuel/google-drive/optics_COSMIC/" file = "COSMIC M101 LTP slope and height.csv" FILES = [ "COSMIC_M101_LTP_slope_and_height.csv", "COSMIC_M111_LTP_slope_and_height.csv", "COSMIC_M112_LTP_slope_and_height.csv", "COSMIC_M121_LTP_slope_and_height.csv", "qerlinM201.dat", "QERLIN_M203_data_Trace_Line_1.csv", "amberM202faceUpResidSlope.dat" ] for i, ifile in enumerate(FILES): print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> file", ifile, type(file)) # "amberM202faceUpResidSlope.dat" input = directory + ifile f = open(input, "r") txt = f.read() f.close() txt = txt.replace("g", " ") txt = txt.replace(",,,", ",") txt = txt.replace(",,,", ",") txt = txt.replace('"', '') txt = txt.replace(",", " ") txt = txt.split("\n") for ii in range(5): print(">>>>", txt[ii]) a = numpy.loadtxt(txt, skiprows=1) print(a.shape) # plot(a[:,0],a[:,-1]*1e3,title="raw heights "+file) print(">> RAW slope error: %f urad RMS" % (a[:, 1].std() * 1e6)) dm = dabam() dm = dabam.initialize_from_external_data(txt, column_index_abscissas=0, column_index_ordinates=1, skiprows=1, useHeightsOrSlopes=1, to_SI_abscissas=1e-3, to_SI_ordinates=1.0, detrending_flag=1) if True: if i <= 3: CALC_HEIGHT_RMS = a[:, 5].std() * 1e6 CALC_HEIGHT_RMS_FACTOR = 1e-9 CALC_SLOPE_RMS = a[:, 3].std() * 1e6 CALC_SLOPE_RMS_FACTOR = 1e-6 print(">> RAW slope error (detrended): %f urad RMS" % (a[:, 3].std() * 1e6)) print(">> RAW height error (detrended): %f nm RMS" % (a[:, 5].std() * 1e3)) else: CALC_HEIGHT_RMS = None CALC_HEIGHT_RMS_FACTOR = None CALC_SLOPE_RMS = None CALC_SLOPE_RMS_FACTOR = None dm.metadata_set_info( YEAR_FABRICATION=None, SURFACE_SHAPE=None, FUNCTION=None, LENGTH=None, WIDTH=None, THICK=None, LENGTH_OPTICAL=(a[:, 0].max() - a[:, 0].min()) * 1e-3, SUBSTRATE=None, COATING=None, FACILITY="ALS", INSTRUMENT=None, POLISHING=None, ENVIRONMENT=None, SCAN_DATE=None, CALC_HEIGHT_RMS=CALC_HEIGHT_RMS, CALC_HEIGHT_RMS_FACTOR=CALC_HEIGHT_RMS_FACTOR, CALC_SLOPE_RMS=CALC_SLOPE_RMS, CALC_SLOPE_RMS_FACTOR=CALC_SLOPE_RMS_FACTOR, USER_EXAMPLE=None, USER_REFERENCE="From file: %s" % file, USER_ADDED_BY="Antoine Wojdyla and Manuel Sanchez del Rio", ) # dm.plot("heights") # # print(dm.metadata) dm.write_output_dabam_files(filename_root="dabam-%03d" % (i + 1), loaded_from_file=txt) print(">> RAW slope error: %f urad RMS" % (a[:, 1].std() * 1e6)) if i <= 3: print(">> RAW slope error (detrended): %f urad RMS" % (a[:, 3].std() * 1e6)) print(">> RAW height error (detrended): %f nm RMS" % (a[:, 5].std() * 1e6)) print(">> DABAM slope error: %f urad RMS" % (dm.zSlopesUndetrended.std() * 1e6)) print(">> DABAM slope error (detrended): %f urad RMS" % (dm.zSlopes.std() * 1e6)) print(">> RAW height error (detrended): %f nm RMS" % (dm.zHeights.std() * 1e9)) return i
def ellipse_fit(entry_number = 21, fit_method=1, fit_function='dabam', ibounded=1,do_plots=1): """ :param entry_number: dabam entry number :param fit_method: fit elliptical heights (0), fit elliptical slopes (1) :param fit_function: 'dabam' , 'amparo', 'xianbo' :param ibounded: 0 curve_fit (no guess), 1=leastsq, 2=bounded :param do_plot: 1 display plots :return: """ # #get profiles # import dabam dm = dabam.dabam() dm.inputs["entryNumber"] = entry_number dm.inputs["setDetrending"] = -1 dm.load() # # # p0 = dm.h["ELLIPSE_DESIGN_P"] q0 = dm.h["ELLIPSE_DESIGN_Q"] theta0 = dm.h["ELLIPSE_DESIGN_THETA"] # y axis is horizonta, z axis is vertical y0 = dm.sy z0 = dm.zprof zp0 = dm.sz if fit_method == 0: # ellipse fitting heights hshift = 0.0 #nm vshift = 0.0 # nm #preprocessors if entry_number == 4: z0 -= z0.min() elif entry_number == 6: imin = z0.argmin() z0 -= z0[imin] y0 -= y0[imin] y0 *= -1.0 elif entry_number == 19: pass elif entry_number == 20: hshift = -15e3 elif entry_number == 21: y0 -= y0[y0.size/2] if fit_function == "amparo": fitfunc_ell_heights = lambda p, x: func_ellipse_heights_amparo(x, p[0], p[1], p[2], p[3], p[4]) print("Using function definition: AMPARO") elif fit_function == "xianbo": fitfunc_ell_heights = lambda p, x: func_ellipse_heights_xianbo(x, p[0], p[1], p[2], p[3], p[4]) print("Using function definition: XIANBO") else: fitfunc_ell_heights = lambda p, x: func_ellipse_heights_dabam(x, p[0], p[1], p[2], p[3], p[4]) print("Using function definition: DABAM") print("======== Fitting heights =======") errfunc_ell_heights = lambda p, x, y: fitfunc_ell_heights(p, x) - y p_guess = [p0,q0,theta0,hshift,vshift] if ibounded == 0: print("======== Curve fitting without guess =======") if fit_function == "amparo": popt, cov_x = curve_fit(func_ellipse_heights_amparo, y0, z0, maxfev=10000) elif fit_function == "xianbo": popt, cov_x = curve_fit(func_ellipse_heights_xianbo, y0, z0, maxfev=10000) else: popt, cov_x = curve_fit(func_ellipse_heights_dabam, y0, z0, maxfev=10000) elif ibounded == 1: print("======== Least Squares fitting =======") popt, cov_x, infodic, mesg, ier = leastsq(errfunc_ell_heights, p_guess,args=(y0, z0), full_output=True) else: print("======== Bounded Least Squares fitting =======") # https://github.com/jjhelmus/leastsqbound-scipy from leastsqbound import leastsqbound bounds = [ (p0*0.998,p0*1.002) , (q0*0.8,q0*1.2), (theta0*0.98,theta0*1.02), (-0.01,0.01), (-0.001,0.001)] popt, cov_x, infodic, mesg, ier = leastsqbound(errfunc_ell_heights, p_guess, args=(y0,z0), full_output=True, bounds=bounds) print(">>>>> p_guess:", p_guess) print(">>>>> popt:", popt) z1 = fitfunc_ell_heights(p_guess, y0) z2 = fitfunc_ell_heights(popt, y0) zp1 = numpy.gradient(z1,y0[1]-y0[0]) zp2 = numpy.gradient(z2,y0[1]-y0[0]) rms_values = ( 1e9*(z0-z1).std(),1e9*(z0-z2).std(), 1e6*numpy.gradient(z0-z1,y0[1]-y0[0]).std(),1e6*numpy.gradient(z0-z2,y0[1]-y0[0]).std()) print ('Height error RMS z0-z1: %.3f nm'%(1e9*(z0-z1).std())) print ('Slope error RMS z0-z1: %.3f urad'%(1e6*numpy.gradient(z0-z1,y0[1]-y0[0]).std())) print ('height error RMS z0-z2: %.3f nm'%(1e9*(z0-z2).std())) print ('Slope error RMS z0-z2: %.3f urad'%(1e6*numpy.gradient(z0-z2,y0[1]-y0[0]).std())) #dump file outFile = "fit.spec" f = open(outFile,'w') f.write("#F %s\n"%outFile) f.write("\n#S 1 heights profiles\n") f.write("#N 5\n") f.write("#L coordinate [mm] heights_orig [um] ellipse_guess [um] ellipse_fit [um] heights-fit [nm]\n") for i in range(y0.size): f.write("%f %f %f %f %f \n"%(y0[i]*1e3,z0[i]*1e6,z1[i]*1e6,z2[i]*1e6,(z0[i]-z2[i])*1e9)) f.close() if fit_method == 1: # ellipse, slopes fit #preprocessors ellipse fitting slopes if entry_number == 4: pass elif entry_number == 6: pass elif entry_number == 19: pass elif entry_number == 20: pass elif entry_number == 21: pass if fit_function == "amparo": fitfunc_ell_slopes = lambda p, x: func_ellipse_slopes_amparo(x, p[0], p[1], p[2], p[3]) elif fit_function == "dabam": fitfunc_ell_slopes = lambda p, x: func_ellipse_slopes_dabam(x, p[0], p[1], p[2], p[3]) else: print("Not implemented function: ",fit_function) raise NotImplementedError print("======== Fitting slopes =======") errfunc_ell_slopes = lambda p, x, y: fitfunc_ell_slopes(p, x) - y p_guess = [p0,q0,theta0,0.0] zp1 = fitfunc_ell_slopes(p_guess, y0) if ibounded == 0: print("======== Curve fitting without guess =======") if fit_function == "amparo": popt, cov_x = curve_fit(func_ellipse_slopes_amparo, y0, zp0, maxfev=10000) elif fit_function == "dabam": popt, cov_x = curve_fit(func_ellipse_slopes_dabam, y0, zp0, maxfev=10000) else: print("Not implemented function: ",fit_function) raise NotImplementedError elif ibounded == 1: print("======== Least Squares fitting =======") popt, cov_x, infodic, mesg, ier = leastsq(errfunc_ell_slopes, p_guess, args=(y0, zp0), full_output=True) else: print("======== Bounded Least Squares fitting =======") # https://github.com/jjhelmus/leastsqbound-scipy from leastsqbound import leastsqbound bounds = [ (p0*0.9,p0*1.1) , (q0*0.9,q0*1.1), (theta0*0.9,theta0*1.1), (-2.0,2.0)] popt, cov_x, infodic, mesg, ier = leastsqbound(errfunc_ell_slopes, p_guess, args=(y0,zp0), bounds=bounds,full_output=True) print(">>>>> p_guess:", p_guess) print(">>>>> popt (p,q,theta): ",popt) zp2 = fitfunc_ell_slopes(popt, y0) z1 = cdf(y0,zp1) z2 = cdf(y0,zp2) rms_values = (1e9*(cdf(y0,zp0-zp1)).std(),1e9*(cdf(y0,zp0-zp2)).std(), 1e6*(zp0-zp1).std(),1e6*(zp0-zp2).std() ) print ('Height error RMS z0-z1: %.3f nm'%(1e9*(cdf(y0,zp0-zp1)).std())) print ('Slope error RMS zp0-zp1: %.3f urad'%(1e6*(zp0-zp1).std())) print ('Height error RMS z0-z2: %.3f nm'%(1e9*(cdf(y0,zp0-zp2)).std())) print ('Slope error RMS zp0-zp2: %.3f urad'%(1e6*(zp0-zp2).std())) #dump file outFile = "fit.spec" f = open(outFile,'w') f.write("#F %s\n"%outFile) f.write("\n#S 1 slopes profiles\n") f.write("#N 5\n") f.write("#L coordinate [mm] slopes_orig [urad] ellipse_guess [urad] ellipse_fit [urad] slopes-fit [nrad]\n") for i in range(y0.size): f.write("%f %f %f %f %f \n"%(y0[i]*1e3,zp0[i]*1e6,zp1[i]*1e6,zp2[i]*1e6,(zp0[i]-zp2[i])*1e9)) f.close() print(">>>>> popt (p,q,theta): ",popt) rms_values = ( 1e9*(z0-z1).std(),1e9*(z0-z2).std(), 1e6*numpy.gradient(z0-z1,y0[1]-y0[0]).std(),1e6*numpy.gradient(z0-z2,y0[1]-y0[0]).std()) if ibounded != 0: print ('Height error RMS z0-z1: %.3f nm'%(1e9*(z0-z1).std())) print ('height error RMS z0-z2: %.3f nm'%(1e9*(z0-z2).std())) dd=numpy.concatenate( (y0, z2) ,axis=0).reshape(2,-1).transpose() outFile = "tmp_z2.dat" numpy.savetxt(outFile,dd) print ("File "+outFile+" written to disk:\n") # #plots # if do_plots: # #plots # from matplotlib import pylab as plt if (fit_method == 0): #heights f1 = plt.figure(1) ax = plt.gca() ax.get_xaxis().get_major_formatter().set_useOffset(False) ax.get_yaxis().get_major_formatter().set_useOffset(False) plt.plot(y0*1e3,z0*1e6) plt.plot(y0*1e3,z1*1e6) plt.plot(y0*1e3,z2*1e6) plt.title("height data (blue), starting (green) and optimized (red) ellipse") plt.xlabel("Y [mm]") plt.ylabel("Zp [um]") f2 = plt.figure(2) ax = plt.gca() ax.get_xaxis().get_major_formatter().set_useOffset(False) ax.get_yaxis().get_major_formatter().set_useOffset(False) plt.plot(y0*1e3,(z0-z2)*1e9) plt.title("residual heights") plt.xlabel("Y [mm]") plt.ylabel("Z [nm]") elif fit_method == 1: #slopes f1 = plt.figure(1) ax = plt.gca() ax.get_xaxis().get_major_formatter().set_useOffset(False) ax.get_yaxis().get_major_formatter().set_useOffset(False) plt.plot(y0*1e3,zp0*1e6) if ibounded != 0: plt.plot(y0*1e3,zp1*1e6) plt.plot(y0*1e3,zp2*1e6) plt.title("slopes data (blue), starting (green) and optimized (red) ellipse") plt.xlabel("Y [mm]") plt.ylabel("Zp [urad]") f2 = plt.figure(2) ax = plt.gca() ax.get_xaxis().get_major_formatter().set_useOffset(False) ax.get_yaxis().get_major_formatter().set_useOffset(False) plt.plot(y0*1e3,(zp0-zp2)*1e6) plt.title("residual slopes") plt.xlabel("Y [mm]") plt.ylabel("Zp [urad]") plt.show() return rms_values
from matplotlib import pylab as plt import dabam import numpy do_plots = 0 #create DABAM objects to load experimental and two simulated profiles dm = [dabam.dabam(),dabam.dabam(),dabam.dabam()] # # load input from DABAM # dabam_entry = 12 #dm = dabam.dabam() dm[0].set_input_entryNumber(dabam_entry) dm[0].load() if do_plots: dm[0].set_input_plot("psd_h") dm[0].plot() dm[0].set_input_plot("acov_h") dm[0].plot() # # define inputs for fractal and Gaussian simulated profiles # cl = 0.05 #dm.autocorrelation_heights() # 0.03
def ellipse_fit(entry_number=21, fit_method=1, fit_function='dabam', ibounded=1, do_plots=1): """ :param entry_number: dabam entry number :param fit_method: fit elliptical heights (0), fit elliptical slopes (1) :param fit_function: 'dabam' , 'amparo', 'xianbo' :param ibounded: 0 curve_fit (no guess), 1=leastsq, 2=bounded :param do_plot: 1 display plots :return: """ # #get profiles # import dabam dm = dabam.dabam() dm.inputs["entryNumber"] = entry_number dm.inputs["setDetrending"] = -1 dm.load() # # # p0 = dm.h["ELLIPSE_DESIGN_P"] q0 = dm.h["ELLIPSE_DESIGN_Q"] theta0 = dm.h["ELLIPSE_DESIGN_THETA"] # y axis is horizonta, z axis is vertical y0 = dm.sy z0 = dm.zprof zp0 = dm.sz if fit_method == 0: # ellipse fitting heights hshift = 0.0 #nm vshift = 0.0 # nm #preprocessors if entry_number == 4: z0 -= z0.min() elif entry_number == 6: imin = z0.argmin() z0 -= z0[imin] y0 -= y0[imin] y0 *= -1.0 elif entry_number == 19: pass elif entry_number == 20: hshift = -15e3 elif entry_number == 21: y0 -= y0[y0.size / 2] if fit_function == "amparo": fitfunc_ell_heights = lambda p, x: func_ellipse_heights_amparo( x, p[0], p[1], p[2], p[3], p[4]) print("Using function definition: AMPARO") elif fit_function == "xianbo": fitfunc_ell_heights = lambda p, x: func_ellipse_heights_xianbo( x, p[0], p[1], p[2], p[3], p[4]) print("Using function definition: XIANBO") else: fitfunc_ell_heights = lambda p, x: func_ellipse_heights_dabam( x, p[0], p[1], p[2], p[3], p[4]) print("Using function definition: DABAM") print("======== Fitting heights =======") errfunc_ell_heights = lambda p, x, y: fitfunc_ell_heights(p, x) - y p_guess = [p0, q0, theta0, hshift, vshift] if ibounded == 0: print("======== Curve fitting without guess =======") if fit_function == "amparo": popt, cov_x = curve_fit(func_ellipse_heights_amparo, y0, z0, maxfev=10000) elif fit_function == "xianbo": popt, cov_x = curve_fit(func_ellipse_heights_xianbo, y0, z0, maxfev=10000) else: popt, cov_x = curve_fit(func_ellipse_heights_dabam, y0, z0, maxfev=10000) elif ibounded == 1: print("======== Least Squares fitting =======") popt, cov_x, infodic, mesg, ier = leastsq(errfunc_ell_heights, p_guess, args=(y0, z0), full_output=True) else: print("======== Bounded Least Squares fitting =======") # https://github.com/jjhelmus/leastsqbound-scipy from leastsqbound import leastsqbound bounds = [(p0 * 0.998, p0 * 1.002), (q0 * 0.8, q0 * 1.2), (theta0 * 0.98, theta0 * 1.02), (-0.01, 0.01), (-0.001, 0.001)] popt, cov_x, infodic, mesg, ier = leastsqbound(errfunc_ell_heights, p_guess, args=(y0, z0), full_output=True, bounds=bounds) print(">>>>> p_guess:", p_guess) print(">>>>> popt:", popt) z1 = fitfunc_ell_heights(p_guess, y0) z2 = fitfunc_ell_heights(popt, y0) zp1 = numpy.gradient(z1, y0[1] - y0[0]) zp2 = numpy.gradient(z2, y0[1] - y0[0]) rms_values = (1e9 * (z0 - z1).std(), 1e9 * (z0 - z2).std(), 1e6 * numpy.gradient(z0 - z1, y0[1] - y0[0]).std(), 1e6 * numpy.gradient(z0 - z2, y0[1] - y0[0]).std()) print('Height error RMS z0-z1: %.3f nm' % (1e9 * (z0 - z1).std())) print('Slope error RMS z0-z1: %.3f urad' % (1e6 * numpy.gradient(z0 - z1, y0[1] - y0[0]).std())) print('height error RMS z0-z2: %.3f nm' % (1e9 * (z0 - z2).std())) print('Slope error RMS z0-z2: %.3f urad' % (1e6 * numpy.gradient(z0 - z2, y0[1] - y0[0]).std())) #dump file outFile = "fit.spec" f = open(outFile, 'w') f.write("#F %s\n" % outFile) f.write("\n#S 1 heights profiles\n") f.write("#N 5\n") f.write( "#L coordinate [mm] heights_orig [um] ellipse_guess [um] ellipse_fit [um] heights-fit [nm]\n" ) for i in range(y0.size): f.write("%f %f %f %f %f \n" % (y0[i] * 1e3, z0[i] * 1e6, z1[i] * 1e6, z2[i] * 1e6, (z0[i] - z2[i]) * 1e9)) f.close() if fit_method == 1: # ellipse, slopes fit #preprocessors ellipse fitting slopes if entry_number == 4: pass elif entry_number == 6: pass elif entry_number == 19: pass elif entry_number == 20: pass elif entry_number == 21: pass if fit_function == "amparo": fitfunc_ell_slopes = lambda p, x: func_ellipse_slopes_amparo( x, p[0], p[1], p[2], p[3]) elif fit_function == "dabam": fitfunc_ell_slopes = lambda p, x: func_ellipse_slopes_dabam( x, p[0], p[1], p[2], p[3]) else: print("Not implemented function: ", fit_function) raise NotImplementedError print("======== Fitting slopes =======") errfunc_ell_slopes = lambda p, x, y: fitfunc_ell_slopes(p, x) - y p_guess = [p0, q0, theta0, 0.0] zp1 = fitfunc_ell_slopes(p_guess, y0) if ibounded == 0: print("======== Curve fitting without guess =======") if fit_function == "amparo": popt, cov_x = curve_fit(func_ellipse_slopes_amparo, y0, zp0, maxfev=10000) elif fit_function == "dabam": popt, cov_x = curve_fit(func_ellipse_slopes_dabam, y0, zp0, maxfev=10000) else: print("Not implemented function: ", fit_function) raise NotImplementedError elif ibounded == 1: print("======== Least Squares fitting =======") popt, cov_x, infodic, mesg, ier = leastsq(errfunc_ell_slopes, p_guess, args=(y0, zp0), full_output=True) else: print("======== Bounded Least Squares fitting =======") # https://github.com/jjhelmus/leastsqbound-scipy from leastsqbound import leastsqbound bounds = [(p0 * 0.9, p0 * 1.1), (q0 * 0.9, q0 * 1.1), (theta0 * 0.9, theta0 * 1.1), (-2.0, 2.0)] popt, cov_x, infodic, mesg, ier = leastsqbound(errfunc_ell_slopes, p_guess, args=(y0, zp0), bounds=bounds, full_output=True) print(">>>>> p_guess:", p_guess) print(">>>>> popt (p,q,theta): ", popt) zp2 = fitfunc_ell_slopes(popt, y0) z1 = cdf(y0, zp1) z2 = cdf(y0, zp2) rms_values = (1e9 * (cdf(y0, zp0 - zp1)).std(), 1e9 * (cdf(y0, zp0 - zp2)).std(), 1e6 * (zp0 - zp1).std(), 1e6 * (zp0 - zp2).std()) print('Height error RMS z0-z1: %.3f nm' % (1e9 * (cdf(y0, zp0 - zp1)).std())) print('Slope error RMS zp0-zp1: %.3f urad' % (1e6 * (zp0 - zp1).std())) print('Height error RMS z0-z2: %.3f nm' % (1e9 * (cdf(y0, zp0 - zp2)).std())) print('Slope error RMS zp0-zp2: %.3f urad' % (1e6 * (zp0 - zp2).std())) #dump file outFile = "fit.spec" f = open(outFile, 'w') f.write("#F %s\n" % outFile) f.write("\n#S 1 slopes profiles\n") f.write("#N 5\n") f.write( "#L coordinate [mm] slopes_orig [urad] ellipse_guess [urad] ellipse_fit [urad] slopes-fit [nrad]\n" ) for i in range(y0.size): f.write("%f %f %f %f %f \n" % (y0[i] * 1e3, zp0[i] * 1e6, zp1[i] * 1e6, zp2[i] * 1e6, (zp0[i] - zp2[i]) * 1e9)) f.close() print(">>>>> popt (p,q,theta): ", popt) rms_values = (1e9 * (z0 - z1).std(), 1e9 * (z0 - z2).std(), 1e6 * numpy.gradient(z0 - z1, y0[1] - y0[0]).std(), 1e6 * numpy.gradient(z0 - z2, y0[1] - y0[0]).std()) if ibounded != 0: print('Height error RMS z0-z1: %.3f nm' % (1e9 * (z0 - z1).std())) print('height error RMS z0-z2: %.3f nm' % (1e9 * (z0 - z2).std())) dd = numpy.concatenate((y0, z2), axis=0).reshape(2, -1).transpose() outFile = "tmp_z2.dat" numpy.savetxt(outFile, dd) print("File " + outFile + " written to disk:\n") # #plots # if do_plots: # #plots # from matplotlib import pylab as plt if (fit_method == 0): #heights f1 = plt.figure(1) ax = plt.gca() ax.get_xaxis().get_major_formatter().set_useOffset(False) ax.get_yaxis().get_major_formatter().set_useOffset(False) plt.plot(y0 * 1e3, z0 * 1e6) plt.plot(y0 * 1e3, z1 * 1e6) plt.plot(y0 * 1e3, z2 * 1e6) plt.title( "height data (blue), starting (green) and optimized (red) ellipse" ) plt.xlabel("Y [mm]") plt.ylabel("Zp [um]") f2 = plt.figure(2) ax = plt.gca() ax.get_xaxis().get_major_formatter().set_useOffset(False) ax.get_yaxis().get_major_formatter().set_useOffset(False) plt.plot(y0 * 1e3, (z0 - z2) * 1e9) plt.title("residual heights") plt.xlabel("Y [mm]") plt.ylabel("Z [nm]") elif fit_method == 1: #slopes f1 = plt.figure(1) ax = plt.gca() ax.get_xaxis().get_major_formatter().set_useOffset(False) ax.get_yaxis().get_major_formatter().set_useOffset(False) plt.plot(y0 * 1e3, zp0 * 1e6) if ibounded != 0: plt.plot(y0 * 1e3, zp1 * 1e6) plt.plot(y0 * 1e3, zp2 * 1e6) plt.title( "slopes data (blue), starting (green) and optimized (red) ellipse" ) plt.xlabel("Y [mm]") plt.ylabel("Zp [urad]") f2 = plt.figure(2) ax = plt.gca() ax.get_xaxis().get_major_formatter().set_useOffset(False) ax.get_yaxis().get_major_formatter().set_useOffset(False) plt.plot(y0 * 1e3, (zp0 - zp2) * 1e6) plt.title("residual slopes") plt.xlabel("Y [mm]") plt.ylabel("Zp [urad]") plt.show() return rms_values