def PyExec(self): # Get peaks in dSpacing from file, and check we have what we need, before doing anything expected_peaks_d = EnggUtils.read_in_expected_peaks(self.getPropertyValue("ExpectedPeaksFromFile"), self.getProperty('ExpectedPeaks').value) if len(expected_peaks_d) < 1: raise ValueError("Cannot run this algorithm without any input expected peaks") in_wks = self.getProperty('Workspace').value wks_indices = EnggUtils.get_ws_indices_from_input_properties(in_wks, self.getProperty('Bank').value, self.getProperty(self.INDICES_PROP_NAME).value) van_wks = self.getProperty("VanadiumWorkspace").value van_integ_wks = self.getProperty('VanIntegrationWorkspace').value van_curves_wks = self.getProperty('VanCurvesWorkspace').value # These corrections rely on ToF<->Dspacing conversions, so ideally they'd be done after the # calibration step, which creates a cycle / chicken-and-egg issue. EnggUtils.apply_vanadium_corrections(self, in_wks, wks_indices, van_wks, van_integ_wks, van_curves_wks) rebinned_ws = self._prepare_ws_for_fitting(in_wks, self.getProperty('RebinBinWidth').value) pos_tbl, peaks_tbl = self._calculate_calib_positions_tbl(rebinned_ws, wks_indices, expected_peaks_d) # Produce 2 results: 'output table' and 'apply calibration' + (optional) calibration file self.setProperty("OutDetPosTable", pos_tbl) self.setProperty("FittedPeaks", peaks_tbl) self._apply_calibration_table(in_wks, pos_tbl) self._output_det_pos_file(self.getPropertyValue('OutDetPosFilename'), pos_tbl)
def _fitCurvesPerBank(self, vanWS, banks, spline_breaks): """ Fits one curve to every bank (where for every bank the data fitted is the result of summing up all the spectra of the bank). The fitting is done in d-spacing. @param vanWS :: Vanadium run workspace to fit, expected in TOF units as they are archived @param banks :: list of banks to consider which is normally all the banks of the instrument @param spline_breaks :: number of break points when fitting spline functions @returns a workspace with fitting results for all banks (3 spectra per bank). The spectra are in dSpacing units. """ curves = {} for b in banks: indices = EnggUtils.getWsIndicesForBank(vanWS, b) if not indices: # no indices at all for this bank, not interested in it, don't add it to the dictionary # (as when doing Calibrate (not-full)) which does CropData() the original workspace continue wsToFit = EnggUtils.cropData(self, vanWS, indices) wsToFit = EnggUtils.convertToDSpacing(self, wsToFit) wsToFit = EnggUtils.sumSpectra(self, wsToFit) fitWS = self._fitBankCurve(wsToFit, b, spline_breaks) curves.update({b: fitWS}) curvesWS = self._prepareCurvesWS(curves) return curvesWS
def _produce_outputs(self, difa, difc, tzero, tbl_name): """ Fills in the output properties as requested via the input properties. Sets the output difz/difc/tzero values. It can also produces a table with these parameters if required in the inputs. @param difa :: the DIFA GSAS parameter as fitted here @param difc :: the DIFC GSAS parameter as fitted here @param tzero :: the TZERO GSAS parameter as fitted here @param tbl_name :: a table name, non-empty if a table workspace should be created with the calibration parameters """ import EnggUtils # mandatory outputs self.setProperty('DIFA', difa) self.setProperty('DIFC', difc) self.setProperty('TZERO', tzero) # optional outputs if tbl_name: EnggUtils.generateOutputParTable(tbl_name, difa, difc, tzero) self.log().information("Output parameters added into a table workspace: %s" % tbl_name)
def PyExec(self): # Get peaks in dSpacing from file, and check we have what we need, before doing anything expectedPeaksD = EnggUtils.readInExpectedPeaks(self.getPropertyValue("ExpectedPeaksFromFile"), self.getProperty('ExpectedPeaks').value) if len(expectedPeaksD) < 1: raise ValueError("Cannot run this algorithm without any input expected peaks") inWS = self.getProperty('Workspace').value WSIndices = EnggUtils.getWsIndicesFromInProperties(inWS, self.getProperty('Bank').value, self.getProperty(self.INDICES_PROP_NAME).value) vanWS = self.getProperty("VanadiumWorkspace").value vanIntegWS = self.getProperty('VanIntegrationWorkspace').value vanCurvesWS = self.getProperty('VanCurvesWorkspace').value # These corrections rely on ToF<->Dspacing conversions, so ideally they'd be done after the # calibration step, which creates a cycle / chicken-and-egg issue. EnggUtils.applyVanadiumCorrections(self, inWS, WSIndices, vanWS, vanIntegWS, vanCurvesWS) rebinnedWS = self._prepareWsForFitting(inWS) posTbl = self._calculateCalibPositionsTbl(rebinnedWS, WSIndices, expectedPeaksD) # Produce 2 results: 'output table' and 'apply calibration' + (optional) calibration file self.setProperty("OutDetPosTable", posTbl) self._applyCalibrationTable(inWS, posTbl) self._outputDetPosFile(self.getPropertyValue('OutDetPosFilename'), posTbl)
def _get_default_peaks(self): """ Gets default peaks for Engg algorithms. Values from CeO2 """ import EnggUtils return EnggUtils.default_ceria_expected_peaks()
def PyExec(self): import EnggUtils # Get peaks in dSpacing from file expectedPeaksD = EnggUtils.readInExpectedPeaks(self.getPropertyValue("ExpectedPeaksFromFile"), self.getProperty('ExpectedPeaks').value) if len(expectedPeaksD) < 1: raise ValueError("Cannot run this algorithm without any input expected peaks") # Get expected peaks in TOF for the detector inWS = self.getProperty("InputWorkspace").value dimType = inWS.getXDimension().getName() if self.EXPECTED_DIM_TYPE != dimType: raise ValueError("This algorithm expects a workspace with %s X dimension, but " "the X dimension of the input workspace is: '%s'" % (self.EXPECTED_DIM_TYPE, dimType)) wsIndex = self.getProperty("WorkspaceIndex").value # FindPeaks will return a list of peaks sorted by the centre found. Sort the peaks as well, # so we can match them with fitted centres later. expectedPeaksToF = sorted(self._expectedPeaksInTOF(expectedPeaksD, inWS, wsIndex)) foundPeaks = self._peaksFromFindPeaks(inWS, expectedPeaksToF, wsIndex) if foundPeaks.rowCount() < len(expectedPeaksToF): txt = "Peaks effectively found: " + str(foundPeaks)[1:-1] self.log().warning("Some peaks from the list of expected peaks were not found by the algorithm " "FindPeaks which this algorithm uses to check that the data has the the " "expected peaks. " + txt) peaksTableName = self.getPropertyValue("OutFittedPeaksTable") difc, zero = self._fitAllPeaks(inWS, wsIndex, (foundPeaks, expectedPeaksD), peaksTableName) self._produceOutputs(difc, zero)
def _fit_results_to_dict(self, ws): """ Turn a workspace with one or more fitting results (3 spectra per curve fitted), that comes with all the spectra appended, into a dictionary of individual fitting results. @param ws workspace with fitting results (3 spectra per curve fitted) as provided by Fit for all banks. @returns dictionary with every individual fitting result (3 spectra) """ curves = {} if 0 != (ws.getNumberHistograms() % 3): raise RuntimeError( "A workspace without instrument definition has been passed, so it is " "expected to have fitting results, but it does not have a number of " "histograms multiple of 3. Number of hsitograms found: %d" % ws.getNumberHistograms()) for wi in range(0, int(ws.getNumberHistograms() / 3)): indiv = EnggUtils.crop_data(self, ws, [wi, wi + 2]) # the bank id is +1 because wi starts from 0 bankid = wi + 1 curves.update({bankid: indiv}) return curves
def PyExec(self): import EnggUtils # Get peaks in dSpacing from file expectedPeaksD = EnggUtils.read_in_expected_peaks(self.getPropertyValue("ExpectedPeaksFromFile"), self.getProperty('ExpectedPeaks').value) prog = Progress(self, start=0, end=1, nreports=2) prog.report('Focusing the input workspace') focussed_ws = self._focus_run(self.getProperty('InputWorkspace').value, self.getProperty("VanadiumWorkspace").value, self.getProperty('Bank').value, self.getProperty(self.INDICES_PROP_NAME).value) if len(expectedPeaksD) < 1: raise ValueError("Cannot run this algorithm without any input expected peaks") prog.report('Fitting parameters for the focused run') difc, zero, fitted_peaks = self._fit_params(focussed_ws, expectedPeaksD) self.log().information("Fitted {0} peaks. Resulting difc: {1}, tzero: {2}". format(fitted_peaks.rowCount(), difc, zero)) self.log().information("Peaks fitted: {0}, centers in ToF: {1}". format(fitted_peaks.column("dSpacing"), fitted_peaks.column("X0"))) self._produce_outputs(difc, zero, fitted_peaks)
def _fit_results_to_dict(self, ws): """ Turn a workspace with one or more fitting results (3 spectra per curve fitted), that comes with all the spectra appended, into a dictionary of individual fitting results. @param ws workspace with fitting results (3 spectra per curve fitted) as provided by Fit for all banks. @returns dictionary with every individual fitting result (3 spectra) """ curves = {} if 0 != (ws.getNumberHistograms() % 3): raise RuntimeError("A workspace without instrument definition has been passed, so it is " "expected to have fitting results, but it does not have a number of " "histograms multiple of 3. Number of hsitograms found: %d" % ws.getNumberHistograms()) for wi in range(0, int(ws.getNumberHistograms()/3)): indiv = EnggUtils.crop_data(self, ws, [wi, wi+2]) # the bank id is +1 because wi starts from 0 bankid = wi + 1 curves.update({bankid: indiv}) return curves
def PyExec(self): import EnggUtils max_reports = 20 prog = Progress(self, start=0, end=1, nreports=max_reports) # Get peaks in dSpacing from file prog.report("Reading peaks") expected_peaks_dsp = EnggUtils.read_in_expected_peaks(filename=self.getPropertyValue("ExpectedPeaksFromFile"), expected_peaks=self.getProperty('ExpectedPeaks').value) if len(expected_peaks_dsp) < 1: raise ValueError("Cannot run this algorithm without any input expected peaks") prog.report('Focusing the input workspace') focused_ws = self._focus_run(self.getProperty('InputWorkspace').value, self.getProperty("VanadiumWorkspace").value, self.getProperty('Bank').value, self.getProperty(self.INDICES_PROP_NAME).value, prog) prog.report('Fitting parameters for the focused run') difa, difc, zero, fitted_peaks = self._fit_params(focused_ws, expected_peaks_dsp, prog) self.log().information("Fitted {0} peaks. Resulting DIFA: {1}, DIFC: {2}, TZERO: {3}". format(fitted_peaks.rowCount(), difa, difc, zero)) self.log().information("Peaks fitted: {0}, centers in ToF: {1}". format(fitted_peaks.column("dSpacing"), fitted_peaks.column("X0"))) prog.report("Producing outputs") self._produce_outputs(difa, difc, zero, fitted_peaks) prog.report(max_reports, "Calibration complete")
def PyExec(self): import EnggUtils # Get peaks in dSpacing from file expectedPeaksD = EnggUtils.read_in_expected_peaks( self.getPropertyValue("ExpectedPeaksFromFile"), self.getProperty("ExpectedPeaks").value ) prog = Progress(self, start=0, end=1, nreports=2) prog.report("Focusing the input workspace") focussed_ws = self._focus_run( self.getProperty("InputWorkspace").value, self.getProperty("VanadiumWorkspace").value, self.getProperty("Bank").value, self.getProperty(self.INDICES_PROP_NAME).value, ) if len(expectedPeaksD) < 1: raise ValueError("Cannot run this algorithm without any input expected peaks") prog.report("Fitting parameters for the focused run") difc, zero, fitted_peaks = self._fit_params(focussed_ws, expectedPeaksD) self.log().information( "Fitted {0} peaks. Resulting difc: {1}, tzero: {2}".format(fitted_peaks.rowCount(), difc, zero) ) self.log().information( "Peaks fitted: {0}, centers in ToF: {1}".format(fitted_peaks.column("dSpacing"), fitted_peaks.column("X0")) ) self._produce_outputs(difc, zero, fitted_peaks)
def _divide_by_curves(self, ws, curves): """ Expects a workspace in ToF units. All operations are done in-place (the workspace is input/output). For every bank-curve pair, divides the corresponding spectra in the workspace by the (simulated) fitted curve. The division is done in d-spacing (the input workspace is converted to d-spacing inside this method, but results are converted back to ToF before returning from this method). The curves workspace is expected in d-spacing units (since it comes from fitting a sum of spectra for a bank or group of detectors). This method is capable of dealing with workspaces with range and bin size different from the range and bin size of the curves. It will rebin the curves workspace to match the input 'ws' workspace (using the algorithm RebinToWorkspace). @param ws :: workspace with (sample) spectra to divide by curves fitted to Vanadium spectra @param curves :: dictionary of fitting workspaces (in d-spacing), one per bank. The keys are the bank identifier and the values are their fitting workspaces. The fitting workspaces are expected as returned by the algorithm 'Fit': 3 spectra: original data, simulated data with fit, difference between original and simulated data. """ # Note that this division could use the algorithm 'Divide' # This is simple and more efficient than using divide workspace, which requires # cropping separate workspaces, dividing them separately, then appending them # with AppendSpectra, etc. ws = EnggUtils.convert_to_d_spacing(self, ws) for b in curves: # process all the spectra (indices) in one bank fitted_curve = curves[b] idxs = EnggUtils.get_ws_indices_for_bank(ws, b) if not idxs: pass # This RebinToWorkspace is required here: normal runs will have narrower range of X values, # and possibly different bin size, as compared to (long) Vanadium runs. Same applies to short # Ceria runs (for Calibrate -non-full) and even long Ceria runs (for Calibrate-Full). rebinned_fit_curve = mantid.RebinToWorkspace(WorkspaceToRebin=fitted_curve, WorkspaceToMatch=ws, StoreInADS=False) for i in idxs: # take values of the second spectrum of the workspace (fit simulation - fitted curve) ws.setY(i, np.divide(ws.dataY(i), rebinned_fit_curve.readY(1))) # finally, convert back to ToF EnggUtils.convert_to_TOF(self, ws)
def _produceOutputs(self, difc, zero): """ Just fills in the output properties as requested @param difc :: the difc GSAS parameter as fitted here @param zero :: the zero GSAS parameter as fitted here """ import EnggUtils self.setProperty('Difc', difc) self.setProperty('Zero', zero) # make output table if requested tblName = self.getPropertyValue("OutputParametersTableName") if '' != tblName: EnggUtils.generateOutputParTable(tblName, difc, zero) self.log().information("Output parameters added into a table workspace: %s" % tblName)
def PyExec(self): # Get the run workspace input_ws = self.getProperty('InputWorkspace').value # Get spectra indices either from bank or direct list of indices, checking for errors bank = self.getProperty('Bank').value spectra = self.getProperty(self.INDICES_PROP_NAME).value indices = EnggUtils.get_ws_indices_from_input_properties(input_ws, bank, spectra) detector_positions = self.getProperty("DetectorPositions").value n_reports = 8 prog = Progress(self, start=0, end=1, nreports=n_reports) # Leave only the data for the bank/spectra list requested prog.report('Selecting spectra from input workspace') input_ws = EnggUtils.crop_data(self, input_ws, indices) prog.report('Masking some bins if requested') self._mask_bins(input_ws, self.getProperty('MaskBinsXMins').value, self.getProperty('MaskBinsXMaxs').value) prog.report('Applying vanadium corrections') # Leave data for the same bank in the vanadium workspace too vanadium_ws = self.getProperty('VanadiumWorkspace').value van_integration_ws = self.getProperty('VanIntegrationWorkspace').value van_curves_ws = self.getProperty('VanCurvesWorkspace').value EnggUtils.apply_vanadium_corrections(parent=self, ws=input_ws, indices=indices, vanadium_ws=vanadium_ws, van_integration_ws=van_integration_ws, van_curves_ws=van_curves_ws, progress_range=(0.65, 0.8)) prog.report("Applying calibration if requested") # Apply calibration if detector_positions: self._apply_calibration(input_ws, detector_positions) # Convert to dSpacing prog.report("Converting to d") input_ws = EnggUtils.convert_to_d_spacing(self, input_ws) prog.report('Summing spectra') # Sum the values across spectra input_ws = EnggUtils.sum_spectra(self, input_ws) prog.report('Preparing output workspace') # Convert back to time of flight input_ws = EnggUtils.convert_to_TOF(self, input_ws) prog.report('Normalizing input workspace if needed') if self.getProperty('NormaliseByCurrent').value: self._normalize_by_current(input_ws) # OpenGenie displays distributions instead of pure counts (this is done implicitly when # converting units), so I guess that's what users will expect self._convert_to_distribution(input_ws) if bank: self._add_bank_number(input_ws, bank) self.setProperty("OutputWorkspace", input_ws)
def PyExec(self): # Get the run workspace input_ws = self.getProperty('InputWorkspace').value # Get spectra indices either from bank or direct list of indices, checking for errors bank = self.getProperty('Bank').value spectra = self.getProperty(self.INDICES_PROP_NAME).value indices = EnggUtils.get_ws_indices_from_input_properties(input_ws, bank, spectra) detector_positions = self.getProperty("DetectorPositions").value n_reports = 8 prog = Progress(self, start=0, end=1, nreports=n_reports) # Leave only the data for the bank/spectra list requested prog.report('Selecting spectra from input workspace') input_ws = EnggUtils.crop_data(self, input_ws, indices) prog.report('Masking some bins if requested') self._mask_bins(input_ws, self.getProperty('MaskBinsXMins').value, self.getProperty('MaskBinsXMaxs').value) prog.report('Applying vanadium corrections') # Leave data for the same bank in the vanadium workspace too vanadium_ws = self.getProperty('VanadiumWorkspace').value van_integration_ws = self.getProperty('VanIntegrationWorkspace').value van_curves_ws = self.getProperty('VanCurvesWorkspace').value EnggUtils.apply_vanadium_corrections(parent=self, ws=input_ws, indices=indices, vanadium_ws=vanadium_ws, van_integration_ws=van_integration_ws, van_curves_ws=van_curves_ws, progress_range=(0.65, 0.8)) prog.report("Applying calibration if requested") # Apply calibration if detector_positions: self._apply_calibration(input_ws, detector_positions) # Convert to dSpacing prog.report("Converting to d") input_ws = EnggUtils.convert_to_d_spacing(self, input_ws) prog.report('Summing spectra') # Sum the values across spectra input_ws = EnggUtils.sum_spectra(self, input_ws) prog.report('Preparing output workspace') # Convert back to time of flight input_ws = EnggUtils.convert_to_TOF(self, input_ws) prog.report('Normalizing input workspace if needed') if self.getProperty('NormaliseByCurrent').value: self._normalize_by_current(input_ws) # OpenGenie displays distributions instead of pure counts (this is done implicitly when # converting units), so I guess that's what users will expect self._convert_to_distribution(input_ws) self._add_bank_number(input_ws, bank) self.setProperty("OutputWorkspace", input_ws)
def _produce_outputs(self, difc, zero, fitted_peaks): """ Just fills in the output properties as requested @param difc :: the difc GSAS parameter as fitted here @param zero :: the zero GSAS parameter as fitted here @param fitted_peaks :: table workspace with peak parameters (one peak per row) """ import EnggUtils self.setProperty('Difc', difc) self.setProperty('Zero', zero) self.setProperty('FittedPeaks', fitted_peaks) # make output table if requested tblName = self.getPropertyValue("OutputParametersTableName") if '' != tblName: EnggUtils.generateOutputParTable(tblName, difc, zero) self.log().information("Output parameters added into a table workspace: %s" % tblName)
def _produce_outputs(self, difc, zero, fitted_peaks): """ Just fills in the output properties as requested @param difc :: the difc GSAS parameter as fitted here @param zero :: the zero GSAS parameter as fitted here @param fitted_peaks :: table workspace with peak parameters (one peak per row) """ import EnggUtils self.setProperty("Difc", difc) self.setProperty("Zero", zero) self.setProperty("FittedPeaks", fitted_peaks) # make output table if requested tblName = self.getPropertyValue("OutputParametersTableName") if "" != tblName: EnggUtils.generateOutputParTable(tblName, difc, zero) self.log().information("Output parameters added into a table workspace: %s" % tblName)
def PyExec(self): # Get the run workspace wks = self.getProperty('InputWorkspace').value # Get spectra indices either from bank or direct list of indices, checking for errors bank = self.getProperty('Bank').value spectra = self.getProperty(self.INDICES_PROP_NAME).value indices = EnggUtils.getWsIndicesFromInProperties(wks, bank, spectra) detPos = self.getProperty("DetectorPositions").value nreports = 5 if detPos: nreports += 1 prog = Progress(self, start=0, end=1, nreports=nreports) # Leave only the data for the bank/spectra list requested prog.report('Selecting spectra from input workspace') wks = EnggUtils.cropData(self, wks, indices) prog.report('Masking some bins if requested') self._mask_bins(wks, self.getProperty('MaskBinsXMins').value, self.getProperty('MaskBinsXMaxs').value) prog.report('Preparing input workspace with vanadium corrections') # Leave data for the same bank in the vanadium workspace too vanWS = self.getProperty('VanadiumWorkspace').value vanIntegWS = self.getProperty('VanIntegrationWorkspace').value vanCurvesWS = self.getProperty('VanCurvesWorkspace').value EnggUtils.applyVanadiumCorrections(self, wks, indices, vanWS, vanIntegWS, vanCurvesWS) # Apply calibration if detPos: self._applyCalibration(wks, detPos) # Convert to dSpacing wks = EnggUtils.convertToDSpacing(self, wks) prog.report('Summing spectra') # Sum the values across spectra wks = EnggUtils.sumSpectra(self, wks) prog.report('Preparing output workspace') # Convert back to time of flight wks = EnggUtils.convertToToF(self, wks) prog.report('Normalizing input workspace if needed') if self.getProperty('NormaliseByCurrent').value: self._normalize_by_current(wks) # OpenGenie displays distributions instead of pure counts (this is done implicitly when # converting units), so I guess that's what users will expect self._convertToDistr(wks) self.setProperty("OutputWorkspace", wks)
def PyExec(self): import EnggUtils # Get peaks in dSpacing from file expected_peaks = EnggUtils.read_in_expected_peaks( self.getPropertyValue("ExpectedPeaksFromFile"), self.getProperty('ExpectedPeaks').value) if len(expected_peaks) < 1: raise ValueError( "Cannot run this algorithm without any input expected peaks") # Get expected peaks in TOF for the detector in_wks = self.getProperty("InputWorkspace").value dim_type = in_wks.getXDimension().name if self.EXPECTED_DIM_TYPE != dim_type: raise ValueError( "This algorithm expects a workspace with %s X dimension, but " "the X dimension of the input workspace is: '%s'" % (self.EXPECTED_DIM_TYPE, dim_type)) wks_index = self.getProperty("WorkspaceIndex").value if self._any_expected_peaks_in_ws_range(in_wks, expected_peaks): expected_peaks_tof = sorted(expected_peaks) else: expected_peaks_tof = sorted( self._expected_peaks_in_tof(expected_peaks, in_wks, wks_index)) self._expected_peaks_are_in_tof = False if not self._any_expected_peaks_in_ws_range( in_wks, expected_peaks_tof): raise ValueError( "Expected peak centres lie outside the limits of the workspace x axis" ) found_peaks = self._peaks_from_find_peaks(in_wks, expected_peaks_tof, wks_index) if found_peaks.rowCount() < len(expected_peaks_tof): txt = "Peaks effectively found: " + str(found_peaks)[1:-1] self.log().warning( "Some peaks from the list of expected peaks were not found by the algorithm " "FindPeaks which this algorithm uses to check that the data has the the " "expected peaks. " + txt) peaks_table_name = self.getPropertyValue("OutFittedPeaksTable") fitted_peaks = self._fit_all_peaks(in_wks, wks_index, (found_peaks, expected_peaks), peaks_table_name) # mandatory output self.setProperty('FittedPeaks', fitted_peaks)
def _produce_outputs(self, difa, difc, zero, fitted_peaks): """ Just fills in the output properties as requested @param difa :: the DIFA GSAS parameter as fitted here @param difc :: the DIFC GSAS parameter as fitted here @param zero :: the TZERO GSAS parameter as fitted here @param fitted_peaks :: table workspace with peak parameters (one peak per row) """ import EnggUtils self.setProperty('DIFA', difa) self.setProperty('DIFC', difc) self.setProperty('TZERO', zero) self.setProperty('FittedPeaks', fitted_peaks) # make output table if requested table_name = self.getPropertyValue("OutputParametersTableName") if '' != table_name: EnggUtils.generate_output_param_table(table_name, difa, difc, zero) self.log().information("Output parameters added into a table workspace: %s" % table_name)
def PyExec(self): import EnggUtils # Get the run workspace ws = self.getProperty('InputWorkspace').value # Get spectra indices either from bank or direct list of indices, checking for errors bank = self.getProperty('Bank').value spectra = self.getProperty(self.INDICES_PROP_NAME).value indices = EnggUtils.getWsIndicesFromInProperties(ws, bank, spectra) # Leave the data for the bank we are interested in only ws = EnggUtils.cropData(self, ws, indices) # Apply calibration detPos = self.getProperty("DetectorPositions").value if detPos: self._applyCalibration(ws, detPos) # Leave data for the same bank in the vanadium workspace too vanWS = self.getProperty("VanadiumWorkspace").value # if it is raw data (not precalculated curve), needs to be cropped if EnggUtils.vanadiumWorkspaceIsPrecalculated(ws): vanWS = EnggUtils.cropData(self, vanWS, indices) # These corrections rely on ToF<->Dspacing conversions, so they're done after the calibration step vanFittingWS = EnggUtils.applyVanadiumCorrection(self, ws, vanWS, self.getProperty('VanadiumIntegWorkspace').value) # Convert to dSpacing ws = EnggUtils.convertToDSpacing(self, ws) # Sum the values ws = EnggUtils.sumSpectra(self, ws) # Convert back to time of flight ws = EnggUtils.convertToToF(self, ws) # OpenGenie displays distributions instead of pure counts (this is done implicitly when # converting units), so I guess that's what users will expect self._convertToDistr(ws) self.setProperty("OutputWorkspace", ws) # optinally, generate the workspace with per-bank vanadium fitting curves outVanWSName = self.getPropertyValue('OutVanadiumCurveFits') if outVanWSName: mtd[outVanWSName] = vanFittingWS
def _produce_outputs(self, difc, zero, fitted_peaks): """ Fills in the output properties as requested via the input properties. Sets the output difc, and zero values, and a table workspace with peaks information. It can also produces a table with the difc and zero parameters if this is required in the inputs. @param difc :: the difc GSAS parameter as fitted here @param zero :: the zero GSAS parameter as fitted here @param fitted_peaks :: table workspace with peak parameters (one peak per row) """ import EnggUtils # mandatory outputs self.setProperty('Difc', difc) self.setProperty('Zero', zero) self.setProperty('FittedPeaks', fitted_peaks) # optional outputs tbl_name = self.getPropertyValue("OutParametersTable") if '' != tbl_name: EnggUtils.generateOutputParTable(tbl_name, difc, zero) self.log().information("Output parameters added into a table workspace: %s" % tbl_name)
def _fit_curves_per_bank(self, vanadium_ws, banks, spline_breaks, prog): """ Fits one curve to every bank (where for every bank the data fitted is the result of summing up all the spectra of the bank). The fitting is done in d-spacing. @param vanadium_ws :: Vanadium run workspace to fit, expected in TOF units as they are archived @param banks :: list of banks to consider which is normally all the banks of the instrument @param spline_breaks :: number of break points when fitting spline functions @param prog :: progress reporter @returns a workspace with fitting results for all banks (3 spectra per bank). The spectra are in dSpacing units. """ curves = {} for bank_number, bank in enumerate(banks): prog.report("Fitting bank {} of {}".format(bank_number + 1, len(banks))) indices = EnggUtils.get_ws_indices_for_bank(vanadium_ws, bank) if not indices: # no indices at all for this bank, not interested in it, don't add it to the dictionary # (as when doing Calibrate (not-full)) which does CropData() the original workspace continue prog.report("Cropping") ws_to_fit = EnggUtils.crop_data(self, vanadium_ws, indices) prog.report("Converting to d-spacing") ws_to_fit = EnggUtils.convert_to_d_spacing(self, ws_to_fit) prog.report("Summing spectra") ws_to_fit = EnggUtils.sum_spectra(self, ws_to_fit) prog.report("Fitting bank {} to curve".format(bank_number)) fit_ws = self._fit_bank_curve(ws_to_fit, bank, spline_breaks, prog) curves.update({bank: fit_ws}) curves_ws = self._prepare_curves_ws(curves) return curves_ws
def PyExec(self): # Get peaks in dSpacing from file, and check we have what we need, before doing anything expectedPeaksD = EnggUtils.read_in_expected_peaks( self.getPropertyValue("ExpectedPeaksFromFile"), self.getProperty('ExpectedPeaks').value) if len(expectedPeaksD) < 1: raise ValueError( "Cannot run this algorithm without any input expected peaks") in_wks = self.getProperty('Workspace').value wks_indices = EnggUtils.getWsIndicesFromInProperties( in_wks, self.getProperty('Bank').value, self.getProperty(self.INDICES_PROP_NAME).value) van_wks = self.getProperty("VanadiumWorkspace").value van_integ_wks = self.getProperty('VanIntegrationWorkspace').value van_curves_wks = self.getProperty('VanCurvesWorkspace').value # These corrections rely on ToF<->Dspacing conversions, so ideally they'd be done after the # calibration step, which creates a cycle / chicken-and-egg issue. EnggUtils.applyVanadiumCorrections(self, in_wks, wks_indices, van_wks, van_integ_wks, van_curves_wks) rebinned_ws = self._prepare_ws_for_fitting( in_wks, self.getProperty('RebinBinWidth').value) pos_tbl, peaks_tbl = self._calculate_calib_positions_tbl( rebinned_ws, wks_indices, expectedPeaksD) # Produce 2 results: 'output table' and 'apply calibration' + (optional) calibration file self.setProperty("OutDetPosTable", pos_tbl) self.setProperty("FittedPeaks", peaks_tbl) self._apply_calibration_table(in_wks, pos_tbl) self._output_det_pos_file(self.getPropertyValue('OutDetPosFilename'), pos_tbl)
def PyExec(self): import EnggUtils # Get peaks in dSpacing from file expected_peaks_dsp = EnggUtils.read_in_expected_peaks( self.getPropertyValue("ExpectedPeaksFromFile"), self.getProperty('ExpectedPeaks').value) if len(expected_peaks_dsp) < 1: raise ValueError( "Cannot run this algorithm without any input expected peaks") # Get expected peaks in TOF for the detector in_wks = self.getProperty("InputWorkspace").value dimType = in_wks.getXDimension().getName() if self.EXPECTED_DIM_TYPE != dimType: raise ValueError( "This algorithm expects a workspace with %s X dimension, but " "the X dimension of the input workspace is: '%s'" % (self.EXPECTED_DIM_TYPE, dimType)) wks_index = self.getProperty("WorkspaceIndex").value # FindPeaks will return a list of peaks sorted by the centre found. Sort the peaks as well, # so we can match them with fitted centres later. expected_peaks_ToF = sorted( self._expected_peaks_in_ToF(expected_peaks_dsp, in_wks, wks_index)) found_peaks = self._peaks_from_find_peaks(in_wks, expected_peaks_ToF, wks_index) if found_peaks.rowCount() < len(expected_peaks_ToF): txt = "Peaks effectively found: " + str(found_peaks)[1:-1] self.log().warning( "Some peaks from the list of expected peaks were not found by the algorithm " "FindPeaks which this algorithm uses to check that the data has the the " "expected peaks. " + txt) peaks_table_name = self.getPropertyValue("OutFittedPeaksTable") fitted_peaks = self._fit_all_peaks(in_wks, wks_index, (found_peaks, expected_peaks_dsp), peaks_table_name) # mandatory output self.setProperty('FittedPeaks', fitted_peaks)
def PyExec(self): import EnggUtils focussed_ws = self._focusRun(self.getProperty('InputWorkspace').value, self.getProperty("VanadiumWorkspace").value, self.getProperty('Bank').value, self.getProperty(self.INDICES_PROP_NAME).value) # Get peaks in dSpacing from file expectedPeaksD = EnggUtils.readInExpectedPeaks(self.getPropertyValue("ExpectedPeaksFromFile"), self.getProperty('ExpectedPeaks').value) if len(expectedPeaksD) < 1: raise ValueError("Cannot run this algorithm without any input expected peaks") difc, zero = self._fitParams(focussed_ws, expectedPeaksD) self._produceOutputs(difc, zero)
def PyExec(self): import EnggUtils # Get peaks in dSpacing from file expected_peaks = EnggUtils.read_in_expected_peaks(self.getPropertyValue("ExpectedPeaksFromFile"), self.getProperty('ExpectedPeaks').value) if len(expected_peaks) < 1: raise ValueError("Cannot run this algorithm without any input expected peaks") # Get expected peaks in TOF for the detector in_wks = self.getProperty("InputWorkspace").value dim_type = in_wks.getXDimension().name if self.EXPECTED_DIM_TYPE != dim_type: raise ValueError("This algorithm expects a workspace with %s X dimension, but " "the X dimension of the input workspace is: '%s'" % (self.EXPECTED_DIM_TYPE, dim_type)) wks_index = self.getProperty("WorkspaceIndex").value if self._any_expected_peaks_in_ws_range(in_wks, expected_peaks): expected_peaks_tof = sorted(expected_peaks) else: expected_peaks_tof = sorted(self._expected_peaks_in_tof(expected_peaks, in_wks, wks_index)) self._expected_peaks_are_in_tof = False if not self._any_expected_peaks_in_ws_range(in_wks, expected_peaks_tof): raise ValueError("Expected peak centres lie outside the limits of the workspace x axis") found_peaks = self._peaks_from_find_peaks(in_wks, expected_peaks_tof, wks_index) if found_peaks.rowCount() < len(expected_peaks_tof): txt = "Peaks effectively found: " + str(found_peaks)[1:-1] self.log().warning("Some peaks from the list of expected peaks were not found by the algorithm " "FindPeaks which this algorithm uses to check that the data has the the " "expected peaks. " + txt) peaks_table_name = self.getPropertyValue("OutFittedPeaksTable") fitted_peaks = self._fit_all_peaks(in_wks, wks_index, (found_peaks, expected_peaks), peaks_table_name) # mandatory output self.setProperty('FittedPeaks', fitted_peaks)
def PyExec(self): # Get the run workspace wks = self.getProperty('InputWorkspace').value # Get spectra indices either from bank or direct list of indices, checking for errors bank = self.getProperty('Bank').value spectra = self.getProperty(self.INDICES_PROP_NAME).value indices = EnggUtils.getWsIndicesFromInProperties(wks, bank, spectra) # Leave the data for the bank we are interested in only wks = EnggUtils.cropData(self, wks, indices) prog = Progress(self, start=0, end=1, nreports=3) prog.report('Preparing input workspace') # Leave data for the same bank in the vanadium workspace too vanWS = self.getProperty('VanadiumWorkspace').value vanIntegWS = self.getProperty('VanIntegrationWorkspace').value vanCurvesWS = self.getProperty('VanCurvesWorkspace').value EnggUtils.applyVanadiumCorrections(self, wks, indices, vanWS, vanIntegWS, vanCurvesWS) # Apply calibration detPos = self.getProperty("DetectorPositions").value if detPos: self._applyCalibration(wks, detPos) # Convert to dSpacing wks = EnggUtils.convertToDSpacing(self, wks) prog.report('Summing spectra') # Sum the values wks = EnggUtils.sumSpectra(self, wks) prog.report('Preparing output workspace') # Convert back to time of flight wks = EnggUtils.convertToToF(self, wks) # OpenGenie displays distributions instead of pure counts (this is done implicitly when # converting units), so I guess that's what users will expect self._convertToDistr(wks) self.setProperty("OutputWorkspace", wks)
def PyExec(self): mantid.logger.warning( "EnggCalibrate is deprecated as of May 2021. Please use PDCalibration instead." ) import EnggUtils max_reports = 20 prog = Progress(self, start=0, end=1, nreports=max_reports) # Get peaks in dSpacing from file prog.report("Reading peaks") expected_peaks_dsp = EnggUtils.read_in_expected_peaks( filename=self.getPropertyValue("ExpectedPeaksFromFile"), expected_peaks=self.getProperty('ExpectedPeaks').value) if len(expected_peaks_dsp) < 1: raise ValueError( "Cannot run this algorithm without any input expected peaks") prog.report('Focusing the input workspace') focused_ws = self._focus_run( self.getProperty('InputWorkspace').value, self.getProperty("VanadiumWorkspace").value, self.getProperty('Bank').value, self.getProperty(self.INDICES_PROP_NAME).value, prog) prog.report('Fitting parameters for the focused run') difa, difc, zero, fitted_peaks = self._fit_params( focused_ws, expected_peaks_dsp, prog) self.log().information( "Fitted {0} peaks. Resulting DIFA: {1}, DIFC: {2}, TZERO: {3}". format(fitted_peaks.rowCount(), difa, difc, zero)) self.log().information("Peaks fitted: {0}, centers in ToF: {1}".format( fitted_peaks.column("dSpacing"), fitted_peaks.column("X0"))) prog.report("Producing outputs") self._produce_outputs(difa, difc, zero, fitted_peaks) prog.report(max_reports, "Calibration complete")
def PyExec(self): import EnggUtils # Get peaks in dSpacing from file expectedPeaksD = EnggUtils.readInExpectedPeaks(self.getPropertyValue("ExpectedPeaksFromFile"), self.getProperty('ExpectedPeaks').value) prog = Progress(self, start=0, end=1, nreports=2) prog.report('Focusing the input workspace') focussed_ws = self._focusRun(self.getProperty('InputWorkspace').value, self.getProperty("VanadiumWorkspace").value, self.getProperty('Bank').value, self.getProperty(self.INDICES_PROP_NAME).value) if len(expectedPeaksD) < 1: raise ValueError("Cannot run this algorithm without any input expected peaks") prog.report('Fitting parameters for the focused run') difc, zero = self._fitParams(focussed_ws, expectedPeaksD) self._produceOutputs(difc, zero)
def PyInit(self): self.declareProperty(MatrixWorkspaceProperty("InputWorkspace", "", Direction.Input), doc="Workspace with the calibration run to use.") import EnggUtils self.declareProperty( FloatArrayProperty("ExpectedPeaks", values=EnggUtils.default_ceria_expected_peaks(), direction=Direction.Input), doc="A list of dSpacing values where peaks are expected.") self.declareProperty( FileProperty(name="ExpectedPeaksFromFile", defaultValue="", action=FileAction.OptionalLoad, extensions=[".csv"]), doc= "Load from file a list of dSpacing values to be translated into TOF to find expected " "peaks. This takes precedence over 'ExpectedPeaks' if both options are given." ) peaks_grp = 'Peaks to fit' self.setPropertyGroup('ExpectedPeaks', peaks_grp) self.setPropertyGroup('ExpectedPeaksFromFile', peaks_grp) self.declareProperty( MatrixWorkspaceProperty("VanadiumWorkspace", "", Direction.Input, PropertyMode.Optional), doc= 'Workspace with the Vanadium (correction and calibration) run. Alternatively, ' 'when the Vanadium run has been already processed, the properties can be used' ) self.declareProperty( ITableWorkspaceProperty("VanIntegrationWorkspace", "", Direction.Input, PropertyMode.Optional), doc= 'Results of integrating the spectra of a Vanadium run, with one column ' '(integration result) and one row per spectrum. This can be used in ' 'combination with OutVanadiumCurveFits from a previous execution and ' 'VanadiumWorkspace to provide pre-calculated values for Vanadium correction.' ) self.declareProperty( MatrixWorkspaceProperty('VanCurvesWorkspace', '', Direction.Input, PropertyMode.Optional), doc= 'A workspace2D with the fitting workspaces corresponding to the instrument banks. ' 'This workspace has three spectra per bank, as produced by the algorithm Fit. ' 'This is meant to be used as an alternative input VanadiumWorkspace for testing and ' 'performance reasons. If not given, no workspace is generated.') vana_grp = 'Vanadium (open beam) properties' self.setPropertyGroup('VanadiumWorkspace', vana_grp) self.setPropertyGroup('VanIntegrationWorkspace', vana_grp) self.setPropertyGroup('VanCurvesWorkspace', vana_grp) self.declareProperty( "Bank", '', StringListValidator(EnggUtils.ENGINX_BANKS), direction=Direction.Input, doc="Which bank to calibrate. It can be specified as 1 or 2, or " "equivalently, North or South. See also " + self.INDICES_PROP_NAME + " " "for a more flexible alternative to select specific detectors") self.declareProperty( self.INDICES_PROP_NAME, '', direction=Direction.Input, doc='Sets the spectrum numbers for the detectors ' 'that should be considered in the calibration (all others will be ' 'ignored). This option cannot be used together with Bank, as they overlap. ' 'You can give multiple ranges, for example: "0-99", or "0-9, 50-59, 100-109".' ) banks_grp = 'Banks / spectra' self.setPropertyGroup('Bank', banks_grp) self.setPropertyGroup(self.INDICES_PROP_NAME, banks_grp) self.declareProperty( ITableWorkspaceProperty("DetectorPositions", "", Direction.Input, PropertyMode.Optional), "Calibrated detector positions. If not specified, default ones (from the " "current instrument definition) are used.") self.declareProperty( 'OutputParametersTableName', '', direction=Direction.Input, doc= 'Name for a table workspace with the calibration parameters calculated ' 'from this algorithm: difc and zero parameters for GSAS. these two parameters ' 'are added as two columns in a single row. If not given, no table is ' 'generated.') self.declareProperty( "DIFA", 0.0, direction=Direction.Output, doc= "Calibration parameter DIFA for the bank or range of pixels/detectors given" ) self.declareProperty( "DIFC", 0.0, direction=Direction.Output, doc= "Calibration parameter DIFC for the bank or range of pixels/detectors given" ) self.declareProperty( "TZERO", 0.0, direction=Direction.Output, doc= "Calibration parameter TZERO for the bank or range of pixels/detectors given" ) self.declareProperty( ITableWorkspaceProperty("FittedPeaks", "", Direction.Output), doc= "Information on fitted peaks as produced by the (child) algorithm EnggFitPeaks." ) out_grp = 'Outputs' self.setPropertyGroup('DetectorPositions', out_grp) self.setPropertyGroup('OutputParametersTableName', out_grp) self.setPropertyGroup('DIFA', out_grp) self.setPropertyGroup('DIFC', out_grp) self.setPropertyGroup('TZERO', out_grp) self.setPropertyGroup('FittedPeaks', out_grp)
def PyInit(self): self.declareProperty(MatrixWorkspaceProperty("Workspace", "", Direction.InOut), "Workspace with the calibration run to use. The calibration will be applied on it.") self.declareProperty(MatrixWorkspaceProperty("VanadiumWorkspace", "", Direction.Input, PropertyMode.Optional), "Workspace with the Vanadium (correction and calibration) run.") self.declareProperty(ITableWorkspaceProperty('VanIntegrationWorkspace', '', Direction.Input, PropertyMode.Optional), doc = 'Results of integrating the spectra of a Vanadium run, with one column ' '(integration result) and one row per spectrum. This can be used in ' 'combination with OutVanadiumCurveFits from a previous execution and ' 'VanadiumWorkspace to provide pre-calculated values for Vanadium correction.') self.declareProperty(MatrixWorkspaceProperty('VanCurvesWorkspace', '', Direction.Input, PropertyMode.Optional), doc = 'A workspace2D with the fitting workspaces corresponding to ' 'the instrument banks. This workspace has three spectra per bank, as produced ' 'by the algorithm Fit. This is meant to be used as an alternative input ' 'VanadiumWorkspace for testing and performance reasons. If not given, no ' 'workspace is generated.') vana_grp = 'Vanadium (open beam) properties' self.setPropertyGroup('VanadiumWorkspace', vana_grp) self.setPropertyGroup('VanIntegrationWorkspace', vana_grp) self.setPropertyGroup('VanCurvesWorkspace', vana_grp) self.declareProperty(ITableWorkspaceProperty("OutDetPosTable", "", Direction.Output),\ doc="A table with the detector IDs and calibrated detector positions and " "additional calibration information. The table includes: the old positions " "in V3D format (3D vector with x, y, z values), the new positions in V3D, the " "new positions in spherical coordinates, the change in L2, and the DIFC and " "ZERO parameters.") self.declareProperty("Bank", '', StringListValidator(EnggUtils.ENGINX_BANKS), direction=Direction.Input, doc = "Which bank to calibrate: It can be specified as 1 or 2, or " "equivalently, North or South. See also " + self.INDICES_PROP_NAME + " " "for a more flexible alternative to select specific detectors") self.declareProperty(self.INDICES_PROP_NAME, '', direction=Direction.Input, doc = 'Sets the spectrum numbers for the detectors ' 'that should be considered in the calibration (all others will be ' 'ignored). This option cannot be used together with Bank, as they overlap. ' 'You can give multiple ranges, for example: "0-99", or "0-9, 50-59, 100-109".') banks_grp = 'Banks / spectra' self.setPropertyGroup('Bank', banks_grp) self.setPropertyGroup(self.INDICES_PROP_NAME, banks_grp) self.declareProperty(FileProperty("OutDetPosFilename", "", FileAction.OptionalSave, [".csv"]), doc="Name of the file to save the pre-/post-calibrated detector positions - this " "saves the same information that is provided in the output table workspace " "(OutDetPosTable).") opt_outs_grp = 'Optional outputs' self.setPropertyGroup('OutDetPosFilename', opt_outs_grp) self.declareProperty(FloatArrayProperty("ExpectedPeaks", values=EnggUtils.default_ceria_expected_peaks(), direction=Direction.Input), doc="A list of dSpacing values where peaks are expected.") self.declareProperty(FileProperty(name="ExpectedPeaksFromFile",defaultValue="", action=FileAction.OptionalLoad,extensions = [".csv"]), doc="Load from file a list of dSpacing values to be translated into TOF to " "find expected peaks. This takes precedence over 'ExpectedPeaks' if both " "options are given.") peaks_grp = 'Peaks to fit' self.setPropertyGroup('ExpectedPeaks', peaks_grp) self.setPropertyGroup('ExpectedPeaksFromFile', peaks_grp)
def PyInit(self): self.declareProperty(MatrixWorkspaceProperty("Workspace", "", Direction.InOut), "Workspace with the calibration run to use. The calibration will be applied on it.") self.declareProperty(MatrixWorkspaceProperty("VanadiumWorkspace", "", Direction.Input, PropertyMode.Optional), "Workspace with the Vanadium (correction and calibration) run.") self.declareProperty(ITableWorkspaceProperty('VanIntegrationWorkspace', '', Direction.Input, PropertyMode.Optional), doc='Results of integrating the spectra of a Vanadium run, with one column ' '(integration result) and one row per spectrum. This can be used in ' 'combination with OutVanadiumCurveFits from a previous execution and ' 'VanadiumWorkspace to provide pre-calculated values for Vanadium correction.') self.declareProperty(MatrixWorkspaceProperty('VanCurvesWorkspace', '', Direction.Input, PropertyMode.Optional), doc='A workspace2D with the fitting workspaces corresponding to ' 'the instrument banks. This workspace has three spectra per bank, as produced ' 'by the algorithm Fit. This is meant to be used as an alternative input ' 'VanadiumWorkspace for testing and performance reasons. If not given, no ' 'workspace is generated.') vana_grp = 'Vanadium (open beam) properties' self.setPropertyGroup('VanadiumWorkspace', vana_grp) self.setPropertyGroup('VanIntegrationWorkspace', vana_grp) self.setPropertyGroup('VanCurvesWorkspace', vana_grp) self.declareProperty(ITableWorkspaceProperty("OutDetPosTable", "", Direction.Output), doc="A table with the detector IDs and calibrated detector positions and " "additional calibration information. The table includes: the old positions " "in V3D format (3D vector with x, y, z values), the new positions in V3D, the " "new positions in spherical coordinates, the change in L2, and the DIFA, " "DIFC and TZERO calibration parameters.") self.declareProperty(ITableWorkspaceProperty("FittedPeaks", "", Direction.Output), doc="Information on fitted peaks. The table has one row per calibrated " "detector contains. In each row, the parameters of all the peaks fitted " "are specified together with the the expected peak value (in d-spacing). " "The expected values are given in the field labelled 'dSpacing'. When " "fitting back-to-back exponential functions, the 'X0' column has the fitted " "peak center.") self.declareProperty("Bank", '', StringListValidator(EnggUtils.ENGINX_BANKS), direction=Direction.Input, doc="Which bank to calibrate: It can be specified as 1 or 2, or " "equivalently, North or South. See also " + self.INDICES_PROP_NAME + " " "for a more flexible alternative to select specific detectors") self.declareProperty(self.INDICES_PROP_NAME, '', direction=Direction.Input, doc='Sets the spectrum numbers for the detectors ' 'that should be considered in the calibration (all others will be ' 'ignored). This option cannot be used together with Bank, as they overlap. ' 'You can give multiple ranges, for example: "0-99", or "0-9, 50-59, 100-109".') banks_grp = 'Banks / spectra' self.setPropertyGroup('Bank', banks_grp) self.setPropertyGroup(self.INDICES_PROP_NAME, banks_grp) self.declareProperty(FileProperty("OutDetPosFilename", "", FileAction.OptionalSave, [".csv"]), doc="Name of the file to save the pre-/post-calibrated detector positions - this " "saves the same information that is provided in the output table workspace " "(OutDetPosTable).") # The default value of '-0.0005' is borrowed from OG routines self.declareProperty('RebinBinWidth', defaultValue='-0.0005', direction=Direction.Input, doc="Before calculating the calibrated positions (fitting peaks) this algorithms " "re-bins the input sample data using a single bin width parameter. This option is" "to change the default bin width which is set to the value traditionally used for " "the Engin-X instrument") opt_outs_grp = 'Optional outputs' self.setPropertyGroup('OutDetPosFilename', opt_outs_grp) self.declareProperty(FloatArrayProperty("ExpectedPeaks", values=EnggUtils.default_ceria_expected_peaks(), direction=Direction.Input), doc="A list of dSpacing values where peaks are expected.") self.declareProperty(FileProperty(name="ExpectedPeaksFromFile",defaultValue="", action=FileAction.OptionalLoad,extensions = [".csv"]), doc="Load from file a list of dSpacing values to be translated into TOF to " "find expected peaks. This takes precedence over 'ExpectedPeaks' if both " "options are given.") peaks_grp = 'Peaks to fit' self.setPropertyGroup('ExpectedPeaks', peaks_grp) self.setPropertyGroup('ExpectedPeaksFromFile', peaks_grp)
def PyInit(self): self.declareProperty( MatrixWorkspaceProperty("InputWorkspace", "", Direction.Input), doc="Workspace with the calibration run to use.", ) import EnggUtils self.declareProperty( FloatArrayProperty( "ExpectedPeaks", values=EnggUtils.default_ceria_expected_peaks(), direction=Direction.Input ), doc="A list of dSpacing values where peaks are expected.", ) self.declareProperty( FileProperty( name="ExpectedPeaksFromFile", defaultValue="", action=FileAction.OptionalLoad, extensions=[".csv"] ), doc="Load from file a list of dSpacing values to be translated into TOF to " "find expected peaks. This takes precedence over 'ExpectedPeaks' if both " "options are given.", ) peaks_grp = "Peaks to fit" self.setPropertyGroup("ExpectedPeaks", peaks_grp) self.setPropertyGroup("ExpectedPeaksFromFile", peaks_grp) self.declareProperty( MatrixWorkspaceProperty("VanadiumWorkspace", "", Direction.Input, PropertyMode.Optional), doc="Workspace with the Vanadium (correction and calibration) run. " "Alternatively, when the Vanadium run has been already processed, " "the properties can be used", ) self.declareProperty( ITableWorkspaceProperty("VanIntegrationWorkspace", "", Direction.Input, PropertyMode.Optional), doc="Results of integrating the spectra of a Vanadium run, with one column " "(integration result) and one row per spectrum. This can be used in " "combination with OutVanadiumCurveFits from a previous execution and " "VanadiumWorkspace to provide pre-calculated values for Vanadium correction.", ) self.declareProperty( MatrixWorkspaceProperty("VanCurvesWorkspace", "", Direction.Input, PropertyMode.Optional), doc="A workspace2D with the fitting workspaces corresponding to " "the instrument banks. This workspace has three spectra per bank, as produced " "by the algorithm Fit. This is meant to be used as an alternative input " "VanadiumWorkspace for testing and performance reasons. If not given, no " "workspace is generated.", ) vana_grp = "Vanadium (open beam) properties" self.setPropertyGroup("VanadiumWorkspace", vana_grp) self.setPropertyGroup("VanIntegrationWorkspace", vana_grp) self.setPropertyGroup("VanCurvesWorkspace", vana_grp) self.declareProperty( "Bank", "", StringListValidator(EnggUtils.ENGINX_BANKS), direction=Direction.Input, doc="Which bank to calibrate. It can be specified as 1 or 2, or " "equivalently, North or South. See also " + self.INDICES_PROP_NAME + " " "for a more flexible alternative to select specific detectors", ) self.declareProperty( self.INDICES_PROP_NAME, "", direction=Direction.Input, doc="Sets the spectrum numbers for the detectors " "that should be considered in the calibration (all others will be " "ignored). This option cannot be used together with Bank, as they overlap. " 'You can give multiple ranges, for example: "0-99", or "0-9, 50-59, 100-109".', ) banks_grp = "Banks / spectra" self.setPropertyGroup("Bank", banks_grp) self.setPropertyGroup(self.INDICES_PROP_NAME, banks_grp) self.declareProperty( ITableWorkspaceProperty("DetectorPositions", "", Direction.Input, PropertyMode.Optional), "Calibrated detector positions. If not specified, default ones (from the " "current instrument definition) are used.", ) self.declareProperty( "OutputParametersTableName", "", direction=Direction.Input, doc="Name for a table workspace with the calibration parameters calculated " "from this algorithm: difc and zero parameters for GSAS. these two parameters " "are added as two columns in a single row. If not given, no table is " "generated.", ) self.declareProperty( "Difc", 0.0, direction=Direction.Output, doc="Calibrated Difc value for the bank or range of pixels/detectors given", ) self.declareProperty( "Zero", 0.0, direction=Direction.Output, doc="Calibrated Zero value for the bank or range of pixels/detectors given", ) self.declareProperty( ITableWorkspaceProperty("FittedPeaks", "", Direction.Output), doc="Information on fitted peaks as produced by the (child) algorithm " "EnggFitPeaks.", ) out_grp = "Outputs" self.setPropertyGroup("DetectorPositions", out_grp) self.setPropertyGroup("OutputParametersTableName", out_grp) self.setPropertyGroup("Difc", out_grp) self.setPropertyGroup("Zero", out_grp) self.setPropertyGroup("FittedPeaks", out_grp)