예제 #1
0
    def PyExec(self):

        self.check_platform_support()

        from IndirectBayes import (CalcErange, GetXYE)
        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 = int(self._elastic)
        o_w1 = int(self._width)
        o_res = int(self._res_norm)

        # fortran code uses background choices defined using the following numbers
        setup_prog.report('Encoding input options')
        o_bgd = ['Zero', 'Flat', 'Sloping'].index(self._background)
        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)
        self.check_energy_range_for_zeroes(first_data_point, 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 not self._loop:
            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 {0}'.format(prog))
        logger.information(' Number of spectra = {0} '.format(nsam))
        logger.information(' Erange : {0}  to {1} '.format(erange[0], erange[1]))

        setup_prog.report('Reading files')
        Wy, We = self._read_width_file(self._width, self._wfile, totalNoSam)
        dtn, xsc = self._read_norm_file(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, prob3 = [], [], [], []
        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)
        xProb = np.append(xProb, xQ)
        eProb = np.zeros(4 * nsam)

        group = ''
        workflow_prog = Progress(self, start=0.3, end=0.7, nreports=nsam * 3)
        for spectrum in range(0, nsam):
            logger.information('Group {0} at angle {1} '.format(spectrum, theta[spectrum]))
            nsp = spectrum + 1

            nout, bnorm, Xdat, Xv, Yv, Ev = CalcErange(self._samWS, spectrum, erange, nbin)
            Ndat = nout[0]
            Imin = nout[1]
            Imax = nout[2]
            if prog == 'QLd':
                mm = spectrum
            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[spectrum], rscl, bnorm]

            if prog == 'QLr':
                workflow_prog.report('Processing Sample number {0} as Lorentzian'.format(spectrum))
                nd, xout, yout, eout, yfit, yprob = QLr.qlres(numb, Xv, Yv, Ev, reals, fitOp,
                                                              Xdat, Xb, Yb, Wy, We, dtn, xsc,
                                                              wrks, wrkr, lwrk)
                logger.information(' Log(prob) : {0} {1} {2} {3}'.format(yprob[0], yprob[1], yprob[2], yprob[3]))
            elif prog == 'QLd':
                workflow_prog.report('Processing Sample number {0}'.format(spectrum))
                nd, xout, yout, eout, yfit, yprob = QLd.qldata(numb, Xv, Yv, Ev, reals, fitOp,
                                                               Xdat, Xb, Yb, Eb, Wy, We,
                                                               wrks, wrkr, lwrk)
                logger.information(' Log(prob) : {0} {1} {2} {3}'.format(yprob[0], yprob[1], yprob[2], yprob[3]))
            elif prog == 'QSe':
                workflow_prog.report('Processing Sample number {0} as Stretched Exp'.format(spectrum))
                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]
            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')
                dataF2 = yfit_list[2]
                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'

                dataF3 = yfit_list[3]
                datX = np.append(datX, dataX)
                datY = np.append(datY, dataF3[:nd])
                datE = np.append(datE, dataG)
                res3 = dataF3[:nd] - yout[:nd]
                datX = np.append(datX, dataX)
                datY = np.append(datY, res3)
                datE = np.append(datE, dataG)
                nsp += 2
                names += ',fit.3,diff.3'

                res_plot.append(4)
                prob0.append(yprob[0])
                prob1.append(yprob[1])
                prob2.append(yprob[2])
                prob3.append(yprob[3])

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

            workflow_prog.report('Creating OutputWorkspace')
            s_api.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')
        s_api.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]])
            yPr3 = np.array([prob3[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])
                yPr3 = np.append(yPr3, prob3[m])
            yProb = yPr0
            yProb = np.append(yProb, yPr1)
            yProb = np.append(yProb, yPr2)
            yProb = np.append(yProb, yPr3)

            prob_axis_names = '0 Peak, 1 Peak, 2 Peak, 3 Peak'
            s_api.CreateWorkspace(OutputWorkspace=probWS, DataX=xProb, DataY=yProb, DataE=eProb,
                                  Nspec=4, UnitX='MomentumTransfer', VerticalAxisUnit='Text',
                                  VerticalAxisValues=prob_axis_names)
            outWS = self.C2Fw(fname)
        elif self._program == 'QSe':
            comp_prog.report('Running C2Se')
            outWS = self.C2Se(fname)

        # Sort x axis
        s_api.SortXAxis(InputWorkspace=outWS, OutputWorkspace=outWS, EnableLogging=False)

        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')
        s_api.CopyLogs(InputWorkspace=self._samWS, OutputWorkspace=outWS)
        log_prog.report('Adding Sample logs to Output workspace')
        self._add_sample_logs(outWS, prog, erange, nbins)
        log_prog.report('Copying logs to fit Workspace')
        s_api.CopyLogs(InputWorkspace=self._samWS, OutputWorkspace=fitWS)
        log_prog.report('Adding sample logs to Fit workspace')
        self._add_sample_logs(fitWS, prog, erange, nbins)
        log_prog.report('Finalising log copying')

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

        if self._program == 'QL':
            s_api.SortXAxis(InputWorkspace=probWS, OutputWorkspace=probWS, EnableLogging=False)
            self.setProperty('OutputWorkspaceProb', probWS)
예제 #2
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')