1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15  import tempfile, os 
 16  from diffpy.srrietveld.exceptions import SrrError 
 17   
 19      """ Monte Carlo Sampling for diffraction pattern.  
 20      """ 
 21 -    def __init__(self, fit, snum, stype="Normal"): 
  22          """Initialization. 
 23   
 24          fit     --- a diffpy.refinementdata.Refinement object that stores a fit with only one pattern 
 25          snum    --- number of samplings 
 26          stype   --- type of sampling distribution 
 27          """ 
 28          self.fit = fit 
 29          self.snum = snum 
 30          self.stype = stype 
 31          self.engine = self.getEngine() 
 32          self.tempDir = tempfile.mkdtemp() 
 33          return 
  34       
 36          """Get engine type from fit object.  
 37          """ 
 38          classname = self.fit.getAttr("rietveldcls") 
 39          if classname.count("gsas") == 1: 
 40              engine = "gsas" 
 41          else: 
 42              engine = "fullprof" 
 43          return engine 
  44                        
 46          """Convert data file if neccessary. 
 47          """ 
 48          from diffpy.srrietveld.addon.datafile import DataFileConverter as DFC 
 49           
 50           
 51          fullpath = self.fit.getObject("Pattern").getObject(0).get("Datafile")[0] 
 52          instrumentfile = str(self.fit.getObject("Pattern").getObject(0).get("Instrumentfile")[0]) 
 53          if not os.path.exists(fullpath): 
 54              raise SrrError("Can not access the data file: " + fullpath) 
 55   
 56          expfilepath = os.path.join(os.getcwd(), self.fit.name + ".EXP") 
 57          filebasename = os.path.basename(fullpath) 
 58          rootname, extname = os.path.splitext(filebasename) 
 59          newfullpath = os.path.join(self.tempDir, filebasename)  
 60          dfc = DFC(fullpath, instrumentfile) 
 61           
 62           
 63          if extname.lower() == ".xye":  
 64              self.genSamplingFromxye(fullpath, newfullpath, 1, self.snum, dfc) 
 65          elif extname.lower() == ".chi": 
 66              self.genSamplingFromchi(fullpath, newfullpath, 1, self.snum, dfc) 
 67          elif extname.lower() in [".gsa", ".gda"]:  
 68              self.genSamplingFromtimemap(fullpath, newfullpath, 1, self.snum, dfc, expfilepath) 
 69          else: 
 70              raise NotImplementedError  
 71   
 72          return self.fit 
  73   
 75          """Sampling num of times based on distribution and save the new datafile in newfullpath.  
 76          """ 
 77          import random 
 78          self.fit.reshape((num+1, ), ["SampleId", ], repeat=True) 
 79          pattern = self.fit.getObject("Pattern").getObject(0) 
 80          datafilelist = pattern.get("Datafile") 
 81          datadict = importFromGSAStimemap(fullpath, 1) 
 82          ys = datadict["yobs"] 
 83          ss = datadict["sobs"] 
 84          dstring = "" 
 85          sidlist = [] 
 86          for i in range(1, num+1): 
 87              dline = "" 
 88              sidlist.append(i) 
 89              for idx in range(len(ys)): 
 90                  y_int = ys[idx] 
 91                  s_int = ss[idx] 
 92                  y_rad = random.gauss(y_int, s_int) 
 93                  if y_rad <= 0.0 : 
 94                      y_rad = 2 * y_int - y_rad 
 95                  if y_rad == 0.0: 
 96                      y_rad = y_int 
 97                  dstring += "%8.1f%8.1f" % (y_rad, s_int) 
 98                  if (idx+1)%5 == 0: 
 99                      dline += "%-80s\r\n" % dstring 
100                      dstring = "" 
101                  elif idx == len(ys)-1: 
102                      dline += "%-80s\r\n" % dstring 
103                      dstring = "" 
104              datafullpath = newfullpath[:-4] + str(i) + ".gsa" 
105              headerline = datadict["header"] 
106              allline = headerline + dline 
107              dfc.writeDataFile(allline, datafullpath) 
108              if self.engine == "fullprof": 
109                  outfullpath = newfullpath[:-4] + str(i) + ".dat" 
110                  dfc.toFPFile(datafullpath, outfullpath, 1, expfilepath) 
111                  datafullpath = outfullpath 
112              datafilelist[i] = datafullpath 
113          self.fit.set("SampleId", sidlist)  
114          self.fit.resetStatus() 
115          return 
 116   
117   
119          """Sampling num of times based on distribution and save the new datafile in newfullpath.  
120          """ 
121          self.fit.reshape((num+1, ), ["SampleId", ], repeat=True) 
122          pattern = self.fit.getObject("Pattern").getObject(0) 
123          datafilelist = pattern.get("Datafile") 
124          for i in range(1, num+1): 
125              if self.engine == "fullprof": 
126                  datafullpath = newfullpath[:-4] + str(i) + ".xye"  
127                  dfc.xyetoFP(fullpath, datafullpath, 1, self.stype) 
128              else: 
129                  datafullpath = newfullpath[:-4] + str(i) + ".gsa" 
130                  dfc.toGSASFile(fullpath, datafullpath, 1, self.stype) 
131              datafilelist[i] = datafullpath 
132           
133          self.fit.resetStatus() 
134          return  
 135       
137          """Sampling num of times based on distribution and save the new datafile in newfullpath.  
138          """ 
139          self.fit.reshape((num+1, ), ["SampleId", ], repeat=True) 
140          pattern = self.fit.getObject("Pattern").getObject(0) 
141          datafilelist = pattern.get("Datafile") 
142          for i in range(1, num+1): 
143              if self.engine == "fullprof": 
144                  datafullpath = newfullpath[:-4] + str(i) + ".chi"  
145                  dfc.chitoFP(fullpath, datafullpath, 1, self.stype) 
146              else: 
147                  datafullpath = newfullpath[:-4] + str(i) + ".gsa" 
148                  dfc.toGSASFile(fullpath, datafullpath, 1, self.stype) 
149              datafilelist[i] = datafullpath 
150           
151          self.fit.resetStatus() 
152          return 
  153          
155      """Import a GSAS .gsa/gda file and get the dict of y, sd 
156   
157      Arguments: 
158          - datafilename : full-path name of .gsa/gda file; 
159   
160      Return:  datadict: a dictionary that includes series of yobs, sobs 
161      """ 
162      try: 
163          ffile = open(datafilename, "r") 
164          lines = ffile.readlines() 
165          ffile.close() 
166      except IOError: 
167          errmsg = "Fatal Error: Cannot Open File %-20s"% (datafilename) 
168          raise IOError, errmsg 
169       
170      datadict = {"header": "", "yobs": [], "sobs": []} 
171      firstbankline = False 
172      bankline = False 
173      for line in lines: 
174          terms = line.strip().split() 
175          if terms[0] == "BANK" and terms[1] == str(bankid): 
176              firstbankline = True 
177              bankline = True 
178              datadict["header"] += line 
179          elif terms[0] == "BANK" and terms[1] != str(bankid): 
180              firstbankline = False 
181              bankline = True  
182          elif firstbankline == False and bankline == False: 
183              datadict["header"] += line 
184          elif firstbankline == True and bankline == True: 
185              for i in range(5): 
186                  try:  
187                      datadict["yobs"].append(float(terms[2*i])) 
188                      datadict["sobs"].append(float(terms[2*i+1])) 
189                  except: 
190                      break 
191      return datadict 
 192   
194      """Import a GSAS .raw file and get the dict of y, sd 
195   
196      Arguments: 
197          - datafilename : full-path name of .raw file; 
198   
199      Return:  datadict: a dictionary that includes series of yobs, sobs 
200      """ 
201      try: 
202          ffile = open(datafilename, "r") 
203          lines = ffile.readlines() 
204          ffile.close() 
205      except IOError: 
206          errmsg = "Fatal Error: Cannot Open File %-20s"% (datafilename) 
207          raise IOError, errmsg 
208       
209      datadict = {"header": "", "countid": [], "yobs": [], "sobs": []} 
210      firstbankline = False 
211      bankline = False 
212      for line in lines: 
213          id = lines.index(line) 
214          terms = line.strip().split() 
215          if terms[0] == "BANK": 
216              bankline = True 
217              if terms[1] == str(bankid): 
218                  firstbankline = True             
219                  datadict["header"] += line 
220          elif firstbankline == False and bankline == False: 
221              datadict["header"] += line 
222          elif firstbankline == True and bankline == True: 
223              for i in range(10): 
224                  try:  
225                      datadict["countid"].append(int(line[8*i:(8*i+2)])) 
226                      yobs = int(line[(8*i+2):(8*i+7)]) 
227                      datadict["yobs"].append(yobs) 
228                      datadict["sobs"].append(yobs**0.5) 
229                  except: 
230                      break 
231      return datadict 
 232