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

Source Code for Module diffpy.srrietveld.convert.strategyfile

  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  """ Parse different strategy file provided by users """ 
 16   
 17  __id__ = "$Id: strategyfile.py 6671 2011-07-29 02:22:12Z yshang $" 
 18   
 19  import os 
 20  from diffpy.srrietveld.exceptions import SrrFileError 
 21   
22 -class StrategyFile:
23 ''' Parse the strategy file into a list of dictionaries for later refinement 24 [{method: [[fullpath, value, constrain formula], ...]}, {...}, ...] 25 '''
26 - def __init__(self, fit, strategyfile=None, strategy=None):
27 """ Initialization """ 28 self.fit = fit 29 self.strategyfile = strategyfile 30 # Default value of strategy is None, then make it empty. 31 # NOTE: if make the default value to be empty list, then strategy will 32 # be a static variable and every initiation of StrategyFile the 33 # passed in strategy variable will keep the previous value, which is 34 # highly undesired 35 if strategy is None: 36 strategy = [] 37 self.strategy = strategy 38 self.variableid = 0 39 40 if strategyfile: 41 self.parseStrategyFile() 42 43 if strategy: 44 # if only input strategylist(assume list in good format), 45 # need to reset variableid 46 self.ResetVariableId() 47 return
48
49 - def readFile(self):
50 """ Read file """ 51 sifile = open(self.strategyfile, "rU") 52 self.inlines = sifile.readlines() 53 sifile.close() 54 return
55
56 - def parseStrategyFile(self):
57 """ Parse .txt format file 58 strateylist = [{method: [[fullpath, value, constrain formula], ...]}, {...}, ...] 59 method: 'Rietveld' or 'Lebail' 60 fullpath: full path of parameter; 61 value: initial value of refined parameter; 62 formula of constraint: 1.0*Var_paramname 63 """ 64 # 1. read file 65 self.readFile() 66 67 # 2. parse the content into list 68 paramlist = [] 69 method = "" 70 step = {} 71 stepn = -1 72 for ln, line in enumerate(self.inlines): 73 line = line.strip() 74 if not line: 75 continue 76 if line.startswith('#'): 77 continue 78 terms = line.split() 79 #if terms[0] in [""]: 80 # continue 81 82 if len(terms) == 3: # the first parameter in a step 83 # save the last step 84 if stepn >= 0: 85 step[method] = paramlist 86 self.strategy.append(step) 87 stepn += 1 88 89 step = {} 90 paramlist = [] 91 92 method = terms[0] 93 generalpath = terms[1] 94 generalformula = terms[2] 95 96 elif len(terms) == 2: # the following parameters in a step 97 generalpath = terms[0] 98 generalformula = terms[1] 99 else: 100 raise SrrFileError("The format of strategy file is wrong in line %d" % ln) 101 102 # add last step paramlist if method is the same 103 #if self.strategy: 104 # lastmethod, lastparamlist = self.strategy[-1].items()[0] 105 # if lastmethod == method: 106 # for param in lastparamlist: 107 # paramlist.append(param) 108 109 # specify the template into used cases 110 #FIXME: since generalized strategy files are used, some of the 111 # parameters may not exist, for example the sig0 in profile -4 112 # if it failed, then continue to the next line 113 try: 114 pftuplelist = self.transRefinables(generalpath, generalformula) 115 except: 116 continue 117 for fullpath, formula in pftuplelist: 118 paramlist.append([fullpath, '', formula]) 119 120 # get the last step 121 step[method] = paramlist 122 self.strategy.append(step) 123 124 return
125
126 - def ResetVariableId(self):
127 """ When input strategylist, need to reset variableid. 128 """ 129 variableids = [] 130 for step in self.strategy: 131 for param in step.values()[0]: 132 variableid = param[2].split("_")[1] 133 if variableid not in variableids: 134 variableids.append(variableid) 135 self.variableid += 1 136 param[2].replace(variableid, str(self.variableid)) 137 return
138
139 - def transRefinables(self, generalpath, generalformula):
140 """ Translate the generalpath and generalformula in strategyfile 141 And return the pftuplelist containing the list of parameters for the project. 142 """ 143 pftuplelist = [] 144 # special treatment needs for Lattice 145 if generalpath.endswith("Lattice"): 146 parpaths = [] 147 for name in ["a", "b", "c", "alpha", "beta", "gamma"]: 148 parpaths.extend(self._parsePath(generalpath.replace("Lattice", name))) 149 elif generalpath.endswith("Background"): 150 # FIXME: the group indexing of upper node is not supported, such as 151 # pattern[:].Background.BCK[:] while BCK[:] is interpreted, but pattern[:] 152 # is not expanded 153 backgroundobj = self.fit.getByPath(generalpath) 154 if isinstance(backgroundobj, list): 155 backgroundobj = backgroundobj[0] 156 157 if backgroundobj.get("BCK"): 158 generalpath += ".BCK[:]" 159 else: 160 generalpath += ".BACK[:]" 161 parpaths = self._parsePath(generalpath) 162 else: 163 parpaths = self._parsePath(generalpath) 164 for path in parpaths: 165 self.variableid += 1 166 formula = generalformula.split("_")[0] + "_" + str(self.variableid) 167 pftuplelist.append((path, formula)) 168 169 return pftuplelist
170 171
172 - def _parsePath(self, path):
173 """Parse a path having a form as ABC[1], without '.' 174 175 path -- the path to an parameter or parameter array 176 return: a list of translated paths. 177 """ 178 import re 179 res = re.search(r'(.+)\[([0-9:]+)\]$', path) 180 if res: 181 parpath, index= res.groups() 182 183 # The code below build either a slice or an int from the string 184 if index.count(':') > 0: 185 # try to make a slice 186 index = slice(*[{True: lambda n: None, False: int}[x == ''](x) 187 for x in (index.split(':') + ['', '', ''])[:3]]) 188 else: 189 index = int(index) 190 191 datasets = self.fit.getByPath(parpath) 192 if not isinstance(datasets, list): 193 datasets = [datasets, ] 194 195 paths = [] 196 for dataset in datasets: 197 if isinstance(index, int): 198 paths.append(dataset.path + '[%i]'%index) 199 else: 200 n = dataset.shape[-1] 201 start, stop, step = index.indices(n) 202 parpath = dataset.path 203 for i in range(start, stop, step): 204 paths.append(parpath+'[%i]'%i) 205 206 return paths 207 208 datasets = self.fit.getByPath(path) 209 if not isinstance(datasets, list): 210 # it may be a list or not 211 datasets = [datasets,] 212 213 return [dataset.path for dataset in datasets]
214
215 - def writeToFile(self, fullpath):
216 '''write the strateg list to a local file. The strategy is read from the 217 strategy member variable, no the lines 218 fullpath - the file path to write into 219 return''' 220 import diffpy.srrietveld.gui.srrguiglobals as GLOBALS 221 lines = [] 222 lines.append("# SrRietveld project file: %s" % GLOBALS.project.basepath + GLOBALS.project.name) 223 lines.append("# Refinement name:" + self.fit.name) 224 for step in self.strategy: 225 method = step.keys()[0] # each step got only one key, the method 226 line = "" 227 for ln, param in enumerate(step[method]): 228 datapath = param[0].split('.', 1)[-1] 229 fomular = param[2] 230 if ln == 0: # the first step,add the refinement method 231 line = "\t".join([method, datapath, fomular]) 232 else: 233 line = "\t".join(["\t", datapath, fomular]) 234 235 lines.append(line) 236 237 with open(fullpath, "w") as f: 238 f.write(os.linesep.join(lines)) 239 240 return
241
242 - def getStrategy(self):
243 """ Get the strategy list """ 244 return self.strategy
245
246 - def setStrategy(self, strategylist):
247 """ Set new list to strategylist """ 248 self.strategy = strategylist 249 return
250
251 - def getStrategyStep(self, step):
252 """ Get the step dict """ 253 return self.strategy[step-1]
254
255 - def getStepParamList(self, step):
256 """ Get strategy for certain step """ 257 if step == 0: 258 return [] 259 else: 260 return self.strategy[step-1].values()[0]
261
262 - def getStepMethod(self, step):
263 """ Get method for certain step """ 264 if step == 0: # no strategy, default Rietveld 265 return "Rietveld" 266 else: 267 return self.strategy[step-1].keys()[0]
268
269 - def getStrategyId(self, stepstrategy):
270 """ Get the order of the stepstrategy """ 271 return self.strategy.index(stepstrategy) + 1
272
273 - def getNumStep(self):
274 """ Get total number of steps """ 275 return len(self.strategy)
276
277 - def getNewVariableId(self):
278 """ Get new variable id """ 279 self.variableid += 1 280 return self.variableid
281
282 - def mergeParamList(self, newparam, paramlist):
283 """ Form a new paramlist """ 284 currparamlist = [] 285 currparamlist.append(newparam) 286 for param in paramlist: 287 currparamlist.append(param) 288 return currparamlist
289
290 - def getPosParamFullPath(self, id):
291 """ Get Fullpath for id parameter in strategyeditor """ 292 paramlist, stepparamid = self.getPosParamListId(id) 293 param = paramlist[stepparamid] 294 return param[0]
295
296 - def removePosParam(self, id):
297 """ Remove the position in strategyeditor from parameter list """ 298 paramlist, stepparamid = self.getPosParamListId(id) 299 paramlist.pop(stepparamid) 300 return
301
302 - def addPosParam(self, id, param):
303 """ Add the parameter into paramlist """ 304 paramlist, stepparamid = self.getPosParamListId(id) 305 paramlist.insert(stepparamid, param) 306 return
307
308 - def getPosParamListId(self, id):
309 """ Get corresponding paramlist to id of strategyeditor """ 310 paramid = 0 311 stepid = 0 312 for step in self.strategy: 313 stepid += 1 314 paramlist = step.values()[0] 315 stepparamid = -1 316 for param in paramlist: 317 paramid += 1 318 stepparamid += 1 319 if (paramid+stepid) == id: 320 return paramlist, stepparamid 321 return
322
323 - def removeStep(self, step):
324 """ Remove the step from list """ 325 self.strategy.pop(step-1) 326 return
327
328 - def addParam(self, step, posid, fullpath, value='', formula=None):
329 """ Add the fullpath into parameter list """ 330 strategystep = self.strategy[step-1] 331 paramlist = strategystep.values()[0] 332 if formula == None: 333 self.variableid += 1 334 formula = "1.0*Var_" + str(self.variableid) 335 paramlist.insert(posid, [fullpath, value, formula]) 336 return
337
338 - def addNewStep(self, step, method, paramlist):
339 """ Addd new strategystep """ 340 self.strategy.insert(step, {method: paramlist}) 341 return
342
343 - def clear(self):
344 """ Clean the strategy list """ 345 self.strategy = [] 346 return
347