Changeset 5399809 in sasmodels for sasmodels/kernelpy.py
- Timestamp:
- Aug 21, 2018 1:32:40 PM (6 years ago)
- Branches:
- master, core_shell_microgels, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
- Children:
- 2a12351b
- Parents:
- c57ee9e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/kernelpy.py
r6e7ba14 r5399809 182 182 radius = ((lambda: 0.0) if effective_radius_type == 0 183 183 else (lambda: self._radius(effective_radius_type))) 184 res = _loops(self._parameter_vector, self._form, self._volume, radius,185 self.q_input.nq, call_details, values, cutoff)186 return res184 self.result = _loops( 185 self._parameter_vector, self._form, self._volume, radius, 186 self.q_input.nq, call_details, values, cutoff) 187 187 188 188 def release(self): … … 213 213 # # 214 214 ################################################################ 215 216 # WARNING: Trickery ahead 217 # The parameters[] vector is embedded in the closures for form(), 218 # form_volume() and form_radius(). We set the initial vector from 219 # the values for the model parameters. As we loop through the polydispesity 220 # mesh, we update the components with the polydispersity values before 221 # calling the respective functions. 215 222 n_pars = len(parameters) 216 223 parameters[:] = values[2:n_pars+2] 224 217 225 if call_details.num_active == 0: 218 pd_norm = float(form_volume()) 219 scale = values[0]/(pd_norm if pd_norm != 0.0 else 1.0) 220 background = values[1] 221 return scale*form() + background 222 223 pd_value = values[2+n_pars:2+n_pars + call_details.num_weights] 224 pd_weight = values[2+n_pars + call_details.num_weights:] 225 226 weight_norm = 0.0 227 weighted_volume = 0.0 228 weighted_radius = 0.0 229 partial_weight = np.NaN 230 weight = np.NaN 231 232 p0_par = call_details.pd_par[0] 233 p0_length = call_details.pd_length[0] 234 p0_index = p0_length 235 p0_offset = call_details.pd_offset[0] 236 237 pd_par = call_details.pd_par[:call_details.num_active] 238 pd_offset = call_details.pd_offset[:call_details.num_active] 239 pd_stride = call_details.pd_stride[:call_details.num_active] 240 pd_length = call_details.pd_length[:call_details.num_active] 241 242 total = np.zeros(nq, 'd') 243 for loop_index in range(call_details.num_eval): 244 # update polydispersity parameter values 245 if p0_index == p0_length: 246 pd_index = (loop_index//pd_stride)%pd_length 247 parameters[pd_par] = pd_value[pd_offset+pd_index] 248 partial_weight = np.prod(pd_weight[pd_offset+pd_index][1:]) 249 p0_index = loop_index%p0_length 250 251 weight = partial_weight * pd_weight[p0_offset + p0_index] 252 parameters[p0_par] = pd_value[p0_offset + p0_index] 253 p0_index += 1 254 if weight > cutoff: 255 # Call the scattering function 256 # Assume that NaNs are only generated if the parameters are bad; 257 # exclude all q for that NaN. Even better would be to have an 258 # INVALID expression like the C models, but that is too expensive. 259 Iq = np.asarray(form(), 'd') 260 if np.isnan(Iq).any(): 261 continue 262 263 # update value and norm 264 total += weight * Iq 265 weight_norm += weight 266 weighted_volume += weight * form_volume() 267 weighted_radius += weight * form_radius() 226 total = form() 227 weight_norm = 1.0 228 weighted_volume = form_volume() 229 weighted_radius = form_radius() 230 231 else: 232 pd_value = values[2+n_pars:2+n_pars + call_details.num_weights] 233 pd_weight = values[2+n_pars + call_details.num_weights:] 234 235 weight_norm = 0.0 236 weighted_volume = 0.0 237 weighted_radius = 0.0 238 partial_weight = np.NaN 239 weight = np.NaN 240 241 p0_par = call_details.pd_par[0] 242 p0_length = call_details.pd_length[0] 243 p0_index = p0_length 244 p0_offset = call_details.pd_offset[0] 245 246 pd_par = call_details.pd_par[:call_details.num_active] 247 pd_offset = call_details.pd_offset[:call_details.num_active] 248 pd_stride = call_details.pd_stride[:call_details.num_active] 249 pd_length = call_details.pd_length[:call_details.num_active] 250 251 total = np.zeros(nq, 'd') 252 for loop_index in range(call_details.num_eval): 253 # update polydispersity parameter values 254 if p0_index == p0_length: 255 pd_index = (loop_index//pd_stride)%pd_length 256 parameters[pd_par] = pd_value[pd_offset+pd_index] 257 partial_weight = np.prod(pd_weight[pd_offset+pd_index][1:]) 258 p0_index = loop_index%p0_length 259 260 weight = partial_weight * pd_weight[p0_offset + p0_index] 261 parameters[p0_par] = pd_value[p0_offset + p0_index] 262 p0_index += 1 263 if weight > cutoff: 264 # Call the scattering function 265 # Assume that NaNs are only generated if the parameters are bad; 266 # exclude all q for that NaN. Even better would be to have an 267 # INVALID expression like the C models, but that is expensive. 268 Iq = np.asarray(form(), 'd') 269 if np.isnan(Iq).any(): 270 continue 271 272 # update value and norm 273 total += weight * Iq 274 weight_norm += weight 275 weighted_volume += weight * form_volume() 276 weighted_radius += weight * form_radius() 268 277 269 278 result = np.hstack((total, weight_norm, weighted_volume, weighted_radius))
Note: See TracChangeset
for help on using the changeset viewer.