class FittingTabModelTest(unittest.TestCase): def setUp(self): self.model = FittingTabModel(setup_context()) self.model.context.ads_observer.unsubscribe() def test_convert_function_string_into_dict(self): trial_function = FunctionFactory.createInitialized( 'name=GausOsc,A=0.2,Sigma=0.2,Frequency=0.1,Phi=0') name = self.model.get_function_name(trial_function) self.assertEqual(name, 'GausOsc') def test_do_single_fit_and_return_functions_correctly(self): x_data = range(0, 100) y_data = [5 + x * x for x in x_data] workspace = CreateWorkspace(x_data, y_data) trial_function = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') parameter_dict = { 'Function': trial_function, 'InputWorkspace': workspace, 'Minimizer': 'Levenberg-Marquardt', 'StartX': 0.0, 'EndX': 100.0, 'EvaluationType': 'CentrePoint' } output_workspace, parameter_table_name, fitting_function, fit_status, fit_chi_squared, covariance_matrix = self.model.do_single_fit_and_return_workspace_parameters_and_fit_function( parameter_dict) parameter_table = AnalysisDataService.retrieve(parameter_table_name) self.assertAlmostEqual(parameter_table.row(0)['Value'], 5.0) self.assertAlmostEqual(parameter_table.row(1)['Value'], 0.0) self.assertAlmostEqual(parameter_table.row(2)['Value'], 1.0) self.assertEqual(fit_status, 'success') self.assertAlmostEqual(fit_chi_squared, 0.0) def test_add_workspace_to_ADS_adds_workspace_to_ads_in_correct_group_structure( self): workspace = CreateWorkspace([0, 0], [0, 0]) workspace_name = 'test_workspace_name' workspace_directory = 'root/' self.model.add_workspace_to_ADS(workspace, workspace_name, workspace_directory) self.assertTrue(AnalysisDataService.doesExist(workspace_name)) self.assertTrue(AnalysisDataService.doesExist('root')) def test_do_sequential_fit_correctly_delegates_to_do_single_fit(self): trial_function = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') self.model.do_single_fit = mock.MagicMock(return_value=(trial_function, 'success', 0.56)) workspace = "MUSR1223" parameter_dict = { 'Function': trial_function, 'InputWorkspace': workspace, 'Minimizer': 'Levenberg-Marquardt', 'StartX': 0.0, 'EndX': 100.0, 'EvaluationType': 'CentrePoint' } self.model.get_parameters_for_single_fit = mock.MagicMock( return_value=parameter_dict) self.model.do_sequential_fit([workspace] * 5) self.assertEqual(self.model.do_single_fit.call_count, 5) self.model.do_single_fit.assert_called_with( { 'Function': mock.ANY, 'InputWorkspace': workspace, 'Minimizer': 'Levenberg-Marquardt', 'StartX': 0.0, 'EndX': 100.0, 'EvaluationType': 'CentrePoint' }, True) def test_do_simultaneous_fit_adds_single_input_workspace_to_fit_context_with_globals( self): trial_function = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') x_data = range(0, 100) y_data = [5 + x * x for x in x_data] workspace = CreateWorkspace(x_data, y_data) parameter_dict = { 'Function': trial_function, 'InputWorkspace': [workspace.name()], 'Minimizer': 'Levenberg-Marquardt', 'StartX': [0.0], 'EndX': [100.0], 'EvaluationType': 'CentrePoint' } global_parameters = ['A0'] self.model.do_simultaneous_fit(parameter_dict, global_parameters) fit_context = self.model.context.fitting_context self.assertEqual(1, len(fit_context)) self.assertEqual(global_parameters, fit_context.fit_list[0].parameters.global_parameters) def test_do_simultaneous_fit_adds_multi_input_workspace_to_fit_context( self): # create function single_func = ';name=FlatBackground,$domains=i,A0=0' multi_func = 'composite=MultiDomainFunction,NumDeriv=1' + single_func + single_func + ";" trial_function = FunctionFactory.createInitialized(multi_func) x_data = range(0, 100) y_data = [5 + x * x for x in x_data] workspace1 = CreateWorkspace(x_data, y_data) workspace2 = CreateWorkspace(x_data, y_data) parameter_dict = { 'Function': trial_function, 'InputWorkspace': [workspace1.name(), workspace2.name()], 'Minimizer': 'Levenberg-Marquardt', 'StartX': [0.0] * 2, 'EndX': [100.0] * 2, 'EvaluationType': 'CentrePoint' } self.model.do_simultaneous_fit(parameter_dict, global_parameters=[]) fit_context = self.model.context.fitting_context self.assertEqual(1, len(fit_context)) def test_get_function_name_returns_correctly_for_composite_functions(self): function_string = 'name=FlatBackground,A0=22.5129;name=Polynomial,n=0,A0=-22.5221;name=ExpDecayOsc,A=-0.172352,Lambda=0.111109,Frequency=-0.280031,Phi=-3.03983' function_object = FunctionFactory.createInitialized(function_string) name_as_string = self.model.get_function_name(function_object) self.assertEqual(name_as_string, 'FlatBackground,Polynomial,ExpDecayOsc') def test_get_function_name_returns_correctly_for_composite_functions_multi_domain_function( self): function_string = 'composite=MultiDomainFunction,NumDeriv=true;(composite=CompositeFunction,NumDeriv=false,' \ '$domains=i;name=FlatBackground,A0=-0.800317;name=Polynomial,n=0,A0=0.791112;name=ExpDecayOsc,' \ 'A=0.172355,Lambda=0.111114,Frequency=0.280027,Phi=-0.101717);(composite=CompositeFunction,' \ 'NumDeriv=false,$domains=i;name=FlatBackground,A0=1.8125;name=Polynomial,n=0,A0=-1.81432;' \ 'name=ExpDecayOsc,A=0.17304,Lambda=0.102673,Frequency=0.278695,Phi=-0.0461353);' \ '(composite=CompositeFunction,NumDeriv=false,$domains=i;name=FlatBackground,A0=1.045;' \ 'name=Polynomial,n=0,A0=-1.04673;name=ExpDecayOsc,A=-0.170299,Lambda=0.118256,Frequency=0.281085,Phi=-0.155812)' function_object = FunctionFactory.createInitialized(function_string) name_as_string = self.model.get_function_name(function_object) self.assertEqual(name_as_string, 'FlatBackground,Polynomial,ExpDecayOsc') def test_get_function_name_truncates_function_with_more_than_three_composite_members( self): function_string = 'name=ExpDecayOsc,A=-5.87503,Lambda=0.0768409,Frequency=0.0150173,Phi=-1.15833;name=GausDecay,' \ 'A=-1.59276,Sigma=0.361339;name=ExpDecayOsc,A=-5.87503,Lambda=0.0768409,Frequency=0.0150173,' \ 'Phi=-1.15833;name=ExpDecayMuon,A=-0.354664,Lambda=-0.15637;name=DynamicKuboToyabe,' \ 'BinWidth=0.050000000000000003,Asym=7.0419,Delta=0.797147,Field=606.24,Nu=2.67676e-09' function_object = FunctionFactory.createInitialized(function_string) name_as_string = self.model.get_function_name(function_object) self.assertEqual(name_as_string, 'ExpDecayOsc,GausDecay,ExpDecayOsc,...') def test_get_function_name_does_truncate_for_exactly_four_members(self): function_string = 'name=ExpDecayOsc,A=-5.87503,Lambda=0.0768409,Frequency=0.0150173,Phi=-1.15833;name=GausDecay,' \ 'A=-1.59276,Sigma=0.361339;name=ExpDecayOsc,A=-5.87503,Lambda=0.0768409,Frequency=0.0150173,' \ 'Phi=-1.15833;name=ExpDecayMuon,A=-0.354664,Lambda=-0.15637' function_object = FunctionFactory.createInitialized(function_string) name_as_string = self.model.get_function_name(function_object) self.assertEqual(name_as_string, 'ExpDecayOsc,GausDecay,ExpDecayOsc,...') def test_change_plot_guess_returns_when_given_bad_parameters(self): self.model.context = mock.Mock() self.model.change_plot_guess(True, {}) self.assertEqual( 0, self.model.context.fitting_context.notify_plot_guess_changed. call_count) def test_change_plot_guess_notifies_of_change_when_function_removed_but_plot_guess_true( self): self.model.context = mock.Mock() self.model.change_plot_guess(True, { 'Function': None, 'InputWorkspace': 'ws' }) self.model.context.fitting_context.notify_plot_guess_changed.assert_called_with( True, None) def test_change_plot_guess_evaluates_the_function(self): self.model.context = mock.Mock() with mock.patch( 'Muon.GUI.Common.fitting_tab_widget.fitting_tab_model.EvaluateFunction' ) as mock_evaluate: parameters = { 'Function': 'func', 'InputWorkspace': 'ws', 'StartX': 0, 'EndX': 1 } self.model.change_plot_guess(True, parameters) mock_evaluate.assert_called_with( InputWorkspace='ws', Function='func', StartX=parameters['StartX'], EndX=parameters['EndX'], OutputWorkspace='__unknown_interface_fitting_guess') @mock.patch('Muon.GUI.Common.fitting_tab_widget.fitting_tab_model.mantid') @mock.patch( 'Muon.GUI.Common.fitting_tab_widget.fitting_tab_model.EvaluateFunction' ) def test_change_plot_guess_writes_log_and_returns_if_function_evaluation_fails( self, mock_evaluate, mock_mantid): self.model.context = mock.Mock() mock_evaluate.side_effect = RuntimeError() parameters = { 'Function': 'func', 'InputWorkspace': 'ws', 'StartX': 0, 'EndX': 1 } self.model.change_plot_guess(True, parameters) mock_evaluate.assert_called_with( InputWorkspace='ws', Function='func', StartX=parameters['StartX'], EndX=parameters['EndX'], OutputWorkspace='__unknown_interface_fitting_guess') mock_mantid.logger.error.assert_called_with( 'Could not evaluate the function.') self.assertEqual( 0, self.model.context.fitting_context.notify_plot_guess_changed. call_count) @mock.patch( 'Muon.GUI.Common.fitting_tab_widget.fitting_tab_model.AnalysisDataService' ) @mock.patch( 'Muon.GUI.Common.fitting_tab_widget.fitting_tab_model.EvaluateFunction' ) def test_change_plot_guess_notifies_subscribers_if_workspace_in_ads( self, mock_evaluate, mock_ads): self.model.context = mock.Mock() mock_ads.doesExist.return_value = True parameters = { 'Function': 'func', 'InputWorkspace': 'ws', 'StartX': 0, 'EndX': 1 } self.model.change_plot_guess(True, parameters) mock_evaluate.assert_called_with( InputWorkspace='ws', Function='func', StartX=parameters['StartX'], EndX=parameters['EndX'], OutputWorkspace='__unknown_interface_fitting_guess') self.assertEqual( 1, self.model.context.fitting_context.notify_plot_guess_changed. call_count) self.model.context.fitting_context.notify_plot_guess_changed.assert_called_with( True, '__unknown_interface_fitting_guess') def test_evaluate_single_fit_calls_correctly_for_single_fit(self): self.model.fit_type = "Single" workspace = ["MUSR:62260;bwd"] plot_fit = True trial_function = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') self.model.do_single_fit = mock.MagicMock(return_value=(trial_function, 'success', 0.56)) parameter_dict = {'Test': 0} self.model.get_parameters_for_single_fit = mock.MagicMock( return_value=parameter_dict) self.model.evaluate_single_fit(workspace, plot_fit) self.model.do_single_fit.assert_called_once_with( parameter_dict, plot_fit) def test_evaluate_single_fit_calls_correct_function_for_simultaneous_fit( self): self.model.fit_type = "Simultaneous" workspace = ["MUSR:62260;bwd"] plot_fit = True self.model.global_parameters = ['A0'] trial_function = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') self.model.do_simultaneous_fit = mock.MagicMock( return_value=(trial_function, 'success', 0.56)) parameter_dict = {'Test': 0} self.model.get_parameters_for_simultaneous_fit = mock.MagicMock( return_value=parameter_dict) self.model.evaluate_single_fit(workspace, plot_fit) self.model.do_simultaneous_fit.assert_called_once_with( parameter_dict, ['A0'], plot_fit) def test_evaluate_single_fit_calls_correctly_for_single_tf_fit(self): self.model.fit_type = "Single" self.model.tf_asymmetry_mode = True workspace = ["MUSR:62260;bwd"] plot_fit = True trial_function = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') self.model.do_single_tf_fit = mock.MagicMock( return_value=(trial_function, 'success', 0.56)) parameter_dict = {'Test': 0} self.model.get_parameters_for_single_tf_fit = mock.MagicMock( return_value=parameter_dict) self.model.evaluate_single_fit(workspace, plot_fit) self.model.do_single_tf_fit.assert_called_once_with( parameter_dict, plot_fit) def test_evaluate_single_fit_calls_correct_function_for_simultaneous_tf_fit( self): self.model.fit_type = "Simultaneous" self.model.tf_asymmetry_mode = True workspace = ["MUSR:62260;bwd"] plot_fit = True self.model.global_parameters = ['A0'] trial_function = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') self.model.do_simultaneous_tf_fit = mock.MagicMock( return_value=(trial_function, 'success', 0.56)) parameter_dict = {'Test': 0} self.model.get_parameters_for_simultaneous_tf_fit = mock.MagicMock( return_value=parameter_dict) self.model.evaluate_single_fit(workspace, plot_fit) self.model.do_simultaneous_tf_fit.assert_called_once_with( parameter_dict, ['A0'], plot_fit) def test_do_sequential_fit_calls_fetches_calls_single_fit_correctly(self): workspace_list = ["MUSR62260;bwd", "MUSR62260;fwd"] plot_fit = True self.model.tf_asymmetry_mode = False use_initial_values = True self.model.do_single_fit = mock.MagicMock(return_value=("test", 'success', 0.56)) self.model.do_sequential_fit(workspace_list, plot_fit, use_initial_values) self.assertEqual(self.model.do_single_fit.call_count, 2) def test_do_sequential_fit_uses_previous_values_if_requested(self): workspace_list = ["MUSR62260;bwd", "MUSR62260;fwd"] plot_fit = True self.model.tf_asymmetry_mode = False use_initial_values = False self.model.set_fit_function_parameter_values = mock.MagicMock() trial_function_in = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') trial_function_out = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 5, A1 = 5, A2 = 5') self.model.do_single_fit = mock.MagicMock( return_value=(trial_function_out, 'success', 0.56)) parameter_dict = {'Function': trial_function_in} self.model.get_parameters_for_single_fit = mock.MagicMock( return_value=parameter_dict) self.model.do_sequential_fit(workspace_list, plot_fit, use_initial_values) self.model.set_fit_function_parameter_values.assert_called_once_with( trial_function_in, [5, 5, 5]) def test_create_equivalent_workspace_name_returns_expected_name(self): workspace_list = ["MUSR62260;bwd", "MUSR62260;fwd"] expected_name = "MUSR62260;bwd-MUSR62260;fwd" equiv_name = self.model.create_equivalent_workspace_name( workspace_list) self.assertEqual(equiv_name, expected_name) def test_get_ws_fit_function_returns_correct_function_for_single_fit(self): workspace = ["MUSR62260;fwd"] trial_function_1 = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') trial_function_2 = trial_function_1.clone() self.model.ws_fit_function_map = { "MUSR62260;bwd": trial_function_1, "MUSR62260;fwd": trial_function_2 } return_function = self.model.get_ws_fit_function(workspace) self.assertEqual(return_function, trial_function_2) def test_get_ws_fit_function_returns_correct_function_if_simultaneous_fit( self): workspaces = ["MUSR62260;fwd", "MUSR62260;bwd"] trial_function_1 = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') trial_function_2 = trial_function_1.clone() self.model.ws_fit_function_map = { "MUSR62260;fwd-MUSR62260;bwd": trial_function_1, "MUSR62261;fwd-MUSR62261;bwd": trial_function_2 } return_function = self.model.get_ws_fit_function(workspaces) self.assertEqual(return_function, trial_function_1)
class FittingTabModelTest(unittest.TestCase): def setUp(self): self.model = FittingTabModel(setup_context()) self.model.context.ads_observer.unsubscribe() self.model.fitting_options = { "startX": START_X, "endX": END_X, "evaluation_type": EVALUATION_TYPE, "minimiser": MINIMISER, "fit_type": "Single", "tf_asymmetry_mode": False } def setup_fit_workspace_map(self, workspace_list, fit_functions): self.model.ws_fit_function_map = {} for workspace, fit_function in zip(workspace_list, fit_functions): key = self.model.create_workspace_key([workspace]) self.model.ws_fit_function_map[key] = fit_function def setup_multi_fit_workspace_map(self, workspace_list, fit_functions): self.model.ws_fit_function_map = {} for workspace, fit_function in zip(workspace_list, fit_functions): key = self.model.create_workspace_key(workspace) self.model.ws_fit_function_map[key] = fit_function def test_convert_function_string_into_dict(self): trial_function = FunctionFactory.createInitialized( 'name=GausOsc,A=0.2,Sigma=0.2,Frequency=0.1,Phi=0') name = self.model.get_function_name(trial_function) self.assertEqual(name, 'GausOsc') def test_do_single_fit_and_return_functions_correctly(self): x_data = range(0, 100) y_data = [5 + x * x for x in x_data] workspace = CreateWorkspace(x_data, y_data) trial_function = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') parameter_dict = { 'Function': trial_function, 'InputWorkspace': workspace, 'Minimizer': 'Levenberg-Marquardt', 'StartX': 0.0, 'EndX': 100.0, 'EvaluationType': 'CentrePoint' } output_workspace, parameter_table_name, fitting_function, fit_status, fit_chi_squared, covariance_matrix = \ self.model.do_single_fit_and_return_workspace_parameters_and_fit_function(parameter_dict) parameter_table = AnalysisDataService.retrieve(parameter_table_name) self.assertAlmostEqual(parameter_table.row(0)['Value'], 5.0) self.assertAlmostEqual(parameter_table.row(1)['Value'], 0.0) self.assertAlmostEqual(parameter_table.row(2)['Value'], 1.0) self.assertEqual(fit_status, 'success') self.assertAlmostEqual(fit_chi_squared, 0.0) def test_add_workspace_to_ADS_adds_workspace_to_ads_in_correct_group_structure( self): workspace = CreateWorkspace([0, 0], [0, 0]) workspace_name = 'test_workspace_name' workspace_directory = 'root/' self.model.add_workspace_to_ADS(workspace, workspace_name, workspace_directory) self.assertTrue(AnalysisDataService.doesExist(workspace_name)) self.assertTrue(AnalysisDataService.doesExist('root')) def test_do_sequential_fit_correctly_delegates_to_do_single_fit(self): trial_function = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') self.model.do_single_fit = mock.MagicMock(return_value=(trial_function, 'success', 0.56)) workspace = "MUSR1223" parameter_dict = { 'Function': trial_function, 'InputWorkspace': workspace, 'Minimizer': 'Levenberg-Marquardt', 'StartX': 0.0, 'EndX': 100.0, 'EvaluationType': 'CentrePoint' } self.model.get_parameters_for_single_fit = mock.MagicMock( return_value=parameter_dict) self.model.do_sequential_fit([workspace] * 5) self.assertEqual(self.model.do_single_fit.call_count, 5) self.model.do_single_fit.assert_called_with({ 'Function': mock.ANY, 'InputWorkspace': workspace, 'Minimizer': 'Levenberg-Marquardt', 'StartX': 0.0, 'EndX': 100.0, 'EvaluationType': 'CentrePoint' }) def test_do_simultaneous_fit_adds_single_input_workspace_to_fit_context_with_globals( self): trial_function = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') x_data = range(0, 100) y_data = [5 + x * x for x in x_data] workspace = CreateWorkspace(x_data, y_data) parameter_dict = { 'Function': trial_function, 'InputWorkspace': [workspace.name()], 'Minimizer': 'Levenberg-Marquardt', 'StartX': [0.0], 'EndX': [100.0], 'EvaluationType': 'CentrePoint' } global_parameters = ['A0'] self.model.do_simultaneous_fit(parameter_dict, global_parameters) fit_context = self.model.context.fitting_context self.assertEqual(1, len(fit_context)) self.assertEqual(global_parameters, fit_context.fit_list[0].parameters.global_parameters) def test_do_simultaneous_fit_adds_multi_input_workspace_to_fit_context( self): # create function single_func = ';name=FlatBackground,$domains=i,A0=0' multi_func = 'composite=MultiDomainFunction,NumDeriv=1' + single_func + single_func + ";" trial_function = FunctionFactory.createInitialized(multi_func) x_data = range(0, 100) y_data = [5 + x * x for x in x_data] workspace1 = CreateWorkspace(x_data, y_data) workspace2 = CreateWorkspace(x_data, y_data) parameter_dict = { 'Function': trial_function, 'InputWorkspace': [workspace1.name(), workspace2.name()], 'Minimizer': 'Levenberg-Marquardt', 'StartX': [0.0] * 2, 'EndX': [100.0] * 2, 'EvaluationType': 'CentrePoint' } self.model.do_simultaneous_fit(parameter_dict, global_parameters=[]) fit_context = self.model.context.fitting_context self.assertEqual(1, len(fit_context)) def test_get_function_name_returns_correctly_for_composite_functions(self): function_string = 'name=FlatBackground,A0=22.5129;name=Polynomial,n=0,A0=-22.5221;' \ 'name=ExpDecayOsc,A=-0.172352,Lambda=0.111109, Frequency=-0.280031,Phi=-3.03983' function_object = FunctionFactory.createInitialized(function_string) name_as_string = self.model.get_function_name(function_object) self.assertEqual(name_as_string, 'FlatBackground,Polynomial,ExpDecayOsc') def test_get_function_name_returns_correctly_for_composite_functions_multi_domain_function( self): function_string = 'composite=MultiDomainFunction,NumDeriv=true;(composite=CompositeFunction,NumDeriv=false,' \ '$domains=i;name=FlatBackground,A0=-0.800317;name=Polynomial,n=0,A0=0.791112;name=ExpDecayOsc,' \ 'A=0.172355,Lambda=0.111114,Frequency=0.280027,Phi=-0.101717);(composite=CompositeFunction,' \ 'NumDeriv=false,$domains=i;name=FlatBackground,A0=1.8125;name=Polynomial,n=0,A0=-1.81432;' \ 'name=ExpDecayOsc,A=0.17304,Lambda=0.102673,Frequency=0.278695,Phi=-0.0461353);' \ '(composite=CompositeFunction,NumDeriv=false,$domains=i;name=FlatBackground,A0=1.045;' \ 'name=Polynomial,n=0,A0=-1.04673;name=ExpDecayOsc,A=-0.170299,Lambda=0.118256,Frequency=0.281085,Phi=-0.155812)' function_object = FunctionFactory.createInitialized(function_string) name_as_string = self.model.get_function_name(function_object) self.assertEqual(name_as_string, 'FlatBackground,Polynomial,ExpDecayOsc') def test_get_function_name_truncates_function_with_more_than_three_composite_members( self): function_string = 'name=ExpDecayOsc,A=-5.87503,Lambda=0.0768409,Frequency=0.0150173,Phi=-1.15833;name=GausDecay,' \ 'A=-1.59276,Sigma=0.361339;name=ExpDecayOsc,A=-5.87503,Lambda=0.0768409,Frequency=0.0150173,' \ 'Phi=-1.15833;name=ExpDecayMuon,A=-0.354664,Lambda=-0.15637;name=DynamicKuboToyabe,' \ 'BinWidth=0.050000000000000003,Asym=7.0419,Delta=0.797147,Field=606.24,Nu=2.67676e-09' function_object = FunctionFactory.createInitialized(function_string) name_as_string = self.model.get_function_name(function_object) self.assertEqual(name_as_string, 'ExpDecayOsc,GausDecay,ExpDecayOsc,...') def test_get_function_name_does_truncate_for_exactly_four_members(self): function_string = 'name=ExpDecayOsc,A=-5.87503,Lambda=0.0768409,Frequency=0.0150173,Phi=-1.15833;name=GausDecay,' \ 'A=-1.59276,Sigma=0.361339;name=ExpDecayOsc,A=-5.87503,Lambda=0.0768409,Frequency=0.0150173,' \ 'Phi=-1.15833;name=ExpDecayMuon,A=-0.354664,Lambda=-0.15637' function_object = FunctionFactory.createInitialized(function_string) name_as_string = self.model.get_function_name(function_object) self.assertEqual(name_as_string, 'ExpDecayOsc,GausDecay,ExpDecayOsc,...') def test_change_plot_guess_notifies_of_change_when_function_removed_but_plot_guess_true( self): self.model.context = mock.Mock() self.model._get_guess_parameters = mock.Mock(return_value=[None, 'ws']) self.model.change_plot_guess(True, ['ws'], 0) self.model.context.fitting_context.notify_plot_guess_changed.assert_called_with( True, None) def test_change_plot_guess_evaluates_the_function(self): self.model.context = mock.Mock() with mock.patch( 'Muon.GUI.Common.fitting_tab_widget.fitting_tab_model.EvaluateFunction' ) as mock_evaluate: self.model._get_guess_parameters = mock.Mock( return_value=['func', 'ws']) self.model.change_plot_guess(True, workspace_names=['ws'], index=0) mock_evaluate.assert_called_with( InputWorkspace='ws', Function='func', StartX=START_X, EndX=END_X, OutputWorkspace='__unknown_interface_fitting_guess') @mock.patch('Muon.GUI.Common.fitting_tab_widget.fitting_tab_model.mantid') @mock.patch( 'Muon.GUI.Common.fitting_tab_widget.fitting_tab_model.EvaluateFunction' ) def test_change_plot_guess_writes_log_and_returns_if_function_evaluation_fails( self, mock_evaluate, mock_mantid): self.model.context = mock.Mock() mock_evaluate.side_effect = RuntimeError() self.model._get_guess_parameters = mock.Mock( return_value=['func', 'ws']) self.model.change_plot_guess(True, workspace_names=['ws'], index=0) mock_evaluate.assert_called_with( InputWorkspace='ws', Function='func', StartX=START_X, EndX=END_X, OutputWorkspace='__unknown_interface_fitting_guess') mock_mantid.logger.error.assert_called_with( 'Could not evaluate the function.') self.assertEqual( 0, self.model.context.fitting_context.notify_plot_guess_changed. call_count) @mock.patch( 'Muon.GUI.Common.fitting_tab_widget.fitting_tab_model.AnalysisDataService' ) @mock.patch( 'Muon.GUI.Common.fitting_tab_widget.fitting_tab_model.EvaluateFunction' ) def test_change_plot_guess_notifies_subscribers_if_workspace_in_ads( self, mock_evaluate, mock_ads): self.model.context = mock.Mock() mock_ads.doesExist.return_value = True self.model._get_guess_parameters = mock.Mock( return_value=['func', 'ws']) self.model.change_plot_guess(True, workspace_names=['ws'], index=0) mock_evaluate.assert_called_with( InputWorkspace='ws', Function='func', StartX=START_X, EndX=END_X, OutputWorkspace='__unknown_interface_fitting_guess') self.assertEqual( 1, self.model.context.fitting_context.notify_plot_guess_changed. call_count) self.model.context.fitting_context.notify_plot_guess_changed.assert_called_with( True, '__unknown_interface_fitting_guess') def test_evaluate_single_fit_calls_correctly_for_single_fit(self): workspace = ["MUSR:62260;bwd"] trial_function = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') self.model.do_single_fit = mock.MagicMock(return_value=(trial_function, 'success', 0.56)) parameter_dict = {'Test': 0} self.model.get_parameters_for_single_fit = mock.MagicMock( return_value=parameter_dict) self.model.evaluate_single_fit(workspace) self.model.do_single_fit.assert_called_once_with(parameter_dict) def test_evaluate_single_fit_calls_correct_function_for_simultaneous_fit( self): self.model.fitting_options["fit_type"] = "Simultaneous" self.model.fitting_options["global_parameters"] = ['A0'] workspace = ["MUSR:62260;bwd"] trial_function = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') self.model.do_simultaneous_fit = mock.MagicMock( return_value=(trial_function, 'success', 0.56)) parameter_dict = {'Test': 0} self.model.get_parameters_for_simultaneous_fit = mock.MagicMock( return_value=parameter_dict) self.model.evaluate_single_fit(workspace) self.model.do_simultaneous_fit.assert_called_once_with( parameter_dict, ['A0']) def test_evaluate_single_fit_calls_correctly_for_single_tf_fit(self): self.model.tf_asymmetry_mode = True self.model.fitting_options["tf_asymmetry_mode"] = True workspace = ["MUSR:62260;bwd"] trial_function = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') self.model.do_single_tf_fit = mock.MagicMock( return_value=(trial_function, 'success', 0.56)) parameter_dict = {'Test': 0} self.model.get_parameters_for_single_tf_fit = mock.MagicMock( return_value=parameter_dict) self.model.evaluate_single_fit(workspace) self.model.do_single_tf_fit.assert_called_once_with(parameter_dict) def test_evaluate_single_fit_calls_correct_function_for_simultaneous_tf_fit( self): self.model.fitting_options["fit_type"] = "Simultaneous" self.model.fitting_options["global_parameters"] = ['A0'] self.model.fitting_options["tf_asymmetry_mode"] = True workspace = ["MUSR:62260;bwd"] trial_function = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') self.model.do_simultaneous_tf_fit = mock.MagicMock( return_value=(trial_function, 'success', 0.56)) parameter_dict = {'Test': 0} self.model.get_parameters_for_simultaneous_tf_fit = mock.MagicMock( return_value=parameter_dict) self.model.evaluate_single_fit(workspace) self.model.do_simultaneous_tf_fit.assert_called_once_with( parameter_dict, ['A0']) def test_do_sequential_fit_calls_fetches_calls_single_fit_correctly(self): workspace_list = ["MUSR62260;bwd", "MUSR62260;fwd"] self.model.tf_asymmetry_mode = False use_initial_values = True self.model.do_single_fit = mock.MagicMock(return_value=("test", 'success', 0.56)) self.model.do_sequential_fit(workspace_list, use_initial_values) self.assertEqual(self.model.do_single_fit.call_count, 2) def test_do_sequential_fit_uses_previous_values_if_requested(self): workspace_list = ["MUSR62260;bwd", "MUSR62260;fwd"] self.model.tf_asymmetry_mode = False use_initial_values = False self.model.set_fit_function_parameter_values = mock.MagicMock() trial_function_in = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') trial_function_out = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 5, A1 = 5, A2 = 5') self.model.do_single_fit = mock.MagicMock( return_value=(trial_function_out, 'success', 0.56)) parameter_dict = {'Function': trial_function_in} self.model.get_parameters_for_single_fit = mock.MagicMock( return_value=parameter_dict) self.model.do_sequential_fit(workspace_list, use_initial_values) self.model.set_fit_function_parameter_values.assert_called_once_with( trial_function_in, [5, 5, 5]) def test_create_workspace_key_generates_expected_key(self): workspace_list = ["MUSR62260;bwd", "MUSR62260;fwd"] expected_key = frozenset(workspace_list) key = self.model.create_workspace_key(workspace_list) self.assertEqual(key, expected_key) def test_create_workspace_key_generates_same_hash_for_permutated_workspace_list( self): workspace_list = ["MUSR62260;bwd", "MUSR62260;fwd", "MUSR62260;bot"] workspace_list_1 = ["MUSR62260;bwd", "MUSR62260;bot", "MUSR62260;fwd"] key = self.model.create_workspace_key(workspace_list) key_1 = self.model.create_workspace_key(workspace_list_1) self.assertEqual(hash(key), hash(key_1)) def test_get_ws_fit_function_returns_correct_function_for_single_fit(self): workspace = ["MUSR62260;fwd"] workspace_1 = ["MUSR62260;fwd"] key = self.model.create_workspace_key(workspace) key_1 = self.model.create_workspace_key(workspace_1) trial_function_1 = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') trial_function_2 = trial_function_1.clone() self.model.ws_fit_function_map = { key: trial_function_1, key_1: trial_function_2 } return_function = self.model.get_ws_fit_function(workspace) self.assertEqual(return_function, trial_function_2) def test_get_ws_fit_function_returns_correct_function_if_simultaneous_fit( self): workspaces = ["MUSR62260;fwd", "MUSR62260;bwd"] workspaces_1 = ["MUSR62260;top", "MUSR62260;bot"] key = self.model.create_workspace_key(workspaces) key_1 = self.model.create_workspace_key(workspaces_1) trial_function_1 = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') trial_function_2 = trial_function_1.clone() self.model.ws_fit_function_map = { key: trial_function_1, key_1: trial_function_2 } return_function = self.model.get_ws_fit_function(workspaces) self.assertEqual(return_function, trial_function_1) def test_get_parameters_for_simultaneous_fit_returns_correctly(self): workspaces = [["MUSR62260;fwd", "MUSR62260;bwd"], ["MUSR62260;top", "MUSR62260;bot"]] trial_function = FunctionFactory.createInitialized( EXAMPLE_MULTI_DOMAIN_FUNCTION) fit_functions = [trial_function, trial_function.clone()] self.setup_multi_fit_workspace_map(workspaces, fit_functions) result = self.model.get_parameters_for_simultaneous_fit(workspaces[1]) self.assertEqual(result['Function'], fit_functions[1]) self.assertEqual(result['InputWorkspace'], workspaces[1]) self.assertEqual(result['Minimizer'], 'Levenberg-Marquardt') self.assertEqual(result['StartX'], [START_X] * len(workspaces)) self.assertEqual(result['EndX'], [END_X] * len(workspaces)) self.assertEqual(result['EvaluationType'], 'CentrePoint') def test_get_parameters_for_single_fit_returns_correctly(self): workspace_list = ["MUSR62260;fwd", "MUSR62260;top"] trial_function = FunctionFactory.createInitialized( 'name = Quadratic, A0 = 0, A1 = 0, A2 = 0') fit_functions = [trial_function, trial_function.clone()] self.setup_fit_workspace_map(workspace_list, fit_functions) result = self.model.get_parameters_for_single_fit(workspace_list[0]) self.assertEqual(result['Function'], fit_functions[0]) self.assertEqual(result['InputWorkspace'], workspace_list[0]) self.assertEqual(result['Minimizer'], 'Levenberg-Marquardt') self.assertEqual(result['StartX'], START_X) self.assertEqual(result['EndX'], END_X) self.assertEqual(result['EvaluationType'], 'CentrePoint') def test_get_parameters_for_tf_single_fit_returns_correctlyn(self): workspace_list = ["MUSR62260;fwd", "MUSR62260;top"] trial_function = FunctionFactory.createInitialized( EXAMPLE_TF_ASYMMETRY_FUNCTION) un_normalised_workspace_name = '__MUSR62260; Group; fwd; Asymmetry_unnorm' fit_functions = [trial_function, trial_function.clone()] self.setup_fit_workspace_map(workspace_list, fit_functions) self.model.context.group_pair_context.get_unormalisised_workspace_list = mock.MagicMock( return_value=[un_normalised_workspace_name]) result = self.model.get_parameters_for_single_tf_fit(workspace_list[0]) self.assertEqual( result, { 'InputFunction': fit_functions[0], 'Minimizer': 'Levenberg-Marquardt', 'OutputFitWorkspace': mock.ANY, 'ReNormalizedWorkspaceList': workspace_list[0], 'StartX': START_X, 'EndX': END_X, 'UnNormalizedWorkspaceList': un_normalised_workspace_name }) def test_get_parameters_for_tf_simultaneous_fit_returns_correctly(self): workspaces = [["MUSR62260;fwd", "MUSR62260;bwd"], ["MUSR62260;top", "MUSR62260;bot"]] trial_function = FunctionFactory.createInitialized( EXAMPLE_TF_ASYMMETRY_FUNCTION) un_normalised_workspace_names = [ '__MUSR62260; Group; fwd; Asymmetry_unnorm', '__MUSR22725; Group; bwd; Asymmetry_unnorm' ] fit_functions = [trial_function, trial_function.clone()] self.setup_multi_fit_workspace_map(workspaces, fit_functions) self.model.context.group_pair_context.get_unormalisised_workspace_list = mock.MagicMock( return_value=un_normalised_workspace_names) result = self.model.get_parameters_for_simultaneous_tf_fit( workspaces[1]) self.assertEqual( result, { 'InputFunction': fit_functions[1], 'Minimizer': MINIMISER, 'OutputFitWorkspace': mock.ANY, 'ReNormalizedWorkspaceList': workspaces[1], 'StartX': START_X, 'EndX': END_X, 'UnNormalizedWorkspaceList': un_normalised_workspace_names }) def test_get_parameters_for_single_tf_calculation_returns_correctly(self): trial_function = FunctionFactory.createInitialized( EXAMPLE_TF_ASYMMETRY_FUNCTION) workspace = "MUSR62260;fwd" un_normalised_workspace_name = '__MUSR62260; Group; fwd; Asymmetry_unnorm' self.model.context.group_pair_context.get_unormalisised_workspace_list = mock.MagicMock( return_value=[un_normalised_workspace_name]) result = self.model.get_params_for_single_tf_function_calculation( workspace, trial_function) self.assertEqual( result, { 'InputFunction': trial_function, 'Minimizer': MINIMISER, 'OutputFitWorkspace': 'fit', 'ReNormalizedWorkspaceList': workspace, 'StartX': START_X, 'EndX': END_X, 'UnNormalizedWorkspaceList': un_normalised_workspace_name }) def test_get_parameters_for_multi_tf_calculation_returns_correctly(self): trial_function = FunctionFactory.createInitialized( EXAMPLE_TF_ASYMMETRY_FUNCTION) workspaces = ["MUSR62260;fwd", "MUSR62260;bwd"] un_normalised_workspace_names = [ '__MUSR62260; Group; fwd; Asymmetry_unnorm', '__MUSR62260; Group; bwd; Asymmetry_unnorm' ] self.model.context.group_pair_context.get_unormalisised_workspace_list = mock.MagicMock( return_value=un_normalised_workspace_names) result = self.model.get_params_for_multi_tf_function_calculation( workspaces, trial_function) self.assertEqual( result, { 'InputFunction': trial_function, 'Minimizer': MINIMISER, 'OutputFitWorkspace': 'fit', 'ReNormalizedWorkspaceList': workspaces, 'StartX': START_X, 'EndX': END_X, 'UnNormalizedWorkspaceList': un_normalised_workspace_names }) def test_create_double_pulse_alg_initialses_algorithm_with_correct_values( self): self.model.context.gui_context['DoublePulseTime'] = 2.0 double_pulse_alg = self.model._create_double_pulse_alg() self.assertEquals( double_pulse_alg.getProperty("PulseOffset").value, 2.0) self.assertAlmostEquals( double_pulse_alg.getProperty("FirstPulseWeight").value, 0.287, places=3) self.assertAlmostEquals( double_pulse_alg.getProperty("SecondPulseWeight").value, 0.713, places=3) def test_that_single_fit_initialises_algorithm_with_correct_values_for_tf_asymmetry_double_pulse_mode( self): workspace_name = 'MUSR62260; Group; fwd;' pulse_offset = 2.0 self.model.context.gui_context['DoublePulseTime'] = pulse_offset self.model.context.gui_context['DoublePulseEnabled'] = True parameters = self.model.get_parameters_for_single_tf_fit( workspace_name) self.assertEquals(parameters['PulseOffset'], pulse_offset) self.assertEquals(parameters['EnableDoublePulse'], True) self.assertAlmostEquals(parameters['FirstPulseWeight'], 0.287, places=3) def test_that_single_fit_initialises_algorithm_with_correct_values_for_simultaneous_tf_asymmetry_double_pulse_mode( self): workspace_name = 'MUSR62260; Group; fwd;' pulse_offset = 2.0 self.model.context.gui_context['DoublePulseTime'] = pulse_offset self.model.context.gui_context['DoublePulseEnabled'] = True parameters = self.model.get_parameters_for_simultaneous_tf_fit( workspace_name) self.assertEquals(parameters['PulseOffset'], pulse_offset) self.assertEquals(parameters['EnableDoublePulse'], True) self.assertAlmostEquals(parameters['FirstPulseWeight'], 0.287, places=3)