Ejemplo n.º 1
0
        def calibrate_region_of_interest(ceria_d_ws, roi: str,
                                         grouping_kwarg: dict,
                                         cal_output: dict) -> None:
            """
            Focus the processed ceria workspace (dSpacing) over the chosen region of interest, and run the calibration
            using this result
            :param ceria_d_ws: Workspace containing the processed ceria data converted to dSpacing
            :param roi: String describing chosen region of interest
            :param grouping_kwarg: Dict containing kwarg to pass to DiffractionFocussing to select the roi
            :param cal_output: Dictionary to append with the output of PDCalibration for the chosen roi
            """
            # focus ceria
            focused_ceria = DiffractionFocussing(InputWorkspace=ceria_d_ws,
                                                 **grouping_kwarg)
            ApplyDiffCal(InstrumentWorkspace=focused_ceria,
                         ClearCalibration=True)
            ConvertUnits(InputWorkspace=focused_ceria,
                         OutputWorkspace=focused_ceria,
                         Target='TOF')

            # calibration of focused data over chosen region of interest
            kwargs["InputWorkspace"] = focused_ceria
            kwargs["OutputCalibrationTable"] = "engggui_calibration_" + roi
            kwargs["DiagnosticWorkspaces"] = "diag_" + roi

            cal_roi = run_pd_calibration(kwargs)[0]
            cal_output[roi] = cal_roi
Ejemplo n.º 2
0
    def _calibrate_runs_in_map(self, drange_map):

        for d_range, wrksp in drange_map.items():
            normalised = NormaliseByCurrent(
                InputWorkspace=wrksp,
                OutputWorkspace="normalised_sample",
                StoreInADS=False,
                EnableLogging=False)

            aligned = AlignDetectors(InputWorkspace=normalised,
                                     CalibrationFile=self._cal,
                                     OutputWorkspace="aligned_sample",
                                     StoreInADS=False,
                                     EnableLogging=False)

            focussed = DiffractionFocussing(InputWorkspace=aligned,
                                            GroupingFileName=self._cal,
                                            OutputWorkspace="focussed_sample",
                                            StoreInADS=False,
                                            EnableLogging=False)

            drange_map[d_range] = CropWorkspace(
                InputWorkspace=focussed,
                XMin=d_range[0],
                XMax=d_range[1],
                OutputWorkspace="calibrated_sample",
                StoreInADS=False,
                EnableLogging=False)
Ejemplo n.º 3
0
 def _run_focus(input_workspace, tof_output_name, curves, grouping_ws,
                region_calib) -> None:
     """Focus the processed full instrument workspace over the chosen region of interest
     :param input_workspace: Processed full instrument workspace converted to dSpacing
     :param tof_output_name: Name for the time-of-flight output workspace
     :param curves: Workspace containing the vanadium curves for this region of interest
     :param grouping_ws: Grouping workspace to pass to DiffractionFocussing
     :param region_calib: Region of interest calibration workspace (table ws output from PDCalibration)
     """
     # rename workspace prior to focussing to avoid errors later
     dspacing_output_name = tof_output_name + "_dSpacing"
     # focus sample over specified region of interest
     focused_sample = DiffractionFocussing(
         InputWorkspace=input_workspace,
         OutputWorkspace=dspacing_output_name,
         GroupingWorkspace=grouping_ws)
     curves_rebinned = RebinToWorkspace(WorkspaceToRebin=curves,
                                        WorkspaceToMatch=focused_sample)
     # flux correction - divide focused sample data by rebinned focused vanadium curve data
     Divide(LHSWorkspace=focused_sample,
            RHSWorkspace=curves_rebinned,
            OutputWorkspace=focused_sample,
            AllowDifferentNumberSpectra=True)
     # apply calibration from specified region of interest
     ApplyDiffCal(InstrumentWorkspace=focused_sample,
                  CalibrationWorkspace=region_calib)
     # set bankid for use in fit tab
     run = focused_sample.getRun()
     if region_calib.name() == "engggui_calibration_bank_1":
         run.addProperty("bankid", 1, True)
     elif region_calib.name() == "engggui_calibration_bank_2":
         run.addProperty("bankid", 2, True)
     else:
         run.addProperty("bankid", 3, True)
     # output in both dSpacing and TOF
     ConvertUnits(InputWorkspace=focused_sample,
                  OutputWorkspace=tof_output_name,
                  Target='TOF')
     DeleteWorkspace(curves_rebinned)
Ejemplo n.º 4
0
    def focus_workspace_list(self, ws_name_list, gsas_ws_name_list, group_ws_name):
        """ Do diffraction focus on a list workspaces and also convert them to IDL GSAS
        This is the main execution body to be executed in multi-threading environment
        :param ws_name_list:
        :param gsas_ws_name_list: name for GSAS
        :param group_ws_name: name for grouping workspace
        :return:
        """
        datatypeutility.check_list('Workspace names', ws_name_list)
        datatypeutility.check_list('(Output) GSAS workspace name list', gsas_ws_name_list)
        if len(ws_name_list) != len(gsas_ws_name_list):
            raise RuntimeError('Input workspace names {} have different number than output GSAS workspace names {}'
                               ''.format(ws_name_list, gsas_ws_name_list))

        for index in range(len(ws_name_list)):
            # set GSAS workspace name same as input workspace name
            ws_name = ws_name_list[index]
            gsas_ws_name_list[index] = ws_name
            gsas_ws_name = ws_name

            datatypeutility.check_string_variable('Workspace name', ws_name)
            datatypeutility.check_string_variable('Output GSAS workspace name', gsas_ws_name)
            # skip empty workspace name that might be returned from FilterEvents
            if len(ws_name) == 0:
                continue
            # focus (simple) it is the same but simplied version in diffraction_focus()
            ConvertUnits(InputWorkspace=ws_name, OutputWorkspace=ws_name, Target='dSpacing')
            # diffraction focus
            DiffractionFocussing(InputWorkspace=ws_name, OutputWorkspace=ws_name,
                                 GroupingWorkspace=group_ws_name)
            # convert unit to TOF
            ConvertUnits(InputWorkspace=ws_name, OutputWorkspace=ws_name,
                         Target='TOF', ConvertFromPointData=False)
            # edit instrument
            try:
                EditInstrumentGeometry(Workspace=ws_name,
                                       PrimaryFlightPath=self._focus_instrument_dict['L1'],
                                       SpectrumIDs=self._focus_instrument_dict['SpectrumIDs'],
                                       L2=self._focus_instrument_dict['L2'],
                                       Polar=self._focus_instrument_dict['Polar'],
                                       Azimuthal=self._focus_instrument_dict['Azimuthal'])
            except RuntimeError as run_err:
                print('[WARNING] Non-critical error from EditInstrumentGeometry for {}: {}'
                      ''.format(ws_name, run_err))
        # END-FOR

        return
Ejemplo n.º 5
0
    def _alignAndFocus(self, params, calib, cal_File, group):
        # loading the ISAW detcal file will override the default instrument
        if calib == 'DetCal File':
            LoadIsawDetCal(InputWorkspace='WS', Filename=cal_File)

        if calib in ['Convert Units', 'DetCal File']:
            ConvertUnits(InputWorkspace='WS',
                         Target='dSpacing', OutputWorkspace='WS_d')
        else:
            self.log().notice("\n calibration file : %s" % cal_File)
            AlignDetectors(InputWorkspace='WS', CalibrationFile=cal_File,
                           Outputworkspace='WS_d')

        Rebin(InputWorkspace='WS_d', Params=params, Outputworkspace='WS_d')

        DiffractionFocussing(InputWorkspace='WS_d', GroupingWorkspace=group,
                             PreserveEvents=False, OutputWorkspace='WS_red')
Ejemplo n.º 6
0
    def PyExec(self):
        from mantid.simpleapi import Load, AlignDetectors, DiffractionFocussing

        # Load file to workspace
        _tmpws = Load(Filename=self.getPropertyValue("Filename"))

        # AlignDetectors
        calfile = self.getProperty("CalFilename").value
        _tmpws = AlignDetectors(InputWorkspace=_tmpws, CalibrationFile=calfile)

        # Focus
        _tmpws = DiffractionFocussing(InputWorkspace=_tmpws,
                                      GroupingFileName=calfile)

        # Store reference after algorithm has gone
        self.setProperty("OutputWorkspace", _tmpws)

        DeleteWorkspace(_tmpws)
Ejemplo n.º 7
0
    def calibrator(d_range, workspace):
        normalised = NormaliseByCurrent(InputWorkspace=workspace,
                                        OutputWorkspace="normalised_sample",
                                        StoreInADS=False, EnableLogging=False)

        aligned = AlignDetectors(InputWorkspace=normalised,
                                 CalibrationFile=calibration_file,
                                 OutputWorkspace="aligned_sample",
                                 StoreInADS=False, EnableLogging=False)

        focussed = DiffractionFocussing(InputWorkspace=aligned,
                                        GroupingFileName=calibration_file,
                                        OutputWorkspace="focussed_sample",
                                        StoreInADS=False, EnableLogging=False)

        return CropWorkspace(InputWorkspace=focussed,
                             XMin=d_range[0], XMax=d_range[1],
                             OutputWorkspace="calibrated_sample",
                             StoreInADS=False, EnableLogging=False)
Ejemplo n.º 8
0
 def _get_van_curves_for_roi(region: str, van_processed_inst_ws,
                             grouping_ws):  # -> Workspace
     """
     Retrieve vanadium curves for this roi from the ADS if they exist, create them if not
     :param region: String describing region of interest
     :param van_processed_inst_ws: Processed instrument workspace of this vanadium run
     :param grouping_ws: Grouping workspace for DiffractionFoucussing
     :return: Curves workspace for this roi
     """
     curves_roi_name = CURVES_PREFIX + region
     # check if van curves for roi in ADS (should exist if not first run in session)
     if Ads.doesExist(curves_roi_name):
         return Ads.retrieve(curves_roi_name)
     else:
         # focus processed instrument ws over specified region of interest, iot produce vanadium curves for roi
         focused_curves = DiffractionFocussing(
             InputWorkspace=van_processed_inst_ws,
             OutputWorkspace=curves_roi_name,
             GroupingWorkspace=grouping_ws)
         EnggEstimateFocussedBackground(InputWorkspace=focused_curves,
                                        OutputWorkspace=focused_curves,
                                        NIterations='15',
                                        XWindow=0.03)
         return focused_curves
    def PyExec(self):
        raw_ws = self.getProperty('InputWorkspace').value
        sample_geometry = self.getPropertyValue('SampleGeometry')
        sample_material = self.getPropertyValue('SampleMaterial')
        cal_file_name = self.getPropertyValue('CalFileName')
        SetSample(InputWorkspace=raw_ws,
                  Geometry=sample_geometry,
                  Material=sample_material)
        # find the closest monitor to the sample for incident spectrum
        raw_spec_info = raw_ws.spectrumInfo()
        incident_index = None
        for i in range(raw_spec_info.size()):
            if raw_spec_info.isMonitor(i):
                l2 = raw_spec_info.position(i)[2]
                if not incident_index:
                    incident_index = i
                else:
                    if raw_spec_info.position(incident_index)[2] < l2 < 0:
                        incident_index = i
        monitor = ExtractSpectra(InputWorkspace=raw_ws,
                                 WorkspaceIndexList=[incident_index])
        monitor = ConvertUnits(InputWorkspace=monitor, Target="Wavelength")
        x_data = monitor.dataX(0)
        min_x = np.min(x_data)
        max_x = np.max(x_data)
        width_x = (max_x - min_x) / x_data.size
        fit_spectra = FitIncidentSpectrum(
            InputWorkspace=monitor,
            BinningForCalc=[min_x, 1 * width_x, max_x],
            BinningForFit=[min_x, 10 * width_x, max_x],
            FitSpectrumWith="CubicSpline")
        self_scattering_correction = CalculatePlaczekSelfScattering(
            InputWorkspace=raw_ws, IncidentSpecta=fit_spectra)
        cal_workspace = LoadCalFile(InputWorkspace=self_scattering_correction,
                                    CalFileName=cal_file_name,
                                    Workspacename='cal_workspace',
                                    MakeOffsetsWorkspace=False,
                                    MakeMaskWorkspace=False)
        self_scattering_correction = DiffractionFocussing(
            InputWorkspace=self_scattering_correction,
            GroupingFilename=cal_file_name)

        n_pixel = np.zeros(self_scattering_correction.getNumberHistograms())

        for i in range(cal_workspace.getNumberHistograms()):
            grouping = cal_workspace.dataY(i)
            if grouping[0] > 0:
                n_pixel[int(grouping[0] - 1)] += 1
        correction_ws = CreateWorkspace(
            DataY=n_pixel,
            DataX=[0, 1],
            NSpec=self_scattering_correction.getNumberHistograms())
        self_scattering_correction = Divide(
            LHSWorkspace=self_scattering_correction,
            RHSWorkspace=correction_ws)
        ConvertToDistribution(Workspace=self_scattering_correction)
        self_scattering_correction = ConvertUnits(
            InputWorkspace=self_scattering_correction,
            Target="MomentumTransfer",
            EMode='Elastic')
        DeleteWorkspace('cal_workspace_group')
        DeleteWorkspace(correction_ws)
        DeleteWorkspace(fit_spectra)
        DeleteWorkspace(monitor)
        DeleteWorkspace(raw_ws)
        self.setProperty('OutputWorkspace', self_scattering_correction)
Ejemplo n.º 10
0
def pdcalibration_groups(data_ws,
                         group_ws,
                         cc_diffcal,
                         to_skip,
                         output_basename="_tmp_group_pd_calibration",
                         previous_calibration=None,
                         PeakPositions=DIAMOND,
                         TofBinning=(300,-.001,16666.7),
                         PeakFunction='IkedaCarpenterPV',
                         PeakWindow=0.1,
                         PeakWidthPercent=None,
                         BadCalibThreshold=100):
    """This will perform PDCalibration of the group data and combine the
    results with the results of `cc_calibrate_groups`.

    This works by converting the data into d-spacing using the diffcal
    from the cross-correlation, then grouping the data using
    DiffractionFocussing after which it's converted back into TOF
    using an arbitarty diffcal (the combined of all detectors in the
    group). PDCalibration is performed on this grouped workspace after
    which the diffcal's are all combined according to

    .. math::

        DIFC_{effective} = DIFC_{PD} * DIFC_{CC} / DIFC_{arbitarty}

    :param data_ws: Input calibration raw data (in TOF), assumed to already be correctly masked
    :param group_ws: grouping workspace, e.g. output from LoadDetectorsGroupingFile
    :param cc_diffcal: DiffCal workspace which is the output from cc_calibrate_groups
    :param to_skip: Groups to skip the cross correlation stage
    :param output_basename: Optional name to use for temporay and output workspace
    :param previous_calibration: Optional previous diffcal workspace
    :param PeakPositions: PeakPositions parameter of PDCalibration, default Diamond peaks
    :param TofBinning: TofBinning parameter of PDCalibration, default (300,-.001,16666.7)
    :param PeakFunction: PeakFunction parameter of PDCalibration, default 'IkedaCarpenterPV'
    :param PeakWindow: PeakWindow parameter of PDCalibration, default 0.1
    :param PeakWidthPercent: PeakWidthPercent parameter of PDCalibration, default None
    :param BadCalibThreshold: Threshold for relative difference between calibrated DIFC and engineering value.
    :return: tuple of DiffCal and Mask (both as TableWorkspace objects) holding the combined DiffCal.
    """

    CreateDetectorTable(data_ws, DetectorTableWorkspace="calib_table_bak")

    ApplyDiffCal(data_ws, CalibrationWorkspace=cc_diffcal)
    ConvertUnits(data_ws, Target='dSpacing', OutputWorkspace='_tmp_data_aligned')
    DiffractionFocussing('_tmp_data_aligned', GroupingWorkspace=group_ws, OutputWorkspace='_tmp_data_aligned')

    ConvertUnits('_tmp_data_aligned', Target='TOF', OutputWorkspace='_tmp_data_aligned')

    instrument = data_ws.getInstrument().getName()

    if instrument != 'POWGEN':
        PDCalibration(InputWorkspace='_tmp_data_aligned',
                      TofBinning=TofBinning,
                      PreviousCalibrationTable=previous_calibration,
                      PeakFunction=PeakFunction,
                      PeakPositions=PeakPositions,
                      PeakWindow=PeakWindow,
                      PeakWidthPercent=PeakWidthPercent,
                      OutputCalibrationTable=f'{output_basename}_pd_diffcal',
                      DiagnosticWorkspaces=f'{output_basename}_pd_diag')
        if to_skip:
            ExtractSpectra(data_ws, WorkspaceIndexList=to_skip, OutputWorkspace='_tmp_group_to_skip')
            ExtractUnmaskedSpectra('_tmp_group_to_skip', OutputWorkspace='_tmp_group_to_skip')
            PDCalibration(InputWorkspace='_tmp_group_to_skip',
                          TofBinning=TofBinning,
                          PreviousCalibrationTable=previous_calibration,
                          PeakFunction=PeakFunction,
                          PeakPositions=PeakPositions,
                          PeakWindow=PeakWindow,
                          PeakWidthPercent=PeakWidthPercent,
                          OutputCalibrationTable=f'{output_basename}_pd_diffcal_skip',
                          DiagnosticWorkspaces=f'{output_basename}_pd_diag_skip')
    else:
        pdcalib_for_powgen(mtd['_tmp_data_aligned'],
                           TofBinning,
                           previous_calibration,
                           PeakFunction,
                           PeakPositions,
                           PeakWindow,
                           PeakWidthPercent,
                           f'{output_basename}_pd_diffcal',
                           f'{output_basename}_pd_diag')
        if to_skip:
            ExtractSpectra(data_ws, WorkspaceIndexList=to_skip, OutputWorkspace='_tmp_group_to_skip')
            ExtractUnmaskedSpectra('_tmp_group_to_skip', OutputWorkspace='_tmp_group_to_skip')
            pdcalib_for_powgen(mtd['_tmp_group_to_skip'],
                               [300,-0.0008,16667],
                               previous_calibration,
                               PeakFunction,
                               PeakPositions,
                               PeakWindow,
                               PeakWidthPercent,
                               f'{output_basename}_pd_diffcal_skip',
                               f'{output_basename}_pd_diag_skip')

    CombineDiffCal(PixelCalibration=cc_diffcal,
                   GroupedCalibration=f'{output_basename}_pd_diffcal',
                   CalibrationWorkspace='_tmp_data_aligned',
                   MaskWorkspace=f'{output_basename}_pd_diffcal_mask',
                   OutputWorkspace=f'{output_basename}_cc_pd_diffcal_tmp')

    DeleteWorkspace('_tmp_data_aligned')

    out_table = CreateEmptyTableWorkspace(OutputWorkspace=f'{output_basename}_cc_pd_diffcal')
    out_table.addColumn("int", "detid")
    out_table.addColumn("double", "difc")
    out_table.addColumn("double", "difa")
    out_table.addColumn("double", "tzero")
    num_hist = data_ws.getNumberHistograms()
    for i in range(num_hist):
        difc_bak = mtd['calib_table_bak'].row(i)['DIFC']
        if i in to_skip:
            difc_calib = mtd[f'{output_basename}_pd_diffcal_skip'].row(i)['difc']
        else:
            difc_calib = mtd[f'{output_basename}_cc_pd_diffcal_tmp'].row(i)['difc']
        if mtd[f'{output_basename}_pd_diffcal_mask'].readY(i)[0] == 0.0:
            diff_difc = abs(difc_bak - difc_calib) / difc_calib * 100.0
        else:
            diff_difc = np.inf
        if diff_difc >= BadCalibThreshold:
            difc_calib = difc_bak
        new_row = { 'detid': mtd[f'{output_basename}_cc_pd_diffcal_tmp'].row(i)['detid'],
                    'difc': difc_calib,
                    'difa': mtd[f'{output_basename}_cc_pd_diffcal_tmp'].row(i)['difa'],
                    'tzero': mtd[f'{output_basename}_cc_pd_diffcal_tmp'].row(i)['tzero'] }
        out_table.addRow(new_row)

    DeleteWorkspace(f'{output_basename}_cc_pd_diffcal_tmp')

    return mtd[f'{output_basename}_cc_pd_diffcal']
Ejemplo n.º 11
0
def save_banks(InputWorkspace,
               Filename,
               Title,
               OutputDir,
               Binning=None,
               GroupingWorkspace=None):
    """
    Saves input workspace to processed NeXus file in specified
    output directory with optional rebinning and grouping
    (to coarsen) the output in a bank-by-bank manner. Mainly
    wraps Mantid `SaveNexusProcessed` algorithm.

    :param InputWorkspace: Mantid workspace to save out
    :type InputWorkspace: MatrixWorkspace
    :param Filename: Filename to save output
    :type Filename: str
    :param Title: A title to describe the saved workspace
    :type Title: str
    :param OutputDir: Output directory to save the processed NeXus file
    :type OutputDir: path str
    :param Binning: Optional rebinning of event workspace.
                    See `Rebin` in Mantid for options
    :type Binning: dbl list
    :param GroupingWorkspace: A workspace with grouping
                              information for the output spectra
    :type GroupWorkspace: GroupWorkspace
    """

    # Make a local clone
    CloneWorkspace(InputWorkspace=InputWorkspace, OutputWorkspace="__tmp")
    tmp_wksp = mtd["__tmp"]

    # Rebin if requested
    if Binning:
        tmp_wksp = Rebin(InputWorkspace=tmp_wksp,
                         Params=Binning,
                         PreserveEvents=True)

    # Convert to distributions to remove bin width dependence
    yunit = tmp_wksp.YUnit()
    if yunit == "Counts":
        try:
            ConvertToDistribution(tmp_wksp)
        except BaseException:
            pass

    # Output to desired level of grouping
    isEventWksp = isinstance(tmp_wksp, IEventWorkspace)
    if isEventWksp and GroupingWorkspace and yunit == "Counts":
        tmp_wksp = DiffractionFocussing(InputWorkspace=tmp_wksp,
                                        GroupingWorkspace=GroupingWorkspace,
                                        PreserveEvents=False)

    # Save out wksp to file
    filename = os.path.join(os.path.abspath(OutputDir), Filename)
    SaveNexusProcessed(InputWorkspace=tmp_wksp,
                       Filename=filename,
                       Title=Title,
                       Append=True,
                       PreserveEvents=False,
                       WorkspaceIndexList=range(
                           tmp_wksp.getNumberHistograms()))
    DeleteWorkspace(tmp_wksp)