Changeset c036ddb in sasmodels for sasmodels/product.py
- Timestamp:
- Aug 7, 2018 8:45:45 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:
- 7e923c2
- Parents:
- 7b0abf8
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sasmodels/product.py
r01c8d9e rc036ddb 37 37 ER_ID = "radius_effective" 38 38 VF_ID = "volfraction" 39 BETA_DEFINITION = ("beta_mode", "", 0, [["P*S"],["P*(1+beta*(S-1))"]], "", 40 "Structure factor dispersion calculation mode") 39 41 40 42 # TODO: core_shell_sphere model has suppressed the volume ratio calculation … … 74 76 translate_name = dict((old.id, new.id) for old, new 75 77 in zip(s_pars.kernel_parameters[1:], s_list)) 76 beta _parameter = Parameter("beta_mode", "", 0, [["P*S"],["P*(1+beta*(S-1))"], "", "Structure factor dispersion calculation mode"])77 combined_pars = p_pars.kernel_parameters + s_list + [beta_parameter]78 beta = [Parameter(*BETA_DEFINITION)] if p_info.have_Fq else [] 79 combined_pars = p_pars.kernel_parameters + s_list + beta 78 80 parameters = ParameterTable(combined_pars) 79 81 parameters.max_pd = p_pars.max_pd + s_pars.max_pd … … 152 154 #: Structure factor modelling interaction between particles. 153 155 self.S = S 154 156 155 157 #: Model precision. This is not really relevant, since it is the 156 158 #: individual P and S models that control the effective dtype, … … 170 172 # in opencl; or both in opencl, but one in single precision and the 171 173 # other in double precision). 172 174 173 175 p_kernel = self.P.make_kernel(q_vectors) 174 176 s_kernel = self.S.make_kernel(q_vectors) … … 196 198 # type: (CallDetails, np.ndarray, float, bool) -> np.ndarray 197 199 p_info, s_info = self.info.composition[1] 200 198 201 # if there are magnetic parameters, they will only be on the 199 202 # form factor P, not the structure factor S. … … 207 210 nweights = call_details.num_weights 208 211 weights = values[nvalues:nvalues + 2*nweights] 212 209 213 # Construct the calling parameters for P. 210 214 p_npars = p_info.parameters.npars … … 212 216 p_offset = call_details.offset[:p_npars] 213 217 p_details = make_details(p_info, p_length, p_offset, nweights) 218 214 219 # Set p scale to the volume fraction in s, which is the first of the 215 220 # 'S' parameters in the parameter list, or 2+np in 0-origin. … … 219 224 p_values.append([0.]*spacer) 220 225 p_values = np.hstack(p_values).astype(self.p_kernel.dtype) 226 221 227 # Call ER and VR for P since these are needed for S. 222 228 p_er, p_vr = calc_er_vr(p_info, p_details, p_values) 223 229 s_vr = (volfrac/p_vr if p_vr != 0. else volfrac) 224 230 #print("volfrac:%g p_er:%g p_vr:%g s_vr:%g"%(volfrac,p_er,p_vr,s_vr)) 231 225 232 # Construct the calling parameters for S. 226 233 # The effective radius is not in the combined parameter list, so … … 252 259 s_values.append([0.]*spacer) 253 260 s_values = np.hstack(s_values).astype(self.s_kernel.dtype) 261 254 262 # beta mode is the first parameter after the structure factor pars 255 263 beta_index = 2+p_npars+s_npars 256 264 beta_mode = values[beta_index] 265 257 266 # Call the kernels 258 if beta_mode: # beta: 267 s_result = self.s_kernel.Iq(s_details, s_values, cutoff, False) 268 scale, background = values[0], values[1] 269 if beta_mode: 259 270 F1, F2, volume_avg = self.p_kernel.beta(p_details, p_values, cutoff, magnetic) 271 combined_scale = scale*volfrac/volume_avg 272 # Define lazy results based on intermediate values. 273 # The return value for the calculation should be an ordered 274 # dictionary containing any result the user might want to see 275 # at the end of the calculation, including scalars, strings, 276 # and plottable data. Don't want to build this structure during 277 # fits, only when displaying the final result (or a one-off 278 # computation which asks for it). 279 # Do not use the current hack of storing the intermediate values 280 # in self.results since that leads to awkward threading issues. 281 # Instead return the function along with the bundle of inputs. 282 # P and Q may themselves have intermediate results they want to 283 # include, such as A and B if P = A + B. Might use this mechanism 284 # to return the computed effective radius as well. 285 #def lazy_results(Q, S, F1, F2, scale): 286 # """ 287 # beta = F1**2 / F2 # what about divide by zero errors? 288 # return { 289 # 'P' : Data1D(Q, scale*F2), 290 # 'beta': Data1D(Q, beta), 291 # 'S' : Data1D(Q, S), 292 # 'Seff': Data1D(Q, 1 + beta*(S-1)), 293 # 'I' : Data1D(Q, scale*(F2 + (F1**2)*(S-1)) + background), 294 # } 295 #lazy_pars = s_result, F1, F2, combined_scale 296 self.results = [F2, s_result] 297 final_result = combined_scale*(F2 + (F1**2)*(s_result - 1)) + background 260 298 else: 261 299 p_result = self.p_kernel.Iq(p_details, p_values, cutoff, magnetic) 262 s_result = self.s_kernel.Iq(s_details, s_values, cutoff, False) 263 #print("p_npars",p_npars,s_npars,p_er,s_vr,values[2+p_npars+1:2+p_npars+s_npars]) 300 # remember the parts for plotting later 301 self.results = [p_result, s_result] 302 final_result = scale*(p_result*s_result) + background 303 264 304 #call_details.show(values) 265 305 #print("values", values) … … 272 312 #plt.subplot(212); plt.loglog(self.s_kernel.q_input.q, s_result, '-') 273 313 #plt.figure() 274 if beta_mode:#beta275 beta_factor = F1**2/F2276 Sq_eff = 1+beta_factor*(s_result - 1)277 self.results = [F2, Sq_eff,F1,s_result]278 final_result = volfrac*values[0]*(F2 + (F1**2)*(s_result - 1))/volume_avg+values[1]279 #final_result = volfrac * values[0] * F2 * Sq_eff / volume_avg + values[1]280 else:281 # remember the parts for plotting later282 self.results = [p_result, s_result]283 final_result = values[0]*(p_result*s_result) + values[1]284 314 return final_result 285 315
Note: See TracChangeset
for help on using the changeset viewer.