Exemple #1
0
    def setIon(self, symnum):
        """
        set ion's information 

        synumber    --  string, the symbol+number, such as O+2
        
        return      --  None
        """
        verifyType(symnum, str)

        # split by + or -
        if symnum.count("+") == 1:
            terms = symnum.split("+")
            number = int(terms[1])
        elif symnum.count("-") == 1:
            terms = symnum.split("-")
            number = -1 * int(terms[1])
        else:
            errmsg = "%-30s: Input parameter 'symnum' is invalid! symnum = %-15s"%\
                     (self.__class__.__name___+".setIon( )", symnum)
            raise RietError, errmsg

        self.set("Symbol", terms[0])
        self.set("number", number)

        return
Exemple #2
0
    def setIon(self, symnum):
        """
        set ion's information 

        synumber    --  string, the symbol+number, such as O+2
        
        return      --  None
        """
        verifyType(symnum, str)

        # split by + or -
        if symnum.count("+") == 1:
            terms  = symnum.split("+")
            number = int(terms[1])
        elif symnum.count("-") == 1:
            terms = symnum.split("-")
            number = -1*int(terms[1])
        else:
            errmsg = "%-30s: Input parameter 'symnum' is invalid! symnum = %-15s"%\
                     (self.__class__.__name___+".setIon( )", symnum)
            raise RietError, errmsg

        self.set("Symbol", terms[0])
        self.set("number", number)

        return
Exemple #3
0
    def addContribution(self, contribution):
        """
        add a Contribution pertinent to this phase

        return  --  None

        contribution  --  Contribution instance
        """
        from diffpy.pyfullprof.contribution import Contribution2Theta
        verifyType(contribution, Contribution2Theta)
        self._contributionlist.append(contribution)
        return
Exemple #4
0
    def delContribution(self, contribution):
        """
        remove the Contribution instance from the Contribution-list

        return  --  None

        contribution    --  instance of Contribution

        Exception   
        1. if contribution is not in self._contributionlist
        """
        verifyType(contribution, Contribution)

        self._contributionlist.remove(contribution)

        return
Exemple #5
0
    def delContribution(self, contribution):
        """
        remove the Contribution instance from the Contribution-list

        return  --  None

        contribution    --  instance of Contribution

        Exception   
        1. if contribution is not in self._contributionlist
        """
        verifyType(contribution, Contribution)

        self._contributionlist.remove(contribution)

        return
Exemple #6
0
    def shiftOrigin(self, dx, dy, dz):
        """
        for the Space group with multiple origin, the implementation in FullProf
        is to shift the position of each atom by a specified amount
        
        return  --  None

        dx      --  float, -1 < dx < 1
        dy      --  float, -1 < dy < 1
        dz      --  float, -1 < dz < 1
        """
        verifyType(dx, float)
        verifyType(dy, float)
        verifyType(dz, float)

        # check range
        if abs(dx)>1 or abs(dy)>1 or abs(dz)>1:
            errmsg = "Phase.shiftOrigin(%-5s, %-5s, %-5s), Shift amount our of range"\
                     (str(dx), str(dy), str(dz))
            raise RietError(errmsg)

        # set shift
        for atom in self.get("Atom"):
            atom.shiftPosition(dx, dy, dz)

        return
Exemple #7
0
    def shiftOrigin(self, dx, dy, dz):
        """
        for the Space group with multiple origin, the implementation in FullProf
        is to shift the position of each atom by a specified amount
        
        return  --  None

        dx      --  float, -1 < dx < 1
        dy      --  float, -1 < dy < 1
        dz      --  float, -1 < dz < 1
        """
        verifyType(dx, float)
        verifyType(dy, float)
        verifyType(dz, float)

        # check range
        if abs(dx) > 1 or abs(dy) > 1 or abs(dz) > 1:
            errmsg = "Phase.shiftOrigin(%-5s, %-5s, %-5s), Shift amount our of range"\
                     (str(dx), str(dy), str(dz))
            raise RietError(errmsg)

        # set shift
        for atom in self.get("Atom"):
            atom.shiftPosition(dx, dy, dz)

        return
Exemple #8
0
def runFullProf(fit, pcrfilename, mode="refine", srtype="r", processdir=dir, userinfo=None, exportsub=False):
    """
    convert fit to FullProf pcr file
    execute Rietveld refinement by FullProf,

    Arguments:
    - fit           :   a fit object to convert to a pcr file and run by FullProf
    - pcrfilename   :   the name of the pcr file that is to write on the disk
    - mode          :   string, for mode.. options = 
                        1. "Refine"     least square refine 
                        2. "Calculate"  just calculate the pattern as the forward calculator
                        3. "pcr"        just print out pcr file
    - srtype        :   string, structure solution type, "r" for "Rietveld", "l" for Lebail
    - userinfo:     :   string, user information to add to pcr file
    - exportsub     :   Boolean (export result in .sub in calculation mode)

    Return          :   1. Refine Mode      FitSummary object
                        2. Calculate Mode   list of list of 2-tuple (or list) for a phase or None
    """
    from diffpy.pyfullprof.fit import Fit
    from diffpy.pyfullprof.pcrfilewriter import pcrFileWriter
    from diffpy.pyfullprof.pcrfilereader import ImportFitFromFullProf
    from diffpy.pyfullprof.fpoutputfileparsers import FPOutFileParser
    from diffpy.pyfullprof.fpuncertaintyreader import FPUncertainty

    # FIXME in 'Calculate' mode, only 1 pattern is allowed NOW!

    def ProcessOutput(infile):
        """
        processing an file thread
        (1) each line in intfile will be stored into a list as string without EOF
        (2) all lines are ordered according to the original order in infile

        infile: an file object
        """
        OutLines = []
        InLines  = infile.readlines()
        for line in InLines:
            newline = line.split("\n")[0]
            OutLines.append(newline)

        return OutLines

    # END FUNCTION:  def ProcessOutput(infile)

    def readFPOutput(lines):
        """ read the output of FullProf output file
          1. Last line contains "=> END"
            - check Chi2: is last Chi2 = "NaN"? "Chi2:-NaN, 
            - refined output 
          2. otherwise to 1
            a) "Error During Opening File" + file_name :  terminate the program
            b) "NO REFLECTIONS FOUND":  as Chi2 = NaN
        algorithm:
        (1) split Chi2 line with ":"

        return  1:  good refinement
                0   not refined
                -1: setup error
                -2: excessive peak overlap 
                -3: singular matrix
        """
        result = 0

        # 1. Exception!
        if len(lines) == 1:
            raise RietError("Fullprof fp2k Does Not Work")

        lastline = lines[-1]
        if lastline.count("=> END") >= 1:

            # 1. collect Chi2
            chi2lines = []
            for line in lines:
                if line.count("Chi2") == 1 and line.count("Rp")==1:
                    chi2lines.append(line)

            # 2. process last chi2 line
            # lastchi2line = chi2lines[len(chi2lines)-1]
            if len(chi2lines) > 1:
                # refinement mode
                lastchi2line = chi2lines[-1]
                if lastchi2line.count("NaN") > 0:
                    # NaN appears in statistic:  refine not done
                    result = 0
                else:
                    # good refinement
                    result = 1
            else:
                # calcuation mode
                result = -1

        else:   # not a normal end
            
            if lastline.count("Error") > 0:
                # Error 
                result = -1
                print "Exception!  FullProf set up error!   " + lastline + "\n"

            elif lastline.count("Excessive peak overlap") == 1:
                # Excessive peak overlap error
                result = -2

            elif lastline.count("Singular Matrix") == 1:
                # Singular Matrix Error
                result = -3

            elif lastline.count("NO REFLECTIONS FOUND") == 1:
                # Singular Matrix Error
                result = -4
        
            else:
                # intial value error
                result = 0

        return result

    # END FUNCTION:  def readFPOutput(lines)
    
    # -1: process input argument
    if userinfo is None:
        userinfo = []
    verifyType(userinfo, list)

    # 0. mandatory setup
    fit.set("Pcr", 1)
    fit.set("Aut", True)

    # 1.  check fit object:
    isvalid = fit.validate(mode)

    if not isvalid:
        dbtag = "1721"
        refine = fit.get("Refine")
        print "Debug Tag: %-20s" % (dbtag)
        print str(refine)
        errmsg = "runFullProf() Fit object is not valid. Abort!"
        raise RietError(errmsg)

    if mode == "calculate":
        # in this mode, data file is not used, but FullProf needs it!
        from diffpy.pyfullprof.utilfunction import checkFileExistence
        pattern   = fit.get("Pattern")[0]
        datafname = pattern.get("Datafile")
        isexist = checkFileExistence(datafname)
        if isexist is not True:
            fakedatafile = True
            fakefilename = datafname
            cmd = "touch %-10s"% (fakefilename)
            os.system(cmd)
        else:
            fakedatafile = False

    # 2. write out the pcr file and run FullProf
    pcrFileWriter(fit, pcrfilename, userinfo, srtype=srtype)
    # get the root name and ext name of the pcr file
    rootName, extname= os.path.splitext(os.path.basename(pcrfilename))
    baseName = os.path.basename(pcrfilename)
    if mode=="pcr":
        return
    shutil.copyfile(pcrfilename, rootName + '.prefit')

    cmd = 'fp2k ' + baseName

    import subprocess
    from diffpy.pyfullprof.environment import FullProfSubprocessArgs
    fp2kArgs = FullProfSubprocessArgs(cwd=processdir, stdout=subprocess.PIPE,
             stderr=subprocess.PIPE, stdin=open(os.devnull))
    
    
    output = subprocess.Popen(('fp2k', baseName ), **fp2kArgs)
    # 3. process output
    CodeOutput = ProcessOutput(output.stdout)
    #print '\n'.join(CodeOutput)
    CodeError  = ProcessOutput(output.stderr)

    output.stdout.close()
    output.stderr.close()
    output.wait()

    if mode == "refine":
        # 4. process fit result
        newfit = Fit(None)
        try:
            importfile   = ImportFitFromFullProf(pcrfilename)
            importresult = importfile.ImportFile(newfit)    
        except RietPCRError, err:
            print "Error Message:  %-30s"% (err)
            importresult = False

        # 5. pass the parameter and constraint information
        summary = FitSummary()

        if importresult is True:
            # 6. build output
            result = readFPOutput(CodeOutput)
            
            outfname = rootName +".out"

            # 6.2 Judge refine result
            # Note:  result > 0 is a more robust flag than refinesuccess
            if result == 0:
                refinesuccess = False
                errmsg = "NAN"
            elif result == -1:
                outparser = FPOutFileParser(newfit, outfname)
                refinesuccess = outparser.getStatus()
                errmsg = outparser.getErrorReason()
            elif result == -2:
                refinesuccess = False
                errmsg = "Excessive Peak Overlap"
            elif result == -3:
                refinesuccess = False
                errmsg = "Singular Matrix"
            elif result == -4:
                refinesuccess = False
                errmsg = "NO REFLECTIONS FOUND"
            else:
                refinesuccess = True
                errmsg = None
                if result < 0:
                    quitmessage = "result = %-5s < 0 means a failure error" % result
                    raise ValueError, quitmessage
            # END-IF-ELSE

            # 6.3 read uncertainty and phase fraction if refine is good 
            if refinesuccess is True: 
                # a) Uncertainty
                fpsigma = FPUncertainty(outfname)
                fpsigma.importUncertainty()
                fpsigma.exportToFit(newfit)

                # b) Phase Fraction
                sumfilename = rootName + ".sum"
                sumparse = FPSumFileParser(sumfilename)
                sumparse.parsePhaseFraction(newfit)
            # END-IF
            # 6.4 Construct Summary
            if result > 0:
                outparser = FPOutFileParser(newfit, outfname)
                summary.set(newfit, outparser, refinesuccess, srtype, errmsg, CodeOutput, CodeError)
            else:
                summary.setRefineStatus(False)
        else:
            # Bad refinement
            summary.setRefineStatus(False)
        # END-IF-ELSE 
        # 7. Process fp2k remainder
        os.rename(pcrfilename, rootName+".posfit")

        # 8. return
        return summary