Ejemplo n.º 1
0
 def monitorTransfit(self, files, foilType, divE):
     isFirstFile = True
     isSingleFile = len(files) == 1
     firstFileName = ""
     for file in files:
         discard, fileName = path.split(file)
         fnNoExt = path.splitext(fileName)[0]
         if isFirstFile:
             firstFileName = fnNoExt
         fileName_Raw = fnNoExt + '_raw'
         fileName_3 = fnNoExt + '_3'
         LoadRaw(Filename=file, OutputWorkspace=fileName_Raw)
         CropWorkspace(InputWorkspace=fileName_Raw, OutputWorkspace=fileName_Raw, XMin=100, XMax=19990)
         NormaliseByCurrent(InputWorkspace=fileName_Raw, OutputWorkspace=fileName_Raw)
         ExtractSingleSpectrum(InputWorkspace=fileName_Raw, OutputWorkspace=fileName_3, WorkspaceIndex=3)
         DeleteWorkspace(fileName_Raw)
         ConvertUnits(InputWorkspace=fileName_3, Target='Energy', OutputWorkspace=fileName_3)
         self.TransfitRebin(fileName_3, fileName_3, foilType, divE)
         if not isFirstFile:
             Plus(LHSWorkspace=firstFileName + '_3', RHSWorkspace=fileName_3, OutputWorkspace=firstFileName + '_3')
             DeleteWorkspace(fileName_3)
         else:
             isFirstFile = False
     if isSingleFile:
         RenameWorkspace(InputWorkspace=firstFileName + '_3', OutputWorkspace=firstFileName + '_monitor')
     else:
         noFiles = len(files) ** (-1)
         CreateSingleValuedWorkspace(OutputWorkspace='scale', DataValue=noFiles)
         Multiply(LHSWorkspace=firstFileName + '_3', RHSWorkspace='scale',
                  OutputWorkspace=firstFileName + '_monitor')
         DeleteWorkspace('scale')
         DeleteWorkspace(firstFileName + '_3')
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 _whole_inst_prefocus(input_workspace, vanadium_integration_ws,
                          full_calib) -> bool:
     """This is used to perform the operations done on the whole instrument workspace, before the chosen region of
     interest is focused using _run_focus
     :param input_workspace: Raw sample run to process prior to focussing over a region of interest
     :param vanadium_integration_ws: Integral of the supplied vanadium run
     :param full_calib: Full instrument calibration workspace (table ws output from PDCalibration)
     :return True if successful, False if aborted
     """
     if input_workspace.getRun().getProtonCharge() > 0:
         NormaliseByCurrent(InputWorkspace=input_workspace,
                            OutputWorkspace=input_workspace)
     else:
         logger.warning(
             f"Skipping focus of run {input_workspace.name()} because it has invalid proton charge."
         )
         return False
     input_workspace /= vanadium_integration_ws
     # replace nans created in sensitivity correction
     ReplaceSpecialValues(InputWorkspace=input_workspace,
                          OutputWorkspace=input_workspace,
                          NaNValue=0,
                          InfinityValue=0)
     ApplyDiffCal(InstrumentWorkspace=input_workspace,
                  CalibrationWorkspace=full_calib)
     ConvertUnits(InputWorkspace=input_workspace,
                  OutputWorkspace=input_workspace,
                  Target='dSpacing')
     return True
Ejemplo n.º 4
0
    def PyExec(self):
        self._loadCharacterizations()
        charac = ""
        if mtd.doesExist("characterizations"):
            charac = "characterizations"

        # arguments for both AlignAndFocusPowder and AlignAndFocusPowderFromFiles
        self._alignArgs['OutputWorkspace'] = self.getPropertyValue("OutputWorkspace")
        self._alignArgs['RemovePromptPulseWidth'] = self.getProperty("RemovePromptPulseWidth").value
        self._alignArgs['CompressTolerance'] = COMPRESS_TOL_TOF
        self._alignArgs['PreserveEvents'] = True
        self._alignArgs['CalFileName'] = self.getProperty("CalibrationFile").value
        self._alignArgs['Params']=self.getProperty("Binning").value
        self._alignArgs['ResampleX']=self.getProperty("ResampleX").value
        self._alignArgs['Dspacing']=True
        self._alignArgs['CropWavelengthMin'] = self.getProperty('CropWavelengthMin').value
        self._alignArgs['CropWavelengthMax'] = self.getProperty('CropWavelengthMax').value
        self._alignArgs['ReductionProperties'] = '__snspowderreduction'

        wksp = self.getProperty("InputWorkspace").value
        if wksp is None:  # run from file with caching
            wksp = AlignAndFocusPowderFromFiles(Filename=self.getProperty("Filename").value,
                                                CacheDir=self.getProperty("CacheDir").value,
                                                MaxChunkSize=self.getProperty("MaxChunkSize").value,
                                                FilterBadPulses=self.getProperty("FilterBadPulses").value,
                                                Characterizations=charac,
                                                FrequencyLogNames=self.getProperty("FrequencyLogNames").value,
                                                WaveLengthLogNames=self.getProperty("WaveLengthLogNames").value,
                                                **(self._alignArgs))
        else:  # process the input workspace
            self.log().information("Using input workspace. Ignoring properties 'Filename', " +
                                   "'OutputWorkspace', 'MaxChunkSize', and 'FilterBadPulses'")

            # get the correct row of the table
            PDDetermineCharacterizations(InputWorkspace=wksp,
                                         Characterizations=charac,
                                         ReductionProperties="__snspowderreduction",
                                         FrequencyLogNames=self.getProperty("FrequencyLogNames").value,
                                         WaveLengthLogNames=self.getProperty("WaveLengthLogNames").value)

            wksp = AlignAndFocusPowder(InputWorkspace=wksp,
                                       **(self._alignArgs))

        wksp = NormaliseByCurrent(InputWorkspace=wksp, OutputWorkspace=wksp)
        wksp.getRun()['gsas_monitor'] = 1
        if self._iparmFile is not None:
            wksp.getRun()['iparm_file'] = self._iparmFile

        wksp = SetUncertainties(InputWorkspace=wksp, OutputWorkspace=wksp,
                                SetError="sqrtOrOne")
        SaveGSS(InputWorkspace=wksp,
                Filename=self.getProperty("PDFgetNFile").value,
                SplitFiles=False, Append=False,
                MultiplyByBinWidth=False,
                Bank=mantid.pmds["__snspowderreduction"]["bank"].value,
                Format="SLOG", ExtendedHeader=True)

        self.setProperty("OutputWorkspace", wksp)
Ejemplo n.º 5
0
def _calculate_vanadium_integral(van_ws, run_no):  # -> Workspace
    """
    Calculate the integral of the normalised vanadium workspace
    :param van_ws: Chosen vanadium run workspace
    :return: Integrated workspace
    """
    ws = NormaliseByCurrent(
        InputWorkspace=van_ws,
        OutputWorkspace=str(run_no) + "_" +
        INTEGRATED_WORKSPACE_NAME)  # create new name ws here
    # sensitivity correction for van
    ws_integ = Integration(InputWorkspace=ws, OutputWorkspace=ws)
    ws_integ /= van_ws.blocksize()
    return ws_integ
Ejemplo n.º 6
0
    def _alignAndFocus(self, filename, wkspname, detCalFilename,
                       withUnfocussed, progStart, progDelta):
        # create the unfocussed name
        if withUnfocussed:
            unfocussed = wkspname.replace('_red', '')
            unfocussed = unfocussed + '_d'
        else:
            unfocussed = ''

        # process the data
        if detCalFilename:
            progEnd = progStart + .45 * progDelta
            # have to load and override the instrument here
            Load(Filename=filename,
                 OutputWorkspace=wkspname,
                 startProgress=progStart,
                 endProgress=progEnd)
            progStart = progEnd
            progEnd += .45 * progDelta

            LoadIsawDetCal(InputWorkspace=wkspname, Filename=detCalFilename)

            AlignAndFocusPowder(
                InputWorkspace=wkspname,
                OutputWorkspace=wkspname,
                UnfocussedWorkspace=unfocussed,  # can be empty string
                startProgress=progStart,
                endProgress=progEnd,
                **self.alignAndFocusArgs)
            progStart = progEnd
        else:
            progEnd = progStart + .9 * progDelta
            # pass all of the work to the child algorithm
            AlignAndFocusPowderFromFiles(
                Filename=filename,
                OutputWorkspace=wkspname,
                MaxChunkSize=self.chunkSize,
                UnfocussedWorkspace=unfocussed,  # can be empty string
                startProgress=progStart,
                endProgress=progEnd,
                **self.alignAndFocusArgs)
            progStart = progEnd

        progEnd = progStart + .1 * progDelta
        NormaliseByCurrent(InputWorkspace=wkspname,
                           OutputWorkspace=wkspname,
                           startProgress=progStart,
                           endProgress=progEnd)

        return wkspname, unfocussed
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 load(ws_name,
         input_files,
         geometry=None,
         chemical_formula=None,
         mass_density=None,
         **align_and_focus_args):
    AlignAndFocusPowderFromFiles(OutputWorkspace=ws_name,
                                 Filename=input_files,
                                 Absorption=None,
                                 **align_and_focus_args)
    NormaliseByCurrent(InputWorkspace=ws_name,
                       OutputWorkspace=ws_name,
                       RecalculatePCharge=True)
    if geometry and chemical_formula and mass_density:
        set_sample(ws_name, geometry, chemical_formula, mass_density)

    ConvertUnits(InputWorkspace=ws_name,
                 OutputWorkspace=ws_name,
                 Target="MomentumTransfer",
                 EMode="Elastic")
    return ws_name
def load_data_and_normalise(filename,
                            spectrumMin=1,
                            spectrumMax=19461,
                            outputWorkspace="sample"):
    """
    Function to load in raw data, crop and normalise
    :param filename: file path to .raw
    :param spectrumMin: min spec to load (default incl. all monitors)
    :param spectrumMax: max spec to load (default includes only bank 1)
    :param outputWorkspace: name of output workspace (can be specified to stop workspaces being overwritten)
    :return: normalised and cropped data with xunit wavelength (excl. monitors)
    """
    sample, mon = LoadRaw(Filename=filename,
                          SpectrumMin=spectrumMin,
                          SpectrumMax=spectrumMax,
                          LoadMonitors="Separate",
                          OutputWorkspace=outputWorkspace)
    for ws in [sample, mon]:
        CropWorkspace(InputWorkspace=ws,
                      OutputWorkspace=ws,
                      XMin=6000,
                      XMax=99000)
        NormaliseByCurrent(InputWorkspace=ws, OutputWorkspace=ws)
        ConvertUnits(InputWorkspace=ws,
                     OutputWorkspace=ws,
                     Target='Wavelength')
    NormaliseToMonitor(InputWorkspace=sample,
                       OutputWorkspace=sample,
                       MonitorWorkspaceIndex=3,
                       MonitorWorkspace=mon)
    ReplaceSpecialValues(InputWorkspace=sample,
                         OutputWorkspace=sample,
                         NaNValue=0,
                         InfinityValue=0)
    CropWorkspace(InputWorkspace=sample,
                  OutputWorkspace=sample,
                  XMin=0.8,
                  XMax=9.3)
    return sample
Ejemplo n.º 10
0
def _calculate_vanadium_processed_instrument(van_ws, full_calib_ws,
                                             integral_ws,
                                             run_no):  # -> Workspace
    """
    Calculate the processed whole-instrument workspace
    :param van_ws: Chosen vanadium run workspace
    :param full_calib_ws: Table workspace from the full instrument calibration (output from PDCalibration)
    :param integral_ws: Vanadium integral workspace
    :return: Whole instrument processed workspace
    """
    ws = NormaliseByCurrent(
        InputWorkspace=van_ws,
        OutputWorkspace=str(run_no) + "_" +
        PROCESSED_WORKSPACE_NAME)  # create new name ws here
    ApplyDiffCal(InstrumentWorkspace=ws, CalibrationWorkspace=full_calib_ws)
    ConvertUnits(InputWorkspace=ws, OutputWorkspace=ws, Target='dSpacing')
    # van sensitivity correction
    ws /= integral_ws
    ReplaceSpecialValues(InputWorkspace=ws,
                         OutputWorkspace=ws,
                         NaNValue=0,
                         InfinityValue=0)
    return ws
Ejemplo n.º 11
0
    def PyExec(self):
        # Retrieve all relevant notice

        in_Runs = self.getProperty("RunNumbers").value

        maskWSname = self._getMaskWSname()

        # either type of file-based calibration is stored in the same variable
        calib = self.getProperty("Calibration").value
        if calib == "Calibration File":
            cal_File = self.getProperty("CalibrationFilename").value
        elif calib == 'DetCal File':
            cal_File = self.getProperty('DetCalFilename').value
            cal_File = ','.join(cal_File)
        else:
            cal_File = None

        params = self.getProperty("Binning").value
        norm = self.getProperty("Normalization").value

        if norm == "From Processed Nexus":
            norm_File = self.getProperty("NormalizationFilename").value
            LoadNexusProcessed(Filename=norm_File, OutputWorkspace='normWS')
            normWS = 'normWS'
        elif norm == "From Workspace":
            normWS = str(self.getProperty("NormalizationWorkspace").value)
        else:
            normWS = None

        group_to_real = {
            'Banks': 'Group',
            'Modules': 'bank',
            '2_4 Grouping': '2_4Grouping'
        }
        group = self.getProperty('GroupDetectorsBy').value
        real_name = group_to_real.get(group, group)

        if not mtd.doesExist(group):
            if group == '2_4 Grouping':
                group = '2_4_Grouping'
            CreateGroupingWorkspace(InstrumentName='SNAP',
                                    GroupDetectorsBy=real_name,
                                    OutputWorkspace=group)

        Process_Mode = self.getProperty("ProcessingMode").value

        prefix = self.getProperty("OptionalPrefix").value

        # --------------------------- REDUCE DATA -----------------------------

        Tag = 'SNAP'
        for r in in_Runs:
            self.log().notice("processing run %s" % r)
            self.log().information(str(self.get_IPTS_Local(r)))
            if self.getProperty("LiveData").value:
                Tag = 'Live'
                LoadPreNexusLive(Instrument='SNAP', OutputWorkspace='WS')
            else:
                Load(Filename='SNAP' + str(r), OutputWorkspace='WS')
                NormaliseByCurrent(InputWorkspace='WS', OutputWorkspace='WS')

            CompressEvents(InputWorkspace='WS', OutputWorkspace='WS')
            CropWorkspace(InputWorkspace='WS',
                          OutputWorkspace='WS',
                          XMax=50000)
            RemovePromptPulse(InputWorkspace='WS',
                              OutputWorkspace='WS',
                              Width='1600',
                              Frequency='60.4')

            if maskWSname is not None:
                MaskDetectors(Workspace='WS', MaskedWorkspace=maskWSname)

            self._alignAndFocus(params, calib, cal_File, group)

            normWS = self._generateNormalization('WS_red', norm, normWS)
            WS_nor = None
            if normWS is not None:
                WS_nor = 'WS_nor'
                Divide(LHSWorkspace='WS_red',
                       RHSWorkspace=normWS,
                       OutputWorkspace='WS_nor')
                ReplaceSpecialValues(Inputworkspace='WS_nor',
                                     OutputWorkspace='WS_nor',
                                     NaNValue='0',
                                     NaNError='0',
                                     InfinityValue='0',
                                     InfinityError='0')

            new_Tag = Tag
            if len(prefix) > 0:
                new_Tag += '_' + prefix

            # Edit instrument geomety to make final workspace smaller on disk
            det_table = PreprocessDetectorsToMD(
                Inputworkspace='WS_red', OutputWorkspace='__SNAP_det_table')
            polar = np.degrees(det_table.column('TwoTheta'))
            azi = np.degrees(det_table.column('Azimuthal'))
            EditInstrumentGeometry(Workspace='WS_red',
                                   L2=det_table.column('L2'),
                                   Polar=polar,
                                   Azimuthal=azi)
            if WS_nor is not None:
                EditInstrumentGeometry(Workspace='WS_nor',
                                       L2=det_table.column('L2'),
                                       Polar=polar,
                                       Azimuthal=azi)
            mtd.remove('__SNAP_det_table')

            # Save requested formats
            basename = '%s_%s_%s' % (new_Tag, r, group)
            self._save(r, basename, norm)

            # temporary workspace no longer needed
            DeleteWorkspace(Workspace='WS')

            # rename everything as appropriate and determine output workspace name
            RenameWorkspace(Inputworkspace='WS_d',
                            OutputWorkspace='%s_%s_d' % (new_Tag, r))
            RenameWorkspace(Inputworkspace='WS_red',
                            OutputWorkspace=basename + '_red')
            if norm == 'None':
                outputWksp = basename + '_red'
            else:
                outputWksp = basename + '_nor'
                RenameWorkspace(Inputworkspace='WS_nor',
                                OutputWorkspace=basename + '_nor')
            if norm == "Extracted from Data":
                RenameWorkspace(Inputworkspace='peak_clip_WS',
                                OutputWorkspace='%s_%s_normalizer' %
                                (new_Tag, r))

            # delte some things in production
            if Process_Mode == "Production":
                DeleteWorkspace(Workspace='%s_%s_d' %
                                (new_Tag, r))  # was 'WS_d'

                if norm != "None":
                    DeleteWorkspace(Workspace=basename +
                                    '_red')  # was 'WS_red'

                if norm == "Extracted from Data":
                    DeleteWorkspace(Workspace='%s_%s_normalizer' %
                                    (new_Tag, r))  # was 'peak_clip_WS'

            propertyName = 'OutputWorkspace_' + str(outputWksp)
            self.declareProperty(
                WorkspaceProperty(propertyName, outputWksp, Direction.Output))
            self.setProperty(propertyName, outputWksp)
Ejemplo n.º 12
0
    def run_calibration(ceria_ws, bank, calfile, spectrum_numbers, full_calib):
        """
        Creates Engineering calibration files with PDCalibration
        :param ceria_ws: The workspace with the ceria data.
        :param bank: The bank to crop to, both if none.
        :param calfile: The custom calibration file to crop to, not used if none.
        :param spectrum_numbers: The spectrum numbers to crop to, no crop if none.
        :return: dict containing calibrated diffractometer constants, and copy of the raw ceria workspace
        """
        def run_pd_calibration(kwargs_to_pass) -> list:
            """
            Call PDCalibration using the keyword arguments supplied, and return it's default list of output workspaces
            :param kwargs_to_pass: Keyword arguments to supply to the algorithm
            :return: List of output workspaces from PDCalibration
            """
            return PDCalibration(**kwargs_to_pass)

        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

        # need to clone the data as PDCalibration rebins
        ceria_raw = CloneWorkspace(InputWorkspace=ceria_ws)

        # initial process of ceria ws
        NormaliseByCurrent(InputWorkspace=ceria_ws, OutputWorkspace=ceria_ws)
        ApplyDiffCal(InstrumentWorkspace=ceria_ws,
                     CalibrationWorkspace=full_calib)
        ConvertUnits(InputWorkspace=ceria_ws,
                     OutputWorkspace=ceria_ws,
                     Target='dSpacing')

        kwargs = {
            "PeakPositions":
            EnggUtils.default_ceria_expected_peaks(final=True),
            "TofBinning":
            [15500, -0.0003,
             52000],  # using a finer binning now have better stats
            "PeakWindow": 0.04,
            "MinimumPeakHeight": 0.5,
            "PeakFunction": 'BackToBackExponential',
            "CalibrationParameters": 'DIFC+TZERO+DIFA',
            "UseChiSq": True
        }
        cal_output = dict()
        grp_ws = None
        if (spectrum_numbers or calfile) is None:
            if bank == '1' or bank is None:
                grp_ws = EnggUtils.get_bank_grouping_workspace(1, ceria_raw)
                grouping_kwarg = {"GroupingWorkspace": grp_ws}
                calibrate_region_of_interest(ceria_ws, "bank_1",
                                             grouping_kwarg, cal_output)
            if bank == '2' or bank is None:
                grp_ws = EnggUtils.get_bank_grouping_workspace(2, ceria_raw)
                grouping_kwarg = {"GroupingWorkspace": grp_ws}
                calibrate_region_of_interest(ceria_ws, "bank_2",
                                             grouping_kwarg, cal_output)
        elif calfile is None:
            grp_ws = EnggUtils.create_grouping_workspace_from_spectra_list(
                spectrum_numbers, ceria_raw)
            grouping_kwarg = {"GroupingWorkspace": grp_ws}
            calibrate_region_of_interest(ceria_ws, "Cropped", grouping_kwarg,
                                         cal_output)
        else:
            grp_ws = EnggUtils.create_grouping_workspace_from_calfile(
                calfile, ceria_raw)
            grouping_kwarg = {"GroupingWorkspace": grp_ws}
            calibrate_region_of_interest(ceria_ws, "Custom", grouping_kwarg,
                                         cal_output)
        cal_params = list()
        # in the output calfile, rows are present for all detids, only read one from the region of interest
        for bank_cal in cal_output:
            mask_ws_name = "engggui_calibration_" + bank_cal + "_mask"
            mask_ws = Ads.retrieve(mask_ws_name)
            row_no = EnggUtils.get_first_unmasked_specno_from_mask_ws(mask_ws)
            row = cal_output[bank_cal].row(row_no)
            current_fit_params = {
                'difc': row['difc'],
                'difa': row['difa'],
                'tzero': row['tzero']
            }
            cal_params.append(current_fit_params)
        return cal_params, ceria_raw, grp_ws
Ejemplo n.º 13
0
    def PyExec(self):
        _background = bool(self.getProperty("Background").value)
        _load_inst = bool(self.getProperty("LoadInstrument").value)
        _norm_current = bool(self.getProperty("NormaliseByCurrent").value)
        _detcal = bool(self.getProperty("DetCal").value)
        _masking = bool(self.getProperty("MaskFile").value)
        _grouping = bool(self.getProperty("GroupingFile").value)
        _anvred = bool(self.getProperty("SphericalAbsorptionCorrection").value)
        _SA_name = self.getPropertyValue("SolidAngleOutputWorkspace")
        _Flux_name = self.getPropertyValue("FluxOutputWorkspace")

        XMin = self.getProperty("MomentumMin").value
        XMax = self.getProperty("MomentumMax").value
        rebin_param = ','.join([str(XMin), str(XMax), str(XMax)])

        Load(Filename=self.getPropertyValue("Filename"),
             OutputWorkspace='__van',
             FilterByTofMin=self.getProperty("FilterByTofMin").value,
             FilterByTofMax=self.getProperty("FilterByTofMax").value)

        if _norm_current:
            NormaliseByCurrent(InputWorkspace='__van', OutputWorkspace='__van')

        if _background:
            Load(Filename=self.getProperty("Background").value,
                 OutputWorkspace='__bkg',
                 FilterByTofMin=self.getProperty("FilterByTofMin").value,
                 FilterByTofMax=self.getProperty("FilterByTofMax").value)
            if _norm_current:
                NormaliseByCurrent(InputWorkspace='__bkg',
                                   OutputWorkspace='__bkg')
            else:
                pc_van = mtd['__van'].run().getProtonCharge()
                pc_bkg = mtd['__bkg'].run().getProtonCharge()
                mtd['__bkg'] *= pc_van / pc_bkg
            mtd['__bkg'] *= self.getProperty('BackgroundScale').value
            Minus(LHSWorkspace='__van',
                  RHSWorkspace='__bkg',
                  OutputWorkspace='__van')
            DeleteWorkspace('__bkg')

        if _load_inst:
            LoadInstrument(Workspace='__van',
                           Filename=self.getProperty("LoadInstrument").value,
                           RewriteSpectraMap=False)
        if _detcal:
            LoadIsawDetCal(InputWorkspace='__van',
                           Filename=self.getProperty("DetCal").value)

        if _masking:
            LoadMask(Instrument=mtd['__van'].getInstrument().getName(),
                     InputFile=self.getProperty("MaskFile").value,
                     OutputWorkspace='__mask')
            MaskDetectors(Workspace='__van', MaskedWorkspace='__mask')
            DeleteWorkspace('__mask')

        ConvertUnits(InputWorkspace='__van',
                     OutputWorkspace='__van',
                     Target='Momentum')
        Rebin(InputWorkspace='__van',
              OutputWorkspace='__van',
              Params=rebin_param)
        CropWorkspace(InputWorkspace='__van',
                      OutputWorkspace='__van',
                      XMin=XMin,
                      XMax=XMax)

        if _anvred:
            AnvredCorrection(InputWorkspace='__van',
                             OutputWorkspace='__van',
                             LinearScatteringCoef=self.getProperty(
                                 "LinearScatteringCoef").value,
                             LinearAbsorptionCoef=self.getProperty(
                                 "LinearAbsorptionCoef").value,
                             Radius=self.getProperty("Radius").value,
                             OnlySphericalAbsorption='1',
                             PowerLambda='0')

        # Create solid angle
        Rebin(InputWorkspace='__van',
              OutputWorkspace=_SA_name,
              Params=rebin_param,
              PreserveEvents=False)

        # Create flux
        if _grouping:
            GroupDetectors(InputWorkspace='__van',
                           OutputWorkspace='__van',
                           MapFile=self.getProperty("GroupingFile").value)
        else:
            SumSpectra(InputWorkspace='__van', OutputWorkspace='__van')

        Rebin(InputWorkspace='__van',
              OutputWorkspace='__van',
              Params=rebin_param)
        flux = mtd['__van']
        for i in range(flux.getNumberHistograms()):
            el = flux.getSpectrum(i)
            if flux.readY(i)[0] > 0:
                el.divide(flux.readY(i)[0], flux.readE(i)[0])
        SortEvents(InputWorkspace='__van', SortBy="X Value")
        IntegrateFlux(InputWorkspace='__van',
                      OutputWorkspace=_Flux_name,
                      NPoints=10000)
        DeleteWorkspace('__van')

        self.setProperty("SolidAngleOutputWorkspace", mtd[_SA_name])
        self.setProperty("FluxOutputWorkspace", mtd[_Flux_name])
Ejemplo n.º 14
0
    def PyExec(self):
        in_Runs = self.getProperty("RunNumbers").value
        maskWSname = self._getMaskWSname()
        progress = Progress(self, 0., .25, 3)

        # default arguments for AlignAndFocusPowder
        alignAndFocusArgs = {
            'TMax': 50000,
            'RemovePromptPulseWidth': 1600,
            'PreserveEvents': False,
            'Dspacing': True,  # binning parameters in d-space
            'Params': self.getProperty("Binning").value
        }

        # workspace for loading metadata only to be used in LoadDiffCal and
        # CreateGroupingWorkspace
        metaWS = None

        # either type of file-based calibration is stored in the same variable
        calib = self.getProperty("Calibration").value
        detcalFile = None
        if calib == "Calibration File":
            metaWS = self._loadMetaWS(in_Runs[0])
            LoadDiffCal(Filename=self.getPropertyValue("CalibrationFilename"),
                        WorkspaceName='SNAP',
                        InputWorkspace=metaWS,
                        MakeGroupingWorkspace=False,
                        MakeMaskWorkspace=False)
            alignAndFocusArgs['CalibrationWorkspace'] = 'SNAP_cal'
        elif calib == 'DetCal File':
            detcalFile = ','.join(self.getProperty('DetCalFilename').value)
        progress.report('loaded calibration')

        norm = self.getProperty("Normalization").value

        if norm == "From Processed Nexus":
            norm_File = self.getProperty("NormalizationFilename").value
            normalizationWS = 'normWS'
            LoadNexusProcessed(Filename=norm_File,
                               OutputWorkspace=normalizationWS)
            progress.report('loaded normalization')
        elif norm == "From Workspace":
            normalizationWS = str(
                self.getProperty("NormalizationWorkspace").value)
            progress.report('')
        else:
            normalizationWS = None
            progress.report('')

        group = self._generateGrouping(in_Runs[0], metaWS, progress)

        if metaWS is not None:
            DeleteWorkspace(Workspace=metaWS)

        Process_Mode = self.getProperty("ProcessingMode").value

        prefix = self.getProperty("OptionalPrefix").value

        # --------------------------- REDUCE DATA -----------------------------

        Tag = 'SNAP'
        if self.getProperty("LiveData").value:
            Tag = 'Live'

        progStart = .25
        progDelta = (1. - progStart) / len(in_Runs)
        for i, runnumber in enumerate(in_Runs):
            self.log().notice("processing run %s" % runnumber)
            self.log().information(str(self.get_IPTS_Local(runnumber)))

            # put together output names
            new_Tag = Tag
            if len(prefix) > 0:
                new_Tag += '_' + prefix
            basename = '%s_%s_%s' % (new_Tag, runnumber, group)

            if self.getProperty("LiveData").value:
                raise RuntimeError('Live data is not currently supported')
            else:
                Load(Filename='SNAP' + str(runnumber),
                     OutputWorkspace=basename + '_red',
                     startProgress=progStart,
                     endProgress=progStart + .25 * progDelta)
                progStart += .25 * progDelta
            redWS = basename + '_red'

            # overwrite geometry with detcal files
            if calib == 'DetCal File':
                LoadIsawDetCal(InputWorkspace=redWS, Filename=detcalFile)

            # create unfocussed data if in set-up mode
            if Process_Mode == "Set-Up":
                unfocussedWksp = '{}_{}_d'.format(new_Tag, runnumber)
            else:
                unfocussedWksp = ''

            AlignAndFocusPowder(
                InputWorkspace=redWS,
                OutputWorkspace=redWS,
                MaskWorkspace=maskWSname,  # can be empty string
                GroupingWorkspace=group,
                UnfocussedWorkspace=unfocussedWksp,  # can be empty string
                startProgress=progStart,
                endProgress=progStart + .5 * progDelta,
                **alignAndFocusArgs)
            progStart += .5 * progDelta

            # the rest takes up .25 percent of the run processing
            progress = Progress(self, progStart, progStart + .25 * progDelta,
                                2)

            # AlignAndFocusPowder leaves the data in time-of-flight
            ConvertUnits(InputWorkspace=redWS,
                         OutputWorkspace=redWS,
                         Target='dSpacing',
                         EMode='Elastic')

            # Edit instrument geometry to make final workspace smaller on disk
            det_table = PreprocessDetectorsToMD(
                Inputworkspace=redWS, OutputWorkspace='__SNAP_det_table')
            polar = np.degrees(det_table.column('TwoTheta'))
            azi = np.degrees(det_table.column('Azimuthal'))
            EditInstrumentGeometry(Workspace=redWS,
                                   L2=det_table.column('L2'),
                                   Polar=polar,
                                   Azimuthal=azi)
            mtd.remove('__SNAP_det_table')
            progress.report('simplify geometry')

            # AlignAndFocus doesn't necessarily rebin the data correctly
            if Process_Mode == "Set-Up":
                Rebin(InputWorkspace=unfocussedWksp,
                      Params=alignAndFocusArgs['Params'],
                      Outputworkspace=unfocussedWksp)

            NormaliseByCurrent(InputWorkspace=redWS, OutputWorkspace=redWS)

            # normalize the data as requested
            normalizationWS = self._generateNormalization(
                redWS, norm, normalizationWS)
            normalizedWS = None
            if normalizationWS is not None:
                normalizedWS = basename + '_nor'
                Divide(LHSWorkspace=redWS,
                       RHSWorkspace=normalizationWS,
                       OutputWorkspace=normalizedWS)
                ReplaceSpecialValues(Inputworkspace=normalizedWS,
                                     OutputWorkspace=normalizedWS,
                                     NaNValue='0',
                                     NaNError='0',
                                     InfinityValue='0',
                                     InfinityError='0')
                progress.report('normalized')
            else:
                progress.report()

            # rename everything as appropriate and determine output workspace name
            if normalizedWS is None:
                outputWksp = redWS
            else:
                outputWksp = normalizedWS

                if norm == "Extracted from Data" and Process_Mode == "Production":
                    DeleteWorkspace(Workspace=redWS)
                    DeleteWorkspace(Workspace=normalizationWS)

            # Save requested formats
            saveDir = self.getPropertyValue("OutputDirectory").strip()
            if len(saveDir) <= 0:
                self.log().notice('Using default save location')
                saveDir = os.path.join(self.get_IPTS_Local(runnumber),
                                       'shared', 'data')
            self._save(saveDir, basename, outputWksp)

            # set workspace as an output so it gets history
            propertyName = 'OutputWorkspace_' + str(outputWksp)
            self.declareProperty(
                WorkspaceProperty(propertyName, outputWksp, Direction.Output))
            self.setProperty(propertyName, outputWksp)

            # declare some things as extra outputs in set-up
            if Process_Mode != "Production":
                prefix = 'OuputWorkspace_{:d}_'.format(i)
                propNames = [prefix + it for it in ['d', 'norm', 'normalizer']]
                wkspNames = [
                    '%s_%s_d' % (new_Tag, runnumber), basename + '_red',
                    '%s_%s_normalizer' % (new_Tag, runnumber)
                ]
                for (propName, wkspName) in zip(propNames, wkspNames):
                    if mtd.doesExist(wkspName):
                        self.declareProperty(
                            WorkspaceProperty(propName, wkspName,
                                              Direction.Output))
                        self.setProperty(propName, wkspName)