1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 """
16 gsasinstparser.py is to parse the instrument info from .exp/iparm file
17 to get instrument instance for FullProf and GSAS.
18 """
19 from diffpy.srrietveld.exceptions import SrrValueError, SrrError
20
21 __id__ = "$Id: gsasinstparser.py 6462 2011-04-02 00:41:29Z yshang $"
22
24 """ Class to parse the instrument info from GSAS instrument file.
25
26 methods:
27 _readInstFile
28 parseInstType
29 parseTOFInst
30 parseCWInst
31 """
32 - def __init__(self, instfilename, banklist=None, engine="gsas"):
33 """ Initialization
34
35 Arguments:
36 instfilename : str, GSAS readable instrument file
37 banklist : tuple, list of bank IDs for refinement
38
39 Return : None
40 """
41 self._instfilename = instfilename
42 self._banklist = banklist
43 self._content = self._readInstFile()
44 self._engine = engine
45 self._instdict = {}
46 self._instdict["Name"] = self.parseInstType()
47 return
48
50 """ Parse Instrument Info into dict """
51 if self._instdict["Name"] == "TOF":
52 self.parseTOFInst()
53 else:
54 self.parseCWInst()
55 return self._instdict
56
58 """Read the GSAS Instrument file and find the instrument type
59 Return :
60 content : the list of lines in instrument file
61 """
62 try:
63 ifile = open(self._instfilename, "r")
64 ilines = ifile.readlines()
65 ifile.close()
66 except ValueError, e:
67 errmsg = "Cannot open %s : %s!" % (self._instfilename, e.message)
68 raise SrrValueError(errmsg)
69
70 return ilines
71
73 """Read the instrument type from file
74 Return :
75 type : str, type of instrument
76 """
77
78 term = "INS HTYPE"
79 line = self.mapKey(term)
80 sym = line.split()[2]
81
82
83 typedict = {"PNTR": "TOF", "PNCR": "NeutronCW", "PXCR": "Xray"}
84 if sym in typedict.keys():
85 type = typedict[sym]
86
87 return type
88
90 """Read the TOF instrument info
91 Return : self._instdict
92 """
93
94 for bankid in self._banklist:
95
96 term = "INS %iI ITYP"% int(bankid)
97 line = self.mapKey(term)
98 terms = line.split()
99 self._instdict["MEASUREMENT"] = [{}]
100 if self._engine == "gsas":
101 self._instdict["IFIL"] = self._instfilename
102 self._instdict["MEASUREMENT"][0]["TMIN"] = float(terms[4])
103 self._instdict["MEASUREMENT"][0]["TMAX"] = float(terms[5])
104 elif self._engine == "fullprof":
105 self._instdict["MEASUREMENT"][0]["Thmin"] = float(terms[4])
106 self._instdict["MEASUREMENT"][0]["Thmax"] = float(terms[5])
107 else:
108 raise NotImplementedError
109
110
111 term = "INS %i ICONS"% int(bankid)
112 line = self.mapKey(term)
113 terms = line.split()
114 self._instdict["ENERGY"] = [{}]
115 if self._engine == "gsas":
116 self._instdict["ENERGY"][0]["DIFC"] = float(terms[3])
117 self._instdict["ENERGY"][0]["DIFA"] = float(terms[4])
118 self._instdict["ENERGY"][0]["ZERO"] = float(terms[5])
119 elif self._engine == "fullprof":
120 self._instdict["ENERGY"][0]["Dtt1"] = float(terms[3])
121 self._instdict["ENERGY"][0]["Dtt2"] = float(terms[4])
122 self._instdict["ENERGY"][0]["Zero"] = float(terms[5])
123
124
125
126 term = "INS %iPRCF1"% int(bankid)
127 line = self.mapKey(term)
128 if line is not None:
129 self._instdict["PEAKPROFILE"] = [{}]
130 terms = line.split()
131 ptyp = int(terms[2])
132 if self._engine == "gsas":
133 self._instdict["PEAKPROFILE"][0]["CTOF"] = float(terms[4]) * 100
134 else:
135 raise NotImplementedError
136 self._instdict["PEAKPROFILE"][0]["Type"] = "ProfileTOF" + str(ptyp)
137
138 if ptyp == 1:
139 cof_prof = {0: "alp0", 1: "alp1", 2: "bet0", 3: "bet1", 4: "sig0",
140 5: "sig1", 6: "sig2", 7: "s1ec", 8: "s2ec", 9: "rstr",
141 10: "rsta", 11: "rsca"}
142 elif ptyp == 2:
143 cof_prof = {0: "alp0", 1: "alp1", 2: "beta", 3: "switch", 4: "sig0",
144 5: "sig1", 6: "sig2", 7:"gam0", 8: "gam1", 9: "gam2",
145 10: "ptec", 11: "stec", 12: "difc", 13: "difa", 14: "zero"}
146 elif ptyp == 3:
147 cof_prof = {0: "alp", 1: "bet0", 2: "bet1", 3: "sig0", 4: "sig1",
148 5: "sig2", 6: "gam0", 7: "gam1", 8: "gam2", 9: "gsf",
149 10: "g1ec", 11: "g2ec", 12: "rstr", 13: "rsta", 14: "rsca",
150 15: "L11", 16: "L22", 17: "L33", 18: "L12", 19: "L13", 20: "L23"}
151 elif ptyp == 4:
152 cof_prof = {0: "alp", 1: "bet0", 2: "bet1", 3: "sig1", 4: "sig2",
153 5: "gam2", 6: "g2ec", 7: "gsf", 8: "rstr", 9: "rsta", 10: "rsca",
154 11: "eta", 12: "S400"}
155 elif ptyp == 5:
156 cof_prof = {0: "alp", 1: "bet0", 2: "bet1", 3: "sig0", 4: "sig1",
157 5: "sig2", 6: "gam0", 7: "gam1", 8: "gam2", 9: "gsf", 10: "g1ec",
158 11: "g2ec", 12: "rstr", 13: "rsta", 14: "rsca", 15: "D11", 16: "D22",
159 17: "D33", 18: "D12", 19: "D13", 20: "D23"}
160 id_line = 0
161 for k in range(int(terms[3])):
162 if k % 4 == 0:
163 id_line += 1
164 iterm = "INS %iPRCF1%i" % (int(bankid), id_line)
165 pline = self.mapKey(iterm)
166 pterms = pline.split()
167 para_name = cof_prof[k]
168 try:
169 self._instdict["PEAKPROFILE"][0][para_name] = float(pterms[k%4+2])
170 except ValueError, e:
171 errmsg = "Cannot find value for %s : %s!" % (para_name, e.message)
172 raise SrrValueError(errmsg)
173 else:
174 errmsg = "No profile information in instrument file %s!" % self._instfilename
175 raise SrrError(errmsg)
176
177 return
178
180 """Read the CW instrument info
181
182 Return : self._instdict
183 """
184 bankid = int(self._banklist[0])
185
186 term = "INS %i ICONS"% bankid
187 line = self.mapKey(term)
188 if line is not None:
189 terms = line.split()
190 if self._engine == "gsas":
191 self._instdict["IFIL"] = self._instfilename
192 self._instdict["ENERGY"] = [{}]
193 self._instdict["ENERGY"][0]["LAM1"] = float(terms[3])
194 self._instdict["ENERGY"][0]["LAM2"] = float(terms[4])
195 self._instdict["ENERGY"][0]["ZERO"] = float(terms[5])
196 elif self._engine == "fullprof":
197 self._instdict["ENERGY"] = [{}]
198 self._instdict["ENERGY"][0]["Lambda"] = float(terms[3])
199 self._instdict["ENERGY"][0]["Lambda2"] = float(terms[4])
200 self._instdict["ENERGY"][0]["Zero"] = float(terms[5])
201 else:
202 errmsg = "No wavelength information in %s!" % self._instfilename
203 raise SrrError(errmsg)
204
205
206
207 term = "INS %iPRCF1"% bankid
208 line = self.mapKey(term)
209 if line is not None:
210 self._instdict["PEAKPROFILE"] = [{}]
211 terms = line.split()
212 ptyp = int(terms[2])
213 if self._engine == "gsas":
214 self._instdict["PEAKPROFILE"][0]["CTOF"] = float(terms[4]) * 100
215 else:
216 raise NotImplementedError
217 self._instdict["PEAKPROFILE"][0]["Type"] = "Profile2Theta" + str(ptyp)
218
219 if ptyp == 1:
220 cof_prof = {0: "U", 1: "V", 2: "W", 3: "asym", 4: "F1", 5: "F2"}
221 elif ptyp == 2:
222 cof_prof = {0: "GU", 1: "GV", 2: "GW", 3: "LX", 4: "LY", 5: "trns",
223 6: "asym", 7: "shft", 8: "GP", 9: "stec", 10: "ptec",
224 11: "sfec", 12: "L11", 13: "L22", 14: "L33", 15: "L12",
225 16: "L13", 17: "L23"}
226 elif ptyp == 3:
227 cof_prof = {0: "GU", 1: "GV", 2: "GW", 3: "GP", 4: "LX", 5: "LY",
228 6: "SL", 7: "HL", 8: "trns", 9: "shft", 10: "stec",
229 11: "ptec", 12: "sfec", 13: "L11", 14: "L22", 15: "L33",
230 16: "L12", 17: "L13", 18: "L23"}
231 elif ptyp == 4:
232 cof_prof = {0: "GU", 1: "GV", 2: "GW", 3: "GP", 4: "LX", 5: "ptec",
233 6: "trns", 7: "shft", 8: "sfec", 9: "SL", 10: "HL",
234 11: "eta", 12: "S400", 13: "S004"}
235 elif ptyp == 5:
236 cof_prof = {0: "GU", 1: "GV", 2: "GW", 3: "GP", 4: "LX", 5: "LY",
237 6: "SL", 7: "HL", 8: "trns", 9: "shft", 10: "stec",
238 11: "ptec", 12: "sfec", 13: "D11", 14: "D22", 15: "D33",
239 16: "D12", 17: "D13", 18: "D23"}
240
241 id_line = 0
242 for k in range(int(terms[3])):
243 if k % 4 == 0:
244 id_line += 1
245 iterm = "INS %iPRCF1%i" % (bankid, id_line)
246 pline = self.mapKey(iterm)
247 pterms = pline.split()
248 para_name = cof_prof[k]
249 try:
250 self._instdict["PEAKPROFILE"][0][para_name] = float(pterms[k%4+2])
251 except ValueError, e:
252 errmsg = "Cannot find value for %s | %s!" % (para_name, e.message)
253 raise SrrValueError(errmsg)
254 else:
255 errmsg = "No profile information in instrument file %s!" % self._instfilename
256 raise SrrError(errmsg)
257
258 return
259
261 """ Find the FIRST line that includes the key in lines
262
263 Argument:
264 - key : key value
265
266 Return : str
267 """
268 rline = None
269
270 for line in self._content:
271 if line.count(key) == 1:
272 rline = line
273 break
274
275 return rline
276