예제 #1
0
    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)
예제 #2
0
    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
예제 #3
0
    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)
예제 #4
0
    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)
예제 #5
0
    def _get_default_peaks(self):
        """
        Gets default peaks for Engg algorithms. Values from CeO2
        """
        import EnggUtils

        return EnggUtils.default_ceria_expected_peaks()
예제 #6
0
    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
예제 #8
0
    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
예제 #10
0
    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")
예제 #11
0
    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)
예제 #13
0
    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)
예제 #14
0
    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)
예제 #15
0
    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)
예제 #16
0
    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)
예제 #17
0
    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)
예제 #18
0
    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)
예제 #19
0
    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)
예제 #20
0
    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)
예제 #21
0
    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)
예제 #22
0
    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
예제 #23
0
    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)
예제 #24
0
    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
예제 #26
0
    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 _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
예제 #28
0
    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)
예제 #29
0
    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)
예제 #30
0
    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)
예제 #31
0
    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)
예제 #32
0
    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)
예제 #33
0
    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")
예제 #34
0
    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)
예제 #35
0
    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)
예제 #37
0
 def _get_default_peaks(self):
     """
     Gets default peaks for Engg algorithms. Values from CeO2
     """
     import EnggUtils
     return EnggUtils.default_ceria_expected_peaks()
예제 #38
0
    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)
예제 #39
0
    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)