def test_2d_normalize_to_slope_error(self,combination="FF"): mirrorLength = 200.1 # cm Step = 1.0 RandomSeed = 8788 RMS = 0.2e-6 # 2.0e-6 # rad mirrorWidth = 40.0 StepW = 1.0 RandomSeedW = 8788 RMSW = 0.5e-6 # 1.0e-6 if combination == "EE": # TODO: not yet tested input_file = package_dirname("srxraylib.metrology") + "/mirror_1d.txt" values = numpy.loadtxt(input_file) x_l = values[:, 0] y_l = values[:, 1] x_w = values[:, 0] y_w = values[:, 1] print("File loaded: %s, Length:%f, StDev: %g"%(input_file,x_l[-1]-x_l[0],y_l.std())) x,y,z = simulate_profile_2D(random_seed_l=RandomSeed, error_type_l=SLOPE_ERROR, rms_l=RMS, correlation_length_l=30.0,power_law_exponent_beta_l=1.5, random_seed_w=RandomSeedW, error_type_w=SLOPE_ERROR, rms_w=RMSW, correlation_length_w=30.0,power_law_exponent_beta_w=1.5, x_l=x_l,y_l=y_l,x_w=x_w,y_w=y_w, combination=combination) else: x,y,z = simulate_profile_2D(mirror_length=mirrorLength, step_l=Step, random_seed_l=RandomSeed, error_type_l=SLOPE_ERROR, rms_l=RMS, correlation_length_l=30.0,power_law_exponent_beta_l=1.5, mirror_width=mirrorWidth, step_w=StepW, random_seed_w=RandomSeedW, error_type_w=SLOPE_ERROR, rms_w=RMSW, correlation_length_w=30.0,power_law_exponent_beta_w=1.5, combination=combination) tmp1 = slopes(z.T,x,y,return_only_rms=1) print(" target SLOPE error in WIDTH: %g rad"%(RMSW)) print(" target SLOPE error in LENGTH: %g rad"%(RMS)) print(" obtained HEIGHT error (in LENGTH and WIDTH): %g"%(z.std())) print(" obtained SLOPE error in WIDTH: %g"%(tmp1[0])) print(" obtained SLOPE error in LENGTH: %g"%(tmp1[1])) print(" shape x,y,z:",x.shape,y.shape,z.shape) # the LENGTH direction must match!! assert numpy.abs( RMS - tmp1[1] ) < 0.01 * numpy.abs(RMS) if do_plot: from srxraylib.plot.gol import plot_surface plot_surface(z.T*1e7,x,y,xtitle="X [cm]",ytitle="Y [cm",ztitle="Z [nm]",title="test_2d_normalize_to_slope_error")
def calculate_heigth_profile(self, not_interactive_mode=False): try: if self.server.y is None: raise Exception("No Profile Selected") sys.stdout = EmittingStream(textWritten=self.writeStdOut) self.check_fields() combination = "EF" if self.modify_y == 2: profile_1D_y_x_temp = self.si_to_user_units * self.server.y if self.use_undetrended == 0: profile_1D_y_y_temp = self.si_to_user_units * self.server.zHeights else: profile_1D_y_y_temp = self.si_to_user_units * self.server.zHeightsUndetrended first_coord = profile_1D_y_x_temp[0] second_coord = profile_1D_y_x_temp[1] last_coord = profile_1D_y_x_temp[-1] step = numpy.abs(second_coord - first_coord) length = numpy.abs(last_coord - first_coord) n_points_old = len(profile_1D_y_x_temp) if self.new_length > length: difference = self.new_length - length n_added_points = int(difference/step) if difference % step == 0: n_added_points += 1 if n_added_points % 2 != 0: n_added_points += 1 profile_1D_y_x = numpy.arange(n_added_points + n_points_old) * step profile_1D_y_y = numpy.ones(n_added_points + n_points_old) * self.filler_value * 1e-9 * self.si_to_user_units profile_1D_y_y[int(n_added_points/2) : n_points_old + int(n_added_points/2)] = profile_1D_y_y_temp elif self.new_length < length: difference = length - self.new_length n_removed_points = int(difference/step) if difference % step == 0: n_removed_points -= 1 if n_removed_points % 2 != 0: n_removed_points -= 1 if n_removed_points >= 2: profile_1D_y_x = profile_1D_y_x_temp[0 : (n_points_old - n_removed_points)] profile_1D_y_y = profile_1D_y_y_temp[(int(n_removed_points/2) - 1) : (n_points_old - int(n_removed_points/2) - 1)] else: profile_1D_y_x = profile_1D_y_x_temp profile_1D_y_y = profile_1D_y_y_temp else: profile_1D_y_x = profile_1D_y_x_temp profile_1D_y_y = profile_1D_y_y_temp else: if self.modify_y == 0: profile_1D_y_x = self.si_to_user_units * self.server.y elif self.modify_y == 1: profile_1D_y_x = self.si_to_user_units * self.server.y * self.scale_factor_y if self.use_undetrended == 0: profile_1D_y_y = self.si_to_user_units * self.server.zHeights else: profile_1D_y_y = self.si_to_user_units * self.server.zHeightsUndetrended if self.center_y: first_coord = profile_1D_y_x[0] last_coord = profile_1D_y_x[-1] length = numpy.abs(last_coord - first_coord) profile_1D_y_x_temp = numpy.linspace(-length/2, length/2, len(profile_1D_y_x)) profile_1D_y_x = profile_1D_y_x_temp if self.renormalize_y == 0: rms_y = None else: if self.error_type_y == profiles_simulation.FIGURE_ERROR: rms_y = self.si_to_user_units * self.rms_y * 1e-9 # from nm to user units else: rms_y = self.rms_y * 1e-6 # from urad to rad xx, yy, zz = profiles_simulation.simulate_profile_2D(combination = combination, error_type_l = self.error_type_y, rms_l = rms_y, x_l = profile_1D_y_x, y_l = profile_1D_y_y, mirror_width = self.dimension_x, step_w = self.step_x, rms_w = 0.0) self.xx = xx self.yy = yy self.zz = zz # in user units self.axis.clear() x_to_plot, y_to_plot = numpy.meshgrid(xx, yy) z_to_plot = zz * 1e9 / self.si_to_user_units #nm self.axis.plot_surface(x_to_plot, y_to_plot, z_to_plot, rstride=1, cstride=1, cmap=cm.autumn, linewidth=0.5, antialiased=True) sloperms = profiles_simulation.slopes(zz.T, xx, yy, return_only_rms=1) title = ' Slope error rms in X direction: %f $\mu$rad' % (sloperms[0]*1e6) + '\n' + \ ' Slope error rms in Y direction: %f $\mu$rad' % (sloperms[1]*1e6) self.axis.set_xlabel("X [" + self.workspace_units_label + "]") self.axis.set_ylabel("Y [" + self.workspace_units_label + "]") self.axis.set_zlabel("Z [nm]") self.axis.set_title(title) self.axis.mouse_init() if not not_interactive_mode: try: self.plot_canvas[5].draw() except: pass self.tabs.setCurrentIndex(6) QMessageBox.information(self, "QMessageBox.information()", "Height Profile calculated: if the result is satisfactory,\nclick \'Generate Height Profile File\' to complete the operation ", QMessageBox.Ok) except Exception as exception: QMessageBox.critical(self, "Error", exception.args[0], QMessageBox.Ok)
def test_2d_normalize_to_slope_error(self, combination="FF"): mirrorLength = 200.1 # cm Step = 1.0 RandomSeed = 8788 RMS = 0.2e-6 # 2.0e-6 # rad mirrorWidth = 40.0 StepW = 1.0 RandomSeedW = 8788 RMSW = 0.5e-6 # 1.0e-6 if combination == "EE": # TODO: not yet tested input_file = package_dirname( "srxraylib.metrology") + "/mirror_1d.txt" values = numpy.loadtxt(input_file) x_l = values[:, 0] y_l = values[:, 1] x_w = values[:, 0] y_w = values[:, 1] print("File loaded: %s, Length:%f, StDev: %g" % (input_file, x_l[-1] - x_l[0], y_l.std())) x, y, z = simulate_profile_2D(random_seed_l=RandomSeed, error_type_l=SLOPE_ERROR, rms_l=RMS, correlation_length_l=30.0, power_law_exponent_beta_l=1.5, random_seed_w=RandomSeedW, error_type_w=SLOPE_ERROR, rms_w=RMSW, correlation_length_w=30.0, power_law_exponent_beta_w=1.5, x_l=x_l, y_l=y_l, x_w=x_w, y_w=y_w, combination=combination) else: x, y, z = simulate_profile_2D(mirror_length=mirrorLength, step_l=Step, random_seed_l=RandomSeed, error_type_l=SLOPE_ERROR, rms_l=RMS, correlation_length_l=30.0, power_law_exponent_beta_l=1.5, mirror_width=mirrorWidth, step_w=StepW, random_seed_w=RandomSeedW, error_type_w=SLOPE_ERROR, rms_w=RMSW, correlation_length_w=30.0, power_law_exponent_beta_w=1.5, combination=combination) tmp1 = slopes(z.T, x, y, return_only_rms=1) print(" target SLOPE error in WIDTH: %g rad" % (RMSW)) print(" target SLOPE error in LENGTH: %g rad" % (RMS)) print(" obtained HEIGHT error (in LENGTH and WIDTH): %g" % (z.std())) print(" obtained SLOPE error in WIDTH: %g" % (tmp1[0])) print(" obtained SLOPE error in LENGTH: %g" % (tmp1[1])) print(" shape x,y,z:", x.shape, y.shape, z.shape) # the LENGTH direction must match!! assert numpy.abs(RMS - tmp1[1]) < 0.01 * numpy.abs(RMS) if do_plot: from srxraylib.plot.gol import plot_surface plot_surface(z.T * 1e7, x, y, xtitle="X [cm]", ytitle="Y [cm", ztitle="Z [nm]", title="test_2d_normalize_to_slope_error")
def calculate_heigth_profile(self, not_interactive_mode=False): try: sys.stdout = EmittingStream(textWritten=self.writeStdOut) self.check_fields() #### LENGTH if self.kind_of_profile_y == 2: combination = "E" if self.delimiter_y == 1: profile_1D_y_x, profile_1D_y_y = numpy.loadtxt(self.heigth_profile_1D_file_name_y, delimiter='\t', unpack=True) else: profile_1D_y_x, profile_1D_y_y = numpy.loadtxt(self.heigth_profile_1D_file_name_y, unpack=True) profile_1D_y_x *= self.conversion_factor_y_x * self.workspace_units_to_cm # to cm profile_1D_y_y *= self.conversion_factor_y_y * self.workspace_units_to_cm # to cm if self.modify_y == 2: profile_1D_y_x_temp = profile_1D_y_x profile_1D_y_y_temp = profile_1D_y_y first_coord = profile_1D_y_x_temp[0] second_coord = profile_1D_y_x_temp[1] last_coord = profile_1D_y_x_temp[-1] step = numpy.abs(second_coord - first_coord) length = numpy.abs(last_coord - first_coord) n_points_old = len(profile_1D_y_x_temp) if self.new_length > length: difference = self.new_length - length n_added_points = int(difference/step) if difference % step == 0: n_added_points += 1 if n_added_points % 2 != 0: n_added_points += 1 profile_1D_y_x = numpy.arange(n_added_points + n_points_old) * step profile_1D_y_y = numpy.ones(n_added_points + n_points_old) * self.filler_value * 1e-9 * self.si_to_user_units profile_1D_y_y[int(n_added_points/2) : n_points_old + int(n_added_points/2)] = profile_1D_y_y_temp elif self.new_length < length: difference = length - self.new_length n_removed_points = int(difference/step) if difference % step == 0: n_removed_points -= 1 if n_removed_points % 2 != 0: n_removed_points -= 1 if n_removed_points >= 2: profile_1D_y_x = profile_1D_y_x_temp[0 : (n_points_old - n_removed_points)] profile_1D_y_y = profile_1D_y_y_temp[(int(n_removed_points/2) - 1) : (n_points_old - int(n_removed_points/2) - 1)] else: profile_1D_y_x = profile_1D_y_x_temp profile_1D_y_y = profile_1D_y_y_temp else: profile_1D_y_x = profile_1D_y_x_temp profile_1D_y_y = profile_1D_y_y_temp elif self.modify_y == 1: profile_1D_y_x *= self.scale_factor_y if self.center_y: first_coord = profile_1D_y_x[0] last_coord = profile_1D_y_x[-1] length = numpy.abs(last_coord - first_coord) profile_1D_y_x_temp = numpy.linspace(-length/2, length/2, len(profile_1D_y_x)) profile_1D_y_x = profile_1D_y_x_temp if self.renormalize_y == 0: rms_y = None else: if self.error_type_y == profiles_simulation.FIGURE_ERROR: rms_y = self.rms_y * 1e-7 # from nm to cm else: rms_y = self.rms_y * 1e-6 # from urad to rad else: if self.kind_of_profile_y == 0: combination = "F" else: combination = "G" profile_1D_y_x = None profile_1D_y_y = None if self.error_type_y == profiles_simulation.FIGURE_ERROR: rms_y = self.rms_y * 1e-7 # from nm to cm else: rms_y = self.rms_y * 1e-6 # from urad to rad #### WIDTH if self.kind_of_profile_x == 2: combination += "E" if self.delimiter_x == 1: profile_1D_x_x, profile_1D_x_y = numpy.loadtxt(self.heigth_profile_1D_file_name_x, delimiter='\t', unpack=True) else: profile_1D_x_x, profile_1D_x_y = numpy.loadtxt(self.heigth_profile_1D_file_name_x, unpack=True) profile_1D_x_x *= self.conversion_factor_x_x * self.workspace_units_to_cm profile_1D_x_y *= self.conversion_factor_x_y * self.workspace_units_to_cm if self.modify_x == 2: profile_1D_x_x_temp = profile_1D_x_x profile_1D_x_y_temp = profile_1D_x_y first_coord = profile_1D_x_x_temp[0] second_coord = profile_1D_x_x_temp[1] last_coord = profile_1D_x_x_temp[-1] step = numpy.abs(second_coord - first_coord) length = numpy.abs(last_coord - first_coord) n_points_old = len(profile_1D_x_x_temp) if self.new_length > length: difference = self.new_length - length n_added_points = int(difference/step) if difference % step == 0: n_added_points += 1 if n_added_points % 2 != 0: n_added_points += 1 profile_1D_x_x = numpy.arange(n_added_points + n_points_old) * step profile_1D_x_y = numpy.ones(n_added_points + n_points_old) * self.filler_value * 1e-9 * self.si_to_user_units profile_1D_x_y[int(n_added_points/2) : n_points_old + int(n_added_points/2)] = profile_1D_x_y_temp elif self.new_length < length: difference = length - self.new_length n_removed_points = int(difference/step) if difference % step == 0: n_removed_points -= 1 if n_removed_points % 2 != 0: n_removed_points -= 1 if n_removed_points >= 2: profile_1D_x_x = profile_1D_x_x_temp[0 : (n_points_old - n_removed_points)] profile_1D_x_y = profile_1D_x_y_temp[(int(n_removed_points/2) - 1) : (n_points_old - int(n_removed_points/2) - 1)] else: profile_1D_x_x = profile_1D_x_x_temp profile_1D_x_y = profile_1D_x_y_temp else: profile_1D_x_x = profile_1D_x_x_temp profile_1D_x_y = profile_1D_x_y_temp elif self.modify_x == 1: profile_1D_x_x *= self.scale_factor_x if self.center_x: first_coord = profile_1D_x_x[0] last_coord = profile_1D_x_x[-1] length = numpy.abs(last_coord - first_coord) profile_1D_x_x_temp = numpy.linspace(-length/2, length/2, len(profile_1D_x_x)) profile_1D_x_x = profile_1D_x_x_temp if self.renormalize_x == 0: rms_x = None else: if self.error_type_x == profiles_simulation.FIGURE_ERROR: rms_x = self.rms_x * 1e-7 # from nm to cm else: rms_x = self.rms_x * 1e-6 # from urad to rad else: profile_1D_x_x = None profile_1D_x_y = None if self.kind_of_profile_x == 0: combination += "F" else: combination += "G" if self.error_type_x == profiles_simulation.FIGURE_ERROR: rms_x = self.rms_x * 1e-7 # from nm to cm else: rms_x = self.rms_x * 1e-6 # from urad to rad xx, yy, zz = profiles_simulation.simulate_profile_2D(combination = combination, mirror_length = self.dimension_y * self.workspace_units_to_cm, # to cm step_l = self.step_y * self.workspace_units_to_cm, # to cm random_seed_l = self.montecarlo_seed_y, error_type_l = self.error_type_y, rms_l = rms_y, power_law_exponent_beta_l = self.power_law_exponent_beta_y, correlation_length_l = self.correlation_length_y * self.workspace_units_to_cm, # to cm x_l = profile_1D_y_x, y_l = profile_1D_y_y, mirror_width = self.dimension_x * self.workspace_units_to_cm, # to cm step_w = self.step_x * self.workspace_units_to_cm, random_seed_w = self.montecarlo_seed_x, error_type_w = self.error_type_x, rms_w = rms_x, power_law_exponent_beta_w = self.power_law_exponent_beta_x, correlation_length_w = self.correlation_length_x * self.workspace_units_to_cm, # to cm x_w = profile_1D_x_x, y_w = profile_1D_x_y) self.xx = xx / self.workspace_units_to_cm # to user units self.yy = yy / self.workspace_units_to_cm # to user units self.zz = zz / self.workspace_units_to_cm # to user units self.axis.clear() x_to_plot, y_to_plot = numpy.meshgrid(self.xx, self.yy) z_to_plot = zz * 1e7 self.axis.plot_surface(x_to_plot, y_to_plot, z_to_plot, rstride=1, cstride=1, cmap=cm.autumn, linewidth=0.5, antialiased=True) sloperms = profiles_simulation.slopes(zz.T, xx, yy, return_only_rms=1) title = ' Slope error rms in X direction: %f $\mu$rad' % (sloperms[0]*1e6) + '\n' + \ ' Slope error rms in Y direction: %f $\mu$rad' % (sloperms[1]*1e6) self.axis.set_xlabel("X [" + self.workspace_units_label + "]") self.axis.set_ylabel("Y [" + self.workspace_units_label + "]") self.axis.set_zlabel("Z [nm]") self.axis.set_title(title) self.axis.mouse_init() if not not_interactive_mode: self.figure_canvas.draw() QMessageBox.information(self, "QMessageBox.information()", "Height Profile calculated: if the result is satisfactory,\nclick \'Generate Height Profile File\' to complete the operation ", QMessageBox.Ok) except Exception as exception: QMessageBox.critical(self, "Error", exception.args[0], QMessageBox.Ok)
def gen_figure_error(L=400e-3, W=40e-3, stepL=1e-3, stepW=1e-3, rmsL=1e-9, rmsW=1e-9, betaL=2.0, betaW=2.0, typeL='h', typeW='h', seedL=8787, seedW=8454, filename='', plot=False, print_out=False): from srxraylib.metrology import profiles_simulation # ==== Main Parameters ============================== # if (typeL == 'h'): typeL = 0 # (0) Normalize by Height RMS, (1) Normalize by Slope RMS elif (typeL == 's'): typeL = 1 if (typeW == 'h'): typeW = 0 # (0) Normalize by Height RMS, (1) Normalize by Slope RMS elif (typeW == 's'): typeW = 1 if (seedL == 0): fct = 1e4 if np.random.random() <= 0.5 else 1e3 seedL = int(np.random.random() * fct) if (seedW == 0): fct = 1e4 if np.random.random() <= 0.5 else 1e3 seedW = int(np.random.random() * fct) # ==== Creates 2D matrix ============================ # x, y, z = profiles_simulation.simulate_profile_2D( combination='FF', mirror_length=L, step_l=stepL, random_seed_l=seedL, error_type_l=typeL, rms_l=rmsL, power_law_exponent_beta_l=betaL, mirror_width=W, step_w=stepW, random_seed_w=seedW, error_type_w=typeW, rms_w=rmsW, power_law_exponent_beta_w=betaW) # ==== Formats matrix to the required by function === # mtx_fmt = np.zeros((len(x) + 1, len(y) + 1)) mtx_fmt[0, 1:] = y mtx_fmt[1:, 0] = x mtx_fmt[1:, 1:] = np.transpose(z) if (print_out): print(filename) print('RMS = {0:.3f} nm'.format(np.std(z[:, 0] * 1e9))) print('PV = {0:.3f} nm\n'.format( np.max(z[:, 0] * 1e9) - np.min(z[:, 0] * 1e9))) # # ==== Writes files for shadow input ================ # if (filename != ''): write_shadow_height_error(mtx_fmt, filename, 1e3, ' ') # [mm] # # ==== Preview Plots ================================ # if (plot): plt.figure(figsize=(6, 1)) plt.pcolormesh(y, x, np.transpose(z)) plt.autoscale(enable=True, tight=True) plt.figure() plt.plot(y, z[:, 0] * 1e9) plt.xlabel('L') plt.ylabel('height error') plt.show() return mtx_fmt