Package diffpy :: Package srrietveld :: Package convert :: Module gsasinstparser
[frames] | no frames]

Source Code for Module diffpy.srrietveld.convert.gsasinstparser

  1  ############################################################################## 
  2  # 
  3  # diffpy.srrietveld by DANSE Diffraction group 
  4  #                   Simon J. L. Billinge 
  5  #                   (c) 2009 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  """ 
 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   
23 -class GSASInstFile:
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
49 - def parseInstInfo(self):
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
57 - def _readInstFile(self):
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
72 - def parseInstType(self):
73 """Read the instrument type from file 74 Return : 75 type : str, type of instrument 76 """ 77 # 1. parse the htype from file 78 term = "INS HTYPE" 79 line = self.mapKey(term) 80 sym = line.split()[2] 81 82 # 2. match to the instrument type 83 typedict = {"PNTR": "TOF", "PNCR": "NeutronCW", "PXCR": "Xray"} 84 if sym in typedict.keys(): 85 type = typedict[sym] 86 87 return type
88
89 - def parseTOFInst(self):
90 """Read the TOF instrument info 91 Return : self._instdict 92 """ 93 # 1. Import 94 for bankid in self._banklist: 95 # 1.1 Find the TMIN, TMAX 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 # 1.2 Find geometry DIFC/Dtt1, DIFA/Dtt2 and Zero 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 # 1.3 Profile & Decay 125 # As default, choose the first profile 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
179 - def parseCWInst(self):
180 """Read the CW instrument info 181 182 Return : self._instdict 183 """ 184 bankid = int(self._banklist[0]) 185 # 1. Find geometry Lambda/Lambda2 and Zero 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 # 3. Profile 206 # As default, choose the first profile 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
260 - def mapKey(self, key):
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