def run_fitting(): """ Setup simulation and fit """ real_data = get_real_data_values() # setting artificial uncertainties (uncertainty sigma equals a half # of experimental data value) uncertainties = real_data * 0.5 fit_objective = ba.FitObjective() fit_objective.addSimulationAndData(get_simulation, real_data, uncertainties) plot_observer = ba.PlotterSpecular(units=ba.AxesUnits.RQ4) fit_objective.initPrint(10) fit_objective.initPlot(10, plot_observer) fit_objective.setObjectiveMetric("Chi2", "L1") params = ba.Parameters() params.add("ti_thickness", 50 * ba.angstrom, min=10 * ba.angstrom, max=60 * ba.angstrom) minimizer = ba.Minimizer() minimizer.setMinimizer("Genetic", "", "MaxIterations=40;PopSize=10") result = minimizer.minimize(fit_objective.evaluate, params) fit_objective.finalize(result)
def run_fitting(): """ Setup simulation and fit """ real_data = load_real_data() fit_objective = ba.FitObjective() fit_objective.addSimulationAndData(get_simulation, real_data) # Print fit progress on every n-th iteration. fit_objective.initPrint(10) # Plot fit progress on every n-th iteration. Will slow down fit. fit_objective.initPlot(10) params = ba.Parameters() params.add("cylinder_height", 4.*nm, min=0.01) params.add("cylinder_radius", 6.*nm, min=0.01) params.add("prism_height", 4.*nm, min=0.01) params.add("prism_base_edge", 6.*nm, min=0.01) minimizer = ba.Minimizer() result = minimizer.minimize(fit_objective.evaluate, params) fit_objective.finalize(result) print("Fitting completed.") print("chi2:", result.minValue()) for fitPar in result.parameters(): print(fitPar.name(), fitPar.value, fitPar.error)
def run_fitting(): """ main function to run fitting """ data1 = create_real_data(0.1 * deg) data2 = create_real_data(0.4 * deg) fit_objective = ba.FitObjective() fit_objective.addSimulationAndData(simulation1, data1, 1.0) fit_objective.addSimulationAndData(simulation2, data2, 1.0) fit_objective.initPrint(10) # creating custom observer which will draw fit progress plotter = PlotObserver() fit_objective.initPlot(10, plotter.update) params = ba.Parameters() params.add("radius_a", 4.*nm, min=2.0, max=10.0) params.add("radius_b", 6.*nm, vary=False) params.add("height", 4.*nm, min=2.0, max=10.0) minimizer = ba.Minimizer() result = minimizer.minimize(fit_objective.evaluate, params) fit_objective.finalize(result)
def run_fitting(): """ main function to run fitting """ real_data = create_real_data() # prints info about available minimizers print(ba.MinimizerFactory().catalogToString()) # prints detailed info about available minimizers and their options print(ba.MinimizerFactory().catalogDetailsToString()) fit_objective = ba.FitObjective() fit_objective.addSimulationAndData(get_simulation, real_data, 1.0) fit_objective.initPrint(10) params = ba.Parameters() params.add("cylinder_height", 4. * nm, min=0.01) params.add("cylinder_radius", 6. * nm, min=0.01) params.add("prism_height", 4. * nm, min=0.01) params.add("prism_base_edge", 12. * nm, min=0.01) minimizer = ba.Minimizer() # Uncomment one of the line below to adjust minimizer settings """ Setting Minuit2 minimizer with Migrad algorithm, limiting number of iterations. Minimization will try to respect MaxFunctionCalls value. """ # minimizer.setMinimizer("Minuit2", "Migrad", "MaxFunctionCalls=50") """ Setting two options at once. Strategy=2 promises more accurate fit. """ # minimizer.setMinimizer("Minuit2", "Migrad", "MaxFunctionCalls=500;Strategy=2") """ Setting Minuit2 minimizer with Fumili algorithm. """ # minimizer.setMinimizer("Minuit2", "Fumili") """ Setting Levenberg-Marquardt algorithm. """ # minimizer.setMinimizer("GSLLMA") result = minimizer.minimize(fit_objective.evaluate_residuals, params) fit_objective.finalize(result) print("Fitting completed.") print("chi2:", result.minValue()) for fitPar in result.parameters(): print(fitPar.name(), fitPar.value, fitPar.error)
def run_fitting(): """ Setups and runs fit. """ fit_objective = ba.FitObjective() fit_objective.addSimulationAndData(get_simulation, real_data()) fit_objective.initPrint(10) params = ba.Parameters() params.add("radius", 4. * nm, min=0.01) minimizer = ba.Minimizer() result = minimizer.minimize(fit_objective.evaluate, params) fit_objective.finalize(result)
def test_DecayingSinFit(self): params = ba.Parameters() params.add(ba.Parameter('amp', 1, ba.AttLimits.positive())) params.add(ba.Parameter('decay', 0.1, ba.AttLimits.positive())) params.add(ba.Parameter('phase', 0.1, ba.AttLimits.limited(0.0, 3.1))) params.add(ba.Parameter('frequency', 1.0, ba.AttLimits.positive())) model = DecayingSin() minimizer = ba.Minimizer() result = minimizer.minimize(model.objective_function, params) print(result.toString()) # check found parameter values np.testing.assert_almost_equal(result.parameters().values(), model.m_params.values(), 3)
def run_fitting(): real_data = load_real_data() fit_objective = ba.FitObjective() fit_objective.addSimulationAndData(create_simulation, real_data, 1.0) fit_objective.initPrint(10) fit_objective.initPlot(10) params = ba.Parameters() params.add("radius", 5. * nm, min=4.0, max=6.0, step=0.1 * nm) params.add("sigma", 0.55, min=0.2, max=0.8, step=0.01) params.add("distance", 27. * nm, min=20.0, max=70.0) minimizer = ba.Minimizer() result = minimizer.minimize(fit_objective.evaluate, params) fit_objective.finalize(result)
def run_fitting(): """ Runs fitting. """ real_data = create_real_data() objective = MyObjective() objective.addSimulationAndData(get_simulation, real_data, 1.0) objective.initPrint(10) params = ba.Parameters() params.add('radius', value=7 * nm, min=5 * nm, max=8 * nm) params.add('length', value=10 * nm, min=8 * nm, max=14 * nm) minimizer = ba.Minimizer() result = minimizer.minimize(objective.evaluate_residuals, params) objective.finalize(result)
def run_fitting(): """ main function to run fitting """ real_data = create_real_data() fit_objective = ba.FitObjective() fit_objective.addSimulationAndData(get_simulation, real_data, 1.0) fit_objective.initPrint(10) fit_objective.initPlot(10) params = ba.Parameters() params.add("radius", 6.*nm, min=4.0, max=8.0) params.add("height", 9.*nm, min=8.0, max=12.0) minimizer = ba.Minimizer() result = minimizer.minimize(fit_objective.evaluate, params) fit_objective.finalize(result)
def run_fit(): ref_data = np.loadtxt("experimental_data.txt.gz") objective = ba.FitObjective() objective.initPlot(10) objective.initPrint(10) objective.addSimulationAndData(get_simulation, ref_data) params = ba.Parameters() params.add("radius", value=9.5*nm, min=9*nm, max=11*nm) params.add("length", value=31.0*nm, min=30*nm, max=35*nm) minimizer = ba.Minimizer() minimizer.setMinimizer("Genetic") result = minimizer.minimize(objective.evaluate, params) objective.finalize(result) print("Done")
def test_SimpleMinimizer(self): minimizer = ba.Minimizer() minimizer.setMinimizer("Test") pars = ba.Parameters() pars.add(ba.Parameter("par0", 0.0)) pars.add(ba.Parameter("par1", 1.0)) pars.add(ba.Parameter("par2", 2.0)) helper = TestMinimizerHelper() result = minimizer.minimize(helper.objective_function, pars) # return value of objective function was propagated to MinimizerResult self.assertEqual(result.minValue(), 42.0) # objective function was called twice #(once by test minimizer, and second time during return type deduction) self.assertEqual(helper.m_ncalls, 2) # starting values of fit parameters were correctly send to objective func self.assertEqual(list(helper.m_pars.values()), [0.0, 1.0, 2.0])
def run_fitting(): """ main function to run fitting """ real_data = create_real_data() fit_objective = ba.FitObjective() fit_objective.addSimulationAndData(get_simulation, real_data, 1.0) fit_objective.initPrint(10) fit_objective.initPlot(10) params = ba.Parameters() params.add("radius", 5. * nm, vary=False) params.add("height", 9. * nm, min=8. * nm, max=12. * nm) params.add("scale", 1.5, min=1.0, max=3.0) params.add("background", 200, min=100.0, max=2000.0, step=100.0) minimizer = ba.Minimizer() result = minimizer.minimize(fit_objective.evaluate, params) fit_objective.finalize(result)
def run_fitting(): """ Setup simulation and fit """ real_data = get_real_data_values() fit_objective = ba.FitObjective() fit_objective.addSimulationAndData(get_simulation, real_data, 1.0) plot_observer = ba.PlotterSpecular() fit_objective.initPrint(10) fit_objective.initPlot(10, plot_observer) params = ba.Parameters() params.add("ti_thickness", 50 * ba.angstrom, min=10 * ba.angstrom, max=60 * ba.angstrom) minimizer = ba.Minimizer() result = minimizer.minimize(fit_objective.evaluate, params) fit_objective.finalize(result)
def run_fitting(): """ main function to run fitting """ real_data = create_real_data() fit_objective = ba.FitObjective() fit_objective.addSimulationAndData(get_simulation, real_data, 1.0) fit_objective.initPrint(10) fit_objective.initPlot(10) """ Setting fitting parameters with starting values. Here we select starting values being quite far from true values to puzzle our minimizer's as much as possible. """ params = ba.Parameters() params.add("height", 1. * nm, min=0.01, max=30.0, step=0.05 * nm) params.add("radius", 20. * nm, min=0.01, max=30.0, step=0.05 * nm) """ Now we run first minimization round using the Genetic minimizer. The Genetic minimizer is able to explore large parameter space without being trapped by some local minimum. """ minimizer = ba.Minimizer() minimizer.setMinimizer("Genetic", "", "MaxIterations=2;RandomSeed=1") result = minimizer.minimize(fit_objective.evaluate, params) fit_objective.finalize(result) best_params_so_far = result.parameters() """ Second fit will use another minimizer. It starts from best parameters found in previous minimization and then continues until fit converges. """ minimizer.setMinimizer("Minuit2", "Migrad") result = minimizer.minimize(fit_objective.evaluate, best_params_so_far) fit_objective.finalize(result)
def run_fitting(): """ main function to run fitting """ fit_objective = ba.FitObjective() fit_objective.addSimulationAndData(get_simulation_1, data_1[:, 1], 1.0) fit_objective.addSimulationAndData(get_simulation_2, data_2[:, 1], 1.0) fit_objective.initPrint(10) # creating custom observer which will draw fit progress plotter = PlotterSpecular() fit_objective.initPlot(10, plotter) params = ba.Parameters() params.add("Ag_dens_f", 1.0, min=0.5, max=2.0) params.add("SiO_dens_f", 1.0, min=0.95, max=1.1) params.add("Ag_thick", 20.0 * nm, min=15 * nm, max=30 * nm) params.add("SiO_thick", 5.0 * nm, min=3 * nm, max=8 * nm) minimizer = ba.Minimizer() result = minimizer.minimize(fit_objective.evaluate, params) fit_objective.finalize(result)
def test_RosenbrockFit(self): """ Testing fit of rosenbrock function """ params = ba.Parameters() params.add( ba.Parameter("x", -1.2, ba.AttLimits.limited(-5.0, 5.0), 0.01)) params.add( ba.Parameter("y", 1.0, ba.AttLimits.limited(-5.0, 5.0), 0.01)) model = Rosenbrock() minimizer = ba.Minimizer() result = minimizer.minimize(model.objective_function, params) print(result.toString()) # check found parameter values np.testing.assert_almost_equal(result.parameters().values(), model.m_expected_params, 3) # check found minimum np.testing.assert_almost_equal(result.minValue(), model.m_expected_minimum, 3)
def run_fitting(i_img): # for this thesis just batch simulations, no fitting. # passing the simulation through the fitting mechanism # still useful for processing experimental and # simulation patterns simultaneously global first_run global batch_sim global init_radius global init_height global init_height_flattening_ratio global init_lattice_length global init_damping_length global init_disorder_parameter global init_beam_intensity if batch_sim == True: # setting the simulation parameters d_eff = 11.6 * (0.1 * (i_img - 11)) / 150 init_lattice_length = 2 * np.pi / (0.628 + 1.499 * math.exp(-d_eff / 3.31)) init_height = 1.519 + 1.367 * d_eff - 0.038 * (d_eff**2) init_radius = init_height / 3.1 init_height_flattening_ratio = 0.66 init_disorder_parameter = 0.25 init_damping_length = 30 * nm init_beam_intensity = 4.15e+09 real_data = load_real_data(i_img) fit_objective = ba.FitObjective() fit_objective.addSimulationAndData(get_simulation, real_data) fit_objective.initPrint(1) fit_objective.initPlot(1, PlotObserver( )) #plotting frequency on screen (increase if OpenGL error) params = ba.Parameters( ) #parameter limits only relevant for full fitting, otherwise ignored min_height = 0.1 max_height = 20 min_lattice_length = 0.1 max_lattice_length = 20 min_radius = 0.1 max_radius = 20 min_damping_length = 10 max_damping_length = 1000 min_disorder_parameter = 0.1 max_disorder_parameter = 0.5 min_beam_intensity = 1e+8 max_beam_intensity = 1e+12 params.add("radius", value=init_radius, min=min_radius, max=max_radius, step=0.1 * nm, vary=True) params.add("height", value=init_height, min=min_height, max=max_height, step=0.1 * nm, vary=True) params.add("height_flattening_ratio", value=init_height_flattening_ratio, min=0.55, max=0.75, step=0.01, vary=True) params.add("lattice_length", value=init_lattice_length, min=min_lattice_length, max=max_lattice_length, step=0.1 * nm, vary=True) params.add("damping_length", value=init_damping_length, min=min_damping_length, max=max_damping_length, step=10 * nm, vary=True) params.add("disorder_parameter", value=init_disorder_parameter, min=min_disorder_parameter, max=max_disorder_parameter, step=0.01, vary=True) params.add("beam_intensity", init_beam_intensity, min=min_beam_intensity, max=max_beam_intensity, vary=False) minimizer = ba.Minimizer() minimizer.setMinimizer("Test") # normal simulation (no fitting) #minimizer.setMinimizer("Minuit2", "Migrad", "MaxFunctionCalls=0;Strategy=2;") # minimizer for fitting result = minimizer.minimize(fit_objective.evaluate, params) # runs the simulation fit_objective.finalize(result) fig_name = output_folder + 'fitting_img_#32_' + repr(i_img) + '.png' plt.savefig(fig_name, dpi=500) plt.close(1) print("Fitting completed.") print("chi2:", result.minValue()) for fitPar in result.parameters(): print(fitPar.name(), fitPar.value, fitPar.error) experimental_data = fit_objective.experimentalData() simulation_data = fit_objective.simulationResult() difference = fit_objective.relativeDifference() zmin = 0.1 # range of the colormap zmax = 100 mpl.rcParams['image.cmap'] = 'jet' # saves figures in jet colormap plt.figure(2, figsize=(8, 6)) ba.plot_colormap(experimental_data, title="Experimental data", zmin=zmin, zmax=zmax, units=ba.AxesUnits.QSPACE, xlabel=None, ylabel=None, zlabel='', aspect=None) fig_name = output_folder + 'exp_data_#32_' + repr(i_img) + '_jet' + '.png' plt.savefig(fig_name, dpi=500) plt.close(2) plt.figure(3, figsize=(8, 6)) ba.plot_colormap(simulation_data, title="Simulation result", zmin=zmin, zmax=zmax, units=ba.AxesUnits.QSPACE, xlabel=None, ylabel=None, zlabel='', aspect=None) fig_name = output_folder + 'sim_data_#32_' + repr(i_img) + '_jet' + '.png' plt.savefig(fig_name, dpi=500) plt.close(3) mpl.rcParams[ 'image.cmap'] = 'nipy_spectral' #saves figures in spectral colormap plt.figure(4, figsize=(8, 6)) ba.plot_colormap(experimental_data, title="Experimental data", zmin=zmin, zmax=zmax, units=ba.AxesUnits.QSPACE, xlabel=None, ylabel=None, zlabel='', aspect=None) fig_name = output_folder + 'exp_data_#32_' + repr( i_img) + '_spectrum' + '.png' plt.savefig(fig_name, dpi=500) plt.close(4) plt.figure(5, figsize=(8, 6)) ba.plot_colormap(simulation_data, title="Simulation result", zmin=zmin, zmax=zmax, units=ba.AxesUnits.QSPACE, xlabel=None, ylabel=None, zlabel='', aspect=None) fig_name = output_folder + 'sim_data_#32_' + repr( i_img) + '_spectrum' + '.png' plt.savefig(fig_name, dpi=500) plt.close(5)