Changeset 8fb2a94 in sasmodels for explore/realspace.py
- Timestamp:
- Jan 11, 2018 1:51:11 PM (7 years ago)
- Branches:
- master, core_shell_microgels, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
- Children:
- c11d09f
- Parents:
- 97be877
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
explore/realspace.py
r97be877 r8fb2a94 244 244 return values, self._adjust(points) 245 245 246 def calc_Iqxy(qx, qy, rho, points, volume=1, view=(0, 0, 0)): 247 x, y, z = points.T 246 NUMBA = False 247 if NUMBA: 248 from numba import njit 249 @njit("f8[:](f8[:],f8[:],f8[:],f8[:],f8[:],f8[:],f8[:])") 250 def _Iqxy(values, x, y, z, qa, qb, qc): 251 Iq = np.zeros_like(qa) 252 for j in range(len(Iq)): 253 total = 0. + 0j 254 for k in range(len(Iq)): 255 total += values[k]*np.exp(1j*(qa[j]*x[k] + qb[j]*y[k] + qc[j]*z[k])) 256 Iq[j] = abs(total)**2 257 return Iq 258 259 def calc_Iqxy(qx, qy, rho, points, volume=1.0, view=(0, 0, 0)): 248 260 qx, qy = np.broadcast_arrays(qx, qy) 249 261 qa, qb, qc = invert_view(qx, qy, view) 250 262 rho, volume = np.broadcast_arrays(rho, volume) 251 263 values = rho*volume 264 x, y, z = points.T 252 265 253 266 # I(q) = |sum V(r) rho(r) e^(1j q.r)|^2 / sum V(r) 254 Iq = [abs(np.sum(values*np.exp(1j*(qa_k*x + qb_k*y + qc_k*z))))**2 255 for qa_k, qb_k, qc_k in zip(qa.flat, qb.flat, qc.flat)] 256 return np.array(Iq).reshape(qx.shape) / np.sum(volume) 267 if NUMBA: 268 Iq = _Iqxy(values, x, y, z, qa.flatten(), qb.flatten(), qc.flatten()) 269 else: 270 Iq = [abs(np.sum(values*np.exp(1j*(qa_k*x + qb_k*y + qc_k*z))))**2 271 for qa_k, qb_k, qc_k in zip(qa.flat, qb.flat, qc.flat)] 272 return np.asarray(Iq).reshape(qx.shape) / np.sum(volume) 257 273 258 274 def _calc_Pr_nonuniform(r, rho, points): … … 275 291 print("processing %d of %d"%(k, len(rho)-1)) 276 292 Pr = extended_Pr[1:-1] 277 return Pr / Pr.max() 278 279 def calc_Pr(r, rho, points): 280 # P(r) with uniform steps in r is 3x faster; check if we are uniform 281 # before continuing 282 if np.max(np.abs(np.diff(r) - r[0])) > r[0]*0.01: 283 return _calc_Pr_nonuniform(r, rho, points) 284 293 return Pr 294 295 def _calc_Pr_uniform(r, rho, points): 285 296 # Make Pr a little be bigger than necessary so that only distances 286 297 # min < d < max end up in Pr 287 n_max =len(r)298 dr, n_max = r[0], len(r) 288 299 extended_Pr = np.zeros(n_max+1, 'd') 289 300 t0 = time.clock() 290 301 t_next = t0 + 3 291 row_zero = np.zeros(len(rho), 'i')292 302 for k, rho_k in enumerate(rho[:-1]): 293 303 distances = sqrt(np.sum((points[k] - points[k+1:])**2, axis=1)) 294 304 weights = rho_k * rho[k+1:] 295 index = np.minimum(np.asarray(distances/ r[0], 'i'), n_max)305 index = np.minimum(np.asarray(distances/dr, 'i'), n_max) 296 306 # Note: indices may be duplicated, so "Pr[index] += w" will not work!! 297 307 extended_Pr += np.bincount(index, weights, n_max+1) … … 305 315 # we are only accumulating the upper triangular distances. 306 316 #Pr = Pr * 2 / len(rho)**2 307 return Pr / Pr.max()317 return Pr 308 318 309 319 # Can get an additional 2x by going to C. Cuda/OpenCL will allow even … … 327 337 } 328 338 """ 339 340 if NUMBA: 341 @njit("f8[:](f8[:], f8[:], f8[:,:])") 342 def _calc_Pr_uniform_jit(r, rho, points): 343 dr = r[0] 344 n_max = len(r) 345 Pr = np.zeros_like(r) 346 for j in range(len(rho) - 1): 347 x, y, z = points[j, 0], points[j, 1], points[j, 2] 348 for k in range(j+1, len(rho)): 349 distance = sqrt((x - points[k, 0])**2 350 + (y - points[k, 1])**2 351 + (z - points[k, 2])**2) 352 index = int(distance/dr) 353 if index < n_max: 354 Pr[index] += rho[j] * rho[k] 355 # Make Pr independent of sampling density. The factor of 2 comes because 356 # we are only accumulating the upper triangular distances. 357 #Pr = Pr * 2 / len(rho)**2 358 return Pr 359 360 361 def calc_Pr(r, rho, points): 362 # P(r) with uniform steps in r is 3x faster; check if we are uniform 363 # before continuing 364 if np.max(np.abs(np.diff(r) - r[0])) > r[0]*0.01: 365 Pr = _calc_Pr_nonuniform(r, rho, points) 366 else: 367 if NUMBA: 368 Pr = _calc_Pr_uniform_jit(r, rho, points) 369 else: 370 Pr = _calc_Pr_uniform(r, rho, points) 371 return Pr / Pr.max() 372 329 373 330 374 def j0(x): … … 404 448 q = np.logspace(-3, 0, 200) 405 449 r = shape.r_bins(q, r_step=0.01) 406 sampling_density = 50000 / shape.volume()450 sampling_density = 6*5000 / shape.volume() 407 451 rho, points = shape.sample(sampling_density) 452 t0 = time.time() 408 453 Pr = calc_Pr(r, rho-rho_solvent, points) 454 print("calc Pr time", time.time() - t0) 409 455 Iq = calc_Iq(q, r, Pr) 410 456 theory = (q, fn(q)) if fn is not None else None … … 586 632 def fn(q): 587 633 return csbox_Iq(q, a, b, c, da, db, dc, slda, sldb, sldc, sld_core) 588 check_shape(shape, fn)634 #check_shape(shape, fn) 589 635 590 636 view = (20, 30, 40) … … 592 638 return csbox_Iqxy(qx, qy, a, b, c, da, db, dc, 593 639 slda, sldb, sldc, sld_core, view=view) 594 #check_shape_2d(shape, fn_xy, view=view)640 check_shape_2d(shape, fn_xy, view=view) 595 641 596 642 if __name__ == "__main__":
Note: See TracChangeset
for help on using the changeset viewer.