class SymmetryMatrix33(SymmetryMatrix): ParamDict = { "S11": IntInfo("S11", "S[1, 1]", 0), "S12": IntInfo("S12", "S[1, 2]", 0), "S13": IntInfo("S13", "S[1, 3]", 0), "S21": IntInfo("S21", "S[2, 1]", 0), "S22": IntInfo("S22", "S[2, 2]", 0), "S23": IntInfo("S23", "S[2, 3]", 0), "S31": IntInfo("S31", "S[3, 1]", 0), "S32": IntInfo("S32", "S[3, 2]", 0), "S33": IntInfo("S33", "S[3, 3]", 0), "T1": FloatInfo("T1", "T[1]", 0.0), "T2": FloatInfo("T2", "T[2]", 0.0), "T3": FloatInfo("T3", "T[3]", 0.0), } ObjectDict = {} ObjectListDict = {} def __init__(self, parent): """ initialization: extending """ SymmetryMatrix.__init__(self, parent) return
class OperatorSetSymmetry(OperatorSet): """ the main container of a set of symmetry operators """ ParamDict = { "Nsym": IntInfo("Nsym", "crystallographic symmetry operators number", 0, 0, None), "Cen": EnumInfo("Cen", "centrosymmetry flag", 1, { 1: "1", 2: "2" }, [1, 2]), "Laue": EnumInfo( "Laue", "Laue class for magnetic symmetry", 1, { 1: "1", 2: "", 3: "", 4: "", 5: "", 6: "", 7: "", 8: "", 9: "", 10: "", 11: "", 12: "", 13: "", 14: "" }, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]), "Nsym": IntInfo("Nsym", "symmetry operator number", 0), "MagMat": IntInfo("MagMat", "magnetic matrix number", 0), "DepMat": IntInfo("DepMat", "displacement matrix number", 0), } ObjectDict = {} ObjectListDict = { "OperatorCombo": ObjectInfo("SetOperatorCombo", "OperatorCombo", 0, None), } def __init__(self, parent): """ initialization """ RietveldClass.__init__(self, parent) return
class BkgdPoly(RietveldClass): """ one order of polynomial background: designed for flexible order of polynomial background calculation NOT USED NOW """ ParamDict = { "order": IntInfo("order", "polynomial term order", 0), "Bkgd": RefineInfo("Bkgd", "background value", 0.0), } ObjectDict = {} ObjectListDict = {} def __init__(self, Parent, order=None, value=None): """ initialization order: polynomial order value: Bkgd """ RietveldClass.__init__(self, Parent) if order is not None: self.set("order", order) if value is not None: self.set("Bkgd", value) return
class OperatorSetBasisFunction(OperatorSet): ParamDict = { "Ireps": IntInfo("Ireps", "number of irreducible representation", 0, 0, None), "Complex": EnumInfo("Complex", "atomic basis funtion complex number or not", 0, { 0: "real", 1: "complex" }, [0, 1]), } ObjectDict = {} ObjectListDict = { "Icompl": ObjectInfo("SetIcompl", "Icompl", 0, 1), } def __init__(self, parent): """ initialization """ RietveldClass.__init__(self, parent) return
class MonteCarlo(RietveldClass): # Optional (Cry=2): Monte Carlo search parameters ParamDict = { "NCONF": IntInfo("NCONF", "Number of Configuration", 1, 1, None), "NSOLU": IntInfo("NSOLU", "Number of Solution", 1, 1, None), "NREFLEXF": IntInfo("NREFLEXF", "Number of Reflection", 0, 0, None), "NSCALE": IntInfo("NSCALEF", "Scale Factor", 0) } ObjectDict = {} ObjectListDict = {} def __init__(self, Parent): RietveldClass.__init__(self, Parent) return
class DistanceRestraint(RietveldClass): """ soft distance contraints attribute: - CATOD1: StringInfo("CATOD1", "Atom 1", ""), - CATOD2: StringInfo("CATOD2", "Atom 2", ""), - ITnum: IntInfo("ITnum", "symmetry operator number", 0), - T1: FloatInfo("T1", "translation part 1 of symmetry operator", 0.0), - T2: FloatInfo("T2", "translation part 2 of symmetry operator", 0.0), - T3: FloatInfo("T3", "translation part 3 of symmetry operator", 0.0), - Dist: FloatInfo("Dist", "required distance", 1.0), - Sigma: FloatInfo("Sigma", "required distance deviation", 1.0), """ ParamDict = { "CATOD1": StringInfo("CATOD1", "Atom 1", ""), "CATOD2": StringInfo("CATOD2", "Atom 2", ""), "ITnum": IntInfo("ITnum", "symmetry operator number", 0), "T1": FloatInfo("T1", "translation part 1 of symmetry operator", 0.0), "T2": FloatInfo("T2", "translation part 2 of symmetry operator", 0.0), "T3": FloatInfo("T3", "translation part 3 of symmetry operator", 0.0), "Dist": FloatInfo("Dist", "required distance", 1.0), "Sigma": FloatInfo("Sigma", "required distance deviation", 1.0), } def __init__(self, parent): """initialization""" RietveldClass.__init__(self, parent) return
class BasisFunctionComplex(BasisFunction): ParamDict = { "I1": IntInfo("I1", "basis function complex component 1", 0), "I2": IntInfo("I2", "basis function complex component 1", 0), "I3": IntInfo("I3", "basis function complex component 1", 0), } ObjectDict = {} ObjectListDict = {} def __init__(self, parent): """ initialization: extending """ BasisFunction.__init__(self, parent) return
class BasisFunction(RietveldClass): ParamDict = { "R1": IntInfo("R1", "basis function real component 1", 0), "R2": IntInfo("R2", "basis function real component 1", 0), "R3": IntInfo("R3", "basis function real component 1", 0), } ObjectDict = {} ObjectListDict = {} def __init__(self, parent): """ initialization """ RietveldClass.__init__(self, parent) return
def __init__(self, parent, nbas): """ initialization """ RietveldClass.__init__(self, parent) for i in xrange(0, nbas): param_name = "Ireps" + str(i) self.ParamDict[param_name] = IntInfo( param_name, "real/pure imaginary BSF coefficient flags" + str(i), 0) self.__dict__[param_name] = self.ParamDict[param_name].get( "Default") return
class SimulatedAnnealing(RietveldClass): # Simulated (Cry=3): Simulated annealing parameters ParamDict = { "T_INI": FloatInfo("T_INI", "Initial Temperature", 0.0, '', 0.0, None), "ANNEAL": FloatInfo("ANNEAL", "Reduction Factor of the temperature between the MC Cycles", 0.9, '', 0.0, None), "ACCEPT": FloatInfo("ACCEPT", "Lowest percentage of accepted configurations", 0.5, '', 0.0, None), "NUMTEMPS": IntInfo("NUMTEMPS", "Maximum number of temperature", 1, 1, None), "NUMTHCYC": IntInfo("NUMTHCYC", "Number of Monte Carlo Cycles", 1, 1, None), "INITCONF": EnumInfo("INITCONF", "Initial Configuration", 0, { 0: "random", 1: "given" }, [0, 1]), "SEED_Random": StringInfo("SEED_Random", "Randomized Seed", ""), "NCONF": IntInfo("NCONF", "Number of Configuration", 1, 1, None), "NSOLU": IntInfo("NSOLU", "Number of Solution", 1, 1, None), "NREFLEXF": IntInfo("NREFLEXF", "Number of Reflection", 0, 0, None), "NSCALE": IntInfo("NSCALEF", "Scale Factor", 0), "NALGOR": EnumInfo( "NALGOR", "Algorithm", 0, { 0: "Corana algorithm", 1: "Corana algorithm is selected using as initial steps", 2: "Conventional algorithm using fixed steps" }, [2, 0, 1]), "ISWAP": IntInfo("ISWAP", "Interchange of Atoms", 0, 0, None), } ObjectDict = {} ObjectListDict = { "CPL": ObjectInfo("CPLList", "CPL", 0, None), } def __init__(self, Parent): RietveldClass.__init__(self, Parent) return
class Ion(RietveldClass): """ Ion for anion or cation """ ParamDict = { "Symbol": StringInfo("Symbol", "Ion's symbol", ""), "number": IntInfo("number", "number of ion", 0), } ObjectDict = {} ObjectListDict = {} def __init__(self, parent): """ initialization """ RietveldClass.__init__(self, parent) return 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
class RotationalMatrix33(RotationalMatrix): ParamDict = { "R11": IntInfo("R11", "R[1, 1]", 0), "R12": IntInfo("R12", "R[1, 2]", 0), "R13": IntInfo("R13", "R[1, 3]", 0), "R21": IntInfo("R21", "R[2, 1]", 0), "R22": IntInfo("R22", "R[2, 2]", 0), "R23": IntInfo("R23", "R[2, 3]", 0), "R31": IntInfo("R31", "R[3, 1]", 0), "R32": IntInfo("R32", "R[3, 2]", 0), "R33": IntInfo("R33", "R[3, 3]", 0), "Phase": FloatInfo("Phase", "Phase", 0.0, "2PI"), } ObjectDict = {} ObjectListDict = {} def __init__(self, parent): """ initialization: extending """ RotationalMatrix.__init__(self, parent) return
class BackgroundFourierwindow(Background): """ Background with Fourier window filtering """ ParamDict = { "FWINDOW": IntInfo("FWINDOW", "Fourier window filtering number", 0), } ObjectDict = {} ObjectListDict = {} def __init__(self, parent): """ initialization """ Background.__init__(self, parent) return
class TimeRev(RietveldClass): """ Time revolving of magnetic attribute: - NS: independent symmetry operator number - TimeRev_1 - ... - TimeRev_NS """ ParamDict = { "NS": IntInfo("NS", "independent symmetry operator number", 6), } ObjectDict = {} ObjectListDict = {} def __init__(self, parent, ns): """ initialization ns = NS """ # PJ: data module does not exist dead code, commented out ''' import data RietveldClass.__init__(self, parent) if ns > 0: self.set("NS", ns) else: raise NotImplementedError, "NS = " + str(ns) + " cannot be 0" for i in xrange(0, self.get("NS")+1): param_name = "TimeRev"+str(i) TimeRev.__dict__[param_name] = data.IntData(self.ParamDict[param_name].get("default")) ''' return
class Fit(RietveldClass): """ Fit contains information for a single Rietveld refinement configuration attributes banklist -- list of integers, index of banks used """ ParamDict = { # general information "Name": StringInfo("Name", "Fit Name", "new fit"), \ "Information": StringInfo("Information", "Fit Information", ""), \ "physparam": FloatInfo("physparam", "External Parameter", 0.0), \ # refinement solution information "Chi2": FloatInfo("Chi2", "Chi^2", 0.0, '', 0.0, None), # refinement setup information "Dum": EnumInfo("Dum", "Divergence Control", 0, \ {0: "Regular", \ 1: "criterion of convergence is not applied when shifts are lower than a fraction of standard deviation", \ 2: "stopped in case of local divergence", \ 3: "reflection near excluded regions are not taken into account for Bragg R-factor"}, \ [0, 1, 2, 3]), "Ias": EnumInfo("Ias", "Reordering of Reflections", 0, {0: "At First Cycle", 1: "At Each Cycle"}, [0, 1]), "Cry": EnumInfo("Cry", "Job and Refinement Algorithm", 0, \ {0: "Rietveld refinement", \ 1: "Refinement of single crystal data or integrated intensity of powder data", \ 2: "No least-square method is applied (Monte Carlo)", \ 3: "Simulated Annearing"}, \ [0, 1, 2, 3]), "Opt": BoolInfo("Opt", "Calculation Optimization", False), "Aut": BoolInfo("Aut", "Automatic Mode for Refinement Codes Numbering", False), "NCY": IntInfo("NCY", "Refinement Cycle Number", 1, 1, None), "Eps": FloatInfo("Eps", "Convergence Precision", 0.1, '', 0.0, None), "R_at": FloatInfo("R_at", "Atomic Relaxation Factor", 1.0), "R_an": FloatInfo("R_an", "Anisotropic Relaxation Factor", 1.0), "R_pr": FloatInfo("R_pr", "Profile Relaxation Factor", 1.0), "R_gl": FloatInfo("R_gl", "Global Pamameter Relaxation Factor", 1.0), # output options "Mat": EnumInfo("Mat", "Correlation Matrix Output", 1, {0: "no action", \ 1: "written in CODFIL.dat", \ 2: "diagonal of least square matrix is printed at every cycle"}, [0,1,2]), "Pcr": EnumInfo("Pcr", "Upate .pcr file after refinement", 1, {1: "CODFIL.pcr is re-written with updated parameters", 2: "A new input file is generated named CODFIL.new"}, [2,1]), "Syo": EnumInfo("Syo", "Output of the symmetry operator", 0, {0: "no action", 1: "symmetry operators are written in CODFIL.out"}, [0,1]), "Rpa": EnumInfo("Rpa", "Output .rpa file", 1, {-1:".cif file", 0: "no action", 1: ".rpa file", 2: ".sav file"}, [0,1,2]), "Sym": EnumInfo("Sym", "Output .sym file", 1, {0: "no cation", 1: "prepare CODFIL.sym"}, [0,1]), "Sho": BoolInfo("Sho", "Reduced output", False), "Nre": IntInfo("Nre", "Number of restrainted parameters", 0), } ObjectDict = { "Refine": ObjectInfo("Refine", "Refine"), } ObjectListDict = { #"MonteCarlo": ObjectInfo("MonteCarlo", "MonteCarlo", 0, 1), #"SimulatedAnnealing": ObjectInfo("SimulatedAnneaing", "SimulatedAnnealing", 0, 1), "Pattern": ObjectInfo("PatternList", "Pattern", 1, None), "Phase": ObjectInfo("PhaseList", "Phase", 1, None), "Contribution": ObjectInfo("ContributionList", "Contribution", 0, None), } def __init__(self, parent): """ initialization: add a new Fit, and create the refine object belonged to this fit object """ RietveldClass.__init__(self, parent) # init refine refineobj = Refine(None) self.set("Refine", refineobj) # bank information: This is for some specific pattern data such as ".gss" with different bank self.banklist = [] # internal data self.key = '' self._param_indices = {} self.updateParamIndices(self._param_indices) return def __str__(self): """ customerized output """ rstring = "" rstring += RietveldClass.__str__(self) return rstring def getContribution(self, p1, p2): """ get the contribution by pattern and phase p1: pattern/phase p2: phase/pattern return -- (1) Contribution (2) None if not exist """ from diffpy.pyfullprof.pattern import Pattern from diffpy.pyfullprof.phase import Phase from diffpy.pyfullprof.contribution import Contribution phase = None pattern = None if isinstance(p1, Pattern) and isinstance(p2, Phase): pattern = p1 phase = p2 elif isinstance(p1, Phase) and isinstance(p2, Pattern): pattern = p2 phase = p1 else: raise NotImplementedError, "fit.getContribution: p1 and p2 must be phase and pattern or pattern and phase" contributionlist = self.get("Contribution") for contribution in contributionlist: if contribution._ParentPhase == phase and contribution._ParentPattern == pattern: return contribution # if return will be None, then print out some debugging information if 0: contributionlist = self.get("Contribution") dbmsg = "pyfullprof.core.Fit.getContribution(): Cannot Find a Matching Contribution!\n" dbmsg += "%-20s: Phase -- %-30s Pattern -- %-30s\n" % ( "Input", repr(phase), repr(pattern)) counts = 0 for contribution in contributionlist: addrphase = repr(contribution._ParentPhase) addrpattern = repr(contribution._ParentPattern) dbmsg += "%-20s: Phase -- %-30s Pattern -- %-30s\n" % ( "Contribution " + str(counts), addrphase, addrpattern) counts += 1 print dbmsg return None def getParamList(self): return self.Refine.constraints def updateFit(self, newfit): """Update self with the new fit, which is the resultant Fit instance. newfit -- an instance of Fit """ # update Chi^2 for paramname in self.ParamDict: self.set(paramname, newfit.get(paramname)) for constraint in self.get("Refine").constraints[:]: if constraint.on: path = constraint.path val = newfit.getByPath(path) self.setByPath(path, val) #FIXME: it is a get-around of the engine bug newconstraint = newfit.getConstraintByPath(path) if newconstraint is not None: constraint.sigma = newconstraint.sigma for constraint in self.get("Refine").constraints[:]: print " %-10s %-15s %-15.6f+/- %-11.6f" \ % ( constraint.name, constraint.varName, constraint.getValue(), constraint.sigma) print "\n" return def validate(self, mode="Refine"): """ validate the parameters, subclass and container to meet the refinement requirement Arguments - mode : string, validate mode, (Refine, Calculate) Return : Boolean """ rvalue = RietveldClass.validate(self) errmsg = "" # I. Synchronization of FulProf Parameter & Check Data File Existence for pattern in self.get("Pattern"): # 2.1 data file existence if mode == "Refine": exist = checkFileExistence(pattern.get("Datafile")) if not exist: rvalue = False errmsg += "Data File %-10s Cannot Be Found\n" % ( pattern.get("Datafile")) # 2. Nre nre = 0 for variable in self.get("Refine").get("Variable"): if variable.get("usemin") is True: nre += 1 # End -- for variable in ... self.set("Nre", nre) # Check Validity # 1. parameter if self.get("NCY") < 1: rvalue = False # 2. .hkl file # the reason why not put the checking .hkl file in Contribution is that # there is a sequence number related between pattern sequence # within contribution, it is hard to get this number for pattern in self.get("Pattern"): # scan all Phases pindex = 1 fnamer = pattern.get("Datafile").split(".")[0] usehkl = False for phase in self.get("Phase"): # get contribution contribution = self.getContribution(pattern, phase) if contribution is not None and contribution.get("Irf") == 2: # using reflection usehkl = True # check single phase/contribution hkl file hklfname = fnamer + str(pindex) + ".hkl" try: hklfile = open(hklfname, "r") hklfile.close() except IOError, err: # if no such file exits, update Irf to 0 contribution.set("Irf", 0) # error message output errmsg += "Fit.validate(): Reflection File %-10s Cannot Be Found: " % ( hklfname) errmsg += "Chaning Contribution.Irf to 0 ... Related to Phase[%-5s]" % ( pindex) print errmsg # End -- if contribution is not None and Irf == 2: pindex += 1 # End -- for phase in self.get("Phase"): if usehkl is True: # check overall hkl file hklfname = fnamer + ".hkl" try: hklfile = open(hklfname, "r") hklfile.close() except IOError, err: # if no such file exists, update all Irf to 0 for contribution in self.get("Contribution"): contribution.set("Irf", 0)
class PatternTOF(Pattern): """ Class for Time-of-flight Pattern """ ParamDict = { # experiment set "Bank": IntInfo("Bank", "Bank Index In Pattern File", 1), "Npr": EnumInfo("Npr", "Default Profile", 0, { 0: "Gaussian", 1: "Cauchy", 2: "Modified 1 Lorentzian", 3: "Modified 2 Lorentzian", 4: "Tripled Pseudo-Voigt", 5: "Psuedo-Voigt", 6: "Pearson VII", 7: "Thompson-Cox-Hastings", 8: "Numerical Profile given in CODFIL.shp", 9: "T.O.F. Convolution Pseudo-Voigt", 10: "T.O.F. Convolution Pseudo-Voigt versus d-spacing", 11: "Split Psuedo-Voigt Function", 12: "Pseudo-Voigt function convoluted with axial divergence asymmetry function", 13: "T.O.F. Pseudo-Voigt function convoluted with Ikeda-Carpenter function" }, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]), "Iabscor": EnumInfo("Iabscor", "Absorption Correction", 3, {1: "Flat Plate Perpendicular to Incident Beam", 2: "Cylindrical Sample", 3: "Exponential correction"}, [1, 2, 3]), # refinement parameters and powder data range "Thmin": FloatInfo("Thmin", "Starting Scattering Variable", 0.0, "micro-second"), "Step": FloatInfo("Step", "Step of Scattering Variable", 1.0, "micro-second"), "Thmax": FloatInfo("Thmax", "Ending Scattering Variable", 0.0, "micro-second"), "TwoSinTh": FloatInfo("TwoSinTh", "2*sin(theta)", 0.0, "degree", 0, 360), # 2SinTh # experiment set II: refinable parameters "Zero": RefineInfo("Zero", "Zero Point", 0.0, unit="microsecond"), "Dtt1": RefineInfo("Dtt1", "Dtt1", 0.0), "Dtt2": RefineInfo("Dtt2", "Dtt2", 0.0), "Width": RefineInfo("Width", "Width of the crossover region", 0.0), "xcross": RefineInfo("xcross", "position of center of the crossover region", 0.0), } ObjectDict = {} ObjectListDict = {} def __init__(self, Parent=None): """ initialize: combine dictionaries """ Pattern.__init__(self, Parent) return def addContribution(self, contribution): """ add a Contribution pertinent to this phase return -- None contribution -- Contribution instance """ from diffpy.pyfullprof.contribution import ContributionTOF verifyType(contribution, ContributionTOF) self._contributionlist.append(contribution) return def setCalculation(self): """ set this instance to pattern calculation mode return -- None """ self.set("Job", -3) return def getUnitString(self): """ provide a string to the unit of this pattern return -- string, unit of this type of pattern TOF """ rstring = "Time-of-Flight (micro-second)" return rstring def validate(self): """ validate the parameters, subclass and container to meet the refinement requirement """ rvalue = Pattern.validate(self) # Set: Uni self.set("Uni", 1) # Check: TwoSinTh if abs(self.get("TwoSinTh")) < 1.0E-7: print "Not Allowed: TwoSinTh = 0.0" rvalue = False return rvalue
class Pattern(RietveldClass): """ Pattern contains all the information for a single pattern for Rietveld refinement attributes: _contributionlist -- list, containing related Contribution instance """ ParamDict = { "Name": StringInfo("Name", "Name", "Pattern"), "W_PAT": FloatInfo("W_PAT", "Pattern Weight", 1.0, "", 0.0, 1.0), #"Chi2": FloatInfo("Chi2", "Chi^2", 1.0E+8), "Scale": RefineInfo("Scale", "Scale factor", 1.0E-3), "Rp": FloatInfo("Rp", "Rp", 1.0E+8), "Rwp": FloatInfo("Rwp", "Rwp", 1.0E+8), "Bkpos": FloatInfo("Bkpos", "Origin of Polynomial Background", 47.0, "", 1.0E-8, None), "Wdt": FloatInfo("Wdt", "Cut-off of the peak profile tails", 8.0), "Job": EnumInfo("Job", "Radiation Type", -1, {0: "X-ray", 1: "Neutron Constant Wave", -1: "Neutron T.O.F. and Magnetic", -3: "Pattern Calculation Neutron T.O.F", 2: "Pattern Calculation X-ray", 3: "Pattern Calculation Neutron Constant Wavelength"}, [-1, 1, 0, -3, 2, 3]), "Nba": EnumInfo("Nba", "Background Type", 0, {0: "Polynomial", 1: "From CODFIL.bac", -1: "Debye-like Polynomial", -2: "Fourier Filtering", -3: "Read 6 Additional Polynomial Coefficients", 2: "Linear Interpolation with given background", -4: "Polynomial", -5: "Cubic Spline Interpolation"}, [0, -1, -3, -2, 2, -4, 1, -5]), "NbaPoint": IntInfo("NbaPoint", "number of points for user-defined background", 0, 0, None), "Nor": EnumInfo("Nor", "Preferred Orientation Function", -1, {0: "Preferred Orientation No.1", 1: "Preferred Orientation No.2", -1: "No preferred orientation"}, [0, 1, -1]), "Iwg": EnumInfo("Iwg", "Refinement Weight Scheme", 0, {0: "Standard Least Square Refinement", 1: "Maximum Likelihood Refinement", 2: "Unit Weights"}, [0, 1, 2]), "Res": EnumInfo("Res", "Resolution Function", 0, {0: "Not Given", 1: "Given by File with Resolution Function 1", 2: "Given by File with Resolution Function 2", 3: "Given by File with Resolution Function 3", 4: "List of value 2theta, H_G(2theta), H_L(2theta)", 5: "User Input Resolution File",}, [0, 1, 2, 3, 4, 5]), "Ste": IntInfo("Ste", "Number of data points reduction factor in powder data", 0, 0, None), "Uni": EnumInfo("Uni", "Scattering Variable Unit", 1, {0: "2theta degree", 1: "T.O.F in microseconds", 2: "Energy in keV"}, [1, 0, 2]), "Cor": EnumInfo("Cor", "Intensity Correction", 0, {0: "No Correction", 1: "file with intensity correction is read", 2: "file with coefficients of empirical function"}, [0, 1, 2]), "Datafile": StringInfo("Datafile", "Powder Data File", ""), "Instrumentfile": StringInfo("InstrumentFile", "Instrument file fullpath", ""), "Resofile": StringInfo("Resofile", "Resolution File", ""), # output "Ipr": EnumInfo("Ipr", "Profile integrated intensities output", 3, {0: "no action", 1: "observed and calculated proile intensities written in CODFIL.out", 2: "CODFILn.sub with the calculated profile for each phase are generated", 3: "CODFILn.sub with the calculated profile for each phase are generated, background added to each file"}, [0, 1, 2, 3]), "Ppl": EnumInfo("Ppl", "Various types of calculated output - I", 0, {0: "No action", 1: "MORE TO ADD", 2: "MORE TO ADD", 3: "MORE TO ADD"}, [0, 1, 2, 3]), "Ioc": EnumInfo("Ioc", "Various types of calculated outpout - II", 0, {0: "No action", 1: "MORE TO ADD", 2: "MORE TO ADD"}, [0, 1, 2]), "Ls1": EnumInfo("Ls1", "Various types of calculated outpout - III", 0, {0: "No action", 1: "MORE TO ADD"}, [0, 1]), "Ls2": EnumInfo("Ls2", "Various types of calculated outpout - IV", 0, {0: "No action", 1: "MORE TO ADD", 4: "MORE TO ADD", 5: "unknown operation"}, [0, 1, 4, 5]), "Ls3": EnumInfo("Ls3", "Various types of calculated outpout - V", 0, {0: "No action", 1: "MORE TO ADD"}, [0, 1]), "Prf": EnumInfo("Prf", "Output Format of Rietveld Plot File CODFIL.prf", 0, { 0: "no action", -3: "WinPlot Output", 1: "MORE TO ADD", 2: "MORE TO ADD", 3: "MORE TO ADD", 4: "pl1 File Output"}, [0, -3, 1, 2, 3, 4]), "Ins": EnumInfo("Ins", "Data File Format", 0, {0: "Data in free format", 1: "D1A/D2B format", 2: "D1B old format", 3: "Format corresponding to the ILL instruments D1B and D20", 4: "Brookaven synchrotron data", -4: "Brookaven synchrotron data given by DBWS program", 5: "GENERAL FORMAT for TWO AXIS instrument", 6: "D1A/D2B standard format prepared by D1A(D2B) SUM (ILL), ADDET(LLB), MIPDSUM(LLB) or equivalent programs", 7: "Files from D4 or D20L", 8: "Data from DMC at Paul Scherrer Institute", 10: "X, Y, Sigma format with header lines", 11: "Data from varaible time X-ray collection", 12: "data file conforming to GSAS standard data file", 14: "multiple bank data file from GEM (ISIS).gss file"}, [0, 1, 2, 3, 4, -4, 5, 6, 7, 8, 10, 11, 12, 14]), "Hkl": EnumInfo("Hkl", "Output of Reflection List in CODFIL.hkl", 0, {0: "no action", 1: "MORE TO ADD", 2: "MORE TO ADD", -2: "xpc add", 3: "MORE TO ADD", -3: "MORE TO ADD", 4: "MORE TO ADD", 5: "MORE TO ADD"}, [0, 1, 2, 3, -3, 4, 5]), "Fou": EnumInfo("Fou", "Output of CODEFILE.fou Files", 0, {0: "no action", 1: "MORE TO ADD", 2: "MORE TO ADD", 3: "MORE TO ADD", 4: "MORE TO ADD"}, [0, 1, 2, 3, 4]), "Ana": EnumInfo("Ana", "Reliability of the refinement analysis", 0, {0: "no action", 1: "provides an analysis of the refinement at the end of summary file"}, [0, 1]), "Nex": IntInfo("Nex", "Excluded Region Number", 0), "Nsc": IntInfo("Nsc", "Scatteirng Factor Number", 0), # Histogram usage flag, this flag is added here to be compatible with GSAS "ISUSED" : BoolInfo("ISUSED", 'True if pattern is used in the refinement', default=True), } ObjectDict = { "LPFactor": ObjectInfo("LPFactor", "LPFactor"), "Background": ObjectInfo("Background", "Background"), } ObjectListDict = { "ExcludedRegion": ObjectInfo("SetExcludedRegion", "ExcludedRegion", 0, None), "ScatterFactor": ObjectInfo("SetScatterFactor", "ScatterFactor", 0, None), } def __init__(self, Parent): RietveldClass.__init__(self, Parent) """ init subclass """ background = Background(None) self.set("Background", background) lpfactor = LPFactor(None) self.set("LPFactor", lpfactor) # init attributes self._contributionlist = [] self._reflections = {} return def set(self, param_name, value, index=None): """ function: set value to parameter 'param' param_name: parameter name, can be (1) parameter name (2) subclass name value : (1) corresponding python build-in type (2) an object reference index: for the location in ObjectListDict/ParamListDict """ rvalue = RietveldClass.set(self, param_name, value, index) if param_name == "Nba": nba = self.get(param_name) background = None if nba == 0: background = BackgroundPolynomial(self) background.set("Order", 6) elif nba == 1: background = BackgroundPolynomial(self) background.set("Order", 4) elif nba == -1: background = BackgroundDebye(self) elif nba == -2: background = BackgroundFourierwindow(self) elif nba == -3: background = BackgroundPolynomial(self) background.set("Order", 12) elif nba == -4: background = BackgroundPolynomial(self) background.set("Order", 12) elif nba == 2: background = BackgroundUserDefinedLinear(self) elif nba == -5: background = BackgroundUserDefinedCubic(self) else: errmsg = "Nba = %-10s is not supported" % (nba) raise RietError, errmsg if background is not None: self.set("Background", background) else: pass return rvalue def addBackgroundPoints(self, bkgdpointlist): """ add Background point (x, intensity) to this InterpolatedBackground instance Arguments: bkgdpointlist -- list of 2-tuple(x, intensity) for pre-selected background points Return -- None """ background = self.get("Background") for bkgdtup in bkgdpointlist: # 1. verify the input list term try: pos = bkgdtup[0] bck = bkgdtup[1] except IndexError, err: errmsg = "%-30s: Input Error! Element in input bkgdpointlist is not 2-tuple\n"% \ (self.__class__.__name__+"addBackgroundPoints()") errmsg += "Error message: %-40s"% (err) raise RietError(errmsg) # 2. make Core objects background.set("POS", pos) background.set("BCK", bck) # END -- for bkgdtup in bkgdpointlist: return
class BackgroundPolynomial(Background): """ BackgroundPolynomial is for background represented in polynomial functions """ ParamDict = { "Order": IntInfo("Order", "polynomial order", 0), "Bkpos": FloatInfo("Bkpos", "Origin of Polynomial Background", 1.0, "", 1.0E-8, None), } ParamListDict = { "BACK": RefineInfo("BACK", "Polynomial Background coefficient", 0.0, minsize=0, maxsize=12), } ObjectDict = {} ObjectListDict = {} def __init__(self, parent): """ initalization """ Background.__init__(self, parent) return def set(self, name, value, index=None): """Set the value for a member. name -- a key in ParamDict, ParamListDict, ObjectDict or ObjectListDict value -- the value/object to be set index -- only for ObjectListDict object, to give the location of the object """ Background.set(self, name, value, index) if name == 'Order': n = len(self.BACK) if value > n: for i in range(n, value): self.set('BACK', 0.0) elif value < n: for i in range(n-1, value-1, -1): self.delete('BACK', i) def validate(self): """ check whether the setup meets the requirement according to ObjectListDict and ObjectDict 1. Check the order to be 6 or 12 2. If order = 6, get rid of last 6 parameters from ParamDict """ rvalue = True order = self.get("Order") if not (order == 6 or order == 12): print "%s '%s': The order=%i is invalid."\ %(self.path, self.__class__.__name__, self.Order) rvalue = False if len(self.BACK) != self.Order: print "%s '%s': The order=%i and the number of coefficients=%i do not match."\ %(self.path, self.__class__.__name__, self.Order, len(self.BACK)) rvalue = False return rvalue
class AngleRestraint(RietveldClass): """ soft distance contraints attribute: - CATOD1 = "" - CATOD2 = "" - Itnum1 = 0 - Itnum2 = 0 - T1 = 0.0 - T2 = 0.0 - T3 = 0.0 - t1 = 0.0 - t2 = 0.0 - t3 = 0.0 - Angl = 0.0 - Sigma = 0.0 """ ParamDict = { "CATOD1": StringInfo("CATOD1", "Atom 1", ""), "CATOD2": StringInfo("CATOD2", "Atom 2", ""), "CATOD3": StringInfo("CATOD3", "Atom 3", ""), "ITnum1": IntInfo("ITnum1", "symmetry operator number 1", 0), "ITnum2": IntInfo("ITnum2", "symmetry operator number 2", 0), "T1": FloatInfo("T1", "translation part 1 of symmetry operator of ITnum1", 0.0), "T2": FloatInfo("T2", "translation part 2 of symmetry operator of ITnum1", 0.0), "T3": FloatInfo("T3", "translation part 3 of symmetry operator of ITnum1", 0.0), "t1": FloatInfo("t1", "translation part 1 of symmetry operator of ITnum2", 0.0), "t2": FloatInfo("t2", "translation part 2 of symmetry operator of ITnum2", 0.0), "t3": FloatInfo("t3", "translation part 3 of symmetry operator of ITnum2", 0.0), "Angle": FloatInfo("Angle", "required angle", 1.0), "Sigma": FloatInfo("Sigma", "required angle deviation", 1.0), } ObjectDict = {} ObjectListDict = {} def __init__(self): """ initalization """ RietveldClass.__init__(self, parent) return
class Phase(RietveldClass): """ Phase contains all the information only belongs to a single phase attributes _contributionlist -- list instance containing all the contribution related to this Phase """ ParamDict = { "Name": StringInfo("Name", "Phase Name", ""), "Jbt": EnumInfo( "Jbt", "Structure factor model and refinement method", 0, { 0: "treated with Rietveld method, refining a given structural model", 1: "treated with Rietveld method, pure magnetic", -1: "treated with Rietveld method, pure magentic with magnetic moments", 2: "profile matching method with constant scale factor", -2: "profile matching method with constant scale factor and given CODFiln.hkl", 3: "profile matching method with constant relative intensities for the current phase", -3: "profile matching method with given structure factor in CODFiln.hkl", 4: "intensities of nuclear reflection from Rigid body groups", 5: "intensities of magnetic reflection from conical magnetic structure in real space", 10: "nuclear and magnetic phase with Cartesian magnetic moment", -10: "nuclear and magnetic phase with spherical magnetic moment", 15: "commensurate modulated crystal structure with Cartesian magnetic components", -15: "commensurate modulated crystal structure with spherical magnetic components" }, [0, 1, -1, 2, -2, 3, -3, 4, 5, 10, -10, 15, -15]), "Comment": StringInfo("Comment", "Allowed Options", ""), "a": RefineInfo("a", "a", 1.0), "b": RefineInfo("b", "b", 1.0), "c": RefineInfo("c", "c", 1.0), "alpha": RefineInfo("alpha", "alpha", 90.0), "beta": RefineInfo("beta", "beta", 90.0), "gamma": RefineInfo("gamma", "gamma", 90.0), "Spacegroup": StringInfo("Spacegroup", "Space group", ""), "ATZ": FloatInfo("ATZ", "weight percent coefficient", 1.0, "", 0.0, None), "Isy": EnumInfo( "Isy", "Symmetry opertor reading control", 0, { 0: "symmetry operators generated automatically from the space group symbol", 1: "user-input symmetry operator", -1: "user-input symmetry operator", 2: "basis function" }, [0, 1, -1, 2]), "Str": EnumInfo( "Str", "size strain reading control", 0, { 0: "using selected models", 1: "generalized formulation of strains parameters be used", -1: "using selected models and generalized formulation of strains parameters be used", 2: "generalized formulation of size parameters be used", 3: "generalized formulation of strain and size parameters be used" }, [0, 1, -1, 2, 3]), "Jvi": EnumInfo("Jvi", "Output options", 0, { 0: "no operation", 3: "unknow operation", 1: "", 2: "", 11: "" }, [0, 3, 1, 2, 11]), "Jdi": EnumInfo("Jdi", "Crystallographic output options", 0, { 0: "", 1: "", -1: "", 2: "", 3: "", 4: "" }, [0, 1, -1, 2, 3, 4]), "Dis_max": FloatInfo("Dis_max", "maximum distance between atoms to output", 0.0), "Ang_max": FloatInfo("Ang_max", "maximum angle between atoms to output", 0.0), "BVS": StringInfo("BVS", "BVS calculation flag", ""), "Tolerance": FloatInfo("Tolerance", "Tolerance for the ionic radius", 0.0, "%"), "Hel": BoolInfo("Hel", "Control to constrain a magnetic structure to be helicoidal", False), "Sol": BoolInfo("Sol", "Additional hkl-dependent shifts reading control", False), "Nat": IntInfo("Nat", "Atom Number", 0, 0, None), "Dis": IntInfo("Dis", "distance restraint number", 0, 0, None), "MomMA": IntInfo("MomMA", "number of angle/magnetic restraint", 0, 0, None), "MomMoment": IntInfo("MomMoment", "number of magnetic restraints", 0, 0, None), "MomAngles": IntInfo("MomAngles", "number of angle restraints", 0, 0, None), "Furth": IntInfo("Furth", "user defined parameter number", 0, 0, None), "Nvk": IntInfo("Nvk", "number of propagation vector", 0), "More": BoolInfo("More", "flag for using Jvi, Jdi, Hel, Sol, Mom and Ter", False), "N_Domains": IntInfo("N_Domains", "Number of Domains/twins", 0, 0, None), } ObjectDict = { "OperatorSet": ObjectInfo("OperatorSet", "OperatorSet"), } ObjectListDict = { "TimeRev": ObjectInfo("TimeRev", "TimeRev", 0, 1), "Atom": ObjectInfo("SetAtom", "Atom", 0, None), "PropagationVector": ObjectInfo("SetPropagationVector", "PropagationVector", 0, None), "DistanceRestraint": ObjectInfo("SetDistanceRestraint", "DistanceRestraint", 0, None), "AngleRestraint": ObjectInfo("SetAngleRestraint", "AngleRestraint", 0, None), "MomentRestraint": ObjectInfo("SetMomentRestraint", "MomentRestraint", 0, None), "TransformationMatrixSet": ObjectInfo("TransformationMatrixSet", "TransformationMatrixSet", 0, 1), } def __init__(self, parent): """ initialization: """ RietveldClass.__init__(self, parent) # initialize subclass-object operatorset = OperatorSet(self) self.set("OperatorSet", operatorset) # initialize attributes self._contributionlist = [] return def isCrystalPhase(self): """ tell the user whether this phase is a crystal phase or not Return -- True/False """ jbt = self.get("Jbt") if jbt == 0 or jbt == 2: rvalue = True else: rvalue = False return rvalue def needAtoms(self): jbt = self.get("Jbt") if jbt == 2: return False else: return True def addContribution(self, contribution): """ add a Contribution pertinent to this phase return -- None contribution -- Contribution instance """ from diffpy.pyfullprof.contribution import Contribution verifyType(contribution, Contribution) self._contributionlist.append(contribution) return def getContribution(self): """ get the list of Contribution of this phase return -- list of Contribution """ return self._contributionlist 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 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 def set(self, param_name, value, index=None): """ Phase extending RietveldClass.set() method Arguments: param_name -- string, parameter name value -- instance, value to set """ rvalue = RietveldClass.set(self, param_name, value, index=index) if param_name == "Jvi": self.set("More", True) elif param_name == "Jdi": self.set("More", True) elif param_name == "Hel": self.set("More", True) elif param_name == "Sol": self.set("More", True) elif param_name == "Mom": self.set("More", True) elif param_name == "Ter": self.set("More", True) return rvalue def validate(self): """ validate of class Phase """ rvalue = RietveldClass.validate(self) errmsg = "" # FullProf parameter synchronization # atom nat = len(self.get("Atom")) self.set("Nat", nat) # dis dis = len(self.get("DistanceRestraint")) self.set("Dis", dis) # momma ang = len(self.get("AngleRestraint")) mom = len(self.get("MomentRestraint")) if ang != 0 and mom != 0: raise NotImplementedError, "Angular Restraint and Moment Restraint cannot be used simultaneously" self.set("MomMA", ang + mom) # nvk nvk = len(self.get("PropagationVector")) self.set("Nvk", nvk) # Situation validation # 1. Jbt and Atom Number jbt = self.get("Jbt") if abs(jbt) != 2 and nat == 0: # not Le-Bail (profile match) rvalue = False errmsg += "No Atom is defined while Jbt = %-5s (Not Le-Bail)" % ( jbt) # error message output if errmsg != "": prtmsg = "Phase Invalid Setup: %-60s" % (errmsg) print prtmsg if rvalue is not True: print "Invalidity Deteced In %-10s" % (self.__class__.__name__) return rvalue