Package diffpy :: Package srrietveld :: Package addon :: Module mcsampling
[frames] | no frames]

Source Code for Module diffpy.srrietveld.addon.mcsampling

  1  ############################################################################## 
  2  # 
  3  # diffpy.srrietveld by DANSE Diffraction group 
  4  #                   Simon J. L. Billinge 
  5  #                   (c) 2011 Trustees of the Columbia University 
  6  #                   in the City of New York.  All rights reserved. 
  7  # 
  8  # File coded by:    Peng Tian 
  9  # 
 10  # See AUTHORS.txt for a list of people who contributed. 
 11  # See LICENSE.txt for license information. 
 12  # 
 13  ############################################################################## 
 14   
 15  import tempfile, os 
 16  from diffpy.srrietveld.exceptions import SrrError 
 17   
18 -class MonteCarloSampling:
19 """ Monte Carlo Sampling for diffraction pattern. 20 """
21 - def __init__(self, fit, snum, stype="Normal"):
22 """Initialization. 23 24 fit --- a diffpy.refinementdata.Refinement object that stores a fit with only one pattern 25 snum --- number of samplings 26 stype --- type of sampling distribution 27 """ 28 self.fit = fit 29 self.snum = snum 30 self.stype = stype 31 self.engine = self.getEngine() 32 self.tempDir = tempfile.mkdtemp() 33 return
34
35 - def getEngine(self):
36 """Get engine type from fit object. 37 """ 38 classname = self.fit.getAttr("rietveldcls") 39 if classname.count("gsas") == 1: 40 engine = "gsas" 41 else: 42 engine = "fullprof" 43 return engine
44
45 - def addSampleData(self):
46 """Convert data file if neccessary. 47 """ 48 from diffpy.srrietveld.addon.datafile import DataFileConverter as DFC 49 50 # only one pattern 51 fullpath = self.fit.getObject("Pattern").getObject(0).get("Datafile")[0] 52 instrumentfile = str(self.fit.getObject("Pattern").getObject(0).get("Instrumentfile")[0]) 53 if not os.path.exists(fullpath): 54 raise SrrError("Can not access the data file: " + fullpath) 55 56 expfilepath = os.path.join(os.getcwd(), self.fit.name + ".EXP") 57 filebasename = os.path.basename(fullpath) 58 rootname, extname = os.path.splitext(filebasename) 59 newfullpath = os.path.join(self.tempDir, filebasename) 60 dfc = DFC(fullpath, instrumentfile) 61 62 # sampling based on the datafile format 63 if extname.lower() == ".xye": 64 self.genSamplingFromxye(fullpath, newfullpath, 1, self.snum, dfc) 65 elif extname.lower() == ".chi": 66 self.genSamplingFromchi(fullpath, newfullpath, 1, self.snum, dfc) 67 elif extname.lower() in [".gsa", ".gda"]: #TIMEMAP case 68 self.genSamplingFromtimemap(fullpath, newfullpath, 1, self.snum, dfc, expfilepath) 69 else: 70 raise NotImplementedError 71 72 return self.fit
73
74 - def genSamplingFromtimemap(self, fullpath, newfullpath, bankid, num, dfc, expfilepath):
75 """Sampling num of times based on distribution and save the new datafile in newfullpath. 76 """ 77 import random 78 self.fit.reshape((num+1, ), ["SampleId", ], repeat=True) 79 pattern = self.fit.getObject("Pattern").getObject(0) 80 datafilelist = pattern.get("Datafile") 81 datadict = importFromGSAStimemap(fullpath, 1) 82 ys = datadict["yobs"] 83 ss = datadict["sobs"] 84 dstring = "" 85 sidlist = [] 86 for i in range(1, num+1): 87 dline = "" 88 sidlist.append(i) 89 for idx in range(len(ys)): 90 y_int = ys[idx] 91 s_int = ss[idx] 92 y_rad = random.gauss(y_int, s_int) 93 if y_rad <= 0.0 : 94 y_rad = 2 * y_int - y_rad 95 if y_rad == 0.0: 96 y_rad = y_int 97 dstring += "%8.1f%8.1f" % (y_rad, s_int) 98 if (idx+1)%5 == 0: 99 dline += "%-80s\r\n" % dstring 100 dstring = "" 101 elif idx == len(ys)-1: 102 dline += "%-80s\r\n" % dstring 103 dstring = "" 104 datafullpath = newfullpath[:-4] + str(i) + ".gsa" 105 headerline = datadict["header"] 106 allline = headerline + dline 107 dfc.writeDataFile(allline, datafullpath) 108 if self.engine == "fullprof": 109 outfullpath = newfullpath[:-4] + str(i) + ".dat" 110 dfc.toFPFile(datafullpath, outfullpath, 1, expfilepath) 111 datafullpath = outfullpath 112 datafilelist[i] = datafullpath 113 self.fit.set("SampleId", sidlist) 114 self.fit.resetStatus() 115 return
116 117
118 - def genSamplingFromxye(self, fullpath, newfullpath, bankid, num, dfc):
119 """Sampling num of times based on distribution and save the new datafile in newfullpath. 120 """ 121 self.fit.reshape((num+1, ), ["SampleId", ], repeat=True) 122 pattern = self.fit.getObject("Pattern").getObject(0) 123 datafilelist = pattern.get("Datafile") 124 for i in range(1, num+1): 125 if self.engine == "fullprof": 126 datafullpath = newfullpath[:-4] + str(i) + ".xye" 127 dfc.xyetoFP(fullpath, datafullpath, 1, self.stype) 128 else: 129 datafullpath = newfullpath[:-4] + str(i) + ".gsa" 130 dfc.toGSASFile(fullpath, datafullpath, 1, self.stype) 131 datafilelist[i] = datafullpath 132 133 self.fit.resetStatus() 134 return
135
136 - def genSamplingFromchi(self, fullpath, newfullpath, bankid, num, dfc):
137 """Sampling num of times based on distribution and save the new datafile in newfullpath. 138 """ 139 self.fit.reshape((num+1, ), ["SampleId", ], repeat=True) 140 pattern = self.fit.getObject("Pattern").getObject(0) 141 datafilelist = pattern.get("Datafile") 142 for i in range(1, num+1): 143 if self.engine == "fullprof": 144 datafullpath = newfullpath[:-4] + str(i) + ".chi" 145 dfc.chitoFP(fullpath, datafullpath, 1, self.stype) 146 else: 147 datafullpath = newfullpath[:-4] + str(i) + ".gsa" 148 dfc.toGSASFile(fullpath, datafullpath, 1, self.stype) 149 datafilelist[i] = datafullpath 150 151 self.fit.resetStatus() 152 return
153
154 -def importFromGSAStimemap(datafilename, bankid):
155 """Import a GSAS .gsa/gda file and get the dict of y, sd 156 157 Arguments: 158 - datafilename : full-path name of .gsa/gda file; 159 160 Return: datadict: a dictionary that includes series of yobs, sobs 161 """ 162 try: 163 ffile = open(datafilename, "r") 164 lines = ffile.readlines() 165 ffile.close() 166 except IOError: 167 errmsg = "Fatal Error: Cannot Open File %-20s"% (datafilename) 168 raise IOError, errmsg 169 170 datadict = {"header": "", "yobs": [], "sobs": []} 171 firstbankline = False 172 bankline = False 173 for line in lines: 174 terms = line.strip().split() 175 if terms[0] == "BANK" and terms[1] == str(bankid): 176 firstbankline = True 177 bankline = True 178 datadict["header"] += line 179 elif terms[0] == "BANK" and terms[1] != str(bankid): 180 firstbankline = False 181 bankline = True 182 elif firstbankline == False and bankline == False: 183 datadict["header"] += line 184 elif firstbankline == True and bankline == True: 185 for i in range(5): 186 try: 187 datadict["yobs"].append(float(terms[2*i])) 188 datadict["sobs"].append(float(terms[2*i+1])) 189 except: 190 break 191 return datadict
192
193 -def importFromGSASstd(datafilename, bankid):
194 """Import a GSAS .raw file and get the dict of y, sd 195 196 Arguments: 197 - datafilename : full-path name of .raw file; 198 199 Return: datadict: a dictionary that includes series of yobs, sobs 200 """ 201 try: 202 ffile = open(datafilename, "r") 203 lines = ffile.readlines() 204 ffile.close() 205 except IOError: 206 errmsg = "Fatal Error: Cannot Open File %-20s"% (datafilename) 207 raise IOError, errmsg 208 209 datadict = {"header": "", "countid": [], "yobs": [], "sobs": []} 210 firstbankline = False 211 bankline = False 212 for line in lines: 213 id = lines.index(line) 214 terms = line.strip().split() 215 if terms[0] == "BANK": 216 bankline = True 217 if terms[1] == str(bankid): 218 firstbankline = True 219 datadict["header"] += line 220 elif firstbankline == False and bankline == False: 221 datadict["header"] += line 222 elif firstbankline == True and bankline == True: 223 for i in range(10): 224 try: 225 datadict["countid"].append(int(line[8*i:(8*i+2)])) 226 yobs = int(line[(8*i+2):(8*i+7)]) 227 datadict["yobs"].append(yobs) 228 datadict["sobs"].append(yobs**0.5) 229 except: 230 break 231 return datadict
232