def create_test_model(input_workspaces, function_name, parameters, output_workspace_names=None, logs=None, global_parameters=None): """ Create a list of fits with time series logs on the workspaces :param input_workspaces: See create_test_fits :param function_name: See create_test_fits :param parameters: See create_test_fits :param logs: A list of (name, (values...), (name, (values...))) :param global_parameters: An optional list of tied parameters :return: A list of Fits with workspaces/logs attached """ fits = create_test_fits(input_workspaces, function_name, parameters, output_workspace_names, global_parameters) logs = logs if logs is not None else [] for fit, workspace_name in zip(fits, input_workspaces): add_logs(workspace_name, logs) fitting_context = FittingContext() for fit in fits: fitting_context.add_fit(fit) return fitting_context, ResultsTabModel(fitting_context)
def setup_context(freq=False): loaded_data = MuonLoadData() loaded_data.get_main_field_direction = mock.MagicMock( return_value='transverse') data_context = MuonDataContext(load_data=loaded_data) gui_context = MuonGuiContext() group_context = MuonGroupPairContext( data_context.check_group_contains_valid_detectors) phase_table_context = PhaseTableContext() fitting_context = FittingContext() freq_context = FrequencyContext() if freq: return FrequencyDomainAnalysisContext( muon_data_context=data_context, muon_group_context=group_context, muon_gui_context=gui_context, muon_phase_context=phase_table_context, fitting_context=fitting_context, frequency_context=freq_context) else: return DataAnalysisContext(muon_data_context=data_context, muon_group_context=group_context, muon_gui_context=gui_context, muon_phase_context=phase_table_context, fitting_context=fitting_context)
def test_context_constructor_accepts_fit_list(self): fit_list = [ FitInformation(mock.MagicMock(), 'MuonGuassOsc', mock.MagicMock(), mock.MagicMock()) ] context = FittingContext(fit_list) self.assertEqual(fit_list, context.fit_list)
def setup_context_for_tests(parent_object): parent_object.loaded_data = MuonLoadData() parent_object.loaded_data.get_main_field_direction = mock.MagicMock(return_value='transverse') parent_object.data_context = MuonDataContext(load_data=parent_object.loaded_data) parent_object.gui_context = MuonGuiContext() parent_object.group_context = MuonGroupPairContext(parent_object.data_context.check_group_contains_valid_detectors) parent_object.phase_table_context = PhaseTableContext() parent_object.fitting_context = FittingContext() parent_object.context = MuonContext(muon_data_context=parent_object.data_context, muon_group_context=parent_object.group_context, muon_gui_context=parent_object.gui_context, muon_phase_context=parent_object.phase_table_context, fitting_context=parent_object.fitting_context)
def test_that_when_new_fit_is_performed_function_name_is_set_to_lastest_fit_name( self): parameters = OrderedDict([('Height', (100, 0.1)), ('Cost function value', (1.5, 0))]) fits_func1 = create_test_fits(('ws1', ), 'func1', parameters, []) parameters = OrderedDict([('Height', (100, 0.1)), ('A0', (1, 0.001)), ('Cost function value', (1.5, 0))]) fits_func2 = create_test_fits(('ws2', ), 'func2', parameters, []) model = ResultsTabModel(FittingContext(fits_func1 + fits_func2)) model.on_new_fit_performed() self.assertEqual(model.selected_fit_function(), 'func2')
def test_create_results_table_raises_error_if_number_params_different( self): parameters = OrderedDict([('Height', (100, 0.1)), ('Cost function value', (1.5, 0))]) fits_func1 = create_test_fits(('ws1', ), 'func1', parameters, []) parameters = OrderedDict([('Height', (100, 0.1)), ('A0', (1, 0.001)), ('Cost function value', (1.5, 0))]) fits_func2 = create_test_fits(('ws2', ), 'func2', parameters, []) model = ResultsTabModel(FittingContext(fits_func1 + fits_func2)) selected_results = [('ws1', 0), ('ws2', 1)] self.assertRaises(RuntimeError, model.create_results_table, [], selected_results)
def test_create_results_table_with_mixed_global_non_global_raises_error( self): parameters = OrderedDict([('f0.Height', (100, 0.1)), ('f1.Height', (90, 0.001)), ('Cost function value', (1.5, 0))]) fits_func1 = create_test_fits(('ws1', ), 'func1', parameters, []) fits_globals = create_test_fits(('ws2', ), 'func1', parameters, [], global_parameters=['Height']) model = ResultsTabModel(FittingContext(fits_func1 + fits_globals)) selected_results = [('ws1', 0), ('ws2', 1)] self.assertRaises(RuntimeError, model.create_results_table, [], selected_results)
def setup_context(): loaded_data = MuonLoadData() loaded_data.get_main_field_direction = mock.MagicMock( return_value='transverse') data_context = MuonDataContext(load_data=loaded_data) gui_context = MuonGuiContext() group_context = MuonGroupPairContext( data_context.check_group_contains_valid_detectors) phase_table_context = PhaseTableContext() fitting_context = FittingContext() return MuonContext(muon_data_context=data_context, muon_group_context=group_context, muon_gui_context=gui_context, muon_phase_context=phase_table_context, fitting_context=fitting_context)
def test_create_results_table_with_logs_missing_from_some_workspaces_raises( self): parameters = OrderedDict([('f0.Height', (100, 0.1))]) logs = [('log1', (1., 2.)), ('log2', (3., 4.)), ('log3', (4., 5.)), ('log4', (5., 6.))] fits_logs1 = create_test_fits(('ws1', ), 'func1', parameters, output_workspace_names=('ws1', )) add_logs(fits_logs1[0].input_workspaces[0], logs[:2]) fits_logs2 = create_test_fits(('ws2', ), 'func1', parameters, output_workspace_names=('ws2', )) add_logs(fits_logs2[0].input_workspaces[0], logs[2:]) model = ResultsTabModel(FittingContext(fits_logs1 + fits_logs2)) selected_results = [('ws1', 0), ('ws2', 1)] selected_logs = ['log1', 'log3'] self.assertRaises(RuntimeError, model.create_results_table, selected_logs, selected_results)
class FittingContextTest(GuiTest): def setUp(self): self.fitting_context = FittingContext() def test_context_constructor_accepts_fit_list(self): fit_list = [ FitInformation(mock.MagicMock(), 'MuonGuassOsc', mock.MagicMock(), mock.MagicMock()) ] context = FittingContext(fit_list) self.assertEqual(fit_list, context.fit_list) def test_len_gives_length_of_fit_list(self): self.assertEqual(0, len(self.fitting_context)) self.fitting_context.add_fit( FitInformation(mock.MagicMock(), 'MuonGuassOsc', mock.MagicMock(), mock.MagicMock())) self.assertEqual(1, len(self.fitting_context)) def test_items_can_be_added_to_fitting_context(self): fit_information_object = FitInformation(mock.MagicMock(), 'MuonGuassOsc', mock.MagicMock(), mock.MagicMock()) self.fitting_context.add_fit(fit_information_object) self.assertEqual(fit_information_object, self.fitting_context.fit_list[0]) def test_fitfunctions_gives_list_of_unique_function_names(self): test_fit_function = 'MuonGuassOsc' self.fitting_context.add_fit_from_values(mock.MagicMock(), test_fit_function, mock.MagicMock(), mock.MagicMock(), []) self.fitting_context.add_fit_from_values(mock.MagicMock(), test_fit_function, mock.MagicMock(), mock.MagicMock(), []) fit_functions = self.fitting_context.fit_function_names() self.assertEqual(len(fit_functions), 1) self.assertEqual(test_fit_function, fit_functions[0]) def test_can_add_fits_without_first_creating_fit_information_objects(self): parameter_workspace = mock.MagicMock() input_workspace = mock.MagicMock() output_workspace_names = mock.MagicMock() fit_function_name = 'MuonGuassOsc' fit_information_object = FitInformation(parameter_workspace, fit_function_name, input_workspace, output_workspace_names) self.fitting_context.add_fit_from_values(parameter_workspace, fit_function_name, input_workspace, output_workspace_names) self.assertEqual(fit_information_object, self.fitting_context.fit_list[0]) def test_can_add_fits_with_global_parameters_without_creating_fit_information( self): parameter_workspace = mock.MagicMock() input_workspace = mock.MagicMock() fit_function_name = 'MuonGuassOsc' global_params = ['A'] fit_information_object = FitInformation(parameter_workspace, fit_function_name, input_workspace, global_params) self.fitting_context.add_fit_from_values(parameter_workspace, fit_function_name, input_workspace, global_params) self.assertEqual(fit_information_object, self.fitting_context.fit_list[0]) def test_parameters_are_readonly(self): test_parameters = OrderedDict([('Height', (10., 0.4)), ('A0', (1, 0.01)), ('Cost function', (0.1, 0.))]) fit_params = create_test_fit_parameters(test_parameters) fit_info = FitInformation(fit_params._parameter_workspace, mock.MagicMock(), mock.MagicMock(), mock.MagicMock()) self.assertRaises(AttributeError, setattr, fit_info, "parameters", fit_params) def test_log_names_returns_logs_from_all_fits_by_default(self): time_series_logs = (('ts_1', (1., )), ('ts_2', (3., )), ('ts_3', [2.]), ('ts_4', [3.])) fake1 = create_test_workspace(ws_name='fake1', time_series_logs=time_series_logs[:2]) fake2 = create_test_workspace(ws_name='fake2', time_series_logs=time_series_logs[2:]) self.fitting_context.add_fit( FitInformation(mock.MagicMock(), 'func1', fake1.name(), fake1.name())) self.fitting_context.add_fit( FitInformation(mock.MagicMock(), 'func1', fake2.name(), fake2.name())) log_names = self.fitting_context.log_names() self.assertEqual(len(time_series_logs), len(log_names)) for name, _ in time_series_logs: self.assertTrue(name in log_names, msg="{} not found in log list".format(name)) def test_log_names_respects_filter(self): time_series_logs = (('ts_1', (1., )), ('ts_2', (3., )), ('ts_3', [2.]), ('ts_4', [3.])) fake1 = create_test_workspace(ws_name='fake1', time_series_logs=time_series_logs[:2]) fake2 = create_test_workspace(ws_name='fake2', time_series_logs=time_series_logs[2:]) self.fitting_context.add_fit( FitInformation(mock.MagicMock(), 'func1', fake1.name(), fake1.name())) self.fitting_context.add_fit( FitInformation(mock.MagicMock(), 'func1', fake2.name(), fake2.name())) required_logs = ('ts_2', 'ts_4') log_names = self.fitting_context.log_names( filter_fn=lambda log: log.name in required_logs) self.assertEqual(len(required_logs), len(log_names)) for name in required_logs: self.assertTrue(name in log_names, msg="{} not found in log list".format(name))
def __init__(self, parent=None): super(MuonAnalysisGui, self).__init__(parent) self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setFocusPolicy(QtCore.Qt.StrongFocus) self.setObjectName("MuonAnalysis2") self.current_tab = '' try: check_facility() except AttributeError as error: self.warning_popup(error.args[0]) # initialise the data storing classes of the interface self.loaded_data = MuonLoadData() self.data_context = MuonDataContext('Muon Data', self.loaded_data) self.gui_context = MuonGuiContext() self.group_pair_context = MuonGroupPairContext( self.data_context.check_group_contains_valid_detectors) self.phase_context = PhaseTableContext() self.fitting_context = FittingContext() self.context = DataAnalysisContext( muon_data_context=self.data_context, muon_gui_context=self.gui_context, muon_group_context=self.group_pair_context, fitting_context=self.fitting_context, muon_phase_context=self.phase_context) # create the Dockable plot widget self.fitting_tab = FittingTabWidget(self.context, self) self.plot_widget = PlotWidget( self.context, self.fitting_tab.fitting_tab_presenter.get_selected_fit_workspaces, parent=self) self.dockable_plot_widget_window = PlottingDockWidget( parent=self, plotting_widget=self.plot_widget.view) self.dockable_plot_widget_window.setMinimumWidth(575) # Add dock widget to main Muon analysis window self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dockable_plot_widget_window) # Need this line to stop the bug where the dock window snaps back to its original size after resizing. # 0 argument is arbitrary and has no effect on fit widget size # This is a qt bug reported at (https://bugreports.qt.io/browse/QTBUG-65592) if QT_VERSION >= LooseVersion("5.6"): self.resizeDocks({self.dockable_plot_widget_window}, {1}, QtCore.Qt.Horizontal) self.disable_notifier = GenericObservable() self.disable_observer = GenericObserver( self.disable_notifier.notify_subscribers) self.enable_notifier = GenericObservable() self.enable_observer = GenericObserver( self.enable_notifier.notify_subscribers) # set up other widgets self.load_widget = LoadWidget(self.loaded_data, self.context, self) self.home_tab = HomeTabWidget(self.context, self) self.grouping_tab_widget = GroupingTabWidget(self.context) self.phase_tab = PhaseTabWidget(self.context, self) self.seq_fitting_tab = SeqFittingTabWidget( self.context, self.fitting_tab.fitting_tab_model, self) self.results_tab = ResultsTabWidget(self.context.fitting_context, self.context, self) self.setup_tabs() self.help_widget = HelpWidget("Muon Analysis 2") central_widget = QtWidgets.QWidget() vertical_layout = QtWidgets.QVBoxLayout() vertical_layout.addWidget(self.load_widget.load_widget_view) vertical_layout.addWidget(self.tabs) vertical_layout.addWidget(self.help_widget.view) central_widget.setLayout(vertical_layout) self.setCentralWidget(central_widget) self.setWindowTitle(self.context.window_title) self.setup_load_observers() self.setup_gui_variable_observers() self.setup_grouping_changed_observers() self.setup_instrument_changed_notifier() self.setup_group_calculation_enable_notifier() self.setup_group_calculation_disabler_notifier() self.setup_on_load_enabler() self.setup_on_load_disabler() self.setup_phase_quad_changed_notifier() self.setup_phase_table_changed_notifier() self.setup_fitting_notifier() self.setup_on_recalulation_finished_notifier() self.context.data_context.message_notifier.add_subscriber( self.grouping_tab_widget.group_tab_presenter.message_observer) self.setup_disable_notifier() self.setup_enable_notifier()
def __init__(self, parent=None): super(MuonAnalysisGui, self).__init__(parent) self.setFocusPolicy(QtCore.Qt.StrongFocus) try: check_facility() except AttributeError as error: self.warning_popup(error.args[0]) # initialise the data storing classes of the interface self.loaded_data = MuonLoadData() self.data_context = MuonDataContext('Muon Data', self.loaded_data) self.gui_context = MuonGuiContext() self.group_pair_context = MuonGroupPairContext( self.data_context.check_group_contains_valid_detectors) self.phase_context = PhaseTableContext() self.fitting_context = FittingContext() self.context = MuonContext(muon_data_context=self.data_context, muon_gui_context=self.gui_context, muon_group_context=self.group_pair_context, muon_phase_context=self.phase_context, fitting_context=self.fitting_context, workspace_suffix=' MA') # create the dockable widget self.dockable_plot_widget = PlottingWidget(self.context) self.dockable_plot_widget_window = PlottingDockWidget( parent=self, plotting_widget=self.dockable_plot_widget.view) self.dockable_plot_widget_window.setMinimumWidth(575) # # add dock widget to main Muon analysis window self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dockable_plot_widget_window) # set up other widgets self.load_widget = LoadWidget(self.loaded_data, self.context, self) self.home_tab = HomeTabWidget(self.context, self) self.grouping_tab_widget = GroupingTabWidget(self.context) self.phase_tab = PhaseTabWidget(self.context, self) self.fitting_tab = FittingTabWidget(self.context, self) self.seq_fitting_tab = SeqFittingTabWidget( self.context, self.fitting_tab.fitting_tab_model, self) self.results_tab = ResultsTabWidget(self.context.fitting_context, self.context, self) self.setup_tabs() self.help_widget = HelpWidget("Muon Analysis 2") central_widget = QtWidgets.QWidget() vertical_layout = QtWidgets.QVBoxLayout() vertical_layout.addWidget(self.load_widget.load_widget_view) vertical_layout.addWidget(self.tabs) vertical_layout.addWidget(self.help_widget.view) central_widget.setLayout(vertical_layout) self.setCentralWidget(central_widget) self.setWindowTitle(self.context.window_title) self.setup_load_observers() self.setup_gui_variable_observers() self.setup_grouping_changed_observers() self.setup_instrument_changed_notifier() self.setup_group_calculation_enable_notifier() self.setup_group_calculation_disabler_notifier() self.setup_on_load_enabler() self.setup_on_load_disabler() self.setup_phase_quad_changed_notifier() self.setup_phase_table_changed_notifier() self.setup_fitting_notifier() self.setup_on_recalulation_finished_notifier() self.context.data_context.message_notifier.add_subscriber( self.grouping_tab_widget.group_tab_presenter.message_observer)
def __init__(self, parent=None): super(FrequencyAnalysisGui, self).__init__(parent) self.setFocusPolicy(QtCore.Qt.StrongFocus) try: check_facility() except AttributeError as error: self.warning_popup(error.args[0]) # initialise the data storing classes of the interface self.loaded_data = MuonLoadData() self.data_context = MuonDataContext('Frequency Domain Data', self.loaded_data) self.gui_context = MuonGuiContext() self.group_pair_context = MuonGroupPairContext( self.data_context.check_group_contains_valid_detectors) self.phase_context = PhaseTableContext() self.fitting_context = FittingContext() self.frequency_context = FrequencyContext() self.context = MuonContext(muon_data_context=self.data_context, muon_gui_context=self.gui_context, muon_group_context=self.group_pair_context, muon_phase_context=self.phase_context, fitting_context=self.fitting_context, workspace_suffix=' FD', frequency_context=self.frequency_context) # create the dockable widget self.plot_widget = PlotWidget(self.context) self.dockable_plot_widget_window = PlottingDockWidget( parent=self, plotting_widget=self.plot_widget.view) self.dockable_plot_widget_window.setMinimumWidth(575) # Add dock widget to main Muon analysis window self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dockable_plot_widget_window) # Need this line to stop the bug where the dock window snaps back to its original size after resizing. # This is a qt bug reported at (https://bugreports.qt.io/browse/QTBUG-65592) if QT_VERSION >= LooseVersion("5.6"): self.resizeDocks({self.dockable_plot_widget_window}, {40}, QtCore.Qt.Horizontal) # construct all the widgets. self.load_widget = LoadWidget(self.loaded_data, self.context, self) self.grouping_tab_widget = GroupingTabWidget(self.context) self.home_tab = HomeTabWidget(self.context, self) self.phase_tab = PhaseTabWidget(self.context, self) self.transform = TransformWidget(self.context, FFTWidget, MaxEntWidget, parent=self) self.fitting_tab = FittingTabWidget(self.context, self) self.results_tab = ResultsTabWidget(self.context.fitting_context, self.context, self) self.setup_tabs() self.help_widget = HelpWidget(self.context.window_title) central_widget = QtWidgets.QWidget() vertical_layout = QtWidgets.QVBoxLayout() vertical_layout.addWidget(self.load_widget.load_widget_view) vertical_layout.addWidget(self.tabs) vertical_layout.addWidget(self.help_widget.view) central_widget.setLayout(vertical_layout) self.setCentralWidget(central_widget) self.setWindowTitle(self.context.window_title) self.setup_load_observers() self.setup_gui_variable_observers() self.setup_grouping_changed_observers() self.setup_instrument_changed_notifier() self.setup_group_calculation_enable_notifier() self.setup_group_calculation_disabler_notifier() self.setup_on_load_enabler() self.setup_on_load_disabler() self.setup_phase_quad_changed_notifier() self.setup_phase_table_changed_notifier() self.setup_fitting_notifier() self.setup_on_recalculation_finished_notifier() self.transform.set_up_calculation_observers( self.fitting_tab.fitting_tab_presenter.enable_tab_observer, self.fitting_tab.fitting_tab_presenter.disable_tab_observer) self.transform.new_data_observer( self.fitting_tab.fitting_tab_presenter.input_workspace_observer) self.transform.new_data_observer( self.plot_widget.presenter.input_workspace_observer) self.context.data_context.message_notifier.add_subscriber( self.grouping_tab_widget.group_tab_presenter.message_observer)
def test_default_model_has_no_selected_function_without_fits(self): model = ResultsTabModel(FittingContext()) self.assertTrue(model.selected_fit_function() is None)
def test_updating_model_results_table_name(self): table_name = 'table_name' model = ResultsTabModel(FittingContext()) model.set_results_table_name(table_name) self.assertEqual(model.results_table_name(), table_name)
def test_default_model_has_results_table_name(self): model = ResultsTabModel(FittingContext()) self.assertEqual(model.results_table_name(), DEFAULT_TABLE_NAME)
def __init__(self, parent=None): super(FrequencyAnalysisGui, self).__init__(parent) self.setFocusPolicy(QtCore.Qt.StrongFocus) try: check_facility() except AttributeError as error: self.warning_popup(error.args[0]) # initialise the data storing classes of the interface self.loaded_data = MuonLoadData() self.data_context = MuonDataContext('Frequency Domain Data', self.loaded_data) self.gui_context = MuonGuiContext() self.group_pair_context = MuonGroupPairContext( self.data_context.check_group_contains_valid_detectors) self.phase_context = PhaseTableContext() self.fitting_context = FittingContext() self.context = MuonContext(muon_data_context=self.data_context, muon_gui_context=self.gui_context, muon_group_context=self.group_pair_context, muon_phase_context=self.phase_context, workspace_suffix=' FD', fitting_context=self.fitting_context) # construct all the widgets. self.load_widget = LoadWidget(self.loaded_data, self.context, self) self.grouping_tab_widget = GroupingTabWidget(self.context) self.home_tab = HomeTabWidget(self.context, self) self.phase_tab = PhaseTabWidget(self.context, self) self.transform = TransformWidget(self.context, FFTWidget, MaxEntWidget, parent=self) self.setup_tabs() self.help_widget = HelpWidget("Frequency Domain Analysis") central_widget = QtWidgets.QWidget() vertical_layout = QtWidgets.QVBoxLayout() vertical_layout.addWidget(self.load_widget.load_widget_view) vertical_layout.addWidget(self.tabs) vertical_layout.addWidget(self.help_widget.view) central_widget.setLayout(vertical_layout) self.setCentralWidget(central_widget) self.setWindowTitle("Frequency Domain Analysis") self.setup_load_observers() self.setup_gui_variable_observers() self.setup_alpha_recalculated_observers() self.setup_grouping_changed_observers() self.setup_instrument_changed_notifier() self.setup_group_calculation_enable_notifer() self.setup_group_calculation_disabler_notifer() self.setup_on_load_enabler() self.setup_on_load_disabler() self.setup_phase_quad_changed_notifer() self.setup_phase_table_changed_notifier() self.setup_on_recalulation_finished_notifer() self.context.data_context.message_notifier.add_subscriber( self.grouping_tab_widget.group_tab_presenter.message_observer)
def setUp(self): self.fitting_context = FittingContext()
def test_updating_model_selected_fit_function(self): model = ResultsTabModel(FittingContext()) new_selection = 'func2' model.set_selected_fit_function(new_selection) self.assertEqual(model.selected_fit_function(), new_selection)
def test_model_returns_no_log_selection_if_no_fits_present(self): model = ResultsTabModel(FittingContext()) self.assertEqual(0, len(model.log_selection({})))