1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15  """ datafile.py is to convert different format files into Fullprof/GSAS readable  
 16  format. And save x, y, sigma into data dictionary. 
 17      Fullprof format is the standard XYSigma format. 
 18      GSAS     format is one of the following: 
 19                  1. Timemap; 2. FXYE; 3. ESD; 4. STD. 
 20   
 21  """ 
 22      
 23  __id__ = "$Id: datafile.py 6420 2011-03-29 10:32:46Z yshang $" 
 24   
 25  import os 
 26  import math 
 27  from diffpy.srrietveld.utility import checkFormat 
 28   
 30      """ Unify to convert input data file to engine file and  
 31          save the XYSigma into data dictionary. """ 
 32   
 33 -    def __init__(self, datafullpathname, instrumentfile=None, banklist=None): 
  34          """ Initialization """ 
 35          self.inputfullname = datafullpathname 
 36          self.inputformat = checkFormat(datafullpathname) 
 37          self.instrumentfile = instrumentfile 
 38          self.banklist = banklist 
 39          
 40          self.datadict = {} 
 41          if banklist == None: 
 42              banklist = [1]  
 43          for bankid in banklist: 
 44              self.datadict[int(bankid)] = {"Name":"", "x":[], "y":[], "dy":[]} 
 45          return 
  46   
 48          """ Read input data file """ 
 49          inputfile = open(filename, "r") 
 50          filelines = inputfile.readlines() 
 51          inputfile.close() 
 52          return filelines 
  53          
 55          """ Write output data file """ 
 56          outfile = open(outfilename, "w") 
 57          outfile.write(outlines) 
 58          outfile.close() 
 59          return 
  60   
 61 -    def toFPFile(self, inputfile, outputfile, bankid, expfilename=""): 
  62          """ Convert input file to FullProf readable file. """ 
 63   
 64          dataformat = checkFormat(inputfile) 
 65          if dataformat == "xye": 
 66              self.xyeToFP(inputfile, outputfile, bankid) 
 67          elif dataformat == "chi": 
 68              self.chiToFP(inputfile, outputfile, bankid) 
 69          elif dataformat in ["gsa", "gda", "raw", "fxye"]: 
 70              outbasename = os.path.basename(outputfile) 
 71              processdir = outputfile.split(outbasename)[0] 
 72               
 73               
 74              gsadatafile = self.exportGSASToXYE(inputfile, self.instrumentfile, 
 75                                                  bankid, expfilename, processdir) 
 76               
 77              self.xyeToFP(gsadatafile, outputfile, bankid) 
 78               
 79          else: 
 80              raise NotImplementedError  
 81          return     
  82   
 84          """ Normalize GSAS data file from rawplot to XYSigma format. """ 
 85           
 86          ifile = open(gsadatafile, "r") 
 87          lines = ifile.readlines() 
 88          ifile.close() 
 89   
 90           
 91          outstring = "" 
 92          for id in range(6): 
 93              outstring += "#\n" 
 94          for line in lines[1:]: 
 95              terms = line.strip().split() 
 96              x = float(terms[0])*1000 
 97              y = float(terms[1])/float(terms[2]) 
 98              dy = math.sqrt(float(terms[1]))/float(terms[2]) 
 99              outstring += "%-10.4f     %-10.4f     %-10.5f\n" % (x, y, dy) 
100           
101           
102          self.writeDataFile(outstring, gsadatafile) 
103          return  
 104   
105 -    def toGSASFile(self, inputfile, outputfile, bankid, stype=None): 
 106          """ Convert input file to GSAS readable file. """ 
107   
108          dataformat = checkFormat(inputfile) 
109          if dataformat in ["dat", "chi", "txt", "xye"]: 
110              filelines = self.readDataFile(inputfile) 
111          else: 
112              raise NotImplementedError 
113           
114          datadict = self.datadict[bankid] 
115          datadict["Name"] = outputfile 
116          for line in filelines[4:]: 
117              terms = line.strip().split() 
118              if terms[0] == "#" or len(terms) != 2: 
119                  continue 
120              else: 
121                  try:  
122                      x = float(terms[0]) 
123                      y = float(terms[1]) 
124                       
125                      datadict["x"].append(x) 
126                  except ValueError: 
127                      pass 
128                  try: 
129                      dy = float(terms[2]) 
130                  except: 
131                      dy = math.sqrt(abs(y)) 
132                  datadict["dy"].append(dy) 
133                   
134                  if stype: 
135                      import random  
136                      y_rad = random.gauss(y, dy) 
137                      if y_rad <= 0: 
138                          y = 2 * y - y_rad 
139                      else: 
140                          y = y_rad  
141                  datadict["y"].append(y) 
142   
143          outlines = self.writeGSASStr(bankid) 
144          self.writeDataFile(outlines, outputfile)                     
145   
146          return  
 147       
149          """ Read GSAS file into datadict """ 
150           
151          outbasename = os.path.basename(gsasfile) 
152          outrootname = os.path.splitext(outbasename)[0] 
153          outtxtname = gsasfile.split(outbasename)[0] + outrootname + ".txt" 
154          gsadatafile = self.exportGSASToXY(gsasfile, self.instrumentfile, 
155                                                  bankid, outtxtname) 
156          self.normalizeGSAS(gsadatafile) 
157           
158          filelines = self.readDataFile(gsadatafile) 
159           
160           
161          datadict = self.datadict[bankid] 
162          datadict["Name"] = gsasfile 
163          for line in filelines: 
164              terms = line.strip().split() 
165              if terms == []: 
166                  continue 
167              if terms[0] == "#" and filelines.index(line) < 6: 
168                  pass 
169              else: 
170                  try:  
171                      x = float(terms[0]) 
172                      y = float(terms[1]) 
173                      dy = float(terms[2]) 
174                       
175                      datadict["x"].append(x) 
176                      datadict["y"].append(y) 
177                      datadict["dy"].append(dy) 
178                  except ValueError: 
179                      pass 
180          return 
 181    
183          """ Return string of integrated intensities in GSAS format. 
184          """ 
185          lines = [] 
186          ltitle = 'Angular Profile: %s' % os.path.basename(self.inputfullname) 
187          if len(ltitle) > 80:    ltitle = ltitle[:80] 
188          lines.append("%-80s" % ltitle) 
189          datadict = self.datadict[bankid] 
190          nchan = len(datadict["y"]) 
191          nrec = int(math.ceil(nchan/10.0)) 
192           
193          tth0_cdg = datadict["x"][0] * 100 
194          dtth_cdg = (datadict["x"][-1] - datadict["x"][0]) / \ 
195                          (len(datadict["x"]) - 1) * 100 
196          lbank = "BANK %4i %4i %4i CONST %9.5f %9.5f %9.5f %9.5f STD" % \ 
197                  (bankid, nchan, nrec, tth0_cdg, dtth_cdg, 0, 0) 
198          lines.append("%-80s" % lbank) 
199          lrecs = [ "%2i%6.0f" % (1, iobs) for iobs in datadict["y"] ] 
200          for i in range(0, len(lrecs), 10): 
201              lines.append("".join(lrecs[i:i+10])) 
202          lines[-1] = "%-80s" % lines[-1] 
203          rv = "\r\n".join(lines) + "\r\n" 
204          return rv 
 205   
206 -    def chiToFP(self, chifile, outputfile, bankid, stype=None): 
 207          """ Convert .chi file to Fullprof format file """ 
208            
209           
210          filelines = self.readDataFile(chifile) 
211           
212           
213          datadict = self.datadict[bankid] 
214          datadict["Name"] = outputfile 
215          outlines = "#\n" 
216          outlines += "#\n" 
217          for line in filelines: 
218              terms = line.strip().split() 
219              if terms == []: 
220                  continue 
221              if terms[0] == "#" or filelines.index(line) < 4: 
222                  outlines += line 
223              else: 
224                  try:  
225                      x = float(terms[0]) 
226                      y = float(terms[1]) 
227                      dy = math.sqrt(y) 
228                      if stype: 
229                          import random 
230                          y_rad = random.gauss(y, dy) 
231                          if y_rad <= 0: 
232                              y = 2 * y - y_rad 
233                          else: 
234                              y = y_rad 
235                       
236                      datadict["x"].append(x) 
237                      datadict["y"].append(y) 
238                      datadict["dy"].append(dy) 
239                       
240                      outlines += "%-15s   %-15s   %-15s\n"% (x, y, dy) 
241                  except ValueError: 
242                      pass 
243              
244           
245          self.writeDataFile(outlines, outputfile) 
246          return 
 247      
248 -    def xyeToFP(self, xyefile, outputfile, bankid, stype=None): 
 249          """ Convert XYSigma format file to Fullprof format file """ 
250            
251           
252          filelines = self.readDataFile(xyefile) 
253           
254           
255          datadict = self.datadict[bankid] 
256          datadict["Name"] = outputfile 
257          outlines = "" 
258          for line in filelines: 
259              terms = line.strip().split() 
260              if terms == []: 
261                  continue 
262              if terms[0] == "#" and filelines.index(line) < 6: 
263                  outlines += line 
264              else: 
265                  try:  
266                      x = float(terms[0]) 
267                      y = float(terms[1]) 
268                      dy = float(terms[2]) 
269                      if stype: 
270                          import random 
271                          y_rad = random.gauss(y, dy) 
272                          if y_rad <= 0: 
273                              y = 2 * y - y_rad 
274                          else: 
275                              y = y_rad  
276                       
277                      datadict["x"].append(x) 
278                      datadict["y"].append(y) 
279                      datadict["dy"].append(dy) 
280                       
281                      outlines += "%-15s   %-15s   %-15s\n"% (x, y, dy) 
282                  except ValueError: 
283                      pass 
284              
285           
286          self.writeDataFile(outlines, outputfile) 
287          return 
 288            
289 -    def xyeToChi(self, inputfile, outputfile, bankid): 
 290          """ Convert XYSigma format file to .chi file """ 
291   
292           
293          filelines = self.readDataFile(inputfile) 
294           
295           
296          datadict = self.datadict[bankid] 
297          datadict["Name"] = outputfile 
298          outlines = "" 
299          for line in filelines: 
300              terms = line.strip().split() 
301              if terms[0] == "#" and filelines.index(line) < 4: 
302                  outlines += line 
303                  continue 
304              else: 
305                  try:  
306                      x = float(terms[0]) 
307                      y = float(terms[1]) 
308                      dy = float(terms[2]) 
309                       
310                      datadict["x"].append(x) 
311                      datadict["y"].append(y) 
312                      datadict["dy"].append(dy) 
313                       
314                      outlines += "%-15s   %-15s   %-15s\n"% (x, y, dy) 
315                  except ValueError: 
316                      pass 
317              
318           
319          self.writeDataFile(outlines, outputfile) 
320          return 
 321   
323          """Check whether the file name is right in .EXP file 
324          """ 
325          print expfilename, gsafbasename 
326          flines = self.readDataFile(expfilename) 
327          lid = -1 
328          for line in flines: 
329              lid += 1 
330              if line.count("HST  1  HFIL") == 1: 
331                  terms = line.strip().split() 
332                  if terms[3] == gsafbasename: 
333                      return 
334                  else: 
335                      relen = len(gsafbasename) 
336                      flines[lid] = line[:14] + gsafbasename + line[relen+14:] 
337                      ofile = open(expfilename, "w") 
338                      ofile.writelines(flines) 
339                      ofile.close() 
340                      return 
341          return 
 342   
343 -    def exportGSASToXYE(self, gsafname, iparmfname, bankid, expfilename, processdir): 
 344          """ Run Powpref and Genles to export diffraction pattern from raw GSAS file 
345          """ 
346          import shutil 
347          import diffpy.pygsas.genles   as GL 
348          import diffpy.pygsas.rungsas  as RG 
349   
350           
351          expbasename = os.path.basename(expfilename) 
352          exprootname = os.path.splitext(expbasename)[0] 
353          expdes = os.path.join(processdir, exprootname.upper() + ".EXP") 
354          shutil.copy(expfilename, expdes) 
355           
356          gsafbasename = os.path.basename(gsafname) 
357          self.checkEXPFile(expdes, gsafbasename) 
358           
359          desgsaf = os.path.join(processdir, gsafbasename) 
360          try: 
361              shutil.copy(gsafname, desgsaf) 
362          except: 
363              pass 
364          if iparmfname: 
365              iparmfbasename = os.path.basename(iparmfname) 
366              desiparm = os.path.join(processdir, iparmfbasename) 
367              shutil.copy(iparmfname, desiparm)  
368          GL.runPowGen(exprootname, processdir, "Refine", 0, "l") 
369          lstfile = os.path.join(processdir, exprootname.upper() + ".LST") 
370          lstbkfile = lstfile + "bk" 
371          shutil.move(lstfile, lstbkfile) 
372          RG.runHstdmp(exprootname, processdir, bankid) 
373   
374           
375          outfilename = os.path.join(processdir, exprootname + ".dat") 
376          outlines = ["#\n", "#\n", "#\n", "#\n", "#\n", "#\n"] 
377          hstfile = open(lstfile) 
378          hstlines = hstfile.readlines() 
379          hstfile.close() 
380          hstlen = len(hstlines) 
381          for line_id in range(1, hstlen): 
382              terms = hstlines[line_id].strip().split() 
383              try: 
384                  int(terms[0]) 
385                  x = float(terms[2])*1000 
386                  y = float(terms[3]) 
387                  dy = math.sqrt(1/float(terms[7])) 
388                  newline = "%-10.4f     %-10.4f     %-10.5f\n" % (x, y, dy) 
389                  outlines.append(newline) 
390              except: 
391                  continue 
392          ofile = open(outfilename, "w") 
393          ofile.writelines(outlines) 
394          ofile.close() 
395          return outfilename 
 396   
398      """ Create datadict template for refine.py """ 
399      datadict = {} 
400   
401       
402      infofile = open(datainfofile, "r") 
403      infolines = infofile.readlines() 
404      infofile.close() 
405   
406       
407      for line in infolines: 
408          terms = line.strip().split() 
409          try: 
410              key = int(terms[1]) 
411          except:  
412              key = float(terms[1]) 
413          try: 
414              datadict[key] = {"Name": datadirectory + "/" + terms[0]} 
415          except IOError: 
416              raise IOError("%s isn't recognized!" % datainfofile) 
417   
418      return datadict 
 419   
421      """ Read datafile content based on datafilelist.""" 
422      import os, numpy 
423      xlist = [] 
424      ylist = [] 
425      outfilelist = [] 
426       
427      m = -1  
428      for datafile in datafilelist: 
429          fileid = datafilelist.index(datafile) 
430          dfv = DataFileConverter(datafile, banklist=[1]) 
431          basefilename = os.path.basename(datafile) 
432          if enginename == "fullprof": 
433              outfilename = basefilename.split(".")[0] + ".dat" 
434              dfv.toFPFile(datafile, outfilename, 1) 
435          else: 
436              outfilename = basefilename.split(".")[0] + ".gsa" 
437              dfv.toGSASFile(datafile, outfilename, 1) 
438          xlist.append(dfv.datadict[1]['x']) 
439          ylist.append(dfv.datadict[1]['y']) 
440          outfilelist.append(outfilename) 
441           
442          if m == -1: 
443               
444              m = len(xlist[-1]) 
445           
446           
447          if m != len(ylist[-1]) or m != len(xlist[-1]): 
448              raise ValueError('Data is of wrong length.') 
449               
450           
451      n = len(xlist) 
452      x = numpy.empty((n, m)) 
453      y = numpy.empty((n, m)) 
454       
455      x[:] = xlist 
456      y[:] = ylist 
457               
458      return x, y, outfilelist 
 459