Package diffpy :: Package Structure :: Package Parsers :: Module P_pdffit
[hide private]
[frames] | no frames]

Source Code for Module diffpy.Structure.Parsers.P_pdffit

  1  ############################################################################## 
  2  # 
  3  # Structure         by DANSE Diffraction group 
  4  #                   Simon J. L. Billinge 
  5  #                   (c) 2007 trustees of the Michigan State University. 
  6  #                   All rights reserved. 
  7  # 
  8  # File coded by:    Pavol Juhas 
  9  # 
 10  # See AUTHORS.txt for a list of people who contributed. 
 11  # See LICENSE.txt for license information. 
 12  # 
 13  ############################################################################## 
 14   
 15  """Parser for PDFfit structure format 
 16  """ 
 17   
 18  __id__ = "$Id: P_pdffit.py 2825 2009-03-09 04:33:12Z juhas $" 
 19   
 20  import sys 
 21  import numpy 
 22   
 23  from diffpy.Structure import PDFFitStructure, Lattice, Atom 
 24  from diffpy.Structure import StructureFormatError 
 25  from diffpy.Structure.Parsers import StructureParser 
 26   
27 -class P_pdffit(StructureParser):
28 """Parser for PDFfit structure format. 29 30 stru -- Structure instance used for cif input or output 31 """ 32
33 - def __init__(self):
34 StructureParser.__init__(self) 35 self.format = "pdffit" 36 self.ignored_lines = [] 37 self.stru = None 38 return
39
40 - def parseLines(self, lines):
41 """Parse list of lines in PDFfit format. 42 43 Return Structure object or raise StructureFormatError. 44 """ 45 p_nl = 0 46 rlist = [] 47 try: 48 self.stru = PDFFitStructure() 49 stru = self.stru 50 cell_line_read = False 51 stop = len(lines) 52 while stop>0 and lines[stop-1].strip() == "": 53 stop -= 1 54 ilines = iter(lines[:stop]) 55 # read header of PDFFit file 56 for l in ilines: 57 p_nl += 1 58 words = l.split() 59 if len(words) == 0 or words[0][0] == '#': 60 continue 61 elif words[0] == 'title': 62 stru.title = l.lstrip()[5:].strip() 63 elif words[0] == 'scale': 64 stru.pdffit['scale'] = float(words[1]) 65 elif words[0] == 'sharp': 66 l1 = l.replace(',', ' ') 67 sharp_pars = [ float(w) for w in l1.split()[1:] ] 68 if len(sharp_pars) < 4: 69 stru.pdffit['delta2'] = sharp_pars[0] 70 stru.pdffit['sratio'] = sharp_pars[1] 71 stru.pdffit['rcut'] = sharp_pars[2] 72 else: 73 stru.pdffit['delta2'] = sharp_pars[0] 74 stru.pdffit['delta1'] = sharp_pars[1] 75 stru.pdffit['sratio'] = sharp_pars[2] 76 stru.pdffit['rcut'] = sharp_pars[3] 77 elif words[0] == 'spcgr': 78 key = 'spcgr' 79 start = l.find(key) + len(key) 80 value = l[start:].strip() 81 stru.pdffit['spcgr'] = value 82 elif words[0] == 'shape': 83 self._parse_shape(l) 84 elif words[0] == 'cell': 85 cell_line_read = True 86 l1 = l.replace(',', ' ') 87 latpars = [ float(w) for w in l1.split()[1:7] ] 88 stru.lattice = Lattice(*latpars) 89 elif words[0] == 'dcell': 90 l1 = l.replace(',', ' ') 91 stru.pdffit['dcell'] = [ float(w) for w in l1.split()[1:7] ] 92 elif words[0] == 'ncell': 93 l1 = l.replace(',', ' ') 94 stru.pdffit['ncell'] = [ int(w) for w in l1.split()[1:5] ] 95 elif words[0] == 'format': 96 if words[1] != 'pdffit': 97 emsg = "%d: file is not in PDFfit format" % p_nl 98 raise StructureFormatError(emsg) 99 elif words[0] == 'atoms' and cell_line_read: 100 break 101 else: 102 self.ignored_lines.append(l) 103 # Header reading finished, check if required lines were present. 104 if not cell_line_read: 105 emsg = "%d: file is not in PDFfit format" % p_nl 106 raise StructureFormatError(emsg) 107 # Load data from atom entries. 108 p_natoms = reduce(lambda x,y : x*y, stru.pdffit['ncell']) 109 # we are now inside data block 110 for l in ilines: 111 p_nl += 1 112 wl1 = l.split() 113 element = wl1[0][0].upper() + wl1[0][1:].lower() 114 xyz = [ float(w) for w in wl1[1:4] ] 115 occ = float(wl1[4]) 116 stru.addNewAtom(element, xyz=xyz, occupancy=occ) 117 a = stru.getLastAtom() 118 p_nl += 1 119 wl2 = ilines.next().split() 120 a.sigxyz = [ float(w) for w in wl2[0:3] ] 121 a.sigo = float(wl2[3]) 122 p_nl += 1 123 wl3 = ilines.next().split() 124 p_nl += 1 125 wl4 = ilines.next().split() 126 p_nl += 1 127 wl5 = ilines.next().split() 128 p_nl += 1 129 wl6 = ilines.next().split() 130 a.sigU = numpy.zeros((3,3), dtype=float) 131 a.U11 = float(wl3[0]) 132 a.U22 = float(wl3[1]) 133 a.U33 = float(wl3[2]) 134 a.sigU[0,0] = float(wl4[0]) 135 a.sigU[1,1] = float(wl4[1]) 136 a.sigU[2,2] = float(wl4[2]) 137 a.U12 = float(wl5[0]) 138 a.U13 = float(wl5[1]) 139 a.U23 = float(wl5[2]) 140 a.sigU[0,1] = a.sigU[1,0] = float(wl6[0]) 141 a.sigU[0,2] = a.sigU[2,0] = float(wl6[1]) 142 a.sigU[1,2] = a.sigU[2,1] = float(wl6[2]) 143 if len(stru) != p_natoms: 144 emsg = "expected %d atoms, read %d" % (p_natoms, len(stru)) 145 raise StructureFormatError(emsg) 146 if stru.pdffit['ncell'][:3] != [1,1,1]: 147 superlatpars = [ latpars[i]*stru.pdffit['ncell'][i] 148 for i in range(3) ] + latpars[3:] 149 superlattice = Lattice(*superlatpars) 150 stru.placeInLattice(superlattice) 151 stru.pdffit['ncell'] = [1, 1, 1, p_natoms] 152 except (ValueError, IndexError): 153 emsg = "%d: file is not in PDFfit format" % p_nl 154 exc_type, exc_value, exc_traceback = sys.exc_info() 155 raise StructureFormatError, emsg, exc_traceback 156 return stru
157 158 # End of parseLines 159 160
161 - def toLines(self, stru):
162 """Convert Structure stru to a list of lines in PDFfit format. 163 164 Return list of strings. 165 """ 166 # first, convert stru to PDFFitStructure 167 if not isinstance(stru, PDFFitStructure): 168 pfstru = PDFFitStructure() 169 pfstru.__dict__.update(stru.__dict__) 170 pfstru[:] = stru[:] 171 stru = pfstru 172 lines = [] 173 # default values of standard deviations 174 d_sigxyz = numpy.zeros(3, dtype=float) 175 d_sigo = 0.0 176 d_sigU = numpy.zeros((3,3), dtype=float) 177 # here we can start 178 l = "title " + stru.title 179 lines.append( l.strip() ) 180 lines.append( "format pdffit" ) 181 lines.append( "scale %9.6f" % stru.pdffit["scale"] ) 182 lines.append( "sharp %9.6f, %9.6f, %9.6f, %9.6f" % ( 183 stru.pdffit["delta2"], 184 stru.pdffit["delta1"], 185 stru.pdffit["sratio"], 186 stru.pdffit["rcut"]) ) 187 lines.append( "spcgr " + stru.pdffit["spcgr"] ) 188 if stru.pdffit.get('spdiameter', 0.0) > 0.0: 189 line = 'shape sphere, %g' % stru.pdffit['spdiameter'] 190 lines.append(line) 191 if stru.pdffit.get('stepcut', 0.0) > 0.0: 192 line = 'shape stepcut, %g' % stru.pdffit['stepcut'] 193 lines.append(line) 194 lat = stru.lattice 195 lines.append( "cell %9.6f, %9.6f, %9.6f, %9.6f, %9.6f, %9.6f" % ( 196 lat.a, lat.b, lat.c, lat.alpha, lat.beta, lat.gamma) ) 197 lines.append( "dcell %9.6f, %9.6f, %9.6f, %9.6f, %9.6f, %9.6f" % 198 tuple(stru.pdffit["dcell"]) ) 199 lines.append( "ncell %9i, %9i, %9i, %9i" % (1, 1, 1, len(stru)) ) 200 lines.append( "atoms" ) 201 for a in stru: 202 ad = a.__dict__ 203 lines.append( "%-4s %17.8f %17.8f %17.8f %12.4f" % ( 204 a.element.upper(), a.xyz[0], a.xyz[1], a.xyz[2], a.occupancy) ) 205 sigmas = numpy.concatenate( 206 ( ad.get("sigxyz", d_sigxyz), [ad.get("sigo", d_sigo)] ) ) 207 lines.append( " %18.8f %17.8f %17.8f %12.4f" % tuple(sigmas) ) 208 sigU = ad.get("sigU", d_sigU) 209 Uii = ( a.U[0][0], a.U[1][1], a.U[2][2] ) 210 Uij = ( a.U[0][1], a.U[0][2], a.U[1][2] ) 211 sigUii = ( sigU[0][0], sigU[1][1], sigU[2][2] ) 212 sigUij = ( sigU[0][1], sigU[0][2], sigU[1][2] ) 213 lines.append( " %18.8f %17.8f %17.8f" % Uii ) 214 lines.append( " %18.8f %17.8f %17.8f" % sigUii ) 215 lines.append( " %18.8f %17.8f %17.8f" % Uij ) 216 lines.append( " %18.8f %17.8f %17.8f" % sigUij ) 217 return lines
218 219 # End of toLines 220 221 222 # Protected methods 223 224
225 - def _parse_shape(self, line):
226 """Process shape line from PDFfit file and update self.stru 227 228 line -- line containing data for particle shape correction 229 230 No return value. 231 Raise StructureFormatError for invalid record. 232 """ 233 line_nocommas = line.replace(',', ' ') 234 words = line_nocommas.split() 235 assert words[0] == 'shape' 236 shapetype = words[1] 237 if shapetype == 'sphere': 238 self.stru.pdffit['spdiameter'] = float(words[2]) 239 elif shapetype == 'stepcut': 240 self.stru.pdffit['stepcut'] = float(words[2]) 241 else: 242 emsg = 'Invalid type of particle shape correction %r' % shapetype 243 raise StructureFormatError, emsg 244 return
245 246 247 # End of class P_pdffit 248 249 # Routines 250
251 -def getParser():
252 return P_pdffit()
253 254 # End of file 255