- Timestamp:
- Oct 10, 2016 11:52:19 AM (8 years ago)
- Branches:
- master, ESS_GUI, ESS_GUI_Docs, ESS_GUI_batch_fitting, ESS_GUI_bumps_abstraction, ESS_GUI_iss1116, ESS_GUI_iss879, ESS_GUI_iss959, ESS_GUI_opencl, ESS_GUI_ordering, ESS_GUI_sync_sascalc, costrafo411, magnetic_scatt, release-4.1.1, release-4.1.2, release-4.2.2, ticket-1009, ticket-1094-headless, ticket-1242-2d-resolution, ticket-1243, ticket-1249, ticket885, unittest-saveload
- Children:
- afb93df
- Parents:
- 82b0b05e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/sas/sascalc/fit/MultiplicationModel.py
rcb4ef58 rfd62331 8 8 r""" 9 9 Use for P(Q)\*S(Q); function call must be in the order of P(Q) and then S(Q): 10 The model parameters are combined from both models, P(Q) and S(Q), except 1) ' effect_radius' of S(Q)11 which will be calculated from P(Q) via calculate_ER(), 12 and 2) 'scale' in P model which is synchronized w/ volfraction in S 10 The model parameters are combined from both models, P(Q) and S(Q), except 1) 'radius_effective' of S(Q) 11 which will be calculated from P(Q) via calculate_ER(), 12 and 2) 'scale' in P model which is synchronized w/ volfraction in S 13 13 then P*S is multiplied by a new parameter, 'scale_factor'. 14 14 The polydispersion is applicable only to P(Q), not to S(Q). … … 34 34 ## Parameter details [units, min, max] 35 35 self.details = {} 36 37 ##models 36 37 ## Define parameters to exclude from multiplication model 38 self.excluded_params={'radius_effective','scale','background'} 39 40 ##models 38 41 self.p_model = p_model 39 self.s_model = s_model 42 self.s_model = s_model 40 43 self.magnetic_params = [] 41 44 ## dispersion … … 45 48 ## New parameter:Scaling factor 46 49 self.params['scale_factor'] = 1 47 50 self.params['background'] = 0 51 48 52 ## Parameter details [units, min, max] 49 53 self._set_details() 50 54 self.details['scale_factor'] = ['', 0.0, numpy.inf] 51 55 self.details['background'] = ['',-numpy.inf,numpy.inf] 56 52 57 #list of parameter that can be fitted 53 self._set_fixed_params() 58 self._set_fixed_params() 54 59 ## parameters with orientation 55 60 for item in self.p_model.orientation_params: 56 61 self.orientation_params.append(item) 57 for item in self.p_model.magnetic_params: 58 self.magnetic_params.append(item) 62 for item in self.p_model.magnetic_params: 63 self.magnetic_params.append(item) 59 64 for item in self.s_model.orientation_params: 60 65 if not item in self.orientation_params: … … 66 71 multiplicity = 1 67 72 ## functional multiplicity of the model 68 self.multiplicity = multiplicity 69 73 self.multiplicity = multiplicity 74 70 75 # non-fittable parameters 71 self.non_fittable = p_model.non_fittable 72 self.multiplicity_info = [] 76 self.non_fittable = p_model.non_fittable 77 self.multiplicity_info = [] 73 78 self.fun_list = {} 74 79 if self.non_fittable > 1: 75 80 try: 76 self.multiplicity_info = p_model.multiplicity_info 81 self.multiplicity_info = p_model.multiplicity_info 77 82 self.fun_list = p_model.fun_list 78 83 self.is_multiplicity_model = True … … 82 87 self.is_multiplicity_model = False 83 88 self.multiplicity_info = [0] 84 89 85 90 def _clone(self, obj): 86 91 """ … … 96 101 #obj = copy.deepcopy(self) 97 102 return obj 98 99 103 104 100 105 def _set_dispersion(self): 101 106 """ … … 103 108 applied to s_model 104 109 """ 105 ##set dispersion only from p_model 110 ##set dispersion only from p_model 106 111 for name , value in self.p_model.dispersion.iteritems(): 107 self.dispersion[name] = value 108 112 self.dispersion[name] = value 113 109 114 def getProfile(self): 110 115 """ 111 116 Get SLD profile of p_model if exists 112 117 113 118 :return: (r, beta) where r is a list of radius of the transition points\ 114 119 beta is a list of the corresponding SLD values … … 121 126 x = None 122 127 y = None 123 128 124 129 return x, y 125 130 126 131 def _set_params(self): 127 132 """ 128 133 Concatenate the parameters of the two models to create 129 these model parameters 134 these model parameters 130 135 """ 131 136 132 137 for name , value in self.p_model.params.iteritems(): 133 if not name in self.params.keys() and name != 'scale':138 if not name in self.params.keys() and name not in self.excluded_params: 134 139 self.params[name] = value 135 140 136 141 for name , value in self.s_model.params.iteritems(): 137 #Remove the effect_radiusfrom the (P*S) model parameters.138 if not name in self.params.keys() and name != 'effect_radius':142 #Remove the radius_effective from the (P*S) model parameters. 143 if not name in self.params.keys() and name not in self.excluded_params: 139 144 self.params[name] = value 140 145 141 146 # Set "scale and effec_radius to P and S model as initializing 142 147 # since run P*S comes from P and S separately. 148 self._set_backgrounds() 143 149 self._set_scale_factor() 144 self._set_ effect_radius()145 150 self._set_radius_effective() 151 146 152 def _set_details(self): 147 153 """ 148 154 Concatenate details of the two models to create 149 this model's details 155 this model's details 150 156 """ 151 157 for name, detail in self.p_model.details.iteritems(): 152 if name != 'scale':158 if name not in self.excluded_params: 153 159 self.details[name] = detail 154 160 155 161 for name , detail in self.s_model.details.iteritems(): 156 if not name in self.details.keys() or name != 'effect_radius':162 if not name in self.details.keys() or name not in self.exluded_params: 157 163 self.details[name] = detail 158 164 165 def _set_backgrounds(self): 166 """ 167 Set component backgrounds to zero 168 """ 169 self.p_model.setParam('background',0) 170 self.s_model.setParam('background',0) 171 172 159 173 def _set_scale_factor(self): 160 174 """ … … 162 176 """ 163 177 value = self.params['volfraction'] 164 if value != None: 178 if value != None: 165 179 factor = self.p_model.calculate_VR() 166 180 if factor == None or factor == NotImplemented or factor == 0.0: … … 170 184 self.p_model.setParam('scale', value) 171 185 self.s_model.setParam('volfraction', val) 172 173 def _set_ effect_radius(self):186 187 def _set_radius_effective(self): 174 188 """ 175 189 Set effective radius to S(Q) model 176 190 """ 177 if not ' effect_radius' in self.s_model.params.keys():191 if not 'radius_effective' in self.s_model.params.keys(): 178 192 return 179 193 effective_radius = self.p_model.calculate_ER() 180 194 #Reset the effective_radius of s_model just before the run 181 195 if effective_radius != None and effective_radius != NotImplemented: 182 self.s_model.setParam(' effect_radius', effective_radius)183 196 self.s_model.setParam('radius_effective', effective_radius) 197 184 198 def setParam(self, name, value): 185 """ 199 """ 186 200 Set the value of a model parameter 187 201 188 202 :param name: name of the parameter 189 203 :param value: value of the parameter … … 191 205 # set param to P*S model 192 206 self._setParamHelper( name, value) 193 194 ## setParam to p model 195 # set 'scale' in P(Q) equal to volfraction 207 208 ## setParam to p model 209 # set 'scale' in P(Q) equal to volfraction 196 210 if name == 'volfraction': 197 211 self._set_scale_factor() 198 elif name in self.p_model.getParamList() :212 elif name in self.p_model.getParamList() and name not in self.excluded_params: 199 213 self.p_model.setParam( name, value) 200 201 ## setParam to s model 202 # This is a little bit abundant: Todo: find better way 203 self._set_ effect_radius()204 if name in self.s_model.getParamList() :214 215 ## setParam to s model 216 # This is a little bit abundant: Todo: find better way 217 self._set_radius_effective() 218 if name in self.s_model.getParamList() and name not in self.excluded_params: 205 219 if name != 'volfraction': 206 220 self.s_model.setParam( name, value) 207 221 208 222 209 223 #self._setParamHelper( name, value) 210 224 211 225 def _setParamHelper(self, name, value): 212 226 """ … … 228 242 self.params[item] = value 229 243 return 230 244 231 245 raise ValueError, "Model does not contain parameter %s" % name 232 233 246 247 234 248 def _set_fixed_params(self): 235 249 """ … … 240 254 241 255 self.fixed.sort() 242 243 256 257 244 258 def run(self, x = 0.0): 245 """ 259 """ 246 260 Evaluate the model 247 261 248 262 :param x: input q-value (float or [float, float] as [r, theta]) 249 263 :return: (scattering function value) 250 264 """ 251 265 # set effective radius and scaling factor before run 252 self._set_ effect_radius()266 self._set_radius_effective() 253 267 self._set_scale_factor() 254 268 return self.params['scale_factor'] * self.p_model.run(x) * \ 255 self.s_model.run(x) 269 self.s_model.run(x) + self.params['background'] 256 270 257 271 def runXY(self, x = 0.0): 258 """ 272 """ 259 273 Evaluate the model 260 274 261 275 :param x: input q-value (float or [float, float] as [qx, qy]) 262 276 :return: scattering function value 263 """ 277 """ 264 278 # set effective radius and scaling factor before run 265 self._set_ effect_radius()279 self._set_radius_effective() 266 280 self._set_scale_factor() 267 281 out = self.params['scale_factor'] * self.p_model.runXY(x) * \ 268 self.s_model.runXY(x) 282 self.s_model.runXY(x) + self.params['background'] 269 283 return out 270 271 ## Now (May27,10) directly uses the model eval function 284 285 ## Now (May27,10) directly uses the model eval function 272 286 ## instead of the for-loop in Base Component. 273 287 def evalDistribution(self, x = []): 274 """ 288 """ 275 289 Evaluate the model in cartesian coordinates 276 290 277 291 :param x: input q[], or [qx[], qy[]] 278 292 :return: scattering function P(q[]) 279 293 """ 280 294 # set effective radius and scaling factor before run 281 self._set_ effect_radius()295 self._set_radius_effective() 282 296 self._set_scale_factor() 283 297 out = self.params['scale_factor'] * self.p_model.evalDistribution(x) * \ 284 self.s_model.evalDistribution(x) 298 self.s_model.evalDistribution(x) + self.params['background'] 285 299 return out 286 300 … … 288 302 """ 289 303 Set the dispersion object for a model parameter 290 304 291 305 :param parameter: name of the parameter [string] 292 306 :dispersion: dispersion object of type DispersionModel … … 299 313 return value 300 314 except: 301 raise 315 raise 302 316 303 317 def fill_description(self, p_model, s_model): … … 306 320 """ 307 321 description = "" 308 description += "Note:1) The effect_radius(effective radius) of %s \n"%\322 description += "Note:1) The radius_effective (effective radius) of %s \n"%\ 309 323 (s_model.name) 310 324 description += " is automatically calculated " … … 318 332 description += " for details of individual models." 319 333 self.description += description 320
Note: See TracChangeset
for help on using the changeset viewer.