def setUp(self): # patch away getting a real icon as it can hit a race condition when running tests # in parallel patcher = mock.patch('mantidqt.dialogs.spectraselectordialog.get_icon') self._mock_get_icon = patcher.start() self._mock_get_icon.return_value = QIcon() self.addCleanup(patcher.stop) if self._single_spec_ws is None: self.__class__._single_spec_ws = WorkspaceFactory.Instance().create("Workspace2D", NVectors=1, XLength=1, YLength=1) self.__class__._multi_spec_ws = WorkspaceFactory.Instance().create("Workspace2D", NVectors=200, XLength=1, YLength=1)
def setUp(self): if self._test_ws is None: self.__class__._test_ws = WorkspaceFactory.Instance().create( "Workspace2D", NVectors=2, YLength=5, XLength=5) if self._test_ws_2 is None: self.__class__._test_ws_2 = WorkspaceFactory.Instance().create( "Workspace2D", NVectors=2, YLength=5, XLength=5) AnalysisDataService.addOrReplace('test_ws', self._test_ws) AnalysisDataService.addOrReplace('test_ws_2', self._test_ws_2) self.get_spectra_selection_patcher = mock.patch('mantidqt.plotting.functions.get_spectra_selection') self.addCleanup(self.get_spectra_selection_patcher.stop) self.get_spectra_selection_mock = self.get_spectra_selection_patcher.start()
def test_get_spectra_selection_removes_wrong_workspace_types_from_list( self): table = WorkspaceFactory.Instance().createTable() workspaces = [self._single_spec_ws, table] self.assertEqual( get_spectra_selection(workspaces).workspaces, [self._single_spec_ws])
def test_construction_with_non_MatrixWorkspace_type_removes_non_MatrixWorkspaces_from_list( self): table = WorkspaceFactory.Instance().createTable() workspaces = [self._single_spec_ws, table] ssd = SpectraSelectionDialog(workspaces) spectraselectordialog.RED_ASTERISK = None self.assertEqual(ssd._workspaces, [self._single_spec_ws])
def test_fit_result_matrix_workspace_in_browser_is_viewed_when_clicked( self): if not PYQT5: self.skipTest( "MatrixWorkspaceDisplay and TableWorkspaceDisplay cannot be " "imported in qt4 so the test fails with an error.") from mantidqt.widgets.workspacedisplay.matrix.presenter import MatrixWorkspaceDisplay name = "ws" fig, canvas = self._create_and_plot_matrix_workspace(name) property_browser = self._create_widget(canvas=canvas) property_browser.setOutputName(name) # create fake fit output results matrixWorkspace = WorkspaceFactory.Instance().create("Workspace2D", NVectors=3, YLength=5, XLength=5) AnalysisDataService.Instance().addOrReplace(name + "_Workspace", matrixWorkspace) property_browser.fitting_done_slot(name + "_Workspace") wsList = property_browser.getWorkspaceList() # click on matrix workspace MatrixWorkspaceDisplay.show_view = Mock() item = wsList.item(0).text() property_browser.workspaceClicked.emit(item) self.assertEqual(1, MatrixWorkspaceDisplay.show_view.call_count)
def test_filling_workspace_details_multiple_workspaces_of_different_sizes(self): cropped_ws = WorkspaceFactory.Instance().create("Workspace2D", NVectors=50, XLength=1, YLength=1) for i in range(cropped_ws.getNumberHistograms()): cropped_ws.getSpectrum(i).setSpectrumNo(51 + i) dlg = SpectraSelectionDialog([cropped_ws, self._multi_spec_ws]) self.assertEqual("valid range: 51-100", dlg._ui.specNums.placeholderText()) self.assertEqual("valid range: 0-49", dlg._ui.wkspIndices.placeholderText())
def test_fit_curves_removed_when_workspaces_deleted(self): fig, canvas, _ = self._create_and_plot_matrix_workspace(name="ws") property_browser = self._create_widget(canvas=canvas) manager_mock = Mock() manager_mock.canvas = canvas observer = FigureManagerADSObserver(manager=manager_mock) # noqa: F841 for plot_diff in [True, False]: # create fake fit output results matrixWorkspace = WorkspaceFactory.Instance().create("Workspace2D", NVectors=3, YLength=5, XLength=5) tableWorkspace = WorkspaceFactory.createTable() AnalysisDataService.Instance().addOrReplace("ws_Workspace", matrixWorkspace) AnalysisDataService.Instance().addOrReplace("ws_Parameters", tableWorkspace) AnalysisDataService.Instance().addOrReplace("ws_NormalisedCovarianceMatrix", tableWorkspace) property_browser.plotDiff = Mock(return_value=plot_diff) property_browser.fitting_done_slot("ws_Workspace") if plot_diff: self.assertEqual(3, len(fig.get_axes()[0].lines)) else: self.assertEqual(2, len(fig.get_axes()[0].lines)) AnalysisDataService.Instance().remove("ws_Workspace") AnalysisDataService.Instance().remove("ws_Parameters") AnalysisDataService.Instance().remove("ws_NormalisedCovarianceMatrix") self.assertEqual(1, len(fig.get_axes()[0].lines))
def test_fit_result_workspaces_are_added_to_browser_when_fitting_done( self): name = "ws" fig, canvas, _ = self._create_and_plot_matrix_workspace(name) property_browser = self._create_widget(canvas=canvas) property_browser.setOutputName(name) # create fake fit output results matrixWorkspace = WorkspaceFactory.Instance().create("Workspace2D", NVectors=3, YLength=5, XLength=5) tableWorkspace = WorkspaceFactory.createTable() AnalysisDataService.Instance().addOrReplace(name + "_Workspace", matrixWorkspace) AnalysisDataService.Instance().addOrReplace(name + "_Parameters", tableWorkspace) AnalysisDataService.Instance().addOrReplace( name + "_NormalisedCovarianceMatrix", tableWorkspace) property_browser.fitting_done_slot(name + "_Workspace") workspaceList = property_browser.getWorkspaceList() self.assertEqual(3, workspaceList.count()) self.assertEqual(name + "_NormalisedCovarianceMatrix", workspaceList.item(0).text()) self.assertEqual(name + "_Parameters", workspaceList.item(1).text()) self.assertEqual(name + "_Workspace", workspaceList.item(2).text())
def test_fit_result_matrix_workspace_in_browser_is_viewed_when_clicked( self): from mantidqt.widgets.workspacedisplay.table.presenter import TableWorkspaceDisplay name = "ws" fig, canvas, _ = self._create_and_plot_matrix_workspace(name) property_browser = self._create_widget(canvas=canvas) property_browser.setOutputName(name) # create fake fit output results matrixWorkspace = WorkspaceFactory.Instance().create("Workspace2D", NVectors=3, YLength=5, XLength=5) AnalysisDataService.Instance().addOrReplace(name + "_Workspace", matrixWorkspace) tableWorkspace = WorkspaceFactory.createTable() AnalysisDataService.Instance().addOrReplace(name + "_Parameters", tableWorkspace) property_browser.fitting_done_slot(name + "_Workspace") wsList = property_browser.getWorkspaceList() TableWorkspaceDisplay.show_view = Mock() # click on table workspace item = wsList.item(0).text() property_browser.workspaceClicked.emit(item) self.assertEqual(1, TableWorkspaceDisplay.show_view.call_count)
def test_pcolormesh_from_names_with_non_plottable_workspaces_returns_None( self): table = WorkspaceFactory.Instance().createTable() table_name = 'test_pcolormesh_from_names_with_non_plottable_workspaces_returns_None' AnalysisDataService.Instance().addOrReplace(table_name, table) result = pcolormesh_from_names([table_name]) self.assertEqual(result, None)
def _create_and_plot_matrix_workspace(self, name="workspace"): ws = WorkspaceFactory.Instance().create("Workspace2D", NVectors=2, YLength=5, XLength=5) AnalysisDataService.Instance().addOrReplace(name, ws) fig = plot([ws], spectrum_nums=[1]) canvas = fig.canvas return fig, canvas
def _create_empty_results_table(self, log_selection, results_selection, all_fits): """ Create an empty table workspace to store the results. :param log_selection: See create_results_table :param results_selection: See create_results_table :return: A new TableWorkspace """ table = WorkspaceFactory.Instance().createTable() table.addColumn('str', 'workspace_name', TableColumnType.NoType.value) def float_log(wksp_name, log_name): try: run = ads.Instance().retrieve(wksp_name).run() prop = run.getProperty(log_name) if isinstance(prop, FloatTimeSeriesProperty): return True try: float(prop.value) return True except ValueError: return False except (TypeError, ValueError): for fit in all_fits: for input_workspace in fit.input_workspaces: ws = ads.Instance().retrieve(input_workspace) if ws.run().hasProperty(log_name): return float_log(input_workspace, log_name) for log_name in log_selection: wksp_name = all_fits[0].input_workspaces[0] if log_name in ['run_start', 'run_end']: table.addColumn('str', log_name, TableColumnType.X.value) table.addColumn('float', log_name + '_seconds', TableColumnType.X.value) else: if float_log(wksp_name, log_name): table.addColumn('float', log_name, TableColumnType.X.value) # only add the errors column if the value is numerical table.addColumn('float', _error_column_name(log_name), TableColumnType.XErr.value) else: table.addColumn('str', log_name, TableColumnType.X.value) # assume all fit functions are the same in fit_selection and take # the parameter names from the first fit. parameters = self._find_parameters_for_table(results_selection) for name in parameters.names(): table.addColumn('float', name, TableColumnType.Y.value) if _param_error_should_be_displayed(name): table.addColumn('float', _error_column_name(name), TableColumnType.YErr.value) # The error column will be the most recent one added (columnCount-1) and is corresponding value will be # the second to last (columnCount-2). table.setLinkedYCol(table.columnCount() - 1, table.columnCount() - 2) return table
def _create_parameter_workspace(num_spec, param_table): num_params = param_table.rowCount() param_workspace = WorkspaceFactory.Instance().create( "Workspace2D", num_params, num_spec, num_spec) x_axis = TextAxis.create(num_spec) param_workspace.replaceAxis(0, x_axis) y_axis = TextAxis.create(num_params) for idx, parameter_name in enumerate(param_table.column('Name')): y_axis.setLabel(idx, parameter_name) param_workspace.replaceAxis(1, y_axis) return param_workspace
def _create_workspace_for_group_plot( plot_type: SpectraSelection, workspaces: List[Workspace], plot_index: int, log_name: str, custom_log_values: List[float]) -> MatrixWorkspace: _validate_workspace_choices(workspaces, plot_index) number_of_workspaces = len(workspaces) first_ws = workspaces[0] first_blocksize = first_ws.blocksize() if plot_type == SpectraSelection.Contour: x_size = first_blocksize + 1 else: x_size = first_blocksize matrix_ws = WorkspaceFactory.Instance().create( parent=first_ws, NVectors=number_of_workspaces, XLength=x_size, YLength=first_blocksize) matrix_ws.setYUnitLabel(first_ws.YUnitLabel()) log_values = [] for i in range(number_of_workspaces): ws = workspaces[i] if isinstance(ws, MatrixWorkspace): if plot_type == SpectraSelection.Contour: matrix_ws.applyBinEdgesFromAnotherWorkspace(ws, plot_index, i) else: matrix_ws.applyPointsFromAnotherWorkspace(ws, plot_index, i) matrix_ws.setY(i, ws.readY(plot_index)) matrix_ws.setE(i, ws.readE(plot_index)) if log_name == "Custom": log_values.append( get_single_workspace_log_value( i, log_values=custom_log_values)) else: log_values.append( get_single_workspace_log_value(i, matrix_ws=ws, log_name=log_name)) log_values_axis = NumericAxis.create(len(log_values)) for i in range(len(log_values)): log_values_axis.setValue(i, log_values[i]) matrix_ws.replaceAxis(1, log_values_axis) return matrix_ws
def setUp(self): # patch away getting a real icon as it can hit a race condition when running tests # in parallel patcher = mock.patch('mantidqt.dialogs.spectraselectordialog.get_icon') self._mock_get_icon = patcher.start() self._mock_get_icon.return_value = QIcon() self.addCleanup(patcher.stop) if self._single_spec_ws is None: self.__class__._single_spec_ws = WorkspaceFactory.Instance( ).create("Workspace2D", NVectors=1, XLength=1, YLength=1) self.__class__._multi_spec_ws = WorkspaceFactory.Instance().create( "Workspace2D", NVectors=200, XLength=1, YLength=1) SpectraSelectionDialog._check_number_of_plots = mock.Mock( return_value=True) spectraselectordialog.RED_ASTERISK = None # replaceWidget doesn't exist in Qt4 replace_widget_patcher = mock.patch.object(QVBoxLayout, 'replaceWidget', create=True) replace_widget_patcher.start() self.addCleanup(replace_widget_patcher.stop)
def setUp(self): if self._test_ws is None: self.__class__._test_ws = WorkspaceFactory.Instance().create( "Workspace2D", NVectors=2, YLength=5, XLength=5) if self._test_md_ws is None: self._test_md_ws = CreateMDHistoWorkspace( SignalInput='1,2,3,4,2,1', ErrorInput='1,1,1,1,1,1', Dimensionality=3, Extents='-1,1,-1,1,0.5,6.5', NumberOfBins='1,1,6', Names='x,y,|Q|', Units='mm,km,AA^-1', OutputWorkspace='test_plot_md_from_names_ws')
def test_filling_workspace_details_multiple_workspace_with_spectra_gaps( self): gappy_ws = WorkspaceFactory.Instance().create("Workspace2D", NVectors=50, XLength=1, YLength=1) for i in range(20): gappy_ws.getSpectrum(i).setSpectrumNo(1 + i) for i in range(20, gappy_ws.getNumberHistograms()): gappy_ws.getSpectrum(i).setSpectrumNo(161 + i) dlg = SpectraSelectionDialog([gappy_ws, self._multi_spec_ws]) self.assertEqual("valid range: 1-20, 181-200", dlg._ui.specNums.placeholderText()) self.assertEqual("valid range: 0-49", dlg._ui.wkspIndices.placeholderText())
def test_output_workspace_name_changes_if_more_than_one_plot_of_same_workspace(self, figure_labels_mock): # create a workspace ws = WorkspaceFactory.Instance().create("Workspace2D", NVectors=2, YLength=5, XLength=5) AnalysisDataService.Instance().addOrReplace("workspace", ws) ws_window_names = ["workspace-1", "workspace-2"] figure_labels_mock.return_value = ws_window_names output_name = [] # plot it twice for i in [0, 1]: fig = plot([ws], spectrum_nums=[1]) fig.canvas.get_window_title = Mock(return_value=ws_window_names[i]) browser = self._create_widget(canvas=fig.canvas) # don't want the widget to actually show in test QDockWidget.show = Mock() browser.show() output_name.append(browser.outputName()) self.assertNotEqual(output_name[0], output_name[1])
def test_workspaces_removed_from_workspace_list_widget_if_deleted_from_ADS(self): name = "ws" fig, canvas_mock, _ = self._create_and_plot_matrix_workspace(name) property_browser = self._create_widget(canvas=canvas_mock) property_browser.setOutputName(name) # create fake fit output results matrixWorkspace = WorkspaceFactory.Instance().create("Workspace2D", NVectors=3, YLength=5, XLength=5) AnalysisDataService.Instance().addOrReplace(name + "_Workspace", matrixWorkspace) tableWorkspace = WorkspaceFactory.createTable() AnalysisDataService.Instance().addOrReplace(name + "_Parameters", tableWorkspace) property_browser.fitting_done_slot(name + "_Workspace") AnalysisDataService.Instance().remove(name + "_Parameters") property_browser.postDeleteHandle(name + "_Parameters") wsList = property_browser.getWorkspaceList() self.assertEqual(1, len(wsList))
def _create_empty_results_table(self, log_selection, results_selection, all_fits): """ Create an empty table workspace to store the results. :param log_selection: See create_results_table :param results_selection: See create_results_table :return: A new TableWorkspace """ table = WorkspaceFactory.Instance().createTable() table.addColumn('str', 'workspace_name', TableColumnType.NoType.value) def float_log(wksp_name, log_name): try: run = ads.Instance().retrieve(wksp_name).run() prop = run.getProperty(log_name) if isinstance(prop, FloatTimeSeriesProperty): return True try: float(prop.value) return True except ValueError: return False except (TypeError, ValueError): for fit in all_fits: for input_workspace in fit.input_workspaces: ws = ads.Instance().retrieve(input_workspace) if ws.run().hasProperty(log_name): return float_log(input_workspace, log_name) for log_name in log_selection: wksp_name = all_fits[0].input_workspaces[0] if float_log(wksp_name, log_name): table.addColumn('float', log_name, TableColumnType.X.value) else: table.addColumn('str', log_name, TableColumnType.X.value) # assume all fit functions are the same in fit_selection and take # the parameter names from the first fit. parameters = self._find_parameters_for_table(results_selection) for name in parameters.names(): table.addColumn('float', name, TableColumnType.Y.value) if _param_error_should_be_displayed(name): table.addColumn('float', _error_column_name(name), TableColumnType.YErr.value) return table
def test_filling_workspace_details_single_workspace_with_spectra_gaps( self): gappy_ws = WorkspaceFactory.Instance().create("Workspace2D", NVectors=50, XLength=1, YLength=1) for i in range(10): gappy_ws.getSpectrum(i).setSpectrumNo(1 + i) for i in range(10, 16): gappy_ws.getSpectrum(i).setSpectrumNo(1 + (2 * i)) for i in range(17, 20): gappy_ws.getSpectrum(i).setSpectrumNo(1 + i) for i in range(20, gappy_ws.getNumberHistograms()): gappy_ws.getSpectrum(i).setSpectrumNo(51 + i) dlg = SpectraSelectionDialog([gappy_ws]) self.assertEqual( "valid range: 1-10, 17-21, 23, 25, 27, 29, 31, 71-100", dlg._ui.specNums.placeholderText()) self.assertEqual("valid range: 0-49", dlg._ui.wkspIndices.placeholderText())
def test_changes_apply_to_all_colorfill_plots_if_one_colorbar(self): ws = WorkspaceFactory.Instance().create("Workspace2D", NVectors=1, YLength=5, XLength=5) fig = pcolormesh([ws, ws]) # there should be 3 axes: 2 colorfill plots and 1 colorbar self.assertEqual(3, len(fig.axes)) colorbarEditor = ColorbarAxisEditor(fig.canvas, fig.axes[2]) min_value = 1.0 max_value = 2.0 colorbarEditor.ui.editor_min.text = MagicMock(return_value=min_value) colorbarEditor.ui.editor_max.text = MagicMock(return_value=max_value) colorbarEditor.ui.logBox.isChecked = MagicMock(return_value=True) colorbarEditor.changes_accepted() for ax in range(2): self.assertEqual(min_value, fig.axes[ax].collections[0].norm.vmin) self.assertEqual(max_value, fig.axes[ax].collections[0].norm.vmax) self.assertTrue(isinstance(fig.axes[ax].collections[0].norm, LogNorm))
def _create_empty_results_table(self, log_selection, results_selection): """ Create an empty table workspace to store the results. :param log_selection: See create_results_table :param results_selection: See create_results_table :return: A new TableWorkspace """ table = WorkspaceFactory.Instance().createTable() table.addColumn('str', 'workspace_name', TableColumnType.NoType.value) for log_name in log_selection: table.addColumn('float', log_name, TableColumnType.X.value) # assume all fit functions are the same in fit_selection and take # the parameter names from the first fit. parameters = self._find_parameters_for_table(results_selection) for name in parameters.names(): table.addColumn('float', name, TableColumnType.Y.value) if _param_error_should_be_displayed(name): table.addColumn('float', _error_column_name(name), TableColumnType.YErr.value) return table
def test_get_spectra_selection_raises_error_with_wrong_workspace_type(self): table = WorkspaceFactory.Instance().createTable() self.assertRaises(ValueError, get_spectra_selection, [self._single_spec_ws, table])
def setUp(self): if self._test_ws is None: self.__class__._test_ws = WorkspaceFactory.Instance().create( "Workspace2D", NVectors=2, YLength=5, XLength=5)
def test_plot_from_names_with_non_plottable_workspaces_returns_None(self): table = WorkspaceFactory.Instance().createTable() table_name = 'test_plot_from_names_with_non_plottable_workspaces_returns_None' AnalysisDataService.Instance().addOrReplace(table_name, table) result = plot_from_names([table_name], errors=False, overplot=False) self.assertTrue(result is None)
def test_construction_with_non_MatrixWorkspace_type_raises_exception(self): table = WorkspaceFactory.Instance().createTable() self.assertRaises(ValueError, SpectraSelectionDialog, [self._single_spec_ws, table])
def PyExec(self): workflow_prog = Progress(self, start=0.0, end=0.3, nreports=4) workflow_prog.report('Setting up algorithm') self._setup() input_ws = mtd[self._sample] min_spectrum_index = input_ws.getIndexFromSpectrumNumber( int(self._spectra_range[0])) max_spectrum_index = input_ws.getIndexFromSpectrumNumber( int(self._spectra_range[1])) # Crop to the required spectra range workflow_prog.report('Cropping Workspace') cropped_input = ms.CropWorkspace( InputWorkspace=input_ws, OutputWorkspace='__symm', StartWorkspaceIndex=min_spectrum_index, EndWorkspaceIndex=max_spectrum_index) # Find the smallest data array in the first spectra len_x = len(cropped_input.readX(0)) len_y = len(cropped_input.readY(0)) len_e = len(cropped_input.readE(0)) sample_array_len = min(len_x, len_y, len_e) sample_x = cropped_input.readX(0) # Get slice bounds of array try: workflow_prog.report('Calculating array points') self._calculate_array_points(sample_x, sample_array_len) except Exception as exc: raise RuntimeError( 'Failed to calculate array slice boundaries: %s' % exc.message) max_sample_index = sample_array_len - 1 centre_range_len = self._positive_min_index + self._negative_min_index positive_diff_range_len = max_sample_index - self._positive_max_index output_cut_index = max_sample_index - self._positive_min_index - positive_diff_range_len - 1 new_array_len = 2 * max_sample_index - centre_range_len - 2 * positive_diff_range_len - 1 logger.information('Sample array length = %d' % sample_array_len) logger.information( 'Positive X min at i=%d, x=%f' % (self._positive_min_index, sample_x[self._positive_min_index])) logger.information( 'Negative X min at i=%d, x=%f' % (self._negative_min_index, sample_x[self._negative_min_index])) logger.information( 'Positive X max at i=%d, x=%f' % (self._positive_max_index, sample_x[self._positive_max_index])) logger.information('New array length = %d' % new_array_len) logger.information('Output array LR split index = %d' % output_cut_index) # Create an empty workspace with enough storage for the new data workflow_prog.report('Creating OutputWorkspace') out_ws = WorkspaceFactory.Instance().create( cropped_input, cropped_input.getNumberHistograms(), int(new_array_len), int(new_array_len)) # For each spectrum copy positive values to the negative pop_prog = Progress(self, start=0.3, end=0.95, nreports=out_ws.getNumberHistograms()) for idx in range(out_ws.getNumberHistograms()): pop_prog.report('Populating data in workspace %i' % idx) # Strip any additional array cells x_in = cropped_input.readX(idx)[:sample_array_len] y_in = cropped_input.readY(idx)[:sample_array_len] e_in = cropped_input.readE(idx)[:sample_array_len] # Get some zeroed data to overwrite with copies from sample x_out = np.zeros(new_array_len) y_out = np.zeros(new_array_len) e_out = np.zeros(new_array_len) # Left hand side (reflected) x_out[:output_cut_index] = -x_in[self._positive_max_index - 1:self._positive_min_index:-1] y_out[:output_cut_index] = y_in[self._positive_max_index - 1:self._positive_min_index:-1] e_out[:output_cut_index] = e_in[self._positive_max_index - 1:self._positive_min_index:-1] # Right hand side (copied) x_out[output_cut_index:] = x_in[self._negative_min_index:self. _positive_max_index] y_out[output_cut_index:] = y_in[self._negative_min_index:self. _positive_max_index] e_out[output_cut_index:] = e_in[self._negative_min_index:self. _positive_max_index] # Set output spectrum data out_ws.setX(idx, x_out) out_ws.setY(idx, y_out) out_ws.setE(idx, e_out) logger.information('Symmetrise spectrum %d' % idx) end_prog = Progress(self, start=0.95, end=1.0, nreports=3) end_prog.report('Deleting temp workspaces') ms.DeleteWorkspace(cropped_input) if self._props_output_workspace != '': end_prog.report('Generating property table') self._generate_props_table() self.setProperty('OutputWorkspace', out_ws) end_prog.report('Algorithm Complete')