def test_temperature_log_is_time_series(self):
        outputWorkspaceName = "output_ws"
        EditInstrumentGeometry(self._input_ws,
                               L2="4,8",
                               Polar="0,15",
                               Azimuthal="0,0",
                               DetectorIDs="1,2")
        AddTimeSeriesLog(self._input_ws,
                         'temperature',
                         '2010-09-14T04:20:12',
                         Value='0.0')
        AddTimeSeriesLog(self._input_ws,
                         'temperature',
                         '2010-09-14T04:20:13',
                         Value='0.0')
        AddTimeSeriesLog(self._input_ws,
                         'temperature',
                         '2010-09-14T04:20:14',
                         Value='0.0')
        alg_test = run_algorithm("ComputeCalibrationCoefVan",
                                 VanadiumWorkspace=self._input_ws,
                                 EPPTable=self._table,
                                 OutputWorkspace=outputWorkspaceName)
        self.assertTrue(alg_test.isExecuted())
        wsoutput = AnalysisDataService.retrieve(outputWorkspaceName)

        self._checkDWF(wsoutput, 0.0)
예제 #2
0
    def __loadCacheFile(self, filename, wkspname):
        '''@returns True if a file was loaded'''
        if os.path.exists(filename):
            self.log().notice('Loading cache from {}'.format(filename))
        else:
            return False

        LoadNexusProcessed(Filename=filename, OutputWorkspace=wkspname)
        # TODO LoadNexusProcessed has a bug. When it finds the
        # instrument name without xml it reads in from an IDF
        # in the instrument directory.
        editinstrargs = {}
        for name in PROPS_FOR_INSTR:
            prop = self.getProperty(name)
            if not prop.isDefault:
                editinstrargs[name] = prop.value
        if editinstrargs:
            try:
                EditInstrumentGeometry(Workspace=wkspname, **editinstrargs)
            except RuntimeError as e:
                # treat this as a non-fatal error
                self.log().warning(
                    'Failed to update instrument geometry in cache file: {}'.
                    format(e))

        return True
    def test_dwf(self):
        outputWorkspaceName = "output_ws"

        # change theta to make dwf != 1
        EditInstrumentGeometry(self._input_ws,
                               L2="4,8",
                               Polar="0,15",
                               Azimuthal="0,0",
                               DetectorIDs="1,2")
        alg_test = run_algorithm("ComputeCalibrationCoefVan",
                                 VanadiumWorkspace=self._input_ws,
                                 EPPTable=self._table,
                                 OutputWorkspace=outputWorkspaceName)
        self.assertTrue(alg_test.isExecuted())
        wsoutput = AnalysisDataService.retrieve(outputWorkspaceName)

        # check dwf calculation
        y_sum = sum(self._input_ws.readY(1)[27:75])
        mvan = 0.001 * 50.942 / N_A
        Bcoef = 4.736767162094296 * 1e+20 * hbar * hbar / (2.0 * mvan * k *
                                                           389.0)
        dwf = np.exp(-1.0 * Bcoef *
                     (4.0 * np.pi * np.sin(0.5 * np.radians(15.0)) / 4.0)**2)
        self.assertAlmostEqual(y_sum * dwf, wsoutput.readY(1)[0])

        DeleteWorkspace(wsoutput)
    def test_temperature_from_sample_log(self):
        self._input_ws.mutableRun().addProperty('temperature', 0.0, True)
        outputWorkspaceName = "output_ws"
        EditInstrumentGeometry(self._input_ws, L2="4,8", Polar="0,15",
                               Azimuthal="0,0", DetectorIDs="1,2")
        alg_test = run_algorithm("ComputeCalibrationCoefVan",
                                 VanadiumWorkspace=self._input_ws,
                                 EPPTable=self._table,
                                 OutputWorkspace=outputWorkspaceName)
        self.assertTrue(alg_test.isExecuted())
        wsoutput = AnalysisDataService.retrieve(outputWorkspaceName)

        self._checkDWF(wsoutput, 0.0)

        DeleteWorkspace(wsoutput)
    def test_dwf_using_default_temperature(self):
        outputWorkspaceName = "output_ws"

        # change theta to make dwf != 1
        EditInstrumentGeometry(self._input_ws, L2="4,8", Polar="0,15",
                               Azimuthal="0,0", DetectorIDs="1,2")
        alg_test = run_algorithm("ComputeCalibrationCoefVan",
                                 VanadiumWorkspace=self._input_ws,
                                 EPPTable=self._table,
                                 OutputWorkspace=outputWorkspaceName)
        self.assertTrue(alg_test.isExecuted())
        wsoutput = AnalysisDataService.retrieve(outputWorkspaceName)

        self._checkDWF(wsoutput, 293.0)

        DeleteWorkspace(wsoutput)
예제 #6
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
예제 #7
0
    def test_MARI_axis_cylinder(self):
        """ Test that default axis for MARI is different"""
        ash = Cylinder('Fe', [10, 2])
        res = ash.shape
        self.assertEqual(res['Height'], 10)
        self.assertEqual(res['Radius'], 2)
        self.assertTrue(ash._axis_is_default)
        test_ws = CreateSampleWorkspace(NumBanks=1, BankPixelWidth=1)
        test_ws = ConvertUnits(test_ws, 'DeltaE', Emode='Direct', EFixed=2000)
        cor_ws, corrections = ash.correct_absorption(test_ws, is_fast=True)
        res = ash.shape
        self.assertEqual(res['Axis'], [0., 1., 0])

        EditInstrumentGeometry(test_ws, [1], [0], InstrumentName='MARI')
        cor_ws, corrections = ash.correct_absorption(test_ws, is_fast=True)
        res = ash.shape
        self.assertEqual(res['Axis'], [1., 0., 0])
    def test_disabled_debye_waller_correction(self):
        outputWorkspaceName = "output_ws"

        # change theta to make dwf != 1
        EditInstrumentGeometry(self._input_ws, L2="4,8", Polar="0,15",
                               Azimuthal="0,0", DetectorIDs="1,2")
        alg_test = run_algorithm("ComputeCalibrationCoefVan",
                                 VanadiumWorkspace=self._input_ws,
                                 EPPTable=self._table,
                                 OutputWorkspace=outputWorkspaceName,
                                 EnableDWF=False)
        self.assertTrue(alg_test.isExecuted())
        wsoutput = AnalysisDataService.retrieve(outputWorkspaceName)
        for i in range(wsoutput.getNumberHistograms()):
            self.assertEqual(100., wsoutput.readY(i)[0])
            self.assertEqual(10., wsoutput.readE(i)[0])

        DeleteWorkspace(wsoutput)
    def test_temperature_log_name_from_IPF(self):
        self._input_ws.mutableRun().addProperty('sample.temperature', 0.0, True)
        EditInstrumentGeometry(self._input_ws, L2="4,8", Polar="0,15",
                               Azimuthal="0,0", DetectorIDs="1,2")
        SetInstrumentParameter(
            Workspace=self._input_ws,
            ParameterName="temperature_log_entry",
            ParameterType="String",
            Value="sample.temperature")
        outputWorkspaceName = "output_ws"
        alg_test = run_algorithm("ComputeCalibrationCoefVan",
                                 VanadiumWorkspace=self._input_ws,
                                 EPPTable=self._table,
                                 OutputWorkspace=outputWorkspaceName)
        self.assertTrue(alg_test.isExecuted())
        wsoutput = AnalysisDataService.retrieve(outputWorkspaceName)

        self._checkDWF(wsoutput, 0.)
예제 #10
0
def create_test_ws():
    """
    This creates a workspace with 19 detectors with 2theta from every 5 degress from 0 to 90
    """
    wavelength = 1.7982

    nspec = 19

    ws = CreateWorkspace(DataX=[wavelength - 0.0001, wavelength + 0.0001],
                         DataY=[0.0] * nspec,
                         NSpec=nspec,
                         UnitX="Wavelength",
                         YUnitLabel="Counts")

    EditInstrumentGeometry(ws,
                           PrimaryFlightPath=5.0,
                           SpectrumIDs=list(range(1, nspec+1)),
                           L2=[2.0]*nspec,
                           Polar=list(range(0, 181, 10)),
                           Azimuthal=[0.0]*nspec,
                           DetectorIDs=list(range(1, nspec+1)),
                           InstrumentName="Instrument")

    return ws
예제 #11
0
    def live_reduce(self, input_ws, output_ws):
        ws = input_ws
        counter_ws = mtd['counter']

        index = int(counter_ws.readX(0)[0])

        print('index = ', index)
        counter_ws.dataX(0)[0] += 1

        print('Iteration {0}: Number of events = {1}'.format(index, ws.getNumberEvents()))

        curr_ws_name = 'output_{0}'.format(index)
        CloneWorkspace(InputWorkspace=input_ws, OutputWorkspace=curr_ws_name)
        Rebin(InputWorkspace=input_ws, OutputWorkspace=output_ws, Params='5000., -0.001, 50000.')
        AlignAndFocusPowder(InputWorkspace=mtd[curr_ws_name],
                            OutputWorkspace=curr_ws_name,
                            CalFileName='/SNS/VULCAN/shared/CALIBRATION/2017_8_11_CAL/VULCAN_calibrate_2017_08_17.h5',
                            Params='-0.001',
                            DMin='0.5', DMax='3.5', PreserveEvents=False)
        # PrimaryFlightPath=43, SpectrumIDs='0-2', L2='2,2,2', Polar='90,270,145', Azimuthal='0, 0, 0')
        print('[SpecialDebug] Interface... EditInstrument on {0}'.format(curr_ws_name))
        EditInstrumentGeometry(Workspace=curr_ws_name, PrimaryFlightPath=43.753999999999998,
                               SpectrumIDs='1,2,3',
                               L2='2.00944,2.00944,2.00944', Polar='90,270,150')
예제 #12
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)
    def PyExec(self):
        filenames = self._getLinearizedFilenames('Filename')
        self.filterBadPulses = self.getProperty('FilterBadPulses').value
        self.chunkSize = self.getProperty('MaxChunkSize').value
        self.absorption = self.getProperty('AbsorptionWorkspace').value
        self.charac = self.getProperty('Characterizations').value
        finalname = self.getProperty('OutputWorkspace').valueAsStr

        self.prog_per_file = 1. / float(
            len(filenames))  # for better progress reporting

        # these are also passed into the child-algorithms
        self.kwargs = self.__getAlignAndFocusArgs()

        # outer loop creates chunks to load
        for (i, filename) in enumerate(filenames):
            # default name is based off of filename
            wkspname = os.path.split(filename)[-1].split('.')[0]
            self.__determineCharacterizations(
                filename, wkspname)  # updates instance variable
            cachefile = self.__getCacheName(wkspname)
            wkspname += '_f%d' % i  # add file number to be unique

            if cachefile is not None and os.path.exists(cachefile):
                LoadNexusProcessed(Filename=cachefile,
                                   OutputWorkspace=wkspname)
                # TODO LoadNexusProcessed has a bug. When it finds the
                # instrument name without xml it reads in from an IDF
                # in the instrument directory.
                editinstrargs = {}
                for name in PROPS_FOR_INSTR:
                    prop = self.getProperty(name)
                    if not prop.isDefault:
                        editinstrargs[name] = prop.value
                if editinstrargs:
                    EditInstrumentGeometry(Workspace=wkspname, **editinstrargs)
            else:
                self.__processFile(filename, wkspname,
                                   self.prog_per_file * float(i))
                if cachefile is not None:
                    SaveNexusProcessed(InputWorkspace=wkspname,
                                       Filename=cachefile)

            # accumulate runs
            if i == 0:
                if wkspname != finalname:
                    RenameWorkspace(InputWorkspace=wkspname,
                                    OutputWorkspace=finalname)
            else:
                Plus(LHSWorkspace=finalname,
                     RHSWorkspace=wkspname,
                     OutputWorkspace=finalname,
                     ClearRHSWorkspace=self.kwargs['PreserveEvents'])
                DeleteWorkspace(Workspace=wkspname)
                if self.kwargs['PreserveEvents']:
                    CompressEvents(InputWorkspace=finalname,
                                   OutputWorkspace=finalname)

        # with more than one chunk or file the integrated proton charge is
        # generically wrong
        mtd[finalname].run().integrateProtonCharge()

        # set the output workspace
        self.setProperty('OutputWorkspace', mtd[finalname])
예제 #14
0
    def PyExec(self):
        in_Runs = self.getProperty("RunNumbers").value
        progress = Progress(self, 0., .25, 3)
        finalUnits = self.getPropertyValue("FinalUnits")
        self.chunkSize = self.getProperty('MaxChunkSize').value

        # default arguments for AlignAndFocusPowder
        self.alignAndFocusArgs = {'Tmin': 0,
                                  '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)
            self.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('')

        self.alignAndFocusArgs['GroupingWorkspace'] = self._generateGrouping(in_Runs[0], metaWS, progress)
        self.alignAndFocusArgs['MaskWorkspace'] = self._getMaskWSname(in_Runs[0], metaWS)  # can be empty string

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

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

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

        Tag = 'SNAP'
        progStart = .25
        progDelta = (1.-progStart)/len(in_Runs)

        # --------------------------- PROCESS BACKGROUND ----------------------
        if not self.getProperty('Background').isDefault:
            progDelta = (1. - progStart) / (len(in_Runs) + 1)  # redefine to account for background

            background = 'SNAP_{}'.format(self.getProperty('Background').value)
            self.log().notice("processing run background {}".format(background))
            background, unfocussedBkgd = self._alignAndFocus(background,
                                                             background+'_bkgd_red',
                                                             detCalFilename=detcalFile,
                                                             withUnfocussed=(Process_Mode == 'Set-Up'),
                                                             progStart=progStart, progDelta=progDelta)
        else:
            background = None
            unfocussedBkgd = ''

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

        for i, runnumber in enumerate(in_Runs):
            self.log().notice("processing run %s" % runnumber)

            # put together output names
            new_Tag = Tag
            if len(prefix) > 0:
                new_Tag = prefix + '_' + new_Tag
            basename = '%s_%s_%s' % (new_Tag, runnumber, self.alignAndFocusArgs['GroupingWorkspace'])
            self.log().warning('{}:{}:{}'.format(i, new_Tag, basename))
            redWS, unfocussedWksp = self._alignAndFocus('SNAP_{}'.format(runnumber),
                                                        basename + '_red',
                                                        detCalFilename=detcalFile,
                                                        withUnfocussed=(Process_Mode == 'Set-Up'),
                                                        progStart=progStart, progDelta=progDelta*.5)
            progStart += .5 * progDelta

            # subtract the background if it was supplied
            if background:
                self.log().information('subtracting {} from {}'.format(background, redWS))
                Minus(LHSWorkspace=redWS, RHSWorkspace=background, OutputWorkspace=redWS)
                # intentionally don't subtract the unfocussed workspace since it hasn't been normalized by counting time

            # 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=self.alignAndFocusArgs['Params'],
                      Outputworkspace=unfocussedWksp)
                if background:
                    Rebin(InputWorkspace=unfocussedBkgd, Params=self.alignAndFocusArgs['Params'],
                          Outputworkspace=unfocussedBkgd)
            # 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 - function checks that saving is requested
            self._save(runnumber, basename, outputWksp)

            # set workspace as an output so it gets history
            ConvertUnits(InputWorkspace=str(outputWksp), OutputWorkspace=str(outputWksp), Target=finalUnits,
                         EMode='Elastic')
            self._exportWorkspace('OutputWorkspace_' + str(outputWksp), outputWksp)

            # declare some things as extra outputs in set-up
            if Process_Mode != "Production":
                propprefix = 'OutputWorkspace_{:d}_'.format(i)
                propNames = [propprefix + 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):
                    self._exportWorkspace(propName, wkspName)

        if background:
            ConvertUnits(InputWorkspace=str(background), OutputWorkspace=str(background), Target=finalUnits,
                         EMode='Elastic')
            prefix = 'OutputWorkspace_{}'.format(len(in_Runs))
            propNames = [prefix + it for it in ['', '_d']]
            wkspNames = [background, unfocussedBkgd]
            for (propName, wkspName) in zip(propNames, wkspNames):
                self._exportWorkspace(propName, wkspName)
예제 #15
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)
예제 #16
0
    def PyExec(self):
        filenames = self._getLinearizedFilenames('Filename')
        self.filterBadPulses = self.getProperty('FilterBadPulses').value
        self.chunkSize = self.getProperty('MaxChunkSize').value
        self.absorption = self.getProperty('AbsorptionWorkspace').value
        self.charac = self.getProperty('Characterizations').value
        finalname = self.getPropertyValue('OutputWorkspace')
        useCaching = len(self.getProperty('CacheDir').value) > 0

        # accumulate the unfocused workspace if it was requested
        # empty string means it is not used
        unfocusname = self.getPropertyValue('UnfocussedWorkspace')
        unfocusname_file = ''
        if len(unfocusname) > 0:
            unfocusname_file = '__{}_partial'.format(unfocusname)

        if useCaching:
            # unfocus check only matters if caching is requested
            if unfocusname != '':
                self.log().warning(
                    'CacheDir is specified with "UnfocussedWorkspace" - reading cache files disabled'
                )
        else:
            self.log().warning(
                'CacheDir is not specified - functionality disabled')

        self.prog_per_file = 1. / float(
            len(filenames))  # for better progress reporting

        # these are also passed into the child-algorithms
        self.kwargs = self.__getAlignAndFocusArgs()

        # outer loop creates chunks to load
        for (i, filename) in enumerate(filenames):
            # default name is based off of filename
            wkspname = os.path.split(filename)[-1].split('.')[0]

            if useCaching:
                self.__determineCharacterizations(
                    filename, wkspname, True)  # updates instance variable
                cachefile = self.__getCacheName(wkspname)
            else:
                cachefile = None

            wkspname += '_f%d' % i  # add file number to be unique

            # if the unfocussed data is requested, don't read it from disk
            # because of the extra complication of the unfocussed workspace
            if useCaching and os.path.exists(cachefile) and unfocusname == '':
                LoadNexusProcessed(Filename=cachefile,
                                   OutputWorkspace=wkspname)
                # TODO LoadNexusProcessed has a bug. When it finds the
                # instrument name without xml it reads in from an IDF
                # in the instrument directory.
                editinstrargs = {}
                for name in PROPS_FOR_INSTR:
                    prop = self.getProperty(name)
                    if not prop.isDefault:
                        editinstrargs[name] = prop.value
                if editinstrargs:
                    EditInstrumentGeometry(Workspace=wkspname, **editinstrargs)
            else:
                self.__processFile(filename, wkspname, unfocusname_file,
                                   self.prog_per_file * float(i),
                                   not useCaching)

                # write out the cachefile for the main reduced data independent of whether
                # the unfocussed workspace was requested
                if useCaching:
                    SaveNexusProcessed(InputWorkspace=wkspname,
                                       Filename=cachefile)

            # accumulate runs
            if i == 0:
                if wkspname != finalname:
                    RenameWorkspace(InputWorkspace=wkspname,
                                    OutputWorkspace=finalname)
                if unfocusname != '':
                    RenameWorkspace(InputWorkspace=unfocusname_file,
                                    OutputWorkspace=unfocusname)
            else:
                Plus(LHSWorkspace=finalname,
                     RHSWorkspace=wkspname,
                     OutputWorkspace=finalname,
                     ClearRHSWorkspace=self.kwargs['PreserveEvents'])
                DeleteWorkspace(Workspace=wkspname)

                if unfocusname != '':
                    Plus(LHSWorkspace=unfocusname,
                         RHSWorkspace=unfocusname_file,
                         OutputWorkspace=unfocusname,
                         ClearRHSWorkspace=self.kwargs['PreserveEvents'])
                    DeleteWorkspace(Workspace=unfocusname_file)

                if self.kwargs['PreserveEvents']:
                    CompressEvents(InputWorkspace=finalname,
                                   OutputWorkspace=finalname)
                    # not compressing unfocussed workspace because it is in d-spacing
                    # and is likely to be from a different part of the instrument

        # with more than one chunk or file the integrated proton charge is
        # generically wrong
        mtd[finalname].run().integrateProtonCharge()

        # set the output workspace
        self.setProperty('OutputWorkspace', mtd[finalname])
        if unfocusname != '':
            self.setProperty('UnfocussedWorkspace', mtd[unfocusname])