Package reflectometry :: Package model1d :: Package adaptor :: Module reflModel

Source Code for Module reflectometry.model1d.adaptor.reflModel

  1  import xml.dom as dom 
  2  import xml.dom.minidom as minidom 
  3   
  4  import os, sys 
  5  import traceback 
  6  import numpy 
  7   
  8  from park.fitpark.fitModel         import FitModel 
  9  from park.fitpark.fitTags          import NAME_TAG, CLASSNAME_TAG, DATA_TAG 
 10  from park.fitpark.fitDataHelper    import dataToXml, dataFromXml 
 11  from reflParameterSet import ReflParameterSet, ReflMagParameterSet, REFL_PS_TAG 
 12  from calcReflectivity import CalcReflectivity 
 13   
 14  """ 
 15  A model implementing the reflectometry. 
 16  """ 
 17   
 18  REFL_PM_TAG = 'RM' 
 19   
 20   
21 -class ReflModel(FitModel):
22 """ 23 Model class for Refl. 24 """ 25
26 - def __init__(self, 27 name, 28 magnetic=False 29 ):
30 """ 31 Constructor. A model must have a name. 32 """ 33 FitModel.__init__(self, REFL_PM_TAG, name) 34 self.magnetic = magnetic
35 36
37 - def getClassName(self):
38 """ 39 Return the full class name 40 """ 41 return 'reflModel.ReflModel'
42 43
44 - def clear(self):
45 """ 46 clear the contents of the model. 47 """ 48 self._pmNames = [] 49 self.setData([])
50 51
52 - def getParameters(self):
53 """ 54 Return a list of strings representing the fitting parameter names. 55 The user class override this function. 56 """ 57 pms = [] 58 for name in self._pmNames: 59 pm = getattr(self, name) 60 pms.extend(pm.getParameters()) 61 return pms
62 63
64 - def getLayers(self):
65 """ 66 Return a list of parameters for the model. 67 """ 68 return [getattr(self, name) for name in self._pmNames ]
69 70
71 - def getLayer(self, pname):
72 """ 73 Return a list of parameters for the model. 74 """ 75 return getattr(self, pname)
76 77
78 - def addLayer(self, pmName):
79 """ 80 Add a fitting parameter to the model. 81 pmName is the parameter's name that should not include the model name. 82 """ 83 pm = ReflParameterSet(pmName) 84 setattr(self, pmName, pm) 85 self._pmNames.append(pmName)
86 87 88
89 - def layer(self, 90 name, 91 depth =100.0, 92 sigma =0.0, 93 rho =1.0, 94 mu =0.0, 95 rho_m =0.0, 96 theta_m=0.0 97 ):
98 if self.magnetic: pm = ReflMagParameterSet( name ) 99 else: pm = ReflParameterSet( name ) 100 setattr(self, name, pm) 101 self._pmNames.append( name ) 102 103 pm.depth = depth 104 pm.rough = sigma 105 pm.rho = rho 106 pm.mu = mu 107 if self.magnetic: 108 pm.rho_m = rho_m 109 pm.theta_m = theta_m
110 111
112 - def incident(self,name, depth=100.0, sigma=0.0, rho=1.0, mu=0.0, 113 rho_m=0.0, theta_m=0.0):
114 self.layer(name,depth, sigma,rho,mu,rho_m,theta_m)
115 116
117 - def substrate(self, name, depth=100.0, sigma=0.0, rho=1.0, mu=0.0, 118 rho_m=0.0, theta_m=0.0):
119 self.layer(name,depth, sigma,rho,mu,rho_m,theta_m)
120 121
122 - def interface(self, rough=5.0):
123 index = len(self._pmNames)-1 124 pm=self.getLayer(self._pmNames[index]) 125 pm.rough=rough
126 127
128 - def removeLayer(self, pmName):
129 """ 130 remove a parameter by its name. 131 """ 132 self._pmNames.remove(pmName) 133 delattr(self, pmName)
134 135
136 - def __call__(self):
137 """ 138 Return the result for the simulation. 139 """ 140 xdata = self.getData()[0] 141 R = CalcReflectivity( xdata, self.getLayers() ) 142 143 return R
144 145
146 - def getResidual(self):
147 """ 148 Return a vector to calculate norm2. It is required by 149 leastsq() method to calculate the error bar of parameters. 150 """ 151 if len(self.getData()) == 3: # Q R dR 152 dy = (self() - self.getData()[1])/self.getData()[2] 153 154 elif len(self.getData()) == 4: #Q, dQ, R, dQ 155 dy = (self() - self.getData()[2])/self.getData()[3] 156 157 elif len(self.getData()) == 5: #Q, dQ, R, dQ, Wavelength 158 dy = (self() - self.getData()[2])/self.getData()[3] 159 else: 160 dy = None 161 162 return dy
163 164
165 - def getChisq(self):
166 """ 167 Return the chisq value for the optimization. 168 This provides the default implementation, which is 169 || residual ||^2. 170 """ 171 dy = self.getResidual() 172 return numpy.dot(dy, dy)/len(self.getData()[0])
173 174
175 - def fromPyFile(self, fname):
176 """ 177 Rebuild the object from an python script file 178 """ 179 fin = open( fname, 'r') 180 pyTxts = fin.read() 181 cmds = self._parsePyTexts(pyTxts) 182 for cmd in cmds: 183 exec cmd
184 185
186 - def toPyFile(self, fname):
187 """ 188 Save the object in a file in python format. 189 fname: a file name or a file handler. 190 Return true when successes. 191 """ 192 fout = None 193 try: 194 fout = open(fname, 'w') 195 fout.write(str0) 196 except: 197 pass 198 199 if fout is not None: fd.close()
200 201
202 - def _parsePyTexts(self, pyTxts):
203 """ 204 restore information about Refl model. 205 """ 206 s=pyTxts.strip().split('\n') 207 for i in xrange(len(s)): 208 line=s[i] 209 cmd=line.strip().split('(')[0].strip() 210 if cmd in ('incident','layer','interface', 'substrate'): 211 s[i] = 'self.'+ line 212 return s
213 214
215 - def _parseChildren(self, xmlNode):
216 """ 217 restore information about Refl model. 218 """ 219 for node in xmlNode.childNodes: 220 if node.nodeType == dom.Node.ELEMENT_NODE: 221 if node.nodeName == REFL_PS_TAG: 222 name = node.getAttribute(NAME_TAG) 223 pm = ReflParameterSet(name) 224 pm.parse(node) 225 self._pmNames.append(name) 226 setattr(self, name, pm) 227 228 elif node.nodeName == DATA_TAG: 229 self.setData(dataFromXml(node)) 230 else: 231 pass
232 233 234 235 236 237 238 #======================================================
239 -def demo():
240 REFL_DATA = 'du53.dat' 241 model = ReflModel('M0') 242 model.layer('Air', rho=0.0, mu=0.0) 243 model.interface(8.0) 244 model.layer('dPS', depth=65,rho=1.87, mu=0.01) 245 model.interface(5.0) 246 model.layer('P2VP', depth=35,rho=1.7, mu=0.0) 247 model.interface(5.0) 248 model.layer('Si0x', depth=17,rho=3.8, mu=0.0) 249 model.interface(5.0) 250 model.layer('Si', rho=2.07, mu=0.0) 251 252 model.setData(REFL_DATA) 253 print 'Model:', model.getResidual() 254 print 'chisq:', model.getChisq() 255 print model.getLayers()
256 257
258 -def demo2():
259 model = ReflModel('M0') 260 261 model.layer('Air', rho=0.0, mu=0.0) 262 model.interface(8.0) 263 264 model.layer('layer1', depth=60.0, rho=[1.6,2.4], mu=1.0) 265 model.interface(5.0) 266 267 model.layer('layer2', depth=40.0, rho=1.0, mu=4.0) 268 model.interface(5.0) 269 270 model.layer('Si', rho=2.07, mu=0.0) 271 model.interface(5.0) 272 273 model.setData('test.dat') 274 #print ' Model:', model.getResidual() 275 print 'chisq:', model.getChisq() 276 #print model.getLayers() 277 278 import pylab 279 pylab.semilogy(model.getData()[0], model(), 'r') 280 pylab.errorbar(model.getData()[0], model.getData()[2], model.getData()[3], 281 fmt='.',label="Experiment") 282 pylab.show()
283 284 if __name__ == '__main__': 285 demo() 286