Beispiel #1
0
    def _convert_units_wavelength(self, unit, input_ws, output_ws, target):

        if unit != 'Wavelength':
            # Configure conversion
            if unit == 'dSpacing':
                emode = 'Elastic'
                efixed = 0.0
            elif unit == 'DeltaE':
                emode = 'Indirect'
                from IndirectCommon import getEfixed
                efixed = getEfixed(input_ws)
            else:
                raise ValueError(
                    'Unit %s in sample workspace is not supported' % unit)

            # Do conversion
            # Use temporary workspace so we don't modify data
            s_api.ConvertUnits(InputWorkspace=input_ws,
                               OutputWorkspace=output_ws,
                               Target=target,
                               EMode=emode,
                               EFixed=efixed)

        else:
            # No need to convert
            s_api.CloneWorkspace(InputWorkspace=input_ws,
                                 OutputWorkspace=output_ws)
    def _get_efixed(self, workspace):
        """
        Gets an efixed value form a workspace.

        @param workspace Name of workspace to extract from
        @return Fixed energy value
        """
        from IndirectCommon import getEfixed

        try:
            # Try to get efixed from the parameters first
            efixed = getEfixed(workspace)

        except ValueError:
            # If that fails then get it by taking from group of all detectors
            wsHandle = mtd[workspace]
            spectra_list = list(range(0, wsHandle.getNumberHistograms()))
            GroupDetectors(InputWorkspace=workspace,
                           OutputWorkspace=workspace,
                           SpectraList=spectra_list)
            wsHandle = mtd[workspace]
            det = wsHandle.getDetector(0)
            efixed = wsHandle.getEFixed(det.getID())

        return efixed
    def _convert_units_wavelength(self, unit, input_ws, output_ws, target):

        if unit != 'Wavelength':
        # Configure conversion
            if unit == 'dSpacing':
                emode = 'Elastic'
                efixed = 0.0
            elif unit == 'DeltaE':
                emode = 'Indirect'
                from IndirectCommon import getEfixed
                efixed = getEfixed(input_ws)
            else:
                raise ValueError('Unit %s in sample workspace is not supported' % unit)

            # Do conversion
            # Use temporary workspace so we don't modify data
            s_api.ConvertUnits(InputWorkspace=input_ws,
                               OutputWorkspace=output_ws,
                               Target=target,
                               EMode=emode,
                               EFixed=efixed)

        else:
            # No need to convert
            s_api.CloneWorkspace(InputWorkspace=input_ws,
                                 OutputWorkspace=output_ws)
    def _get_efixed(self, workspace):
        """
        Gets an efixed value form a workspace.

        @param workspace Name of workspace to extract from
        @return Fixed energy value
        """
        from IndirectCommon import getEfixed

        try:
            # Try to get efixed from the parameters first
            efixed = getEfixed(workspace)

        except ValueError:
            # If that fails then get it by taking from group of all detectors
            wsHandle = mtd[workspace]
            spectra_list = list(range(0, wsHandle.getNumberHistograms()))
            GroupDetectors(InputWorkspace=workspace,
                           OutputWorkspace=workspace,
                           SpectraList=spectra_list)
            wsHandle = mtd[workspace]
            det = wsHandle.getDetector(0)
            efixed = wsHandle.getEFixed(det.getID())

        return efixed
Beispiel #5
0
    def _ascii_3d_import(self):
        """
        Import 3D ASCII data (e.g. I(Q, t)).
        """
        logger.notice('Loading ASCII data')
        from IndirectCommon import getEfixed
        from IndirectNeutron import ChangeAngles, InstrParas

        # Read file
        data = []
        x_axis = ('time', 'ns')
        v_axis = ('q', 'ang^-1')
        with open(self._file_name, 'r') as handle:
            for line in handle:
                line = line.strip()

                # Ignore empty lines
                if line == '':
                    continue

                # Data line (if not comment)
                elif line.strip()[0] != '#':
                    line_values = np.array([ast.literal_eval(t.strip()) if 'nan' not in t.lower() else np.nan for t in line.split()])
                    data.append(line_values)

        if x_axis is None or v_axis is None:
            raise ValueError('Data is not in expected format for 3D data')
        logger.debug('X axis: {0}'.format(x_axis))
        logger.debug('V axis: {0}'.format(v_axis))

        # Get axis and Y values
        data = np.swapaxes(np.array(data), 0, 1)
        x_axis_values = data[0,1:]
        v_axis_values = data[1:,0]
        y_values = np.ravel(data[1:,1:])

        # Create the workspace

        wks = CreateWorkspace(OutputWorkspace=self._out_ws,
                              DataX=x_axis_values,
                              DataY=y_values,
                              NSpec=v_axis_values.size,
                              UnitX=x_axis[1],
                              EnableLogging=False)

        # Load the MolDyn instrument
        q_max = v_axis_values[-1]
        instrument = 'MolDyn'
        reflection = '2' if q_max <= 2.0 else '4'
        InstrParas(wks.name(), instrument, 'simul', reflection)

        # Process angles
        efixed = getEfixed(wks.name())
        logger.information('Qmax={0}, Efixed={1}'.format(q_max, efixed))
        wave = 1.8 * math.sqrt(25.2429 / efixed)
        qw = wave * v_axis_values / (4.0 * math.pi)
        theta = 2.0 * np.degrees(np.arcsin(qw))
        ChangeAngles(wks.name(), instrument, theta)

        return wks
    def _pre_process_corrections(self):
        """
        If the sample is not in wavelength then convert the corrections to
        whatever units the sample is in.
        """

        unit_id = mtd[self._sample_ws_name].getAxis(0).getUnit().unitID()
        logger.information('x-unit is ' + unit_id)

        factor_types = ['ass']
        if self._use_can:
            factor_types.extend(['acc', 'acsc', 'assc'])

        for factor_type in factor_types:
            input_name = self._get_correction_factor_ws_name(factor_type)
            output_name = self._corrections + '_' + factor_type

            if unit_id != 'Wavelength':
                # Configure conversion
                if unit_id == 'dSpacing':
                    emode = 'Elastic'
                    efixed = 0.0
                elif unit_id == 'DeltaE':
                    emode = 'Indirect'
                    from IndirectCommon import getEfixed
                    efixed = getEfixed(mtd[self._sample_ws_name])
                else:
                    raise ValueError(
                        'Unit %s in sample workspace is not supported' %
                        unit_id)

                # Do conversion
                ConvertUnits(InputWorkspace=input_name,
                             OutputWorkspace=output_name,
                             Target=unit_id,
                             EMode=emode,
                             EFixed=efixed)

            else:
                # No need to convert
                CloneWorkspace(InputWorkspace=input_name,
                               OutputWorkspace=output_name)

        # Group the temporary factor workspaces (for easy removal later)
        GroupWorkspaces(InputWorkspaces=[
            self._corrections + '_' + f_type for f_type in factor_types
        ],
                        OutputWorkspace=self._corrections)
Beispiel #7
0
def RunParas(ascWS, _instr, run, title):
    ws = mtd[ascWS]
    inst = ws.getInstrument()
    AddSampleLog(Workspace=ascWS, LogName="facility", LogType="String", LogText="ILL")
    ws.getRun()['run_number'] = run
    ws.getRun()['run_title'] = title
    efixed = getEfixed(ascWS)

    facility = ws.getRun().getLogData('facility').value
    logger.information('Facility is ' + facility)
    runNo = ws.getRun()['run_number'].value
    runTitle = ws.getRun()['run_title'].value.strip()
    logger.information('Run : ' + str(runNo) + ' ; Title : ' + runTitle)
    an = inst.getStringParameter('analyser')[0]
    ref = inst.getStringParameter('reflection')[0]
    logger.information('Analyser : ' + an + ref + ' with energy = ' + str(efixed))

    return efixed
Beispiel #8
0
def RunParas(ascWS, _instr, run, title):
    ws = mtd[ascWS]
    inst = ws.getInstrument()
    AddSampleLog(Workspace=ascWS, LogName="facility", LogType="String", LogText="ILL")
    ws.getRun()['run_number'] = run
    ws.getRun()['run_title'] = title
    efixed = getEfixed(ascWS)

    facility = ws.getRun().getLogData('facility').value
    logger.information('Facility is ' + facility)
    runNo = ws.getRun()['run_number'].value
    runTitle = ws.getRun()['run_title'].value.strip()
    logger.information('Run : ' + str(runNo) + ' ; Title : ' + runTitle)
    an = inst.getStringParameter('analyser')[0]
    ref = inst.getStringParameter('reflection')[0]
    logger.information('Analyser : ' + an + ref + ' with energy = ' + str(efixed))

    return efixed
    def _pre_process_corrections(self):
        """
        If the sample is not in wavelength then convert the corrections to
        whatever units the sample is in.
        """

        unit_id = mtd[self._sample_ws_name].getAxis(0).getUnit().unitID()
        logger.information("x-unit is " + unit_id)

        factor_types = ["ass"]
        if self._use_can:
            factor_types.extend(["acc", "acsc", "assc"])

        for factor_type in factor_types:
            input_name = self._get_correction_factor_ws_name(factor_type)
            output_name = self._corrections + "_" + factor_type

            if unit_id != "Wavelength":
                # Configure conversion
                if unit_id == "dSpacing":
                    emode = "Elastic"
                    efixed = 0.0
                elif unit_id == "DeltaE":
                    emode = "Indirect"
                    from IndirectCommon import getEfixed

                    efixed = getEfixed(mtd[self._sample_ws_name])
                else:
                    raise ValueError("Unit %s in sample workspace is not supported" % unit_id)

                # Do conversion
                ConvertUnits(
                    InputWorkspace=input_name, OutputWorkspace=output_name, Target=unit_id, EMode=emode, EFixed=efixed
                )

            else:
                # No need to convert
                CloneWorkspace(InputWorkspace=input_name, OutputWorkspace=output_name)

        # Group the temporary factor workspaces (for easy removal later)
        GroupWorkspaces(
            InputWorkspaces=[self._corrections + "_" + f_type for f_type in factor_types],
            OutputWorkspace=self._corrections,
        )
Beispiel #10
0
def AbsRunFeeder(inputws, geom, beam, ncan, size, density, sigs, siga, avar,
        plotOpt='None'):
    '''Handles the feeding of input and plotting of output for the F2PY
    absorption correction routine.'''
    ws = mtd[inputws]
    ## workdir is default save directory
    workdir = mantid.getConfigProperty('defaultsave.directory')
    ## prefix is instrument short name
    prefix = ws.getInstrument().getName()
    prefix = ConfigService().facility().instrument(prefix).shortName().lower()
    ## sam = run number
    sam = ws.getRun().getLogData("run_number").value
    ## efixed can be taken from the instrument parameter file
    efixed = getEfixed(inputws)
    ## Run the routine
    workspaces = AbsRun(workdir, prefix, sam, geom, beam, ncan, size, density,
        sigs, siga, avar, efixed, inputWS=inputws)
    if ( plotOpt == 'None' ):
        return
    if ( plotOpt == 'Wavelength' or plotOpt == 'Both' ):
        graph = plotSpectrum(workspaces, 0)
    if ( plotOpt == 'Angle' or plotOpt == 'Both' ):
        graph = plotTimeBin(workspaces, 0)
        graph.activeLayer().setAxisTitle(Layer.Bottom, 'Angle')
Beispiel #11
0
    def _get_amplitude_and_fwhm_from_fit(self, workspace):
        from IndirectCommon import getEfixed

        parameter_values = self._get_fit_parameters_from_fit(workspace, getEfixed(self._temporary_fit_name))
        return parameter_values[0], parameter_values[2]
    def PyExec(self):
        from IndirectCommon import getEfixed

        self._setup()

        # Set up progress reporting
        n_prog_reports = 2
        if self._can_ws_name is not None:
            n_prog_reports += 1
        prog = Progress(self, 0.0, 1.0, n_prog_reports)

        efixed = getEfixed(self._sample_ws_name)

        sample_wave_ws = '__sam_wave'
        ConvertUnits(InputWorkspace=self._sample_ws_name,
                     OutputWorkspace=sample_wave_ws,
                     Target='Wavelength',
                     EMode='Indirect',
                     EFixed=efixed,
                     EnableLogging=False)

        sample_thickness = self._sample_outer_radius - self._sample_inner_radius
        logger.information('Sample thickness: ' + str(sample_thickness))

        prog.report('Calculating sample corrections')
        if self._sample_density_type == 'Mass Density':
            builder = MaterialBuilder()
            mat = builder.setFormula(
                self._sample_chemical_formula).setMassDensity(
                    self._sample_density).build()
            self._sample_density = mat.numberDensity
        SetSampleMaterial(sample_wave_ws,
                          ChemicalFormula=self._sample_chemical_formula,
                          SampleNumberDensity=self._sample_density)
        AnnularRingAbsorption(
            InputWorkspace=sample_wave_ws,
            OutputWorkspace=self._ass_ws,
            SampleHeight=3.0,
            SampleThickness=sample_thickness,
            CanInnerRadius=self._can_inner_radius,
            CanOuterRadius=self._can_outer_radius,
            SampleChemicalFormula=self._sample_chemical_formula,
            SampleNumberDensity=self._sample_density,
            NumberOfWavelengthPoints=10,
            EventsPerPoint=self._events)

        group = self._ass_ws

        if self._can_ws_name is not None:
            can1_wave_ws = '__can1_wave'
            can2_wave_ws = '__can2_wave'
            ConvertUnits(InputWorkspace=self._can_ws_name,
                         OutputWorkspace=can1_wave_ws,
                         Target='Wavelength',
                         EMode='Indirect',
                         EFixed=efixed,
                         EnableLogging=False)
            if self._can_scale != 1.0:
                logger.information('Scaling container by: ' +
                                   str(self._can_scale))
                Scale(InputWorkspace=can1_wave_ws,
                      OutputWorkspace=can1_wave_ws,
                      Factor=self._can_scale,
                      Operation='Multiply')
            CloneWorkspace(InputWorkspace=can1_wave_ws,
                           OutputWorkspace=can2_wave_ws,
                           EnableLogging=False)

            can_thickness_1 = self._sample_inner_radius - self._can_inner_radius
            can_thickness_2 = self._can_outer_radius - self._sample_outer_radius
            logger.information('Container thickness: %f & %f' %
                               (can_thickness_1, can_thickness_2))

            if self._use_can_corrections:
                prog.report('Calculating container corrections')
                Divide(LHSWorkspace=sample_wave_ws,
                       RHSWorkspace=self._ass_ws,
                       OutputWorkspace=sample_wave_ws)

                if self._can_density_type == 'Mass Density':
                    builder = MaterialBuilder()
                    mat = builder.setFormula(
                        self._can_chemical_formula).setMassDensity(
                            self._can_density).build()
                    self._can_density = mat.numberDensity
                SetSampleMaterial(can1_wave_ws,
                                  ChemicalFormula=self._can_chemical_formula,
                                  SampleNumberDensity=self._can_density)

                AnnularRingAbsorption(
                    InputWorkspace=can1_wave_ws,
                    OutputWorkspace='__Acc1',
                    SampleHeight=3.0,
                    SampleThickness=can_thickness_1,
                    CanInnerRadius=self._can_inner_radius,
                    CanOuterRadius=self._sample_outer_radius,
                    SampleChemicalFormula=self._can_chemical_formula,
                    SampleNumberDensity=self._can_density,
                    NumberOfWavelengthPoints=10,
                    EventsPerPoint=self._events)

                SetSampleMaterial(can2_wave_ws,
                                  ChemicalFormula=self._can_chemical_formula,
                                  SampleNumberDensity=self._can_density)
                AnnularRingAbsorption(
                    InputWorkspace=can2_wave_ws,
                    OutputWorkspace='__Acc2',
                    SampleHeight=3.0,
                    SampleThickness=can_thickness_2,
                    CanInnerRadius=self._sample_inner_radius,
                    CanOuterRadius=self._can_outer_radius,
                    SampleChemicalFormula=self._can_chemical_formula,
                    SampleNumberDensity=self._can_density,
                    NumberOfWavelengthPoints=10,
                    EventsPerPoint=self._events)

                Multiply(LHSWorkspace='__Acc1',
                         RHSWorkspace='__Acc2',
                         OutputWorkspace=self._acc_ws,
                         EnableLogging=False)
                DeleteWorkspace('__Acc1', EnableLogging=False)
                DeleteWorkspace('__Acc2', EnableLogging=False)

                Divide(LHSWorkspace=can1_wave_ws,
                       RHSWorkspace=self._acc_ws,
                       OutputWorkspace=can1_wave_ws)
                Minus(LHSWorkspace=sample_wave_ws,
                      RHSWorkspace=can1_wave_ws,
                      OutputWorkspace=sample_wave_ws)
                group += ',' + self._acc_ws

            else:
                prog.report('Calculating can scaling')
                Minus(LHSWorkspace=sample_wave_ws,
                      RHSWorkspace=can1_wave_ws,
                      OutputWorkspace=sample_wave_ws)
                Divide(LHSWorkspace=sample_wave_ws,
                       RHSWorkspace=self._ass_ws,
                       OutputWorkspace=sample_wave_ws)

            DeleteWorkspace(can1_wave_ws, EnableLogging=False)
            DeleteWorkspace(can2_wave_ws, EnableLogging=False)

        else:
            Divide(LHSWorkspace=sample_wave_ws,
                   RHSWorkspace=self._ass_ws,
                   OutputWorkspace=sample_wave_ws)

        ConvertUnits(InputWorkspace=sample_wave_ws,
                     OutputWorkspace=self._output_ws,
                     Target='DeltaE',
                     EMode='Indirect',
                     EFixed=efixed,
                     EnableLogging=False)
        DeleteWorkspace(sample_wave_ws, EnableLogging=False)

        prog.report('Recording sample logs')
        sample_log_workspaces = [self._output_ws, self._ass_ws]
        sample_logs = [('sample_shape', 'annulus'),
                       ('sample_filename', self._sample_ws_name),
                       ('sample_inner', self._sample_inner_radius),
                       ('sample_outer', self._sample_outer_radius),
                       ('can_inner', self._can_inner_radius),
                       ('can_outer', self._can_outer_radius)]

        if self._can_ws_name is not None:
            sample_logs.append(('container_filename', self._can_ws_name))
            sample_logs.append(('container_scale', self._can_scale))
            if self._use_can_corrections:
                sample_log_workspaces.append(self._acc_ws)
                sample_logs.append(('container_thickness_1', can_thickness_1))
                sample_logs.append(('container_thickness_2', can_thickness_2))

        log_names = [item[0] for item in sample_logs]
        log_values = [item[1] for item in sample_logs]

        for ws_name in sample_log_workspaces:
            AddSampleLogMultiple(Workspace=ws_name,
                                 LogNames=log_names,
                                 LogValues=log_values,
                                 EnableLogging=False)

        self.setProperty('OutputWorkspace', self._output_ws)

        # Output the Ass workspace if it is wanted, delete if not
        if self._abs_ws == '':
            DeleteWorkspace(self._ass_ws, EnableLogging=False)
            if self._can_ws_name is not None and self._use_can_corrections:
                DeleteWorkspace(self._acc_ws, EnableLogging=False)
        else:
            GroupWorkspaces(InputWorkspaces=group,
                            OutputWorkspace=self._abs_ws,
                            EnableLogging=False)
            self.setProperty('CorrectionsWorkspace', self._abs_ws)
Beispiel #13
0
    def PyExec(self):

        # Check for platform support
        if not is_supported_f2py_platform():
            unsupported_msg = "This algorithm can only be run on valid platforms." \
                              + " please view the algorithm documentation to see" \
                              + " what platforms are currently supported"
            raise RuntimeError(unsupported_msg)

        from IndirectBayes import (CalcErange, GetXYE, ReadNormFile,
                                   ReadWidthFile, QLAddSampleLogs, C2Fw, C2Se,
                                   QuasiPlot)
        from IndirectCommon import (CheckXrange, CheckAnalysers, getEfixed,
                                    GetThetaQ, CheckHistZero, CheckHistSame,
                                    IndentifyDataBoundaries)
        setup_prog = Progress(self, start=0.0, end=0.3, nreports=5)
        self.log().information('BayesQuasi input')

        erange = [self._e_min, self._e_max]
        nbins = [self._sam_bins, self._res_bins]
        setup_prog.report('Converting to binary for Fortran')
        #convert true/false to 1/0 for fortran
        o_el = 1 if self._elastic else 0
        o_w1 = 1 if self._width else 0
        o_res = 1 if self._res_norm else 0

        #fortran code uses background choices defined using the following numbers
        setup_prog.report('Encoding input options')
        if self._background == 'Sloping':
            o_bgd = 2
        elif self._background == 'Flat':
            o_bgd = 1
        elif self._background == 'Zero':
            o_bgd = 0

        fitOp = [o_el, o_bgd, o_w1, o_res]

        setup_prog.report('Establishing save path')
        workdir = config['defaultsave.directory']
        if not os.path.isdir(workdir):
            workdir = os.getcwd()
            logger.information(
                'Default Save directory is not set. Defaulting to current working Directory: '
                + workdir)

        array_len = 4096  # length of array in Fortran
        setup_prog.report('Checking X Range')
        CheckXrange(erange, 'Energy')

        nbin, nrbin = nbins[0], nbins[1]

        logger.information('Sample is ' + self._samWS)
        logger.information('Resolution is ' + self._resWS)

        # Check for trailing and leading zeros in data
        setup_prog.report(
            'Checking for leading and trailing zeros in the data')
        first_data_point, last_data_point = IndentifyDataBoundaries(
            self._samWS)
        if first_data_point > self._e_min:
            logger.warning(
                "Sample workspace contains leading zeros within the energy range."
            )
            logger.warning("Updating eMin: eMin = " + str(first_data_point))
            self._e_min = first_data_point
        if last_data_point < self._e_max:
            logger.warning(
                "Sample workspace contains trailing zeros within the energy range."
            )
            logger.warning("Updating eMax: eMax = " + str(last_data_point))
            self._e_max = last_data_point

        # update erange with new values
        erange = [self._e_min, self._e_max]

        setup_prog.report('Checking Analysers')
        CheckAnalysers(self._samWS, self._resWS)
        setup_prog.report('Obtaining EFixed, theta and Q')
        efix = getEfixed(self._samWS)
        theta, Q = GetThetaQ(self._samWS)

        nsam, ntc = CheckHistZero(self._samWS)

        totalNoSam = nsam

        #check if we're performing a sequential fit
        if self._loop != True:
            nsam = 1

        nres = CheckHistZero(self._resWS)[0]

        setup_prog.report('Checking Histograms')
        if self._program == 'QL':
            if nres == 1:
                prog = 'QLr'  # res file
            else:
                prog = 'QLd'  # data file
                CheckHistSame(self._samWS, 'Sample', self._resWS, 'Resolution')
        elif self._program == 'QSe':
            if nres == 1:
                prog = 'QSe'  # res file
            else:
                raise ValueError('Stretched Exp ONLY works with RES file')

        logger.information('Version is ' + prog)
        logger.information(' Number of spectra = ' + str(nsam))
        logger.information(' Erange : ' + str(erange[0]) + ' to ' +
                           str(erange[1]))

        setup_prog.report('Reading files')
        Wy, We = ReadWidthFile(self._width, self._wfile, totalNoSam)
        dtn, xsc = ReadNormFile(self._res_norm, self._resnormWS, totalNoSam)

        setup_prog.report('Establishing output workspace name')
        fname = self._samWS[:-4] + '_' + prog
        probWS = fname + '_Prob'
        fitWS = fname + '_Fit'
        wrks = os.path.join(workdir, self._samWS[:-4])
        logger.information(' lptfile : ' + wrks + '_' + prog + '.lpt')
        lwrk = len(wrks)
        wrks.ljust(140, ' ')
        wrkr = self._resWS
        wrkr.ljust(140, ' ')

        setup_prog.report('Initialising probability list')
        # initialise probability list
        if self._program == 'QL':
            prob0 = []
            prob1 = []
            prob2 = []
        xQ = np.array([Q[0]])
        for m in range(1, nsam):
            xQ = np.append(xQ, Q[m])
        xProb = xQ
        xProb = np.append(xProb, xQ)
        xProb = np.append(xProb, xQ)
        eProb = np.zeros(3 * nsam)

        group = ''
        workflow_prog = Progress(self, start=0.3, end=0.7, nreports=nsam * 3)
        for m in range(0, nsam):
            logger.information('Group ' + str(m) + ' at angle ' +
                               str(theta[m]))
            nsp = m + 1
            nout, bnorm, Xdat, Xv, Yv, Ev = CalcErange(self._samWS, m, erange,
                                                       nbin)
            Ndat = nout[0]
            Imin = nout[1]
            Imax = nout[2]
            if prog == 'QLd':
                mm = m
            else:
                mm = 0
            Nb, Xb, Yb, Eb = GetXYE(self._resWS, mm,
                                    array_len)  # get resolution data
            numb = [nsam, nsp, ntc, Ndat, nbin, Imin, Imax, Nb, nrbin]
            rscl = 1.0
            reals = [efix, theta[m], rscl, bnorm]

            if prog == 'QLr':
                workflow_prog.report(
                    'Processing Sample number %i as Lorentzian' % nsam)
                nd, xout, yout, eout, yfit, yprob = QLr.qlres(
                    numb, Xv, Yv, Ev, reals, fitOp, Xdat, Xb, Yb, Wy, We, dtn,
                    xsc, wrks, wrkr, lwrk)
                message = ' Log(prob) : ' + str(yprob[0]) + ' ' + str(
                    yprob[1]) + ' ' + str(yprob[2]) + ' ' + str(yprob[3])
                logger.information(message)
            if prog == 'QLd':
                workflow_prog.report('Processing Sample number %i' % nsam)
                nd, xout, yout, eout, yfit, yprob = QLd.qldata(
                    numb, Xv, Yv, Ev, reals, fitOp, Xdat, Xb, Yb, Eb, Wy, We,
                    wrks, wrkr, lwrk)
                message = ' Log(prob) : ' + str(yprob[0]) + ' ' + str(
                    yprob[1]) + ' ' + str(yprob[2]) + ' ' + str(yprob[3])
                logger.information(message)
            if prog == 'QSe':
                workflow_prog.report(
                    'Processing Sample number %i as Stretched Exp' % nsam)
                nd,xout,yout,eout,yfit,yprob=Qse.qlstexp(numb,Xv,Yv,Ev,reals,fitOp,\
                                                        Xdat,Xb,Yb,Wy,We,dtn,xsc,\
                                                        wrks,wrkr,lwrk)
            dataX = xout[:nd]
            dataX = np.append(dataX, 2 * xout[nd - 1] - xout[nd - 2])
            yfit_list = np.split(yfit[:4 * nd], 4)
            dataF1 = yfit_list[1]
            if self._program == 'QL':
                dataF2 = yfit_list[2]
            workflow_prog.report('Processing data')
            dataG = np.zeros(nd)
            datX = dataX
            datY = yout[:nd]
            datE = eout[:nd]
            datX = np.append(datX, dataX)
            datY = np.append(datY, dataF1[:nd])
            datE = np.append(datE, dataG)
            res1 = dataF1[:nd] - yout[:nd]
            datX = np.append(datX, dataX)
            datY = np.append(datY, res1)
            datE = np.append(datE, dataG)
            nsp = 3
            names = 'data,fit.1,diff.1'
            res_plot = [0, 1, 2]
            if self._program == 'QL':
                workflow_prog.report('Processing Lorentzian result data')
                datX = np.append(datX, dataX)
                datY = np.append(datY, dataF2[:nd])
                datE = np.append(datE, dataG)
                res2 = dataF2[:nd] - yout[:nd]
                datX = np.append(datX, dataX)
                datY = np.append(datY, res2)
                datE = np.append(datE, dataG)
                nsp += 2
                names += ',fit.2,diff.2'
                res_plot.append(4)
                prob0.append(yprob[0])
                prob1.append(yprob[1])
                prob2.append(yprob[2])

            # create result workspace
            fitWS = fname + '_Workspaces'
            fout = fname + '_Workspace_' + str(m)

            workflow_prog.report('Creating OutputWorkspace')
            CreateWorkspace(OutputWorkspace=fout, DataX=datX, DataY=datY, DataE=datE,\
                Nspec=nsp, UnitX='DeltaE', VerticalAxisUnit='Text', VerticalAxisValues=names)

            # append workspace to list of results
            group += fout + ','

        comp_prog = Progress(self, start=0.7, end=0.8, nreports=2)
        comp_prog.report('Creating Group Workspace')
        GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=fitWS)

        if self._program == 'QL':
            comp_prog.report('Processing Lorentzian probability data')
            yPr0 = np.array([prob0[0]])
            yPr1 = np.array([prob1[0]])
            yPr2 = np.array([prob2[0]])
            for m in range(1, nsam):
                yPr0 = np.append(yPr0, prob0[m])
                yPr1 = np.append(yPr1, prob1[m])
                yPr2 = np.append(yPr2, prob2[m])
            yProb = yPr0
            yProb = np.append(yProb, yPr1)
            yProb = np.append(yProb, yPr2)
            probWs = CreateWorkspace(OutputWorkspace=probWS, DataX=xProb, DataY=yProb, DataE=eProb,\
                Nspec=3, UnitX='MomentumTransfer')
            outWS = C2Fw(self._samWS[:-4], fname)
            if self._plot != 'None':
                QuasiPlot(fname, self._plot, res_plot, self._loop)
        if self._program == 'QSe':
            comp_prog.report('Runnning C2Se')
            outWS = C2Se(fname)
            if self._plot != 'None':
                QuasiPlot(fname, self._plot, res_plot, self._loop)

        log_prog = Progress(self, start=0.8, end=1.0, nreports=8)
        #Add some sample logs to the output workspaces
        log_prog.report('Copying Logs to outputWorkspace')
        CopyLogs(InputWorkspace=self._samWS, OutputWorkspace=outWS)
        log_prog.report('Adding Sample logs to Output workspace')
        QLAddSampleLogs(outWS, self._resWS, prog, self._background,
                        self._elastic, erange, (nbin, nrbin), self._resnormWS,
                        self._wfile)
        log_prog.report('Copying logs to fit Workspace')
        CopyLogs(InputWorkspace=self._samWS, OutputWorkspace=fitWS)
        log_prog.report('Adding sample logs to Fit workspace')
        QLAddSampleLogs(fitWS, self._resWS, prog, self._background,
                        self._elastic, erange, (nbin, nrbin), self._resnormWS,
                        self._wfile)
        log_prog.report('Finialising log copying')

        if self._save:
            log_prog.report('Saving workspaces')
            fit_path = os.path.join(workdir, fitWS + '.nxs')
            SaveNexusProcessed(InputWorkspace=fitWS, Filename=fit_path)
            out_path = os.path.join(workdir,
                                    outWS + '.nxs')  # path name for nxs file
            SaveNexusProcessed(InputWorkspace=outWS, Filename=out_path)
            logger.information('Output fit file created : ' + fit_path)
            logger.information('Output paramter file created : ' + out_path)

        self.setProperty('OutputWorkspaceFit', fitWS)
        self.setProperty('OutputWorkspaceResult', outWS)
        log_prog.report('Setting workspace properties')

        if self._program == 'QL':
            self.setProperty('OutputWorkspaceProb', probWS)
    def PyExec(self):
        from IndirectCommon import getEfixed

        self._setup()

        # Set up progress reporting
        n_prog_reports = 2
        if self._can_ws_name is not None:
            n_prog_reports += 1
        prog = Progress(self, 0.0, 1.0, n_prog_reports)

        efixed = getEfixed(self._sample_ws)

        sample_wave_ws = '__sam_wave'
        ConvertUnits(InputWorkspace=self._sample_ws, OutputWorkspace=sample_wave_ws,
                     Target='Wavelength', EMode='Indirect', EFixed=efixed)

        SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_number_density)

        prog.report('Calculating sample corrections')
        FlatPlateAbsorption(InputWorkspace=sample_wave_ws,
                            OutputWorkspace=self._ass_ws,
                            SampleHeight=self._sample_height,
                            SampleWidth=self._sample_width,
                            SampleThickness=self._sample_thickness,
                            ElementSize=self._element_size,
                            EMode='Indirect',
                            EFixed=efixed,
                            NumberOfWavelengthPoints=10)

        plot_data = [self._output_ws, self._sample_ws]
        plot_corr = [self._ass_ws]
        group = self._ass_ws

        if self._can_ws_name is not None:
            can_wave_ws = '__can_wave'
            ConvertUnits(InputWorkspace=self._can_ws_name, OutputWorkspace=can_wave_ws,
                         Target='Wavelength', EMode='Indirect', EFixed=efixed)
            if self._can_scale != 1.0:
                logger.information('Scaling container by: ' + str(self._can_scale))
                Scale(InputWorkspace=can_wave_ws, OutputWorkspace=can_wave_ws, Factor=self._can_scale, Operation='Multiply')

            if self._use_can_corrections:
                prog.report('Calculating container corrections')
                Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)

                SetSampleMaterial(can_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_number_density)
                FlatPlateAbsorption(InputWorkspace=can_wave_ws,
                                    OutputWorkspace=self._acc_ws,
                                    SampleHeight=self._sample_height,
                                    SampleWidth=self._sample_width,
                                    SampleThickness=self._can_front_thickness + self._can_back_thickness,
                                    ElementSize=self._element_size,
                                    EMode='Indirect',
                                    EFixed=efixed,
                                    NumberOfWavelengthPoints=10)

                Divide(LHSWorkspace=can_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can_wave_ws)
                Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws)
                plot_corr.append(self._acc_ws)
                group += ',' + self._acc_ws

            else:
                prog.report('Calculating container scaling')
                Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws)
                Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)

            DeleteWorkspace(can_wave_ws)
            plot_data.append(self._can_ws_name)

        else:
            Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)

        ConvertUnits(InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws,
                     Target='DeltaE', EMode='Indirect', EFixed=efixed)
        DeleteWorkspace(sample_wave_ws)

        prog.report('Recording samle logs')
        sample_log_workspaces = [self._output_ws, self._ass_ws]
        sample_logs = [('sample_shape', 'flatplate'),
                       ('sample_filename', self._sample_ws),
                       ('sample_height', self._sample_height),
                       ('sample_width', self._sample_width),
                       ('sample_thickness', self._sample_thickness),
                       ('element_size', self._element_size)]

        if self._can_ws_name is not None:
            sample_logs.append(('container_filename', self._can_ws_name))
            sample_logs.append(('container_scale', self._can_scale))
            if self._use_can_corrections:
                sample_log_workspaces.append(self._acc_ws)
                sample_logs.append(('container_front_thickness', self. _can_front_thickness))
                sample_logs.append(('container_back_thickness', self. _can_back_thickness))

        log_names = [item[0] for item in sample_logs]
        log_values = [item[1] for item in sample_logs]

        for ws_name in sample_log_workspaces:
            AddSampleLogMultiple(Workspace=ws_name, LogNames=log_names, LogValues=log_values)

        self.setProperty('OutputWorkspace', self._output_ws)

        # Output the Ass workspace if it is wanted, delete if not
        if self._abs_ws == '':
            DeleteWorkspace(self._ass_ws)
            if self._can_ws_name is not None and self._use_can_corrections:
                DeleteWorkspace(self._acc_ws)
        else:
            GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._abs_ws)
            self.setProperty('CorrectionsWorkspace', self._abs_ws)

        if self._plot:
            from IndirectImport import import_mantidplot
            mantid_plot = import_mantidplot()
            mantid_plot.plotSpectrum(plot_data, 0)
            if self._abs_ws != '':
                mantid_plot.plotSpectrum(plot_corr, 0)
    def PyExec(self):
        from IndirectCommon import getEfixed

        self._setup()

        # Set up progress reporting
        n_prog_reports = 2
        if self._can_ws_name is not None:
            n_prog_reports += 1
        prog = Progress(self, 0.0, 1.0, n_prog_reports)

        efixed = getEfixed(self._sample_ws)

        sample_wave_ws = "__sam_wave"
        ConvertUnits(
            InputWorkspace=self._sample_ws,
            OutputWorkspace=sample_wave_ws,
            Target="Wavelength",
            EMode="Indirect",
            EFixed=efixed,
            EnableLogging=False,
        )

        if self._sample_density_type == "Mass Density":
            builder = MaterialBuilder()
            mat = builder.setFormula(self._sample_chemical_formula).setMassDensity(self._sample_density).build()
            self._sample_density = mat.numberDensity
        SetSampleMaterial(
            sample_wave_ws, ChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_density
        )

        prog.report("Calculating sample corrections")
        FlatPlateAbsorption(
            InputWorkspace=sample_wave_ws,
            OutputWorkspace=self._ass_ws,
            SampleHeight=self._sample_height,
            SampleWidth=self._sample_width,
            SampleThickness=self._sample_thickness,
            ElementSize=self._element_size,
            EMode="Indirect",
            EFixed=efixed,
            NumberOfWavelengthPoints=10,
        )

        group = self._ass_ws

        if self._can_ws_name is not None:
            can_wave_ws = "__can_wave"
            ConvertUnits(
                InputWorkspace=self._can_ws_name,
                OutputWorkspace=can_wave_ws,
                Target="Wavelength",
                EMode="Indirect",
                EFixed=efixed,
                EnableLogging=False,
            )
            if self._can_scale != 1.0:
                logger.information("Scaling container by: " + str(self._can_scale))
                Scale(
                    InputWorkspace=can_wave_ws,
                    OutputWorkspace=can_wave_ws,
                    Factor=self._can_scale,
                    Operation="Multiply",
                )

            if self._use_can_corrections:
                prog.report("Calculating container corrections")
                Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)

                if self._sample_density_type == "Mass Density":
                    builder = MaterialBuilder()
                    mat = builder.setFormula(self._can_chemical_formula).setMassDensity(self._can_density).build()
                    self._can_density = mat.numberDensity
                SetSampleMaterial(
                    can_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_density
                )

                FlatPlateAbsorption(
                    InputWorkspace=can_wave_ws,
                    OutputWorkspace=self._acc_ws,
                    SampleHeight=self._sample_height,
                    SampleWidth=self._sample_width,
                    SampleThickness=self._can_front_thickness + self._can_back_thickness,
                    ElementSize=self._element_size,
                    EMode="Indirect",
                    EFixed=efixed,
                    NumberOfWavelengthPoints=10,
                )

                Divide(LHSWorkspace=can_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can_wave_ws)
                Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws)
                group += "," + self._acc_ws

            else:
                prog.report("Calculating container scaling")
                Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws)
                Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)

            DeleteWorkspace(can_wave_ws, EnableLogging=False)

        else:
            Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)

        ConvertUnits(
            InputWorkspace=sample_wave_ws,
            OutputWorkspace=self._output_ws,
            Target="DeltaE",
            EMode="Indirect",
            EFixed=efixed,
            EnableLogging=False,
        )
        DeleteWorkspace(sample_wave_ws, EnableLogging=False)

        prog.report("Recording sample logs")
        sample_log_workspaces = [self._output_ws, self._ass_ws]
        sample_logs = [
            ("sample_shape", "flatplate"),
            ("sample_filename", self._sample_ws),
            ("sample_height", self._sample_height),
            ("sample_width", self._sample_width),
            ("sample_thickness", self._sample_thickness),
            ("element_size", self._element_size),
        ]

        if self._can_ws_name is not None:
            sample_logs.append(("container_filename", self._can_ws_name))
            sample_logs.append(("container_scale", self._can_scale))
            if self._use_can_corrections:
                sample_log_workspaces.append(self._acc_ws)
                sample_logs.append(("container_front_thickness", self._can_front_thickness))
                sample_logs.append(("container_back_thickness", self._can_back_thickness))

        log_names = [item[0] for item in sample_logs]
        log_values = [item[1] for item in sample_logs]

        for ws_name in sample_log_workspaces:
            AddSampleLogMultiple(Workspace=ws_name, LogNames=log_names, LogValues=log_values, EnableLogging=False)

        self.setProperty("OutputWorkspace", self._output_ws)

        # Output the Ass workspace if it is wanted, delete if not
        if self._abs_ws == "":
            DeleteWorkspace(self._ass_ws, EnableLogging=False)
            if self._can_ws_name is not None and self._use_can_corrections:
                DeleteWorkspace(self._acc_ws, EnableLogging=False)
        else:
            GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._abs_ws, EnableLogging=False)
            self.setProperty("CorrectionsWorkspace", self._abs_ws)
Beispiel #16
0
    def _ascii_import(self, data, name):
        """
        Import ASCII data.

        @param data Raw ASCII data
        @param name Name of data file
        """

        from IndirectCommon import getEfixed
        from IndirectNeutron import ChangeAngles, InstrParas

        logger.notice('Loading ASCII data: %s' % name)

        val = _split_line(data[3])
        Q = []
        for n in range(1, len(val)):
            Q.append(val[n])

        nQ = len(Q)
        x = []
        y = []
        for n in range(4, len(data)):
            val = _split_line(data[n])
            x.append(val[0])
            yval = val[1:]
            y.append(yval)

        nX = len(x)
        logger.information('nQ = ' + str(nQ))
        logger.information('nT = ' + str(nX))

        xT = np.array(x)
        eZero = np.zeros(nX)
        #Qaxis = ''
        for m in range(0, nQ):
            logger.information('Q[' + str(m + 1) + '] : ' + str(Q[m]))

            S = []
            for n in range(0, nX):
                S.append(y[n][m])

            if m == 0:
                #Qaxis += str(Q[m])
                xDat = xT
                yDat = np.array(S)
                eDat = eZero
            else:
                #Qaxis += ',' + str(Q[m])
                xDat = np.append(xDat, xT)
                yDat = np.append(yDat, np.array(S))
                eDat = np.append(eDat, eZero)

        CreateWorkspace(OutputWorkspace=self._out_ws,
                        DataX=xDat,
                        DataY=yDat,
                        DataE=eDat,
                        Nspec=nQ, UnitX='TOF')

        Qmax = Q[nQ - 1]
        instr = 'MolDyn'
        ana = 'simul'
        if Qmax <= 2.0:
            refl = '2'
        else:
            refl = '4'

        InstrParas(self._out_ws, instr, ana, refl)
        efixed = getEfixed(self._out_ws)# RunParas(self._out_ws, instr, name, name)
        logger.information('Qmax = ' + str(Qmax) + ' ; efixed = ' + str(efixed))
        pi4 = 4.0 * math.pi
        wave = 1.8 * math.sqrt(25.2429 / efixed)
        theta = []
        for n in range(0, nQ):
            qw = wave * Q[n] / pi4
            ang = 2.0 * math.degrees(math.asin(qw))
            theta.append(ang)

        ChangeAngles(self._out_ws, instr, theta)
    def _ascii_3d_import(self):
        """
        Import 3D ASCII data (e.g. I(Q, t)).
        """
        logger.notice('Loading ASCII data')
        from IndirectCommon import getEfixed
        from IndirectNeutron import ChangeAngles, InstrParas

        # Read file
        data = []
        x_axis = ('time', 'ns')
        v_axis = ('q', 'ang^-1')
        with open(self._file_name, 'r') as handle:
            for line in handle:
                line = line.strip()

                # Ignore empty lines
                if line == '':
                    continue

                # Data line (if not comment)
                elif line.strip()[0] != '#':
                    line_values = np.array([
                        ast.literal_eval(t.strip())
                        if 'nan' not in t.lower() else np.nan
                        for t in line.split()
                    ])
                    data.append(line_values)

        if x_axis is None or v_axis is None:
            raise ValueError('Data is not in expected format for 3D data')
        logger.debug('X axis: {0}'.format(x_axis))
        logger.debug('V axis: {0}'.format(v_axis))

        # Get axis and Y values
        data = np.swapaxes(np.array(data), 0, 1)
        x_axis_values = data[0, 1:]
        v_axis_values = data[1:, 0]
        y_values = np.ravel(data[1:, 1:])

        # Create the workspace

        wks = CreateWorkspace(OutputWorkspace=self._out_ws,
                              DataX=x_axis_values,
                              DataY=y_values,
                              NSpec=v_axis_values.size,
                              UnitX=x_axis[1],
                              EnableLogging=False)

        # Load the MolDyn instrument
        q_max = v_axis_values[-1]
        instrument = 'MolDyn'
        reflection = '2' if q_max <= 2.0 else '4'
        InstrParas(wks.name(), instrument, 'simul', reflection)

        # Process angles
        efixed = getEfixed(wks.name())
        logger.information('Qmax={0}, Efixed={1}'.format(q_max, efixed))
        wave = 1.8 * math.sqrt(25.2429 / efixed)
        qw = wave * v_axis_values / (4.0 * math.pi)
        theta = 2.0 * np.degrees(np.arcsin(qw))
        ChangeAngles(wks.name(), instrument, theta)

        return wks
Beispiel #18
0
    def PyExec(self):
        from IndirectCommon import getEfixed

        self._setup()

        # Set up progress reporting
        n_prog_reports = 2
        if self._can_ws_name is not None:
            n_prog_reports += 1
        prog = Progress(self, 0.0, 1.0, n_prog_reports)

        efixed = getEfixed(self._sample_ws)

        sample_wave_ws = '__sam_wave'
        ConvertUnits(InputWorkspace=self._sample_ws, OutputWorkspace=sample_wave_ws,
                     Target='Wavelength', EMode='Indirect', EFixed=efixed, EnableLogging = False)

        if self._sample_density_type == 'Mass Density':
            builder = MaterialBuilder()
            mat = builder.setFormula(self._sample_chemical_formula).setMassDensity(self._sample_density).build()
            self._sample_density = mat.numberDensity
        SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_density)

        prog.report('Calculating sample corrections')
        FlatPlateAbsorption(InputWorkspace=sample_wave_ws,
                            OutputWorkspace=self._ass_ws,
                            SampleHeight=self._sample_height,
                            SampleWidth=self._sample_width,
                            SampleThickness=self._sample_thickness,
                            ElementSize=self._element_size,
                            EMode='Indirect',
                            EFixed=efixed,
                            NumberOfWavelengthPoints=10)

        group = self._ass_ws

        if self._can_ws_name is not None:
            can_wave_ws = '__can_wave'
            ConvertUnits(InputWorkspace=self._can_ws_name, OutputWorkspace=can_wave_ws,
                         Target='Wavelength', EMode='Indirect', EFixed=efixed, EnableLogging = False)
            if self._can_scale != 1.0:
                logger.information('Scaling container by: ' + str(self._can_scale))
                Scale(InputWorkspace=can_wave_ws, OutputWorkspace=can_wave_ws, Factor=self._can_scale, Operation='Multiply')

            if self._use_can_corrections:
                prog.report('Calculating container corrections')
                Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)

                if self._sample_density_type == 'Mass Density':
                    builder = MaterialBuilder()
                    mat = builder.setFormula(self._can_chemical_formula).setMassDensity(self._can_density).build()
                    self._can_density = mat.numberDensity
                SetSampleMaterial(can_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_density)

                FlatPlateAbsorption(InputWorkspace=can_wave_ws,
                                    OutputWorkspace=self._acc_ws,
                                    SampleHeight=self._sample_height,
                                    SampleWidth=self._sample_width,
                                    SampleThickness=self._can_front_thickness + self._can_back_thickness,
                                    ElementSize=self._element_size,
                                    EMode='Indirect',
                                    EFixed=efixed,
                                    NumberOfWavelengthPoints=10)

                Divide(LHSWorkspace=can_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can_wave_ws)
                Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws)
                group += ',' + self._acc_ws

            else:
                prog.report('Calculating container scaling')
                Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws)
                Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)

            DeleteWorkspace(can_wave_ws, EnableLogging = False)

        else:
            Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)

        ConvertUnits(InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws,
                     Target='DeltaE', EMode='Indirect', EFixed=efixed, EnableLogging = False)
        DeleteWorkspace(sample_wave_ws, EnableLogging = False)

        prog.report('Recording sample logs')
        sample_log_workspaces = [self._output_ws, self._ass_ws]
        sample_logs = [('sample_shape', 'flatplate'),
                       ('sample_filename', self._sample_ws),
                       ('sample_height', self._sample_height),
                       ('sample_width', self._sample_width),
                       ('sample_thickness', self._sample_thickness),
                       ('element_size', self._element_size)]

        if self._can_ws_name is not None:
            sample_logs.append(('container_filename', self._can_ws_name))
            sample_logs.append(('container_scale', self._can_scale))
            if self._use_can_corrections:
                sample_log_workspaces.append(self._acc_ws)
                sample_logs.append(('container_front_thickness', self. _can_front_thickness))
                sample_logs.append(('container_back_thickness', self. _can_back_thickness))

        log_names = [item[0] for item in sample_logs]
        log_values = [item[1] for item in sample_logs]

        for ws_name in sample_log_workspaces:
            AddSampleLogMultiple(Workspace=ws_name, LogNames=log_names, LogValues=log_values, EnableLogging = False)

        self.setProperty('OutputWorkspace', self._output_ws)

        # Output the Ass workspace if it is wanted, delete if not
        if self._abs_ws == '':
            DeleteWorkspace(self._ass_ws, EnableLogging = False)
            if self._can_ws_name is not None and self._use_can_corrections:
                DeleteWorkspace(self._acc_ws, EnableLogging = False)
        else:
            GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._abs_ws, EnableLogging = False)
            self.setProperty('CorrectionsWorkspace', self._abs_ws)
Beispiel #19
0
 def _get_e_fixed(self, workspace):
     from IndirectCommon import getEfixed
     return getEfixed(workspace)
Beispiel #20
0
    def PyExec(self):
        run_f2py_compatibility_test()

        from IndirectBayes import (CalcErange, GetXYE)
        from IndirectCommon import (CheckXrange, CheckAnalysers, getEfixed, GetThetaQ, CheckHistZero)
        setup_prog = Progress(self, start=0.0, end=0.3, nreports = 5)
        logger.information('BayesStretch input')
        logger.information('Sample is %s' % self._sam_name)
        logger.information('Resolution is %s' % self._res_name)

        setup_prog.report('Converting to binary for Fortran')
        fitOp = self._encode_fit_ops(self._elastic, self._background)

        setup_prog.report('Establishing save path')
        workdir = self._establish_save_path()

        setup_prog.report('Checking X Range')
        CheckXrange(self._erange, 'Energy')

        setup_prog.report('Checking Analysers')
        CheckAnalysers(self._sam_name, self._res_name)
        setup_prog.report('Obtaining EFixed, theta and Q')
        efix = getEfixed(self._sam_name)
        theta, Q = GetThetaQ(self._sam_name)

        setup_prog.report('Checking Histograms')
        nsam,ntc = CheckHistZero(self._sam_name)

        #check if we're performing a sequential fit
        if self._loop != True:
            nsam = 1

        logger.information('Version is Stretch')
        logger.information('Number of spectra = %s ' % nsam)
        logger.information('Erange : %f to %f ' % (self._erange[0], self._erange[1]))

        setup_prog.report('Creating FORTRAN Input')
        fname = self._sam_name[:-4] + '_Stretch'
        wrks=os.path.join(workdir, self._sam_name[:-4])
        logger.information('lptfile : %s_Qst.lpt' % wrks)
        lwrk=len(wrks)
        wrks.ljust(140, ' ')
        wrkr=self._res_name
        wrkr.ljust(140, ' ')
        eBet0 = np.zeros(self._nbet)                  # set errors to zero
        eSig0 = np.zeros(self._nsig)                  # set errors to zero
        rscl = 1.0
        Qaxis = ''

        workflow_prog = Progress(self, start=0.3, end=0.7, nreports=nsam*3)

        # Empty arrays to hold Sigma and Bet x,y,e values
        xSig, ySig, eSig = [],[],[]
        xBet, yBet, eBet = [],[],[]

        for m in range(nsam):
            logger.information('Group %i at angle %f' % (m, theta[m]))
            nsp = m + 1
            nout, bnorm, Xdat, Xv, Yv, Ev = CalcErange(self._sam_name, m,
                                                       self._erange, self._nbins[0])
            Ndat = nout[0]
            Imin = nout[1]
            Imax = nout[2]

            # get resolution data (4096 = FORTRAN array length)
            Nb, Xb, Yb, _ = GetXYE(self._res_name, 0, 4096)
            numb = [nsam, nsp, ntc, Ndat, self._nbins[0], Imin,
                    Imax, Nb, self._nbins[1], self._nbet, self._nsig]
            reals = [efix, theta[m], rscl, bnorm]

            workflow_prog.report('Processing spectrum number %i' % m)
            xsout, ysout, xbout, ybout, zpout=Que.quest(numb, Xv, Yv, Ev, reals, fitOp,
                                                        Xdat, Xb, Yb, wrks, wrkr, lwrk)
            dataXs = xsout[:self._nsig]               # reduce from fixed FORTRAN array
            dataYs = ysout[:self._nsig]
            dataXb = xbout[:self._nbet]
            dataYb = ybout[:self._nbet]
            zpWS = fname + '_Zp' +str(m)
            if m > 0:
                Qaxis += ','
            Qaxis += str(Q[m])

            dataXz = []
            dataYz = []
            dataEz = []

            for n in range(self._nsig):
                yfit_list = np.split(zpout[:self._nsig*self._nbet], self._nsig)
                dataYzp = yfit_list[n]

                dataXz = np.append(dataXz, xbout[:self._nbet])
                dataYz = np.append(dataYz, dataYzp[:self._nbet])
                dataEz = np.append(dataEz, eBet0)

            zpWS = fname + '_Zp' + str(m)
            self._create_workspace(zpWS, [dataXz, dataYz, dataEz], self._nsig, dataXs, True)

            xSig = np.append(xSig,dataXs)
            ySig = np.append(ySig,dataYs)
            eSig = np.append(eSig,eSig0)
            xBet = np.append(xBet,dataXb)
            yBet = np.append(yBet,dataYb)
            eBet = np.append(eBet,eBet0)

            if m == 0:
                groupZ = zpWS
            else:
                groupZ = groupZ +','+ zpWS

        #create workspaces for sigma and beta
        workflow_prog.report('Creating OutputWorkspace')
        self._create_workspace(fname + '_Sigma', [xSig, ySig, eSig], nsam, Qaxis)
        self._create_workspace(fname + '_Beta', [xBet, yBet, eBet], nsam, Qaxis)

        group = fname + '_Sigma,' + fname + '_Beta'
        fit_ws = fname + '_Fit'
        s_api.GroupWorkspaces(InputWorkspaces=group,
                              OutputWorkspace=fit_ws)
        contour_ws = fname + '_Contour'
        s_api.GroupWorkspaces(InputWorkspaces=groupZ,
                              OutputWorkspace=contour_ws)

        #Add some sample logs to the output workspaces
        log_prog = Progress(self, start=0.8, end =1.0, nreports=6)
        log_prog.report('Copying Logs to Fit workspace')
        copy_log_alg = self.createChildAlgorithm('CopyLogs', enableLogging=False)
        copy_log_alg.setProperty('InputWorkspace', self._sam_name)
        copy_log_alg.setProperty('OutputWorkspace',fit_ws)
        copy_log_alg.execute()

        log_prog.report('Adding Sample logs to Fit workspace')
        self._add_sample_logs(fit_ws, self._erange, self._nbins[0])

        log_prog.report('Copying logs to Contour workspace')
        copy_log_alg.setProperty('InputWorkspace',self._sam_name)
        copy_log_alg.setProperty('OutputWorkspace',contour_ws)
        copy_log_alg.execute()

        log_prog.report('Adding sample logs to Contour workspace')
        self._add_sample_logs(contour_ws, self._erange, self._nbins[0])
        log_prog.report('Finialising log copying')

        self.setProperty('OutputWorkspaceFit', fit_ws)
        self.setProperty('OutputWorkspaceContour', contour_ws)
        log_prog.report('Setting workspace properties')
Beispiel #21
0
    def _calculate_parameters(self):
        """
        Calculates the TransformToIqt parameters and saves in a table workspace.
        """
        from IndirectCommon import getEfixed

        end_prog = 0.3 if self._calculate_errors else 0.9
        workflow_prog = Progress(self, start=0.0, end=end_prog, nreports=8)
        workflow_prog.report('Cropping Workspace')
        CropWorkspace(InputWorkspace=self._sample,
                      OutputWorkspace='__TransformToIqt_sample_cropped',
                      Xmin=self._e_min,
                      Xmax=self._e_max)
        workflow_prog.report('Calculating table properties')
        x_data = mtd['__TransformToIqt_sample_cropped'].readX(0)
        number_input_points = len(x_data) - 1
        num_bins = int(number_input_points / self._number_points_per_bin)
        self._e_width = (abs(self._e_min) + abs(self._e_max)) / num_bins

        workflow_prog.report('Attempting to Access IPF')
        try:
            workflow_prog.report('Access IPF')
            instrument = mtd[self._sample].getInstrument()

            analyserName = instrument.getStringParameter('analyser')[0]
            analyser = instrument.getComponentByName(analyserName)

            if analyser is not None:
                logger.debug(
                    'Found %s component in instrument %s, will look for resolution there'
                    % (analyserName, instrument))
                resolution = analyser.getNumberParameter('resolution')[0]
            else:
                logger.debug(
                    'No %s component found on instrument %s, will look for resolution in top level instrument'
                    % (analyserName, instrument))
                resolution = instrument.getNumberParameter('resolution')[0]

            logger.information('Got resolution from IPF: %f' % resolution)
            workflow_prog.report('IPF resolution obtained')
        except (AttributeError, IndexError):
            workflow_prog.report('Resorting to Default')
            resolution = getEfixed(self._sample) * 0.01
            logger.warning(
                'Could not get the resolution from the IPF, using 1% of the E Fixed value for the '
                'resolution: {0}'.format(resolution))

        resolution_bins = int(round((2 * resolution) / self._e_width))

        if resolution_bins < 5:
            logger.warning(
                'Resolution curve has <5 points. Results may be unreliable.')

        workflow_prog.report('Creating Parameter table')
        param_table = CreateEmptyTableWorkspace(
            OutputWorkspace=self._parameter_table)

        workflow_prog.report('Populating Parameter table')
        param_table.addColumn('int', 'SampleInputBins')
        param_table.addColumn('float', 'BinReductionFactor')
        param_table.addColumn('int', 'SampleOutputBins')
        param_table.addColumn('float', 'EnergyMin')
        param_table.addColumn('float', 'EnergyMax')
        param_table.addColumn('float', 'EnergyWidth')
        param_table.addColumn('float', 'Resolution')
        param_table.addColumn('int', 'ResolutionBins')

        param_table.addRow([
            number_input_points, self._number_points_per_bin, num_bins,
            self._e_min, self._e_max, self._e_width, resolution,
            resolution_bins
        ])

        workflow_prog.report('Deleting temp Workspace')
        if mtd.doesExist('__TransformToIqt_sample_cropped'):
            DeleteWorkspace('__TransformToIqt_sample_cropped')

        self.setProperty('ParameterWorkspace', param_table)
Beispiel #22
0
    def _calculate_parameters(self):
        """
        Calculates the TransformToIqt parameters and saves in a table workspace.
        """
        from IndirectCommon import getEfixed

        end_prog = 0.3 if self._calculate_errors else 0.9
        workflow_prog = Progress(self, start=0.0, end=end_prog, nreports=8)
        workflow_prog.report('Cropping Workspace')
        CropWorkspace(InputWorkspace=self._sample,
                      OutputWorkspace='__TransformToIqt_sample_cropped',
                      Xmin=self._e_min,
                      Xmax=self._e_max)
        workflow_prog.report('Calculating table properties')
        x_data = mtd['__TransformToIqt_sample_cropped'].readX(0)
        number_input_points = len(x_data) - 1
        num_bins = int(number_input_points / self._number_points_per_bin)
        self._e_width = (abs(self._e_min) + abs(self._e_max)) / num_bins

        workflow_prog.report('Attempting to Access IPF')
        try:
            workflow_prog.report('Access IPF')
            instrument = mtd[self._sample].getInstrument()

            analyserName = instrument.getStringParameter('analyser')[0]
            analyser = instrument.getComponentByName(analyserName)

            if analyser is not None:
                logger.debug('Found %s component in instrument %s, will look for resolution there'
                             % (analyserName, instrument))
                resolution = analyser.getNumberParameter('resolution')[0]
            else:
                logger.debug('No %s component found on instrument %s, will look for resolution in top level instrument'
                             % (analyserName, instrument))
                resolution = instrument.getNumberParameter('resolution')[0]

            logger.information('Got resolution from IPF: %f' % resolution)
            workflow_prog.report('IPF resolution obtained')
        except (AttributeError, IndexError):
            workflow_prog.report('Resorting to Default')
            resolution = getEfixed(self._sample) * 0.01
            logger.warning('Could not get the resolution from the IPF, using 1% of the E Fixed value for the '
                           'resolution: {0}'.format(resolution))

        resolution_bins = int(round((2 * resolution) / self._e_width))

        if resolution_bins < 5:
            logger.warning(
                'Resolution curve has <5 points. Results may be unreliable.')

        workflow_prog.report('Creating Parameter table')
        param_table = CreateEmptyTableWorkspace(
            OutputWorkspace=self._parameter_table)

        workflow_prog.report('Populating Parameter table')
        param_table.addColumn('int', 'SampleInputBins')
        param_table.addColumn('float', 'BinReductionFactor')
        param_table.addColumn('int', 'SampleOutputBins')
        param_table.addColumn('float', 'EnergyMin')
        param_table.addColumn('float', 'EnergyMax')
        param_table.addColumn('float', 'EnergyWidth')
        param_table.addColumn('float', 'Resolution')
        param_table.addColumn('int', 'ResolutionBins')

        param_table.addRow([number_input_points, self._number_points_per_bin, num_bins,
                            self._e_min, self._e_max, self._e_width,
                            resolution, resolution_bins])

        workflow_prog.report('Deleting temp Workspace')
        if mtd.doesExist('__TransformToIqt_sample_cropped'):
            DeleteWorkspace('__TransformToIqt_sample_cropped')

        self.setProperty('ParameterWorkspace', param_table)
    def PyExec(self):
        #from IndirectImport import run_f2py_compatibility_test, is_supported_f2py_platform

        run_f2py_compatibility_test()

        from IndirectBayes import (CalcErange, GetXYE, ReadNormFile,
                                   ReadWidthFile, QLAddSampleLogs, C2Fw,
                                   C2Se, QuasiPlot)
        from IndirectCommon import (CheckXrange, CheckAnalysers, getEfixed, GetThetaQ,
                                    CheckHistZero, CheckHistSame)
        setup_prog = Progress(self, start=0.0, end=0.3, nreports = 5)
        self.log().information('BayesQuasi input')

        erange = [self._e_min, self._e_max]
        nbins = [self._sam_bins, self._res_bins]
        setup_prog.report('Converting to binary for Fortran')
        #convert true/false to 1/0 for fortran
        o_el = 1 if self._elastic else 0
        o_w1 = 1 if self._width else 0
        o_res = 1 if self._res_norm else 0

        #fortran code uses background choices defined using the following numbers
        setup_prog.report('Encoding input options')
        if self._background == 'Sloping':
            o_bgd = 2
        elif self._background == 'Flat':
            o_bgd = 1
        elif self._background == 'Zero':
            o_bgd = 0

        fitOp = [o_el, o_bgd, o_w1, o_res]

        setup_prog.report('Establishing save path')
        workdir = config['defaultsave.directory']
        if not os.path.isdir(workdir):
            workdir = os.getcwd()
            logger.information('Default Save directory is not set. Defaulting to current working Directory: ' + workdir)

        array_len = 4096                           # length of array in Fortran
        setup_prog.report('Checking X Range')
        CheckXrange(erange,'Energy')

        nbin,nrbin = nbins[0], nbins[1]

        logger.information('Sample is ' + self._samWS)
        logger.information('Resolution is ' + self._resWS)

        setup_prog.report('Checking Analysers')
        CheckAnalysers(self._samWS,self._resWS)
        setup_prog.report('Obtaining EFixed, theta and Q')
        efix = getEfixed(self._samWS)
        theta, Q = GetThetaQ(self._samWS)

        nsam,ntc = CheckHistZero(self._samWS)

        totalNoSam = nsam

        #check if we're performing a sequential fit
        if self._loop != True:
            nsam = 1

        nres = CheckHistZero(self._resWS)[0]

        setup_prog.report('Checking Histograms')
        if self._program == 'QL':
            if nres == 1:
                prog = 'QLr'                        # res file
            else:
                prog = 'QLd'                        # data file
                CheckHistSame(self._samWS,'Sample',self._resWS,'Resolution')
        elif self._program == 'QSe':
            if nres == 1:
                prog = 'QSe'                        # res file
            else:
                raise ValueError('Stretched Exp ONLY works with RES file')

        logger.information('Version is ' +prog)
        logger.information(' Number of spectra = '+str(nsam))
        logger.information(' Erange : '+str(erange[0])+' to '+str(erange[1]))

        setup_prog.report('Reading files')
        Wy,We = ReadWidthFile(self._width,self._wfile,totalNoSam)
        dtn,xsc = ReadNormFile(self._res_norm,self._resnormWS,totalNoSam)

        setup_prog.report('Establishing output workspace name')
        fname = self._samWS[:-4] + '_'+ prog
        probWS = fname + '_Prob'
        fitWS = fname + '_Fit'
        wrks=os.path.join(workdir, self._samWS[:-4])
        logger.information(' lptfile : '+wrks+'_'+prog+'.lpt')
        lwrk=len(wrks)
        wrks.ljust(140,' ')
        wrkr=self._resWS
        wrkr.ljust(140,' ')

        setup_prog.report('Initialising probability list')
        # initialise probability list
        if self._program == 'QL':
            prob0 = []
            prob1 = []
            prob2 = []
        xQ = np.array([Q[0]])
        for m in range(1,nsam):
            xQ = np.append(xQ,Q[m])
        xProb = xQ
        xProb = np.append(xProb,xQ)
        xProb = np.append(xProb,xQ)
        eProb = np.zeros(3*nsam)

        group = ''
        workflow_prog = Progress(self, start=0.3, end=0.7, nreports=nsam*3)
        for m in range(0,nsam):
            logger.information('Group ' +str(m)+ ' at angle '+ str(theta[m]))
            nsp = m+1
            nout,bnorm,Xdat,Xv,Yv,Ev = CalcErange(self._samWS,m,erange,nbin)
            Ndat = nout[0]
            Imin = nout[1]
            Imax = nout[2]
            if prog == 'QLd':
                mm = m
            else:
                mm = 0
            Nb,Xb,Yb,Eb = GetXYE(self._resWS,mm,array_len)     # get resolution data
            numb = [nsam, nsp, ntc, Ndat, nbin, Imin, Imax, Nb, nrbin]
            rscl = 1.0
            reals = [efix, theta[m], rscl, bnorm]

            if prog == 'QLr':
                workflow_prog.report('Processing Sample number %i as Lorentzian' % nsam)
                nd,xout,yout,eout,yfit,yprob=QLr.qlres(numb,Xv,Yv,Ev,reals,fitOp,
                                                       Xdat,Xb,Yb,Wy,We,dtn,xsc,
                                                       wrks,wrkr,lwrk)
                message = ' Log(prob) : '+str(yprob[0])+' '+str(yprob[1])+' '+str(yprob[2])+' '+str(yprob[3])
                logger.information(message)
            if prog == 'QLd':
                workflow_prog.report('Processing Sample number %i' % nsam)
                nd,xout,yout,eout,yfit,yprob=QLd.qldata(numb,Xv,Yv,Ev,reals,fitOp,
                                                        Xdat,Xb,Yb,Eb,Wy,We,
                                                        wrks,wrkr,lwrk)
                message = ' Log(prob) : '+str(yprob[0])+' '+str(yprob[1])+' '+str(yprob[2])+' '+str(yprob[3])
                logger.information(message)
            if prog == 'QSe':
                workflow_prog.report('Processing Sample number %i as Stretched Exp' % nsam)
                nd,xout,yout,eout,yfit,yprob=Qse.qlstexp(numb,Xv,Yv,Ev,reals,fitOp,\
                                                        Xdat,Xb,Yb,Wy,We,dtn,xsc,\
                                                        wrks,wrkr,lwrk)
            dataX = xout[:nd]
            dataX = np.append(dataX,2*xout[nd-1]-xout[nd-2])
            yfit_list = np.split(yfit[:4*nd],4)
            dataF1 = yfit_list[1]
            if self._program == 'QL':
                dataF2 = yfit_list[2]
            workflow_prog.report('Processing data')
            dataG = np.zeros(nd)
            datX = dataX
            datY = yout[:nd]
            datE = eout[:nd]
            datX = np.append(datX,dataX)
            datY = np.append(datY,dataF1[:nd])
            datE = np.append(datE,dataG)
            res1 = dataF1[:nd] - yout[:nd]
            datX = np.append(datX,dataX)
            datY = np.append(datY,res1)
            datE = np.append(datE,dataG)
            nsp = 3
            names = 'data,fit.1,diff.1'
            res_plot = [0, 1, 2]
            if self._program == 'QL':
                workflow_prog.report('Processing Lorentzian result data')
                datX = np.append(datX,dataX)
                datY = np.append(datY,dataF2[:nd])
                datE = np.append(datE,dataG)
                res2 = dataF2[:nd] - yout[:nd]
                datX = np.append(datX,dataX)
                datY = np.append(datY,res2)
                datE = np.append(datE,dataG)
                nsp += 2
                names += ',fit.2,diff.2'
                res_plot.append(4)
                prob0.append(yprob[0])
                prob1.append(yprob[1])
                prob2.append(yprob[2])

            # create result workspace
            fitWS = fname+'_Workspaces'
            fout = fname+'_Workspace_'+ str(m)

            workflow_prog.report('Creating OutputWorkspace')
            CreateWorkspace(OutputWorkspace=fout, DataX=datX, DataY=datY, DataE=datE,\
                Nspec=nsp, UnitX='DeltaE', VerticalAxisUnit='Text', VerticalAxisValues=names)

            # append workspace to list of results
            group += fout + ','

        comp_prog = Progress(self, start=0.7, end=0.8, nreports=2)
        comp_prog.report('Creating Group Workspace')
        GroupWorkspaces(InputWorkspaces=group,OutputWorkspace=fitWS)

        if self._program == 'QL':
            comp_prog.report('Processing Lorentzian probability data')
            yPr0 = np.array([prob0[0]])
            yPr1 = np.array([prob1[0]])
            yPr2 = np.array([prob2[0]])
            for m in range(1,nsam):
                yPr0 = np.append(yPr0,prob0[m])
                yPr1 = np.append(yPr1,prob1[m])
                yPr2 = np.append(yPr2,prob2[m])
            yProb = yPr0
            yProb = np.append(yProb,yPr1)
            yProb = np.append(yProb,yPr2)
            probWs = CreateWorkspace(OutputWorkspace=probWS, DataX=xProb, DataY=yProb, DataE=eProb,\
                Nspec=3, UnitX='MomentumTransfer')
            outWS = C2Fw(self._samWS[:-4],fname)
            if self._plot != 'None':
                QuasiPlot(fname,self._plot,res_plot,self._loop)
        if self._program == 'QSe':
            comp_prog.report('Runnning C2Se')
            outWS = C2Se(fname)
            if self._plot != 'None':
                QuasiPlot(fname,self._plot,res_plot,self._loop)

        log_prog = Progress(self, start=0.8, end =1.0, nreports=8)
        #Add some sample logs to the output workspaces
        log_prog.report('Copying Logs to outputWorkspace')
        CopyLogs(InputWorkspace=self._samWS, OutputWorkspace=outWS)
        log_prog.report('Adding Sample logs to Output workspace')
        QLAddSampleLogs(outWS, self._resWS, prog, self._background, self._elastic, erange,
                        (nbin, nrbin), self._resnormWS, self._wfile)
        log_prog.report('Copying logs to fit Workspace')
        CopyLogs(InputWorkspace=self._samWS, OutputWorkspace=fitWS)
        log_prog.report('Adding sample logs to Fit workspace')
        QLAddSampleLogs(fitWS, self._resWS, prog, self._background, self._elastic, erange,
                        (nbin, nrbin), self._resnormWS, self._wfile)
        log_prog.report('Finialising log copying')

        if self._save:
            log_prog.report('Saving workspaces')
            fit_path = os.path.join(workdir,fitWS+'.nxs')
            SaveNexusProcessed(InputWorkspace=fitWS, Filename=fit_path)
            out_path = os.path.join(workdir, outWS+'.nxs')                    # path name for nxs file
            SaveNexusProcessed(InputWorkspace=outWS, Filename=out_path)
            logger.information('Output fit file created : ' + fit_path)
            logger.information('Output paramter file created : ' + out_path)

        self.setProperty('OutputWorkspaceFit', fitWS)
        self.setProperty('OutputWorkspaceResult', outWS)
        log_prog.report('Setting workspace properties')

        if self._program == 'QL':
            self.setProperty('OutputWorkspaceProb', probWS)
Beispiel #24
0
    def PyExec(self):
        run_f2py_compatibility_test()

        from IndirectBayes import (CalcErange, GetXYE)
        from IndirectCommon import (CheckXrange, CheckAnalysersOrEFixed,
                                    getEfixed, GetThetaQ, CheckHistZero)
        setup_prog = Progress(self, start=0.0, end=0.3, nreports=5)
        logger.information('BayesStretch input')
        logger.information('Sample is %s' % self._sam_name)
        logger.information('Resolution is %s' % self._res_name)

        setup_prog.report('Converting to binary for Fortran')
        fitOp = self._encode_fit_ops(self._elastic, self._background)

        setup_prog.report('Establishing save path')
        workdir = self._establish_save_path()

        setup_prog.report('Checking X Range')
        CheckXrange(self._erange, 'Energy')

        setup_prog.report('Checking Analysers')
        CheckAnalysersOrEFixed(self._sam_name, self._res_name)
        setup_prog.report('Obtaining EFixed, theta and Q')
        efix = getEfixed(self._sam_name)
        theta, Q = GetThetaQ(self._sam_name)

        setup_prog.report('Checking Histograms')
        nsam, ntc = CheckHistZero(self._sam_name)

        # check if we're performing a sequential fit
        if not self._loop:
            nsam = 1

        logger.information('Version is Stretch')
        logger.information('Number of spectra = %s ' % nsam)
        logger.information('Erange : %f to %f ' %
                           (self._erange[0], self._erange[1]))

        setup_prog.report('Creating FORTRAN Input')
        fname = self._sam_name[:-4] + '_Stretch'
        wrks = os.path.join(workdir, self._sam_name[:-4])
        logger.information('lptfile : %s_Qst.lpt' % wrks)
        lwrk = len(wrks)
        wrks.ljust(140, ' ')
        wrkr = self._res_name
        wrkr.ljust(140, ' ')
        eBet0 = np.zeros(self._nbet)  # set errors to zero
        eSig0 = np.zeros(self._nsig)  # set errors to zero
        rscl = 1.0
        Qaxis = ''

        workflow_prog = Progress(self, start=0.3, end=0.7, nreports=nsam * 3)

        # Empty arrays to hold Sigma and Bet x,y,e values
        xSig, ySig, eSig = [], [], []
        xBet, yBet, eBet = [], [], []

        for m in range(nsam):
            logger.information('Group %i at angle %f' % (m, theta[m]))
            nsp = m + 1
            nout, bnorm, Xdat, Xv, Yv, Ev = CalcErange(self._sam_name, m,
                                                       self._erange,
                                                       self._nbins[0])
            Ndat = nout[0]
            Imin = nout[1]
            Imax = nout[2]

            # get resolution data (4096 = FORTRAN array length)
            Nb, Xb, Yb, _ = GetXYE(self._res_name, 0, 4096)
            numb = [
                nsam, nsp, ntc, Ndat, self._nbins[0], Imin, Imax, Nb,
                self._nbins[1], self._nbet, self._nsig
            ]
            reals = [efix, theta[m], rscl, bnorm]

            workflow_prog.report('Processing spectrum number %i' % m)
            xsout, ysout, xbout, ybout, zpout = Que.quest(
                numb, Xv, Yv, Ev, reals, fitOp, Xdat, Xb, Yb, wrks, wrkr, lwrk)
            dataXs = xsout[:self._nsig]  # reduce from fixed FORTRAN array
            dataYs = ysout[:self._nsig]
            dataXb = xbout[:self._nbet]
            dataYb = ybout[:self._nbet]
            zpWS = fname + '_Zp' + str(m)
            if m > 0:
                Qaxis += ','
            Qaxis += str(Q[m])

            dataXz = []
            dataYz = []
            dataEz = []

            for n in range(self._nsig):
                yfit_list = np.split(zpout[:self._nsig * self._nbet],
                                     self._nsig)
                dataYzp = yfit_list[n]

                dataXz = np.append(dataXz, xbout[:self._nbet])
                dataYz = np.append(dataYz, dataYzp[:self._nbet])
                dataEz = np.append(dataEz, eBet0)

            zpWS = fname + '_Zp' + str(m)
            self._create_workspace(zpWS, [dataXz, dataYz, dataEz], self._nsig,
                                   dataXs, True)

            xSig = np.append(xSig, dataXs)
            ySig = np.append(ySig, dataYs)
            eSig = np.append(eSig, eSig0)
            xBet = np.append(xBet, dataXb)
            yBet = np.append(yBet, dataYb)
            eBet = np.append(eBet, eBet0)

            if m == 0:
                groupZ = zpWS
            else:
                groupZ = groupZ + ',' + zpWS

        # create workspaces for sigma and beta
        workflow_prog.report('Creating OutputWorkspace')
        self._create_workspace(fname + '_Sigma', [xSig, ySig, eSig], nsam,
                               Qaxis)
        self._create_workspace(fname + '_Beta', [xBet, yBet, eBet], nsam,
                               Qaxis)

        group = fname + '_Sigma,' + fname + '_Beta'
        fit_ws = fname + '_Fit'
        s_api.GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=fit_ws)
        contour_ws = fname + '_Contour'
        s_api.GroupWorkspaces(InputWorkspaces=groupZ,
                              OutputWorkspace=contour_ws)

        # Add some sample logs to the output workspaces
        log_prog = Progress(self, start=0.8, end=1.0, nreports=6)
        log_prog.report('Copying Logs to Fit workspace')
        copy_log_alg = self.createChildAlgorithm('CopyLogs',
                                                 enableLogging=False)
        copy_log_alg.setProperty('InputWorkspace', self._sam_name)
        copy_log_alg.setProperty('OutputWorkspace', fit_ws)
        copy_log_alg.execute()

        log_prog.report('Adding Sample logs to Fit workspace')
        self._add_sample_logs(fit_ws, self._erange, self._nbins[0])

        log_prog.report('Copying logs to Contour workspace')
        copy_log_alg.setProperty('InputWorkspace', self._sam_name)
        copy_log_alg.setProperty('OutputWorkspace', contour_ws)
        copy_log_alg.execute()

        log_prog.report('Adding sample logs to Contour workspace')
        self._add_sample_logs(contour_ws, self._erange, self._nbins[0])
        log_prog.report('Finialising log copying')

        # sort x axis
        s_api.SortXAxis(InputWorkspace=fit_ws,
                        OutputWorkspace=fit_ws,
                        EnableLogging=False)
        s_api.SortXAxis(InputWorkspace=contour_ws,
                        OutputWorkspace=contour_ws,
                        EnableLogging=False)

        self.setProperty('OutputWorkspaceFit', fit_ws)
        self.setProperty('OutputWorkspaceContour', contour_ws)
        log_prog.report('Setting workspace properties')
    def PyExec(self):
        from IndirectCommon import getEfixed

        self._setup()

        # Set up progress reporting
        n_prog_reports = 2
        if self._can_ws_name is not None:
            n_prog_reports += 1
        prog = Progress(self, 0.0, 1.0, n_prog_reports)

        efixed = getEfixed(self._sample_ws_name)

        sample_wave_ws = '__sam_wave'
        ConvertUnits(InputWorkspace=self._sample_ws_name, OutputWorkspace=sample_wave_ws,
                     Target='Wavelength', EMode='Indirect', EFixed=efixed, EnableLogging=False)

        sample_thickness = self._sample_outer_radius - self._sample_inner_radius
        logger.information('Sample thickness: ' + str(sample_thickness))

        prog.report('Calculating sample corrections')
        if self._sample_density_type == 'Mass Density':
            builder = MaterialBuilder()
            mat = builder.setFormula(self._sample_chemical_formula).setMassDensity(self._sample_density).build()
            self._sample_density = mat.numberDensity
        SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_density)
        AnnularRingAbsorption(InputWorkspace=sample_wave_ws,
                              OutputWorkspace=self._ass_ws,
                              SampleHeight=3.0,
                              SampleThickness=sample_thickness,
                              CanInnerRadius=self._can_inner_radius,
                              CanOuterRadius=self._can_outer_radius,
                              SampleChemicalFormula=self._sample_chemical_formula,
                              SampleNumberDensity=self._sample_density,
                              NumberOfWavelengthPoints=10,
                              EventsPerPoint=self._events)

        group = self._ass_ws

        if self._can_ws_name is not None:
            can1_wave_ws = '__can1_wave'
            can2_wave_ws = '__can2_wave'
            ConvertUnits(InputWorkspace=self._can_ws_name, OutputWorkspace=can1_wave_ws,
                         Target='Wavelength', EMode='Indirect', EFixed=efixed, EnableLogging=False)
            if self._can_scale != 1.0:
                logger.information('Scaling container by: ' + str(self._can_scale))
                Scale(InputWorkspace=can1_wave_ws, OutputWorkspace=can1_wave_ws, Factor=self._can_scale, Operation='Multiply')
            CloneWorkspace(InputWorkspace=can1_wave_ws, OutputWorkspace=can2_wave_ws, EnableLogging=False)

            can_thickness_1 = self._sample_inner_radius - self._can_inner_radius
            can_thickness_2 = self._can_outer_radius - self._sample_outer_radius
            logger.information('Container thickness: %f & %f' % (can_thickness_1, can_thickness_2))

            if self._use_can_corrections:
                prog.report('Calculating container corrections')
                Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)

                if self._can_density_type == 'Mass Density':
                    builder = MaterialBuilder()
                    mat = builder.setFormula(self._can_chemical_formula).setMassDensity(self._can_density).build()
                    self._can_density = mat.numberDensity
                SetSampleMaterial(can1_wave_ws, ChemicalFormula=self._can_chemical_formula,
                                  SampleNumberDensity=self._can_density)

                AnnularRingAbsorption(InputWorkspace=can1_wave_ws,
                                      OutputWorkspace='__Acc1',
                                      SampleHeight=3.0,
                                      SampleThickness=can_thickness_1,
                                      CanInnerRadius=self._can_inner_radius,
                                      CanOuterRadius=self._sample_outer_radius,
                                      SampleChemicalFormula=self._can_chemical_formula,
                                      SampleNumberDensity=self._can_density,
                                      NumberOfWavelengthPoints=10,
                                      EventsPerPoint=self._events)

                SetSampleMaterial(can2_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_density)
                AnnularRingAbsorption(InputWorkspace=can2_wave_ws,
                                      OutputWorkspace='__Acc2',
                                      SampleHeight=3.0,
                                      SampleThickness=can_thickness_2,
                                      CanInnerRadius=self._sample_inner_radius,
                                      CanOuterRadius=self._can_outer_radius,
                                      SampleChemicalFormula=self._can_chemical_formula,
                                      SampleNumberDensity=self._can_density,
                                      NumberOfWavelengthPoints=10,
                                      EventsPerPoint=self._events)

                Multiply(LHSWorkspace='__Acc1', RHSWorkspace='__Acc2', OutputWorkspace=self._acc_ws, EnableLogging=False)
                DeleteWorkspace('__Acc1', EnableLogging=False)
                DeleteWorkspace('__Acc2', EnableLogging=False)

                Divide(LHSWorkspace=can1_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can1_wave_ws)
                Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can1_wave_ws, OutputWorkspace=sample_wave_ws)
                group += ',' + self._acc_ws

            else:
                prog.report('Calculating can scaling')
                Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can1_wave_ws, OutputWorkspace=sample_wave_ws)
                Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)

            DeleteWorkspace(can1_wave_ws, EnableLogging=False)
            DeleteWorkspace(can2_wave_ws, EnableLogging=False)

        else:
            Divide(LHSWorkspace=sample_wave_ws,
                   RHSWorkspace=self._ass_ws,
                   OutputWorkspace=sample_wave_ws)

        ConvertUnits(InputWorkspace=sample_wave_ws,
                     OutputWorkspace=self._output_ws,
                     Target='DeltaE',
                     EMode='Indirect',
                     EFixed=efixed,
                     EnableLogging=False)
        DeleteWorkspace(sample_wave_ws, EnableLogging=False)

        prog.report('Recording sample logs')
        sample_log_workspaces = [self._output_ws, self._ass_ws]
        sample_logs = [('sample_shape', 'annulus'),
                       ('sample_filename', self._sample_ws_name),
                       ('sample_inner', self._sample_inner_radius),
                       ('sample_outer', self._sample_outer_radius),
                       ('can_inner', self._can_inner_radius),
                       ('can_outer', self._can_outer_radius)]

        if self._can_ws_name is not None:
            sample_logs.append(('container_filename', self._can_ws_name))
            sample_logs.append(('container_scale', self._can_scale))
            if self._use_can_corrections:
                sample_log_workspaces.append(self._acc_ws)
                sample_logs.append(('container_thickness_1', can_thickness_1))
                sample_logs.append(('container_thickness_2', can_thickness_2))

        log_names = [item[0] for item in sample_logs]
        log_values = [item[1] for item in sample_logs]

        for ws_name in sample_log_workspaces:
            AddSampleLogMultiple(Workspace=ws_name, LogNames=log_names, LogValues=log_values, EnableLogging=False)

        self.setProperty('OutputWorkspace', self._output_ws)

        # Output the Ass workspace if it is wanted, delete if not
        if self._abs_ws == '':
            DeleteWorkspace(self._ass_ws, EnableLogging=False)
            if self._can_ws_name is not None and self._use_can_corrections:
                DeleteWorkspace(self._acc_ws, EnableLogging=False)
        else:
            GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._abs_ws, EnableLogging=False)
            self.setProperty('CorrectionsWorkspace', self._abs_ws)
    def PyExec(self):
        run_f2py_compatibility_test()

        from IndirectBayes import (CalcErange, GetXYE, C2Fwater)
        from IndirectCommon import (CheckXrange, CheckAnalysers, getEfixed, GetThetaQ,
                                    CheckHistZero, CheckHistSame)

        erange = [self._e_min, self._e_max]
        nbins = [self._sam_bins, self._res_bins]
        #convert true/false to 1/0 for fortran
        o_el = 1 if self._elastic else 0
        o_w1 = 1 if self._width else 0
        o_res = 1 if self._res_norm else 0

        #fortran code uses background choices defined using the following numbers
        if self._background == 'Sloping':
            o_bgd = 2
        elif self._background == 'Flat':
            o_bgd = 1
        elif self._background == 'Zero':
            o_bgd = 0

        fitOp = [o_el, o_bgd, o_w1, o_res]

        workdir = config['defaultsave.directory']
        if not os.path.isdir(workdir):
            workdir = os.getcwd()
            logger.information('Default Save directory is not set. Defaulting to current working Directory: ' + workdir)

        array_len = 4096                           # length of array in Fortran
        CheckXrange(erange, 'Energy')

        nbin,nrbin = nbins[0], nbins[1]

        logger.information('Sample is ' + self._sam_ws)
        logger.information('Resolution is ' + self._res_ws)

        CheckAnalysersOrEFixed(self._sam_ws, self._res_ws)
        efix = getEfixed(self._sam_ws)
        theta, Q = GetThetaQ(self._sam_ws)

        nsam,ntc = CheckHistZero(self._sam_ws)
        totalNoSam = nsam

        #check if we're performing a sequential fit
        if self._loop != True:
            nsam = 1

        prog = 'QLw'                        # res file
        logger.information('Program is ' + prog)
        logger.information(' Number of spectra = %i' % nsam)
        logger.information(' Erange : %f to %f' % (erange[0], erange[1]))

        dtn, xsc = self._read_width_file(self._res_norm, self._resnorm_ws, totalNoSam)
        Wy, We = self._read_norm_file(self._width,self._wfile,totalNoSam)

        fname = self._sam_ws[:-4] + '_'+ prog
        fit_ws = fname + '_Fit'
        wrks=os.path.join(workdir, self._sam_ws[:-4])
        logger.information(' lptfile : ' + wrks + '_' + prog + '.lpt')
        lwrk=len(wrks)
        wrks.ljust(140, ' ')
        wrkr=self._res_ws
        wrkr.ljust(140, ' ')

        group = ''
        workflow_prog = Progress(self, start=0.3, end=0.7, nreports=nsam*3)
        for m in range(nsam):
            logger.information('Group %i at angle %f' % (m, theta[m]))
            nsp = m + 1
            nout, bnorm, Xdat, Xv, Yv, Ev = CalcErange(self._sam_ws, m, erange, nbin)
            Ndat = nout[0]
            Imin = nout[1]
            Imax = nout[2]
            if prog == 'QLd':
                mm = m
            else:
                mm = 0
            Nb, Xb, Yb, Eb = GetXYE(self._res_ws, mm, array_len)     # get resolution data
            numb = [nsam, nsp, ntc, Ndat, nbin, Imin, Imax, Nb, nrbin]
            rscl = 1.0
            reals = [efix, theta[m], rscl, bnorm]

            workflow_prog.report('Processing spectrum number %i as Water' % m)
            nd,xout,yout,eout,yfit,yprob=QLwat.qlwat(numb, Xv, Yv, Ev, reals, fitOp,
													 Xdat, Xb, Yb, Wy, We, dtn, xsc,
													 wrks, wrkr, lwrk)

            dataX = xout[:nd]
            dataX = np.append(dataX, 2*xout[nd - 1] - xout[nd - 2])
            yfit_list = np.split(yfit[:4*nd], 4)
            dataF1 = yfit_list[1]
            workflow_prog.report('Processing data')
            dataG = np.zeros(nd)
            datX = dataX
            datY = yout[:nd]
            datE = eout[:nd]
            datX = np.append(datX, dataX)
            datY = np.append(datY, dataF1[:nd])
            datE = np.append(datE, dataG)
            res1 = dataF1[:nd] - yout[:nd]
            datX = np.append(datX, dataX)
            datY = np.append(datY, res1)
            datE = np.append(datE, dataG)
            nsp = 3
            names = 'data, fit.1, diff.1'
            res_plot = [0, 1, 2]

            # create result workspace
            fit_ws = fname + '_Workspaces'
            fout = fname + '_Workspace_' + str(m)

            workflow_prog.report('Creating OutputWorkspace')
            CreateWorkspace(OutputWorkspace=fout,
                            DataX=datX,
                            DataY=datY,
                            DataE=datE,
                            Nspec=nsp,
                            UnitX='DeltaE',
                            VerticalAxisUnit='Text',
                            VerticalAxisValues=names)

            # append workspace to list of results
            group += fout + ','

        comp_prog = Progress(self, start=0.7, end=0.8, nreports=2)
        comp_prog.report('Creating Group Workspace')
        GroupWorkspaces(InputWorkspaces=group,
                        OutputWorkspace=fit_ws)

        out_ws = C2Fwater(fname)

        #Add some sample logs to the output workspaces
        CopyLogs(InputWorkspace=self._sam_ws,
                 OutputWorkspace=out_ws)
        self._add_sample_logs(out_ws, prog, erange, nbins)
        CopyLogs(InputWorkspace=self._sam_ws,
                 OutputWorkspace=fit_ws)
        self._add_sample_logs(fit_ws, prog, erange, nbins)

        self.setProperty('OutputWorkspaceFit', fit_ws)
        self.setProperty('OutputWorkspaceResult', out_ws)
 def _get_e_fixed(self, workspace):
     from IndirectCommon import getEfixed
     return getEfixed(workspace)
Beispiel #28
0
    def PyExec(self):
        from IndirectCommon import getEfixed

        self._setup()

        # Set up progress reporting
        n_prog_reports = 2
        if self._can_ws_name is not None:
            n_prog_reports += 1
        prog = Progress(self, 0.0, 1.0, n_prog_reports)

        efixed = getEfixed(self._sample_ws_name)

        sample_wave_ws = '__sam_wave'
        ConvertUnits(InputWorkspace=self._sample_ws_name, OutputWorkspace=sample_wave_ws,
                     Target='Wavelength', EMode='Indirect', EFixed=efixed)

        SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._sample_chemical_formula, SampleNumberDensity=self._sample_number_density)

        prog.report('Calculating sample corrections')
        CylinderAbsorption(InputWorkspace=sample_wave_ws,
                           OutputWorkspace=self._ass_ws,
                           SampleNumberDensity=self._sample_number_density,
                           NumberOfWavelengthPoints=10,
                           CylinderSampleHeight=3.0,
                           CylinderSampleRadius=self._sample_radius,
                           NumberOfSlices=1,
                           NumberOfAnnuli=10)

        plot_data = [self._output_ws, self._sample_ws_name]
        plot_corr = [self._ass_ws]
        group = self._ass_ws

        if self._can_ws_name is not None:
            can_wave_ws = '__can_wave'
            ConvertUnits(InputWorkspace=self._can_ws_name, OutputWorkspace=can_wave_ws,
                         Target='Wavelength', EMode='Indirect', EFixed=efixed)
            if self._can_scale != 1.0:
                logger.information('Scaling can by: ' + str(self._can_scale))
                Scale(InputWorkspace=can_wave_ws, OutputWorkspace=can_wave_ws, Factor=self._can_scale, Operation='Multiply')

            can_thickness = self._can_radius - self._sample_radius
            logger.information('Container thickness: ' + str(can_thickness))

            if self._use_can_corrections:
                # Doing can corrections
                prog.report('Calculating container corrections')
                Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)

                SetSampleMaterial(can_wave_ws, ChemicalFormula=self._can_chemical_formula, SampleNumberDensity=self._can_number_density)
                AnnularRingAbsorption(InputWorkspace=can_wave_ws,
                                      OutputWorkspace=self._acc_ws,
                                      SampleHeight=3.0,
                                      SampleThickness=can_thickness,
                                      CanInnerRadius=0.9*self._sample_radius,
                                      CanOuterRadius=1.1*self._can_radius,
                                      SampleChemicalFormula=self._can_chemical_formula,
                                      SampleNumberDensity=self._can_number_density,
                                      NumberOfWavelengthPoints=10,
                                      EventsPerPoint=self._events)

                Divide(LHSWorkspace=can_wave_ws, RHSWorkspace=self._acc_ws, OutputWorkspace=can_wave_ws)
                Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws)
                plot_corr.append(self._acc_ws)
                group += ',' + self._acc_ws

            else:
                # Doing simple can subtraction
                prog.report('Calculating container scaling')
                Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws)
                Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)

            DeleteWorkspace(can_wave_ws)
            plot_data.append(self._can_ws_name)

        else:
            Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)

        ConvertUnits(InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws,
                     Target='DeltaE', EMode='Indirect', EFixed=efixed)
        DeleteWorkspace(sample_wave_ws)

        # Record sample logs
        prog.report('Recording sample logs')
        sample_log_workspaces = [self._output_ws, self._ass_ws]
        sample_logs = [('sample_shape', 'cylinder'),
                       ('sample_filename', self._sample_ws_name),
                       ('sample_radius', self._sample_radius)]

        if self._can_ws_name is not None:
            sample_logs.append(('container_filename', self._can_ws_name))
            sample_logs.append(('container_scale', self._can_scale))
            if self._use_can_corrections:
                sample_log_workspaces.append(self._acc_ws)
                sample_logs.append(('container_thickness', can_thickness))

        log_names = [item[0] for item in sample_logs]
        log_values = [item[1] for item in sample_logs]

        for ws_name in sample_log_workspaces:
            AddSampleLogMultiple(Workspace=ws_name, LogNames=log_names, LogValues=log_values)

        self.setProperty('OutputWorkspace', self._output_ws)

        # Output the Abs group workspace if it is wanted, delete if not
        if self._abs_ws == '':
            DeleteWorkspace(self._ass_ws)
            if self._can_ws_name is not None and self._use_can_corrections:
                DeleteWorkspace(self._acc_ws)

        else:
            GroupWorkspaces(InputWorkspaces=group, OutputWorkspace=self._abs_ws)
            self.setProperty('CorrectionsWorkspace', self._abs_ws)

        if self._plot:
            from IndirectImport import import_mantidplot
            mantid_plot = import_mantidplot()
            mantid_plot.plotSpectrum(plot_data, 0)
            if self._abs_ws != '':
                mantid_plot.plotSpectrum(plot_corr, 0)