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(): """ 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(): """ 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 test_SimulationBuilderCallback(self): """ Testing simulation construction using Python callback """ pars = ba.Parameters() pars.add(ba.Parameter("par0", 0.0)) pars.add(ba.Parameter("par1", 1.0)) builder = SimulationBuilder() data = builder.create_data() # adding simulation callback and experimental data objective = ba.FitObjective() objective.addSimulationAndData(builder.build_simulation, data, 1.0) self.assertEqual(builder.m_ncalls, 0) self.assertEqual(objective.numberOfFitElements(), 0) # running objective function objective.evaluate(pars) self.assertEqual(builder.m_ncalls, 1) self.assertEqual(objective.numberOfFitElements(), builder.size()) self.assertEqual(builder.m_pars["par0"], 0.0) self.assertEqual(builder.m_pars["par1"], 1.0) # checking arrays of experimental and simulated data expected_sim = [] expected_data = [] for i in range(0, builder.size()): expected_sim.append(0.0) expected_data.append(1.0) self.assertEqual(expected_sim, list(objective.simulation_array())) self.assertEqual(expected_data, list(objective.experimental_array()))
def __init__(self): self.m_x = np.linspace(0.0, 10.0, 100) self.m_params = ba.Parameters() self.m_params.add(ba.Parameter('amp', 10.0)) self.m_params.add(ba.Parameter('decay', 0.05)) self.m_params.add(ba.Parameter('phase', 1.0)) self.m_params.add(ba.Parameter('frequency', 4.0)) self.m_eps_data = np.linspace(0.0, 10.0, 100) self.m_eps_data.fill(0.01) self.m_data = decaying_sin(self.m_params, self.m_x)
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 test_ParametersSetIterator(self): """ Testing of python iterator over defined fit parameters. """ pars = ba.Parameters() self.assertEqual(pars.size(), 0) pars.add(ba.Parameter("par0", 1.0, ba.AttLimits.limitless())) pars.add(ba.Parameter("par1", 2.0, ba.AttLimits.limitless())) expected_names = ["par0", "par1"] for index, p in enumerate(pars): self.assertEqual(p.name(), expected_names[index])
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 test_ParametersAdd(self): """ Testing Parameters::add method """ params = ba.Parameters() params.add("par0", 0.0) params.add("par1", 1.0, min=1.0) params.add("par2", 2.0, max=2.0) params.add("par3", 3.0, min=1.0, max=2.0) params.add("par4", 4.0, vary=False) self.assertTrue(params["par0"].limits().isLimitless()) self.assertTrue(params["par1"].limits().isLowerLimited()) self.assertEqual(params["par1"].limits().lowerLimit(), 1.0) self.assertTrue(params["par2"].limits().isUpperLimited()) self.assertEqual(params["par2"].limits().upperLimit(), 2.0) self.assertTrue(params["par3"].limits().isLimited()) self.assertEqual(params["par3"].limits().lowerLimit(), 1.0) self.assertEqual(params["par3"].limits().upperLimit(), 2.0) self.assertTrue(params["par4"].limits().isFixed())
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 test_FittingObserver(self): """ Testing simulation construction using Python callback """ pars = ba.Parameters() pars.add(ba.Parameter("par0", 0.0)) pars.add(ba.Parameter("par1", 1.0)) # adding simulation callback and experimental data builder = SimulationBuilder() data = builder.create_data() objective = ba.FitObjective() objective.addSimulationAndData(builder.build_simulation, data, 1.0) # adding observer observer = FitObserver() objective.initPlot(5, observer.update) # running objective function 11 times for i in range(0, 11): objective.evaluate(pars) self.assertEqual(observer.m_ncalls, 3) self.assertEqual(observer.m_iterations, [1, 6, 11])
def test_IterationInfo(self): """ Testing map of parameters obtained from IterationInfo """ params = ba.Parameters() params.add("bbb", 1.0) params.add("aaa", 2.0) info = ba.IterationInfo() info.update(params, 3.0) par_map = info.parameterMap() expected_names = ["aaa", "bbb"] expected_values = [2.0, 1.0] names = [] values = [] for key in par_map: names.append(key) values.append(par_map[key]) self.assertEqual(names, expected_names) self.assertEqual(values, expected_values) self.assertEqual(info.iterationCount(), 1)
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)