From 48dc6a0727d40cac7a751c5095690d1273eebcd8 Mon Sep 17 00:00:00 2001 From: Gennady Pospelov <g.pospelov@fz-juelich.de> Date: Mon, 18 Dec 2017 17:33:43 +0100 Subject: [PATCH] Fitting example explaining how to set minimizer options. --- .../ex02_FitBasics/MinimizerOptions.py | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 Examples/python/fitting/ex02_FitBasics/MinimizerOptions.py diff --git a/Examples/python/fitting/ex02_FitBasics/MinimizerOptions.py b/Examples/python/fitting/ex02_FitBasics/MinimizerOptions.py new file mode 100644 index 00000000000..2d8e657b4e8 --- /dev/null +++ b/Examples/python/fitting/ex02_FitBasics/MinimizerOptions.py @@ -0,0 +1,113 @@ +""" +Fitting example: running same fit using various minimizer and their settings. +""" +import bornagain as ba +from bornagain import deg, angstrom, nm + + +def get_sample(cylinder_height=5.0*nm, cylinder_radius=5.0*nm, + prism_length=5.0*nm, prism_height=5.0*nm): + """ + Returns a sample with uncorrelated cylinders and prisms on a substrate. + """ + # defining materials + m_air = ba.HomogeneousMaterial("Air", 0.0, 0.0) + m_substrate = ba.HomogeneousMaterial("Substrate", 6e-6, 2e-8) + m_particle = ba.HomogeneousMaterial("Particle", 6e-4, 2e-8) + + # collection of particles + cylinder_ff = ba.FormFactorCylinder(cylinder_radius, cylinder_height) + cylinder = ba.Particle(m_particle, cylinder_ff) + prism_ff = ba.FormFactorPrism3(prism_length, prism_height) + prism = ba.Particle(m_particle, prism_ff) + particle_layout = ba.ParticleLayout() + particle_layout.addParticle(cylinder, 0.5) + particle_layout.addParticle(prism, 0.5) + interference = ba.InterferenceFunctionNone() + particle_layout.setInterferenceFunction(interference) + + # air layer with particles and substrate form multi layer + air_layer = ba.Layer(m_air) + air_layer.addLayout(particle_layout) + substrate_layer = ba.Layer(m_substrate, 0) + multi_layer = ba.MultiLayer() + multi_layer.addLayer(air_layer) + multi_layer.addLayer(substrate_layer) + return multi_layer + + +def get_simulation(): + """ + Returns a GISAXS simulation with beam and detector defined + """ + simulation = ba.GISASSimulation() + simulation.setDetectorParameters(100, -1.0*deg, 1.0*deg, + 100, 0.0*deg, 2.0*deg) + simulation.setBeamParameters(1.0*angstrom, 0.2*deg, 0.0*deg) + simulation.setBeamIntensity(1e+08) + return simulation + + +def run_fitting(): + """ + run fitting + """ + + # prints info about available minimizers + print(ba.MinimizerFactory().catalogueToString()) + + # prints detailed info about available minimizers and their options + print(ba.MinimizerFactory().catalogueDetailsToString()) + + sample = get_sample() + simulation = get_simulation() + simulation.setSample(sample) + + real_data = ba.IntensityDataIOFactory.readIntensityData( + 'refdata_fitcylinderprisms.int.gz') + + fit_suite = ba.FitSuite() + fit_suite.addSimulationAndRealData(simulation, real_data) + fit_suite.initPrint(10) + + # setting fitting parameters with starting values + fit_suite.addFitParameter("*Cylinder/Height", 4.*nm).setLowerLimited(0.01) + fit_suite.addFitParameter("*Cylinder/Radius", 6.*nm).setLowerLimited(0.01) + fit_suite.addFitParameter("*Prism3/Height", 4.*nm).setLowerLimited(0.01) + fit_suite.addFitParameter("*Prism3/BaseEdge", 12.*nm).setLowerLimited(0.01) + + # 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 and will stop around this value + # fit_suite.setMinimizer("Minuit2", "Migrad", "MaxFunctionCalls=100") + + # Setting two options at once. + # Strategy=2 promises more accurate fit. + # fit_suite.setMinimizer("Minuit2", "Simplex", "MaxFunctionCalls=100;Strategy=2") + + # setting Minuit2 minimizer with Fumili algorithm + # fit_suite.setMinimizer("Minuit2", "Fumili") + + # Setting Levenberg-Marquardt algorithm + # fit_suite.setMinimizer("GSLLMA") + + # Setting Genetic algorithm + # It requires all parameters to be limited, so we recreate parameters with min and max defined + # fit_suite.fitParameters().clear() + # fit_suite.addFitParameter("*Cylinder/Height", 4.*nm).setLimited(3.0, 8.0) + # fit_suite.addFitParameter("*Cylinder/Radius", 6.*nm).setLimited(3.0, 8.0) + # fit_suite.addFitParameter("*Prism3/Height", 4.*nm).setLimited(3.0, 8.0) + # fit_suite.addFitParameter("*Prism3/BaseEdge", 4.*nm).setLimited(3.0, 8.0) + # fit_suite.setMinimizer("Genetic", "Default", "MaxIterations=2;PopSize=200;RandomSeed=1") + + # running fit with default minimizer + fit_suite.runFit() + + print("Fitting completed.") + print("chi2:", fit_suite.getChi2()) + for par in fit_suite.fitParameters(): + print(par.name(), par.value(), par.error()) + +if __name__ == '__main__': + run_fitting() -- GitLab