class TestLMFitModel(unittest.TestCase): @classmethod def setUpClass(cls): file_path = os.path.dirname(os.path.realpath(__file__)) input_path = file_path + '/../../example/data/' sliced_path = input_path + 'example5_6584.hdf5' cls.sliced_data = SlicedData.init_from_hdf5(sliced_path) orbital_paths = [ 'PTCDA_C.cube', 'PTCDA_D.cube', 'PTCDA_E.cube', 'PTCDA_F.cube' ] cls.orbitals = [ OrbitalData.init_from_file(input_path + path, ID) for ID, path in enumerate(orbital_paths) ] cls.expected = np.loadtxt(file_path + '/output/weights_PTCDA') cls.background_expected = np.loadtxt(file_path + '/output/background_expected') def setUp(self): self.lmfit = LMFitModel(TestLMFitModel.sliced_data, TestLMFitModel.orbitals) self.crosshair = CrosshairAnnulusModel() def test_set_crosshair(self): self.lmfit.set_crosshair(self.crosshair) self.assertEqual(self.lmfit.crosshair, self.crosshair) def test_set_axis(self): step_size = 0.24 range_ = [-3, 3] axis = np.linspace(*range_, num=step_size_to_num(range_, step_size), endpoint=True) self.lmfit.set_axis_by_step_size(range_, step_size) npt.assert_almost_equal(self.lmfit.get_sliced_kmap(0).x_axis, axis) def test_set_slices(self): self.lmfit.set_slices([1, 2, 3]) self.lmfit.set_slices([0, 1, 2, 3], combined=True) def test_set_background_equation(self): self.lmfit.set_background_equation('np.exp(a)') npt.assert_equal(self.lmfit.background_equation, ['np.exp(a)', ['a']]) self.assertRaises(ValueError, self.lmfit.set_background_equation, 'np.exp(a') def test_parameters(self): self.lmfit.set_background_equation('np.exp(a)') self.assertEqual(self.lmfit.parameters['w_1'].min, 0) self.assertEqual(self.lmfit.parameters['a'].value, 0) self.assertEqual(self.lmfit.parameters['E_kin'].max, 150) def test_edit_parameter(self): self.lmfit.edit_parameter('w_1', value=1.5) self.assertEqual(self.lmfit.parameters['w_1'].value, 1.5) def test_background(self): range_, dk = [-3.0, 3.0], 0.025 self.lmfit.set_axis_by_step_size(range_, dk) self.lmfit.set_background_equation( '(np.exp(-x**2-y**2)-np.exp(-(x-1)**2-(y-1)**2))/2') background = self.lmfit._get_background(variables={}) npt.assert_almost_equal(background, TestLMFitModel.background_expected) def test_settings(self): lmfit_new = LMFitModel(TestLMFitModel.sliced_data, TestLMFitModel.orbitals) lmfit_new.set_settings(self.lmfit.get_settings()) def test_PTCDA(self): if float(config.get_key('orbital', 'dk3D')) != 0.12: print('WARNING: Test \'test_PTCDA\' from the ' + '\'test_lmfit\' module has not been run. It requires ' + '\'dk3D\' setting from the \'cube\' category to be ' + 'to 0.12.') return # Set certain parameters not being fitted but desired to be changed range_, dk = [-3.0, 3.0], 0.04 self.lmfit.set_axis_by_step_size(range_, dk) self.lmfit.set_polarization('toroid', 'p') self.lmfit.set_background_equation('c') # Set certain fit parameter to desired value self.lmfit.edit_parameter('E_kin', value=27.2) self.lmfit.edit_parameter('alpha', value=40) self.lmfit.edit_parameter('c', value=1, vary=True) # Activate fitting for all weights (i is a dummy ID used in setUpClass) for i in [0, 1, 2, 3]: self.lmfit.edit_parameter('w_' + str(i), vary=True) # Set slices to be used self.lmfit.set_slices('all', combined=False) results = self.lmfit.fit() # Test results weights = np.array([[ result[1].params['w_0'].value, result[1].params['w_1'].value, result[1].params['w_2'].value, result[1].params['w_3'].value ] for result in results]).T npt.assert_almost_equal(weights, TestLMFitModel.expected, decimal=5)
orbitals = [ OrbitalData.init_from_file(data_path / path, ID) for ID, path in enumerate(orbital_paths) ] # Initialize fit as LMFitModel object lmfit = LMFitModel(exp_data, orbitals) # Set common range and delta-k-grid for exp. and sim. kmaps range_, dk = [-3.0, 3.0], 0.04 lmfit.set_axis_by_step_size(range_, dk) lmfit.set_polarization('toroid', 'p') lmfit.set_background_equation('c') # Set parameters not intended for fitting to desired value lmfit.edit_parameter('E_kin', value=27.2, vary=False) lmfit.edit_parameter('alpha', value=40, vary=False) # Activate fitting for background ('c') and all orbital weights lmfit.edit_parameter('c', value=250, vary=True) # constant background for i in [0, 1, 2, 3]: lmfit.edit_parameter('w_' + str(i), vary=True) # Set slices to be used and perform fit lmfit.set_slices('all', combined=False) lmfit.set_fit_method(method='matrix_inversion') results = lmfit.fit() # Extract fitting results weights = np.array([[ result[1].params['w_0'].value, result[1].params['w_1'].value,
# Load orbital for fitting as OrbitalData objects orbital_paths = ['pentacene_HOMO.cube'] orbitals = [OrbitalData.init_from_file( data_path / path, ID) for ID, path in enumerate(orbital_paths)] # Initialize fit as LMFitModel object lmfit = LMFitModel(exp_data, orbitals) # Set common range and delta-k-grid for exp. and sim. kmaps range_, dk = [-3.0, 3.0], 0.04 lmfit.set_axis_by_step_size(range_, dk) lmfit.set_polarization('toroid', 'p') lmfit.set_symmetrization('2-fold') # Set parameters not intended for fitting to desired value lmfit.edit_parameter('E_kin', value=28, vary=False) lmfit.edit_parameter('alpha', value=40, vary=False) lmfit.set_background_equation('c') # Activate fitting for background ('c') and all orbital weights and theta lmfit.edit_parameter('c', value=1, vary=True) # constant background for i in [0]: lmfit.edit_parameter('w_' + str(i), vary=True) lmfit.edit_parameter('theta_' + str(i), min=0, value=5, vary=True) lmfit.edit_parameter('phi_' + str(i), value=90, vary=False) lmfit.edit_parameter('psi_' + str(i), value=90, vary=False) # Set slices to be used and perform fit lmfit.set_slices([2], combined=False) lmfit.set_fit_method(method='leastsq', xtol=1e-12)