def test_set_placeholder_text_raises_error_if_workspaces_have_no_common_spectra(
         self):
     spectra_1 = ExtractSpectra(InputWorkspace=self._multi_spec_ws,
                                StartWorkspaceIndex=0,
                                EndWorkspaceIndex=5)
     spectra_2 = ExtractSpectra(InputWorkspace=self._multi_spec_ws,
                                StartWorkspaceIndex=6,
                                EndWorkspaceIndex=10)
     workspaces = [spectra_1, spectra_2]
     self.assertRaises(Exception,
                       'Error: Workspaces have no common spectra.',
                       SpectraSelectionDialog, workspaces)
예제 #2
0
def _extract_region(workspace: MatrixWorkspace,
                    xmin: float,
                    xmax: float,
                    indexmin: int,
                    indexmax: int,
                    name: str,
                    log_algorithm_calls: bool = True):
    """
    Assuming a MatrixWorkspace crop a region with the given parameters
    :param workspace: A MatrixWorkspace with a vertical SpectraAxis
    :param xmin: X min for bounded region
    :param xmax: X max for bounded region
    :param ymin: Y min for bounded region
    :param ymax: Y max for bounded region
    :param name: A name for the workspace
    """
    if not workspace.isCommonBins():
        # rebin to a common grid using the resolution from the spectrum
        # with the lowest resolution to avoid overbinning
        workspace = _rebin_to_common_grid(workspace, None, None,
                                          log_algorithm_calls)
    return ExtractSpectra(InputWorkspace=workspace,
                          OutputWorkspace=name,
                          XMin=xmin,
                          XMax=xmax,
                          StartWorkspaceIndex=indexmin,
                          EndWorkspaceIndex=indexmax,
                          EnableLogging=log_algorithm_calls)
예제 #3
0
    def test_get_spectra_selection_does_not_use_dialog_for_multiple__single_spectrum(
            self, dialog_mock):
        spectra_1 = ExtractSpectra(InputWorkspace=self._multi_spec_ws,
                                   StartWorkspaceIndex=0,
                                   EndWorkspaceIndex=0)
        spectra_2 = ExtractSpectra(InputWorkspace=self._multi_spec_ws,
                                   StartWorkspaceIndex=1,
                                   EndWorkspaceIndex=1)
        dialog_mock.get_compatible_workspaces.return_value = [
            spectra_1, spectra_2
        ]
        selection = get_spectra_selection([spectra_1, spectra_2])

        dialog_mock.assert_not_called()
        self.assertEqual([0], selection.wksp_indices)
        self.assertEqual([spectra_1, spectra_2], selection.workspaces)
    def runTest(self):
        ws_2d_tubes = self.d2b_2d_tubes_test()
        ws_2d = self.d2b_2d_test()
        ws_1d = self.d2b_1d_test()

        # Check loading and merging, and keeping files separate gives the same results
        ws_2d_merge = self.d2b_2d_tubes_test_using_merge()
        result_merge = CompareWorkspaces(Workspace1=ws_2d,
                                         Workspace2=ws_2d_merge)
        self.assertTrue(result_merge)

        # Check height range given is a subset of a full 2D option
        ws_2d_height = self.d2b_2d_height_test()
        ws_2d_cropped = ExtractSpectra(InputWorkspace=ws_2d[0],
                                       StartWorkspaceIndex=43,
                                       EndWorkspaceIndex=84)
        result_height = CompareWorkspaces(Workspace1=ws_2d_cropped,
                                          Workspace2=ws_2d_height)
        self.assertTrue(result_height)

        GroupWorkspaces([ws_2d_tubes[0], ws_2d[0], ws_1d[0]],
                        OutputWorkspace='grouped_output')
    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)
예제 #6
0
def cc_calibrate_groups(data_ws,
                        group_ws,
                        output_basename="_tmp_group_cc_calibration",
                        previous_calibration=None,
                        Step=0.001,
                        DReference=1.2615,
                        Xmin=1.22,
                        Xmax=1.30,
                        MaxDSpaceShift=None,
                        OffsetThreshold=1E-4,
                        SkipCrossCorrelation=[],
                        PeakFunction="Gaussian",
                        SmoothNPoints=0):
    """This will perform the CrossCorrelate/GetDetectorOffsets on a group
    of detector pixel.

    It works by looping over the different groups in the group_ws,
    extracting all unmasked spectra of a group, then running
    CrossCorrelate and GetDetectorOffsets on just that group, and
    combinning the results at the end. When running a group,
    CrossCorrelate and GetDetectorOffsets could be cycled until
    converging of offsets is reached, given the user input offset
    threshold. If offset threshold is specified to be equal to or
    larger than 1.0, no cycling will be carried out.

    The first unmasked spectra of the group will be used for the
    ReferenceSpectra in CrossCorrelate.

    :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 output_basename: Optional name to use for temporay and output workspace
    :param previous_calibration: Optional previous diffcal workspace
    :param Step: step size for binning of data and input for GetDetectorOffsets, default 0.001
    :param DReference: Derefernce parameter for GetDetectorOffsets, default 1.2615
    :param Xmin: Xmin parameter for CrossCorrelate, default 1.22
    :param Xmax: Xmax parameter for CrossCorrelate, default 1.30
    :param MaxDSpaceShift: MaxDSpaceShift paramter for CrossCorrelate, default None
    :param OffsetThreshold: Convergence threshold for cycling cross correlation, default 1E-4
    :param SkipCrossCorrelation: Skip cross correlation for specified groups
    :param PeakFunction: Peak function to use for extracting the offset
    :param SmoothNPoints: Number of points for smoothing spectra, for cross correlation ONLY
    :return: Combined DiffCal workspace from all the different groups
    """
    if previous_calibration:
        ApplyDiffCal(data_ws, CalibrationWorkspace=previous_calibration)

    data_d = ConvertUnits(data_ws, Target='dSpacing', OutputWorkspace='data_d')

    group_list = np.unique(group_ws.extractY())

    _accum_cc = None
    to_skip = []
    for group in group_list:
        # Figure out input parameters for CrossCorrelate and GetDetectorOffset, specifically
        # for those parameters for which both a single value and a list is accepted. If a
        # list is given, that means different parameter setup will be used for different groups.
        Xmin_group = Xmin[int(group) - 1] if type(Xmin) == list else Xmin
        Xmax_group = Xmax[int(group) - 1] if type(Xmax) == list else Xmax
        MDS_group = MaxDSpaceShift[int(group) - 1] if type(MaxDSpaceShift) == list else MaxDSpaceShift
        DRef_group = DReference[int(group) - 1] if type(DReference) == list else DReference
        OT_group = OffsetThreshold[int(group) - 1] if type(OffsetThreshold) == list else OffsetThreshold
        pf_group = PeakFunction[int(group) - 1] if type(PeakFunction) == list else PeakFunction
        snpts_group = SmoothNPoints[int(group) - 1] if type(SmoothNPoints) == list else SmoothNPoints
        cycling = OT_group < 1.0

        indexes = np.where(group_ws.extractY().flatten() == group)[0]
        sn = np.array(group_ws.getSpectrumNumbers())[indexes]
        try:
            ws_indexes = [data_d.getIndexFromSpectrumNumber(int(i)) for i in sn]
        except RuntimeError:
            # data does not contain spectrum in group
            continue

        if group in SkipCrossCorrelation:
            to_skip.extend(ws_indexes)

        ExtractSpectra(data_d, WorkspaceIndexList=ws_indexes, OutputWorkspace='_tmp_group_cc')
        ExtractUnmaskedSpectra('_tmp_group_cc', OutputWorkspace='_tmp_group_cc')
        ExtractSpectra(data_ws, WorkspaceIndexList=ws_indexes, OutputWorkspace='_tmp_group_cc_raw')
        ExtractUnmaskedSpectra('_tmp_group_cc_raw', OutputWorkspace='_tmp_group_cc_raw')
        num_spectra = mtd['_tmp_group_cc'].getNumberHistograms()
        if num_spectra < 2:
            continue
        Rebin('_tmp_group_cc', Params=f'{Xmin_group},{Step},{Xmax_group}', OutputWorkspace='_tmp_group_cc')
        if snpts_group >= 3:
            SmoothData('_tmp_group_cc', NPoints=snpts_group, OutputWorkspace='_tmp_group_cc')

        # Figure out brightest spectra to be used as the reference for cross correlation.
        CloneWorkspace('_tmp_group_cc_raw', OutputWorkspace='_tmp_group_cc_raw_tmp')
        intg = Integration('_tmp_group_cc_raw_tmp',
                           StartWorkspaceIndex=0,
                           EndWorkspaceIndex=num_spectra-1,
                           OutputWorkspace='_tmp_group_intg')
        brightest_spec_index = int(np.argmax(np.array([intg.readY(i)[0] for i in range(num_spectra)])))

        # Cycling cross correlation. At each step, we will use the obtained offsets and DIFC's from
        # previous step to obtain new DIFC's. In this way, spectra in group will come closer and closer
        # to each other as the cycle goes. This will continue until converging criterion is reached. The
        # converging criterion is set in such a way that the median value of all the non-zero offsets
        # should be smaller than the threshold (user tuned parameter, default to 1E-4, meaning 0.04%
        # relative offset).
        num_cycle = 1
        while True:
            CrossCorrelate('_tmp_group_cc',
                           Xmin=Xmin_group, XMax=Xmax_group,
                           MaxDSpaceShift=MDS_group,
                           ReferenceSpectra=brightest_spec_index,
                           WorkspaceIndexMin=0,
                           WorkspaceIndexMax=num_spectra-1,
                           OutputWorkspace='_tmp_group_cc')

            bin_range = (Xmax_group-Xmin_group)/Step
            GetDetectorOffsets(InputWorkspace='_tmp_group_cc',
                               Step=Step,
                               Xmin=-bin_range, XMax=bin_range,
                               DReference=DRef_group,
                               MaxOffset=1,
                               PeakFunction=pf_group,
                               OutputWorkspace='_tmp_group_cc')

            if group not in SkipCrossCorrelation:
                offsets_tmp = []
                for item in ws_indexes:
                    if abs(mtd['_tmp_group_cc'].readY(item)) != 0:
                        offsets_tmp.append(abs(mtd['_tmp_group_cc'].readY(item)))
                offsets_tmp = np.array(offsets_tmp)
                logger.notice(f'Running group-{group}, cycle-{num_cycle}.')
                logger.notice(f'Median offset (no sign) = {np.median(offsets_tmp)}')
                logger.notice(f'Running group-{group}, cycle-{num_cycle}.')
                logger.notice(f'Median offset (no sign) = {np.median(offsets_tmp)}')
                converged = np.median(offsets_tmp) < OT_group
            else:
                for item in ws_indexes:
                    mtd['_tmp_group_cc'].dataY(item)[0] = 0.0
                logger.notice(f'Cross correlation skipped for group-{group}.')
                converged = True

            if not cycling or converged:
                if cycling and converged:
                    if group not in SkipCrossCorrelation:
                        logger.notice(f'Cross correlation for group-{group} converged, ')
                        logger.notice(f'with offset threshold {OT_group}.')
                break
            else:
                previous_calibration = ConvertDiffCal('_tmp_group_cc',
                                                      PreviousCalibration=previous_calibration,
                                                      OutputWorkspace='_tmp_group_cc_diffcal')
                ApplyDiffCal('_tmp_group_cc_raw', CalibrationWorkspace='_tmp_group_cc_diffcal')
                ConvertUnits('_tmp_group_cc_raw', Target='dSpacing', OutputWorkspace='_tmp_group_cc')
                Rebin('_tmp_group_cc', Params=f'{Xmin_group},{Step},{Xmax_group}', OutputWorkspace='_tmp_group_cc')

            num_cycle += 1

        if not _accum_cc:
            _accum_cc = RenameWorkspace('_tmp_group_cc')
        else:
            _accum_cc += mtd['_tmp_group_cc']
            # DeleteWorkspace('_tmp_group_cc')

    previous_calibration = ConvertDiffCal('_accum_cc',
                                          PreviousCalibration=previous_calibration,
                                          OutputWorkspace=f'{output_basename}_cc_diffcal')

    DeleteWorkspace('_accum_cc')
    DeleteWorkspace('_tmp_group_cc')
    DeleteWorkspace('_tmp_group_cc_raw')
    if cycling and '_tmp_group_cc_diffcal' in mtd:
        DeleteWorkspace('_tmp_group_cc_diffcal')

    return mtd[f'{output_basename}_cc_diffcal'], to_skip
예제 #7
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']
예제 #8
0
def _extract_spectra(workspace, indices):
    return ExtractSpectra(InputWorkspace=workspace,
                          WorkspaceIndexList=indices,
                          OutputWorkspace="__extracted",
                          StoreInADS=False,
                          EnableLogging=False)
예제 #9
0
    def PyExec(self):
        inputWS = self.getProperty("InputWorkspace").value
        outputWS = self.getProperty("OutputWorkspace").valueAsStr
        xmins = self.getProperty("XMin").value
        xmaxs = self.getProperty("XMax").value
        deltas = self.getProperty("Delta").value
        preserveEvents = self.getProperty("PreserveEvents").value

        if self.__use_simple_rebin(xmins, xmaxs, deltas):
            # plain old rebin should have been used
            name = "__{}_rebinned_".format(outputWS)
            params = (xmins[0], deltas[0], xmaxs[0])
            Rebin(InputWorkspace=inputWS,
                  OutputWorkspace=name,
                  Params=params,
                  PreserveEvents=preserveEvents)
            self.setProperty("OutputWorkspace", mtd[name])
            DeleteWorkspace(name)
        else:
            numSpec = inputWS.getNumberHistograms()

            # fill out the values for min and max as appropriate
            xmins = self.__extend_value(numSpec, xmins, replaceNan=True)
            xmaxs = self.__extend_value(numSpec, xmaxs, replaceNan=True)
            deltas = self.__extend_value(numSpec, deltas, replaceNan=False)

            self.log().debug("MIN:  " + str(xmins))
            self.log().debug("DELTA:" + str(deltas))
            self.log().debug("MAX:  " + str(xmaxs))

            # temporary workspaces should be hidden
            names = [
                "__{}_spec_{}".format(outputWS, i) for i in range(len(xmins))
            ]

            # how much the progress bar moves forward for each spectrum
            progStep = float(1) / float(3 * numSpec)

            # crop out each spectra and conjoin to a temporary workspace
            accumulationWS = None
            for i, (name, xmin, xmax,
                    delta) in enumerate(zip(names, xmins, xmaxs, deltas)):
                # don't  go beyond the range of the data
                x = inputWS.readX(i)
                if xmin == Property.EMPTY_DBL:
                    xmin = x[0]
                if xmax == Property.EMPTY_DBL:
                    xmax = x[-1]

                progStart = 3 * i * progStep

                try:
                    # extract the range of the spectrum requested
                    ExtractSpectra(InputWorkspace=inputWS,
                                   OutputWorkspace=name,
                                   StartWorkspaceIndex=i,
                                   EndWorkspaceIndex=i,
                                   XMin=xmin,
                                   XMax=xmax,
                                   startProgress=progStart,
                                   endProgress=(progStart + progStep),
                                   EnableLogging=False)

                    # rebin the data
                    Rebin(InputWorkspace=name,
                          OutputWorkspace=name,
                          Params=(xmin, delta, xmax),
                          PreserveEvents=preserveEvents,
                          startProgress=progStart,
                          endProgress=(progStart + progStep),
                          EnableLogging=False)
                except Exception as e:
                    raise RuntimeError('for index={}: {}'.format(i, e)) from e

                # accumulate
                if accumulationWS is None:
                    accumulationWS = name  # messes up progress during very first step
                else:
                    # this deletes both input workspaces
                    ConjoinWorkspaces(InputWorkspace1=accumulationWS,
                                      InputWorkspace2=name,
                                      startProgress=(progStart + 2 * progStep),
                                      endProgress=(progStart + 3 * progStep),
                                      EnableLogging=False)
            self.setProperty("OutputWorkspace", mtd[accumulationWS])
            DeleteWorkspace(accumulationWS, EnableLogging=False)
예제 #10
0
    def PyExec(self):
        fn = self.getPropertyValue("Filename")
        wsn = self.getPropertyValue("OutputWorkspace")
        #print (fn, wsn)

        self.fxml = self.getPropertyValue("InstrumentXML")

        #load data

        parms_dict, det_udet, det_count, det_tbc, data = self.read_file(fn)
        nrows = int(parms_dict['NDET'])
        #nbins=int(parms_dict['NTC'])
        xdata = np.array(det_tbc)
        xdata_mon = np.linspace(xdata[0], xdata[-1], len(xdata))
        ydata = data.astype(np.float)
        ydata = ydata.reshape(nrows, -1)
        edata = np.sqrt(ydata)
        #CreateWorkspace(OutputWorkspace=wsn,DataX=xdata,DataY=ydata,DataE=edata,
        #                NSpec=nrows,UnitX='TOF',WorkspaceTitle='Data',YUnitLabel='Counts')
        nr, nc = ydata.shape
        ws = WorkspaceFactory.create("Workspace2D",
                                     NVectors=nr,
                                     XLength=nc + 1,
                                     YLength=nc)
        for i in range(nrows):
            ws.setX(i, xdata)
            ws.setY(i, ydata[i])
            ws.setE(i, edata[i])
        ws.getAxis(0).setUnit('tof')
        AnalysisDataService.addOrReplace(wsn, ws)

        #self.setProperty("OutputWorkspace", wsn)
        #print ("ws:", wsn)
        #ws=mtd[wsn]

        # fix the x values for the monitor
        for i in range(nrows - 2, nrows):
            ws.setX(i, xdata_mon)
        self.log().information("set detector IDs")
        #set detetector IDs
        for i in range(nrows):
            ws.getSpectrum(i).setDetectorID(det_udet[i])
        #Sample_logs the header values are written into the sample logs
        log_names = [sl.encode('ascii', 'ignore') for sl in parms_dict.keys()]
        log_values = [
            sl.encode('ascii', 'ignore')
            if isinstance(sl, types.UnicodeType) else str(sl)
            for sl in parms_dict.values()
        ]
        AddSampleLogMultiple(Workspace=wsn,
                             LogNames=log_names,
                             LogValues=log_values)
        SetGoniometer(Workspace=wsn, Goniometers='Universal')
        if (self.fxml == ""):
            LoadInstrument(Workspace=wsn,
                           InstrumentName="Exed",
                           RewriteSpectraMap=True)
        else:
            LoadInstrument(Workspace=wsn,
                           Filename=self.fxml,
                           RewriteSpectraMap=True)
        RotateInstrumentComponent(
            Workspace=wsn,
            ComponentName='Tank',
            Y=1,
            Angle=-float(parms_dict['phi'].encode('ascii', 'ignore')),
            RelativeRotation=False)
        # Separate monitors into seperate workspace
        ExtractSpectra(InputWorkspace=wsn,
                       WorkspaceIndexList=','.join(
                           [str(s) for s in range(nrows - 2, nrows)]),
                       OutputWorkspace=wsn + '_Monitors')
        MaskDetectors(Workspace=wsn,
                      WorkspaceIndexList=','.join(
                          [str(s) for s in range(nrows - 2, nrows)]))
        RemoveMaskedSpectra(InputWorkspace=wsn, OutputWorkspace=wsn)

        self.setProperty("OutputWorkspace", wsn)
예제 #11
0
 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,
                                                                 IncidentSpectra=fit_spectra,
                                                                 ScaleByPackingFraction=False,
                                                                 Version=1)
     # Convert to Q
     self_scattering_correction = ConvertUnits(InputWorkspace=self_scattering_correction,
                                               Target="MomentumTransfer", EMode='Elastic')
     cal_workspace = LoadCalFile(InputWorkspace=self_scattering_correction,
                                 CalFileName=cal_file_name,
                                 Workspacename='cal_workspace',
                                 MakeOffsetsWorkspace=False,
                                 MakeMaskWorkspace=False,
                                 MakeGroupingWorkspace=True)
     ssc_min_x, ssc_max_x = float('inf'), float('-inf')
     for index in range(self_scattering_correction.getNumberHistograms()):
         spec_info = self_scattering_correction.spectrumInfo()
         if not spec_info.isMasked(index) and not spec_info.isMonitor(index):
             ssc_x_data = np.ma.masked_invalid(self_scattering_correction.dataX(index))
             if np.min(ssc_x_data) < ssc_min_x:
                 ssc_min_x = np.min(ssc_x_data)
             if np.max(ssc_x_data) > ssc_max_x:
                 ssc_max_x = np.max(ssc_x_data)
     ssc_width_x = (ssc_max_x - ssc_min_x) / ssc_x_data.size
     # TO DO: calculate rebin parameters per group
     # and run GroupDetectors on each separately
     self_scattering_correction = Rebin(InputWorkspace=self_scattering_correction,
                                        Params=[ssc_min_x, ssc_width_x, ssc_max_x],
                                        IgnoreBinErrors=True)
     self_scattering_correction = GroupDetectors(InputWorkspace=self_scattering_correction,
                                                 CopyGroupingFromWorkspace='cal_workspace_group')
     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)
     DeleteWorkspace('cal_workspace_group')
     DeleteWorkspace(correction_ws)
     DeleteWorkspace(fit_spectra)
     DeleteWorkspace(monitor)
     DeleteWorkspace(raw_ws)
     self.setProperty('OutputWorkspace', self_scattering_correction)
예제 #12
0
    def PyExec(self):
        fn = self.getPropertyValue("Filename")
        wsn = self.getPropertyValue("OutputWorkspace")
        monitor_workspace_name = self.getPropertyValue(
            "OutputMonitorWorkspace")
        if monitor_workspace_name == "":
            self.setPropertyValue("OutputMonitorWorkspace", wsn + '_Monitors')
        # print (fn, wsn)
        self.override_angle = self.getPropertyValue("AngleOverride")
        self.fxml = self.getPropertyValue("InstrumentXML")

        # load data

        parms_dict, det_udet, det_count, det_tbc, data = self.read_file(fn)
        nrows = int(parms_dict['NDET'])
        # nbins=int(parms_dict['NTC'])
        xdata = np.array(det_tbc)
        xdata_mon = np.linspace(xdata[0], xdata[-1], len(xdata))
        ydata = data.astype(float)
        ydata = ydata.reshape(nrows, -1)
        edata = np.sqrt(ydata)
        # CreateWorkspace(OutputWorkspace=wsn,DataX=xdata,DataY=ydata,DataE=edata,
        #                NSpec=nrows,UnitX='TOF',WorkspaceTitle='Data',YUnitLabel='Counts')
        nr, nc = ydata.shape
        ws = WorkspaceFactory.create("Workspace2D",
                                     NVectors=nr,
                                     XLength=nc + 1,
                                     YLength=nc)
        for i in range(nrows):
            ws.setX(i, xdata)
            ws.setY(i, ydata[i])
            ws.setE(i, edata[i])
        ws.getAxis(0).setUnit('tof')
        AnalysisDataService.addOrReplace(wsn, ws)

        # self.setProperty("OutputWorkspace", wsn)
        # print ("ws:", wsn)
        # ws=mtd[wsn]

        # fix the x values for the monitor
        for i in range(nrows - 2, nrows):
            ws.setX(i, xdata_mon)
        self.log().information("set detector IDs")
        # set detetector IDs
        for i in range(nrows):
            ws.getSpectrum(i).setDetectorID(det_udet[i])
        # Sample_logs the header values are written into the sample logs
        log_names = [
            str(sl.encode('ascii', 'ignore').decode())
            for sl in parms_dict.keys()
        ]
        log_values = [
            str(sl.encode('ascii', 'ignore').decode()) if isinstance(
                sl, UnicodeType) else str(sl) for sl in parms_dict.values()
        ]
        for i in range(len(log_values)):
            if ('nan' in log_values[i]) or ('NaN' in log_values[i]):
                log_values[i] = '-1.0'
        AddSampleLogMultiple(Workspace=wsn,
                             LogNames=log_names,
                             LogValues=log_values)
        SetGoniometer(Workspace=wsn, Goniometers='Universal')
        if (self.fxml == ""):
            LoadInstrument(Workspace=wsn,
                           InstrumentName="Exed",
                           RewriteSpectraMap=True)
        else:
            LoadInstrument(Workspace=wsn,
                           Filename=self.fxml,
                           RewriteSpectraMap=True)
        try:
            RotateInstrumentComponent(
                Workspace=wsn,
                ComponentName='Tank',
                Y=1,
                Angle=-float(parms_dict['phi'].encode('ascii', 'ignore')),
                RelativeRotation=False)
        except:
            self.log().warning(
                "The instrument does not contain a 'Tank' component. "
                "This means that you are using a custom XML instrument definition. "
                "OMEGA_MAG will be ignored.")
            self.log().warning(
                "Please make sure that the detector positions in the instrument definition are correct."
            )
        # Separate monitors into seperate workspace
        __temp_monitors = ExtractSpectra(
            InputWorkspace=wsn,
            WorkspaceIndexList=','.join(
                [str(s) for s in range(nrows - 2, nrows)]),
            OutputWorkspace=self.getPropertyValue("OutputMonitorWorkspace"))
        # ExtractSpectra(InputWorkspace = wsn, WorkspaceIndexList = ','.join([str(s) for s in range(nrows-2, nrows)]),
        # OutputWorkspace = wsn + '_Monitors')
        MaskDetectors(Workspace=wsn,
                      WorkspaceIndexList=','.join(
                          [str(s) for s in range(nrows - 2, nrows)]))
        RemoveMaskedSpectra(InputWorkspace=wsn, OutputWorkspace=wsn)

        self.setProperty("OutputWorkspace", wsn)
        self.setProperty("OutputMonitorWorkspace", __temp_monitors)