Changeset 5399809 in sasmodels
- 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
- Location:
- sasmodels
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/core.py
r71b751d r5399809 363 363 model = load_model("cylinder@hardsphere*sphere") 364 364 actual = [p.name for p in model.info.parameters.kernel_parameters] 365 target = ("sld sld_solvent radius length theta phi volfraction" 366 " beta_mode A_sld A_sld_solvent A_radius").split() 365 target = ("sld sld_solvent radius length theta phi" 366 " radius_effective volfraction structure_factor_mode" 367 " A_sld A_sld_solvent A_radius").split() 367 368 assert target == actual, "%s != %s"%(target, actual) 368 369 -
sasmodels/generate.py
r6e7ba14 r5399809 802 802 for p in partable.kernel_parameters)) 803 803 # Define the function calls 804 call_effective_radius = "#define CALL_EFFECTIVE_RADIUS(mode, v) 0.0" 804 805 if partable.form_volume_parameters: 805 806 refs = _call_pars("_v.", partable.form_volume_parameters) 806 807 call_volume = "#define CALL_VOLUME(_v) form_volume(%s)"%(",".join(refs)) 807 call_effective_radius = "#define CALL_EFFECTIVE_RADIUS(mode, _v) effective_radius(mode, %s)"%(",".join(refs)) 808 if model_info.effective_radius_type: 809 call_effective_radius = "#define CALL_EFFECTIVE_RADIUS(mode, _v) effective_radius(mode, %s)"%(",".join(refs)) 808 810 else: 809 811 # Model doesn't have volume. We could make the kernel run a little … … 811 813 # the ifdef's reduce readability more than is worthwhile. 812 814 call_volume = "#define CALL_VOLUME(v) 1.0" 813 call_effective_radius = "#define CALL_EFFECTIVE_RADIUS(mode, v) 0.0"814 815 source.append(call_volume) 815 816 source.append(call_effective_radius) -
sasmodels/kernel.py
r6e7ba14 r5399809 44 44 # type: (CallDetails, np.ndarray, np.ndarray, float, bool) -> np.ndarray 45 45 Pq, Reff = self.Pq_Reff(call_details, values, cutoff, magnetic, effective_radius_type=0) 46 scale = values[0] 47 background = values[1] 48 return scale*Pq + background 46 return Pq 49 47 __call__ = Iq 50 48 … … 53 51 self._call_kernel(call_details, values, cutoff, magnetic, effective_radius_type) 54 52 #print("returned",self.q_input.q, self.result) 55 nout = 2 if self.info.have_Fq else 153 nout = 2 if self.info.have_Fq and self.dim == '1d' else 1 56 54 total_weight = self.result[nout*self.q_input.nq + 0] 57 55 if total_weight == 0.: … … 63 61 # = scale*(sum(w*F^2)/sum w)/(sum (w*V)/sum w) + background 64 62 # = scale/sum (w*V) * sum(w*F^2) + background 63 F2 = self.result[0:nout*self.q_input.nq:nout] 65 64 scale = values[0]/(weighted_volume if weighted_volume != 0.0 else 1.0) 66 65 background = values[1] 66 Pq = scale*F2 + background 67 67 #print("scale",scale,background) 68 return self.result[0:nout*self.q_input.nq:nout], effective_radius68 return Pq, effective_radius 69 69 70 70 def beta(self, call_details, values, cutoff, magnetic, effective_radius_type): -
sasmodels/kernelcl.py
r6e7ba14 r5399809 481 481 # at this point, so instead using 32, which is good on the set of 482 482 # architectures tested so far. 483 extra_q = 3 # total weight, weighted volume and weighted radius 483 484 if self.is_2d: 484 # Note: 16 rather than 15 because result is 1 longer than input. 485 width = ((self.nq+16)//16)*16 485 width = ((self.nq+15+extra_q)//16)*16 486 486 self.q = np.empty((width, 2), dtype=dtype) 487 487 self.q[:self.nq, 0] = q_vectors[0] 488 488 self.q[:self.nq, 1] = q_vectors[1] 489 489 else: 490 # Note: 32 rather than 31 because result is 1 longer than input. 491 width = ((self.nq+32)//32)*32 490 width = ((self.nq+31+extra_q)//32)*32 492 491 self.q = np.empty(width, dtype=dtype) 493 492 self.q[:self.nq] = q_vectors[0] … … 539 538 self.dim = '2d' if q_input.is_2d else '1d' 540 539 # leave room for f1/f2 results in case we need to compute beta for 1d models 541 n um_returns = 1 if self.dim == '2d' else 2 #542 # plus 1 for the normalization value, plus another for R_eff543 self.result = np.empty( (q_input.nq+2)*num_returns,dtype)540 nout = 2 if self.info.have_Fq and self.dim == '1d' else 1 541 # plus 3 weight, volume, radius 542 self.result = np.empty(q_input.nq*nout + 3, self.dtype) 544 543 545 544 # Inputs and outputs for each kernel call … … 549 548 550 549 self.result_b = cl.Buffer(self.queue.context, mf.READ_WRITE, 551 q_input.global_size[0] * n um_returns* dtype.itemsize)550 q_input.global_size[0] * nout * dtype.itemsize) 552 551 self.q_input = q_input # allocated by GpuInput above 553 552 -
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)) -
sasmodels/modelinfo.py
r6e7ba14 r5399809 794 794 info.source = getattr(kernel_module, 'source', []) 795 795 info.c_code = getattr(kernel_module, 'c_code', None) 796 info.effective_radius = getattr(kernel_module, 'effective_radius', None) 796 797 info.ER = None # CRUFT 797 798 info.VR = None # CRUFT -
sasmodels/product.py
rc57ee9e r5399809 301 301 p_details, p_values, cutoff, magnetic, effective_radius_type) 302 302 if effective_radius_type > 0: 303 # Plug R_eff from p into S model (initial value and pd value) 303 304 s_values[2] = s_values[2+s_npars+s_offset[0]] = effective_radius 304 305 s_result = self.s_kernel.Iq(s_details, s_values, cutoff, False) … … 312 313 p_details, p_values, cutoff, magnetic, effective_radius_type) 313 314 if effective_radius_type > 0: 315 # Plug R_eff from p into S model (initial value and pd value) 314 316 s_values[2] = s_values[2+s_npars+s_offset[0]] = effective_radius 315 317 s_result = self.s_kernel.Iq(s_details, s_values, cutoff, False)
Note: See TracChangeset
for help on using the changeset viewer.