def PyExec(self): xvals, flat_yvals, baseline, errors = self._load_data() # Find the index of the peaks given as input # This is necessary as the FindPeakAlgorithm can introduce offset in the data peakids = self._recentre_peak_position(xvals, flat_yvals) # Fit all the peaks and find the best parameters _, param = self.general_fit(xvals, flat_yvals, peakids) # Create table of peak positions peak_table = CreateEmptyTableWorkspace(StoreInADS=False) refit_peak_table = CreateEmptyTableWorkspace(StoreInADS=False) to_refit = self.parse_fit_table(param, peak_table, True) # Refit all the bad peaks by adding stronger constraints _, refitted_params = self.refit_peaks(to_refit) self.parse_fit_table(refitted_params, refit_peak_table, False) # Evaluate the total cost fit_cost = self._evaluate_final_cost(xvals, flat_yvals, baseline, errors, peak_table, refit_peak_table) self.setProperty('PeakProperties', peak_table) self.setProperty('RefitPeakProperties', refit_peak_table) self.setProperty('FitCost', fit_cost)
def test_evaluate_cost_returns_the_expected_value_with_poisson(self): peaks = [(35.2, 0.4), (25.03, 0.1), (10.03, 0.05)] peaks += [(20.003, 0.004), (75.15, 0.2), (5.2, 0.05)] params = [25.03, 35.2, 10.03, 75.15, 20.003, 5.2] fit_table = self.simulate_fit_parameter_output(peaks, 100.034) data_table = CreateEmptyTableWorkspace() refit_data_table = CreateEmptyTableWorkspace() _ = self.alg_instance.parse_fit_table(fit_table, data_table, refit=False) cost = self.alg_instance.evaluate_cost( self.x_values, self.data_ws.readY(0), self.data_ws.readY(1), self.data_ws.readE(0), peak_param=data_table, refit_peak_param=refit_data_table, use_poisson=True) model = self.alg_instance.multi_peak(params, self.x_values, np.zeros(len(self.x_values))) expected = self.alg_instance.poisson_cost( self.data_ws.readY(0) + self.data_ws.readY(1), model + self.data_ws.readY(1)) self.assertAlmostEqual(cost, expected, 3)
def setUp(self): # Creating two peaks on an exponential background with gaussian noise self.x_values = np.linspace(0, 100, 1001) self.centre = [25, 75] self.height = [35, 20] self.width = [10, 5] self.y_values = self.gaussian(self.x_values, self.centre[0], self.height[0], self.width[0]) self.y_values += self.gaussian(self.x_values, self.centre[1], self.height[1], self.width[1]) self.background = 10 * np.ones(len(self.x_values)) # Generating a table with a guess of the position of the centre of the peaks peak_table = CreateEmptyTableWorkspace() peak_table.addColumn(type='float', name='Approximated Centre') peak_table.addRow([self.centre[0] + 2]) peak_table.addRow([self.centre[1] - 3]) # Generating a workspace with the data and a flat background data_ws = CreateWorkspace( DataX=np.concatenate((self.x_values, self.x_values)), DataY=np.concatenate((self.y_values, self.background)), DataE=np.sqrt(np.concatenate((self.y_values, self.background))), NSpec=2) self.data_ws = data_ws self.peak_guess_table = peak_table self.alg_instance = _FitGaussianPeaks.FitGaussianPeaks() self.alg_instance.initialize()
def test_algorithm_estimates_fit_window(self): x_val = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22] y_val = [0, 0, 0, 0, 1, 7, 0, 0, 0, 0, 10, 7] ws = CreateWorkspace(x_val * 2, y_val + [0] * len(y_val), NSpec=2) table = CreateEmptyTableWorkspace() table.addColumn("float", "Centre") table.addRow([20]) with mock.patch( 'plugins.algorithms.WorkflowAlgorithms.FitGaussianPeaks.FitGaussianPeaks.' 'estimate_single_parameters') as mock_estimate_params: mock_estimate_params.return_value = None FitGaussianPeaks(InputWorkspace=ws, PeakGuessTable=table, EstimateFitWindow=True, FitWindowSize=11) centre_index = 10 """ win_size in this case is calculated from EstimatePeakSigma and is estimated to be 2 and FitWindowSize is ignored """ win_size = 2 arguements = mock_estimate_params.call_args_list[0][0] self.assertSequenceEqual(list(arguements[0]), x_val) self.assertSequenceEqual(list(arguements[1]), y_val) self.assertEqual(arguements[2], centre_index) self.assertEqual(arguements[3], win_size) self.assertEqual(len(arguements), 4)
def test_algorithm_uses_right_fit_window(self): x_val = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22] y_val = [0, 0, 0, 0, 1, 7, 0, 0, 0, 0, 10, 7] ws = CreateWorkspace(x_val * 2, y_val + [0] * len(y_val), NSpec=2) table = CreateEmptyTableWorkspace() table.addColumn("float", "Centre") table.addRow([20]) with mock.patch( 'plugins.algorithms.WorkflowAlgorithms.FitGaussianPeaks.FitGaussianPeaks.' 'estimate_single_parameters') as mock_estimate_params: mock_estimate_params.return_value = None FitGaussianPeaks(InputWorkspace=ws, PeakGuessTable=table, EstimateFitWindow=False, FitWindowSize=11) centre_index = 10 # win_size is ( FitWindowSize -1)/2 as method estimate_single_parameters expects in this form win_size = 5 arguements = mock_estimate_params.call_args_list[0][0] self.assertSequenceEqual(list(arguements[0]), x_val) self.assertSequenceEqual(list(arguements[1]), y_val) self.assertEqual(arguements[2], centre_index) self.assertEqual(arguements[3], win_size) self.assertEqual(len(arguements), 4)
def create_fit_tables(self): wslist = [] # ws to be grouped # extract fit parameters and errors nruns = len( self.get_loaded_ws_list()) # num of rows of output workspace # get unique set of function parameters across all workspaces func_params = set( chain(*[ list(d['results'].keys()) for d in self._fit_results.values() ])) for param in func_params: # get max number of repeated func in a model (num columns of output workspace) nfuncs = max([ len(d['results'][param]) for d in self._fit_results.values() if param in d['results'] ]) # make output workspace ipeak = list(range(1, nfuncs + 1)) * nruns ws = CreateWorkspace(OutputWorkspace=param, DataX=ipeak, DataY=ipeak, NSpec=nruns) # axis for labels in workspace axis = TextAxis.create(nruns) for iws, wsname in enumerate(self.get_active_ws_name_list()): if wsname in self._fit_results and param in self._fit_results[ wsname]['results']: fitvals = array( self._fit_results[wsname]['results'][param]) data = vstack( (fitvals, full((nfuncs - fitvals.shape[0], 2), nan))) else: data = full((nfuncs, 2), nan) ws.setY(iws, data[:, 0]) ws.setE(iws, data[:, 1]) # label row axis.setLabel(iws, wsname) ws.replaceAxis(1, axis) wslist += [ws] # table for model summary/info model = CreateEmptyTableWorkspace(OutputWorkspace='model') model.addColumn(type="str", name="Workspace") model.addColumn(type="float", name="chisq/DOF" ) # always is for LM minimiser (users can't change) model.addColumn(type="str", name="status") model.addColumn(type="str", name="Model") for iws, wsname in enumerate(self.get_active_ws_name_list()): if wsname in self._fit_results: row = [ wsname, self._fit_results[wsname]['costFunction'], self._fit_results[wsname]['status'], self._fit_results[wsname]['model'] ] self.write_table_row(model, row, iws) else: self.write_table_row(model, ['', nan, ''], iws) wslist += [model] group_name = self._log_workspaces.name().split('_log')[0] + '_fits' self._fit_workspaces = GroupWorkspaces(wslist, OutputWorkspace=group_name)
def action_copy_spectrum_to_table(self, table): selected_rows = [i.row() for i in table.selectionModel().selectedRows()] if not selected_rows: self.notify_no_selection_to_copy() return ws = table.model().ws table_ws = CreateEmptyTableWorkspace(OutputWorkspace=ws.name() + "_spectra") num_rows = ws.blocksize() table_ws.setRowCount(num_rows) for i, row in enumerate(selected_rows): table_ws.addColumn("double", "XS" + str(row)) table_ws.addColumn("double", "YS" + str(row)) table_ws.addColumn("double", "ES" + str(row)) col_x = 3 * i col_y = 3 * i + 1 col_e = 3 * i + 2 data_y = ws.readY(row) data_x = ws.readX(row) data_e = ws.readE(row) for j in range(num_rows): table_ws.setCell(j, col_x, data_x[j]) table_ws.setCell(j, col_y, data_y[j]) table_ws.setCell(j, col_e, data_e[j])
def action_copy_bin_to_table(self, table): selected_cols = [i.column() for i in table.selectionModel().selectedColumns()] if not selected_cols: self.notify_no_selection_to_copy() return ws = table.model().ws table_ws = CreateEmptyTableWorkspace(OutputWorkspace=ws.name() + "_bins") num_rows = ws.getNumberHistograms() table_ws.setRowCount(num_rows) table_ws.addColumn("double", "X") for i, col in enumerate(selected_cols): table_ws.addColumn("double", "YB" + str(col)) table_ws.addColumn("double", "YE" + str(col)) col_y = 2 * i + 1 col_e = 2 * i + 2 for j in range(num_rows): data_y = ws.readY(j) data_e = ws.readE(j) if i == 0: if ws.axes() > 1: table_ws.setCell(j, 0, ws.getAxis(1).getValue(j)) else: table_ws.setCell(j, 0, j) table_ws.setCell(j, col_y, data_y[col]) table_ws.setCell(j, col_e, data_e[col])
def PyExec(self): self.workspace = self.getProperty("InputWorkspace").value outws_name = self.getPropertyValue("OutputWorkspace") # create table and columns outws = CreateEmptyTableWorkspace(OutputWorkspace=outws_name) columns = ["PeakCentre", "PeakCentreError", "Sigma", "SigmaError", "Height", "HeightError", "chiSq"] nextrow = dict.fromkeys(["WorkspaceIndex"] + columns + ["FitStatus"]) outws.addColumn(type="int", name="WorkspaceIndex", plottype=1) # x for col in columns: outws.addColumn(type="double", name=col) outws.addColumn(type="str", name="FitStatus") nb_hist = self.workspace.getNumberHistograms() for idx in range(nb_hist): nextrow["WorkspaceIndex"] = idx result = self.do_fit_gaussian(idx) if not result: for col in columns: nextrow[col] = 0 nextrow["FitStatus"] = "failed" else: nextrow["FitStatus"] = result[0] nextrow["chiSq"] = result[1] ptable = result[3] for num in range(ptable.rowCount() - 1): row = ptable.row(num) name = row["Name"] nextrow[name] = row["Value"] nextrow[name+"Error"] = row["Error"] DeleteWorkspace(result.OutputParameters) DeleteWorkspace(result.OutputNormalisedCovarianceMatrix) outws.addRow(nextrow) self.setProperty("OutputWorkspace", outws) return
def live_monitor(self, input_ws, output_ws): """ :return: """ # Now get the data, read the first spectra spectra = input_ws.readY(0) # extract the first value from the array count = spectra[0] print(f'Total count: {count}') count = input_ws.getNumberEvents() # output it as a log message logger.notice("Total counts so far " + str(count)) # if my ouput workspace has not been created yet, create it. if not mtd.doesExist(output_ws): table = CreateEmptyTableWorkspace(OutputWorkspace=output_ws) table.setTitle("Event Rate History") table.addColumn("str", "Time") table.addColumn('str', 'EventsS') table.addColumn("int", "Events") table = mtd[output_ws] assert table
def test_that_show_normalised_covariance_matrix_will_not_raise_an_error( self): ws = CreateEmptyTableWorkspace() wrapper = StaticWorkspaceWrapper("CovarianceMatrix", ws) self.view.show_normalised_covariance_matrix(wrapper.workspace, wrapper.workspace_name)
def _get_calib_table(self, args): if self.CALIBTABLE in args: calib_table = args[self.CALIBTABLE] # ensure the correct type is passed # if a string was passed, transform it in mantid object if isinstance(calib_table, str): calib_table = mtd[calib_table] # check that calibTable has the expected form try: if not isinstance(calib_table, ITableWorkspace): raise 1 if calib_table.columnCount() != 2: raise 2 colNames = calib_table.getColumnNames() if colNames[0] != 'Detector ID' or colNames[ 1] != 'Detector Position': raise 3 except: raise RuntimeError( "Invalid type for {0}." "The expected type was ITableWorkspace with 2 columns(Detector ID and Detector Positions)" .format(self.CALIBTABLE)) else: return calib_table else: calib_table = CreateEmptyTableWorkspace( OutputWorkspace="CalibTable") # "Detector ID" column required by ApplyCalibration calib_table.addColumn(type="int", name="Detector ID") # "Detector Position" column required by ApplyCalibration calib_table.addColumn(type="V3D", name="Detector Position") return calib_table
def _get_output_peak(self, args, ideal_tube): delete_peak_table_after = False if self.OUTPUTPEAK in args: output_peak = args[self.OUTPUTPEAK] else: output_peak = False if isinstance(output_peak, ITableWorkspace): if output_peak.columnCount() < len(ideal_tube.getArray()): raise RuntimeError( "Wrong argument {0}. " "It expects a boolean flag, or a ITableWorksapce with columns (TubeId, Peak1,...," "PeakM) for M = number of peaks given in knownPositions". format(self.OUTPUTPEAK)) return output_peak, delete_peak_table_after else: if not output_peak: delete_peak_table_after = True # create the output peak table output_peak = CreateEmptyTableWorkspace( OutputWorkspace="PeakTable") output_peak.addColumn(type='str', name='TubeId') for i in range(len(ideal_tube.getArray())): output_peak.addColumn(type='float', name='Peak%d' % (i + 1)) return output_peak, delete_peak_table_after
def readCalibrationFile(table_name, in_path): """Read a calibration table from file This loads a calibration TableWorkspace from a CSV file. Example of usage: .. code-block:: python saveCalibration('CalibTable','/tmp/myCalibTable.txt') :param table_name: name to call the TableWorkspace :param in_path: the path to the calibration file """ DET = 'Detector ID' POS = 'Detector Position' re_float = re.compile(r"[+-]? *(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?") calibTable = CreateEmptyTableWorkspace(OutputWorkspace=table_name) calibTable.addColumn(type='int', name=DET) calibTable.addColumn(type='V3D', name=POS) with open(in_path, 'r') as file_p: for line in file_p: values = re.findall(re_float, line) if len(values) != 4: continue nextRow = { DET: int(values[0]), POS: V3D(float(values[1]), float(values[2]), float(values[3])) } calibTable.addRow(nextRow)
def _create_indexed_workspace(self, fractional_peaks, ndim, hklm): # Create table with the number of columns we need indexed = CreateEmptyTableWorkspace() names = fractional_peaks.getColumnNames() types = fractional_peaks.columnTypes() # Insert the extra columns for the addtional indicies for i in range(ndim - 3): names.insert(5 + i, 'm{}'.format(i + 1)) types.insert(5 + i, 'double') names = np.array(names) types = np.array(types) # Create columns in the table workspace for name, column_type in zip(names, types): indexed.addColumn(column_type, name) # Copy all columns from original workspace, ignoring HKLs column_data = [] idx = np.arange(0, names.size) hkl_mask = (idx < 5) | (idx > 4 + (ndim - 3)) for name in names[hkl_mask]: column_data.append(fractional_peaks.column(name)) # Insert the addtional HKL columns into the data for i, col in enumerate(hklm.T.tolist()): column_data.insert(i + 2, col) # Insert the columns into the table workspace for i in range(fractional_peaks.rowCount()): row = [column_data[j][i] for j in range(indexed.columnCount())] indexed.addRow(row) return indexed
def test_sample_tof(self): # creates table workspace with mock elastic peak positions and widths: table_ws = CreateEmptyTableWorkspace() table_ws.addColumn("float", "PeakCentre") table_ws.addColumn("float", "Sigma") for row in range(132): table_ws.addRow([1645.2, 15.0]) sampleProperties = { 'SampleMass': 2.93, 'FormulaUnitMass': 50.94, 'EPWidth': 15 } yig_calibration_file = "D7_YIG_calibration_TOF.xml" PolDiffILLReduction(Run='395639', ProcessAs='Sample', OutputWorkspace='sample_tof', SampleAndEnvironmentProperties=sampleProperties, SampleGeometry='None', OutputTreatment='Individual', InstrumentCalibration=yig_calibration_file, ElasticChannelsWorkspace='table_ws', MeasurementTechnique='TOF') self._check_output(mtd['sample_tof'], 339, 132, 2, 'Energy transfer', 'DeltaE', 'Spectrum', 'Label') self._check_process_flag(mtd['sample_tof'], 'Sample')
def generate_peak_guess_table(self, xvals, peakids): peak_table = CreateEmptyTableWorkspace(StoreInADS=False) peak_table.addColumn(type='float', name='centre') for peak_idx in sorted(peakids): peak_table.addRow([xvals[peak_idx]]) return peak_table
def mask_bank(bank_name: str, tubes_fit_success: np.ndarray, output_table: str) -> Optional[TableWorkspace]: r""" Creates a single-column `TableWorkspace` object containing the detector ID's of the unsuccessfully fitted tubes If all tubes were fit successfully, no `TableWorkspace` is created, and `None` is returned. :param bank_name: a string of the form 'bankI' where 'I' is a bank number :param tubes_fit_success: array of boolean containing a True/False entry for each tube, indicating wether the tube was successfully calibrated. :param output_table: name of the output TableWorkspace containing one column for detector ID from tubes not successfully calibrated. :raise AssertionError: the string bank_name does not follow the pattern 'bankI' where 'I' in an integer :return: name of the mask TableWorkspace. Returns `None` if no TableWorkspace is created. """ assert re.match(r'^bank\d+$', bank_name), 'The bank name must be of the form "bankI" where "I" in an integer' if False not in tubes_fit_success: return None # al tubes were fit successfully bank_number = bank_name[4:] # drop 'bank' from bank_name tube_numbers = 1 + np.where(tubes_fit_success == False)[0] # noqa E712 unsuccessfully fitted tube numbers tube_numbers = ','.join([str(n) for n in tube_numbers]) # failing tubes as a string detector_ids = MaskBTP(Instrument='CORELLI', Bank=bank_number, Tube=tube_numbers) table = CreateEmptyTableWorkspace(OutputWorkspace=output_table) table.addColumn('long64', 'Detector ID') [table.addRow([detector_id]) for detector_id in detector_ids.tolist()] if AnalysisDataService.doesExist('CORELLIMaskBTP'): DeleteWorkspaces(['CORELLIMaskBTP']) return mtd[output_table]
def test_that_current_normalised_covariance_matrix_will_return_a_statix_workspace_wrapper_when_a_fit_exists(self): ws = CreateEmptyTableWorkspace() wrapper = StaticWorkspaceWrapper("CovarianceMatrix", ws) self.model._get_normalised_covariance_matrix_for = mock.Mock(return_value=wrapper) covariance_wrapper = self.model.current_normalised_covariance_matrix() self.assertEqual(covariance_wrapper, wrapper)
def trim_calibration_table(input_workspace: InputTable, output_workspace: Optional[str] = None) -> TableWorkspace: r""" Discard trim the X and Z pixel coordinates, since we are only interested in the calibrated Y-coordinate :param input_workspace: :param output_workspace: :return: handle to the trimmed table workspace """ if output_workspace is None: output_workspace = str(input_workspace) # overwrite the input table # Extract detector ID's and Y-coordinates from the input table table = mtd[str(input_workspace)] detector_ids = table.column(0) y_coordinates = [v.Y() for v in table.column(1)] # create the (empty) trimmed table table_trimmed = CreateEmptyTableWorkspace(OutputWorkspace=output_workspace) table_trimmed.addColumn(type='int', name='Detector ID') table_trimmed.addColumn(type='double', name='Detector Y Coordinate') # fill the rows of the trimmed table for detector_id, y_coordinate in zip(detector_ids, y_coordinates): table_trimmed.addRow([detector_id, y_coordinate]) return table_trimmed
def setUp(self): # create sample workspace self.xmin = 2123.33867005 + 4005.75 self.xmax = 2123.33867005 + 7995.75 self._input_ws = CreateSampleWorkspace( Function="User Defined", UserDefinedFunction="name=LinearBackground, \ A0=0.3;name=Gaussian, PeakCentre=8190, Height=5, Sigma=75", NumBanks=2, BankPixelWidth=1, XMin=self.xmin, XMax=self.xmax, BinWidth=10.5, BankDistanceFromSample=4.0, SourceDistanceFromSample=1.4, OutputWorkspace="ws") lognames = "wavelength,TOF1" logvalues = "6.0,2123.33867005" AddSampleLogMultiple(self._input_ws, lognames, logvalues) # create EPP table self._table = CreateEmptyTableWorkspace(OutputWorkspace="epptable") self._table.addColumn(type="double", name="PeakCentre") table_row = {'PeakCentre': 8189.5} for i in range(2): self._table.addRow(table_row)
def make_runinfo_table(self): run_info = CreateEmptyTableWorkspace() run_info.addColumn(type="str", name="Instrument") run_info.addColumn(type="int", name="Run") run_info.addColumn(type="int", name="Bank") run_info.addColumn(type="float", name="uAmps") run_info.addColumn(type="str", name="Title") return run_info
def test_that_has_normalised_covariance_matrix_returns_true_when_there_is_not_a_covariance_matrix( self): ws = CreateEmptyTableWorkspace() wrapper = StaticWorkspaceWrapper("CovarianceMatrix", ws) self.model._get_normalised_covariance_matrix_for = mock.Mock( return_value=wrapper) self.assertTrue(self.model.has_normalised_covariance_matrix())
def test_gui_updated_when_column_removed(self): ws = CreateEmptyTableWorkspace() ws.addColumn("double", "test_col") presenter = TableWorkspaceDisplay(ws) ws.removeColumn('test_col') self.assertEqual(0, presenter.view.columnCount())
def init_corelli_table(name: Optional[str] = None, table_type='calibration') -> TableWorkspace: """ Function that initializes a Corelli calibration TableWorkspace columns """ table: TableWorkspace = CreateEmptyTableWorkspace( OutputWorkspace=name) if name else CreateEmptyTableWorkspace() # expected columns declarations (column_type, column_name) for each type of calibration table column_declarations = { 'calibration': [('int', 'Detector ID'), ('double', 'Detector Y Coordinate')], 'mask': [('int', 'Detector ID')] } for column_type, colum_name in column_declarations[table_type]: table.addColumn(type=column_type, name=colum_name) return table
def create_log_table(self): # run information table run_info = CreateEmptyTableWorkspace() run_info.addColumn(type="str", name="Instrument") run_info.addColumn(type="int", name="Run") run_info.addColumn(type="int", name="Bank") run_info.addColumn(type="float", name="uAmps") run_info.addColumn(type="str", name="Title") self._log_workspaces = GroupWorkspaces([run_info], OutputWorkspace='logs') # a table per logs logs = get_setting(path_handling.INTERFACES_SETTINGS_GROUP, path_handling.ENGINEERING_PREFIX, "logs") if logs: for log in logs.split(','): ws = CreateEmptyTableWorkspace(OutputWorkspace=log) ws.addColumn(type="float", name="avg") ws.addColumn(type="float", name="stdev") self._log_workspaces.add(log)
def test_has_valid_columns(self): corelli_table = init_corelli_table() self.assertEqual(has_valid_columns(corelli_table), True) table_incomplete: TableWorkspace = CreateEmptyTableWorkspace() table_incomplete.addColumn(type="int", name="Detector ID") self.assertEqual(has_valid_columns(table_incomplete), False)
def _createFakePeakPositionTable(self, peakPos): """Create a peak position TableWorkspace with a single column for peakPos.""" tableName = self._names.withSuffix('peak_position_table') table = CreateEmptyTableWorkspace(OutputWorkspace=tableName, EnableLogging=self._subalgLogging) table.addColumn('double', 'PeakCentre') table.addRow((peakPos, )) return table
def test_1d_plots_with_unplottable_type_raises_attributeerror(self): table = CreateEmptyTableWorkspace() _, ax = plt.subplots() self.assertRaises(AttributeError, funcs.plot, ax, table, wkspIndex=0) self.assertRaises(AttributeError, funcs.errorbar, ax, table, wkspIndex=0)
def create_output_table(centre1, centre2): Centre_position = CreateEmptyTableWorkspace() Centre_position.addColumn(type="double", name="X Centre Position") Centre_position.addColumn(type="double", name="Y Centre Position") Centre_position.addRow({ "X Centre Position": centre1, "Y Centre Position": centre2 })