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