1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 import tempfile, os
16 from diffpy.srrietveld.exceptions import SrrError
17
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
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
46 """Convert data file if neccessary.
47 """
48 from diffpy.srrietveld.addon.datafile import DataFileConverter as DFC
49
50
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
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"]:
68 self.genSamplingFromtimemap(fullpath, newfullpath, 1, self.snum, dfc, expfilepath)
69 else:
70 raise NotImplementedError
71
72 return self.fit
73
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
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
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
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
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