def curve_phantom(curve, direction, kappa, px=(20,20,20), vox_dim=(100,100,100), cyl_rad=0.2, max_l=6, dtype=np.float32): # Setup grid xyz = np.array(np.meshgrid( np.linspace(-(px[0]/2)*vox_dim[0], (px[0]/2)*vox_dim[0], px[0]), np.linspace(-(px[1]/2)*vox_dim[1], (px[1]/2)*vox_dim[1], px[1]), np.linspace(-(px[2]/2)*vox_dim[2], (px[2]/2)*vox_dim[2], px[2]))) xyz = np.moveaxis(xyz, [0, 1], [-1, 1]) # Calculate directions and kappas diff = xyz[:,:,:,None,:] - curve dist = np.linalg.norm(diff, axis=-1) min_dist = np.min(dist, axis=-1) # min dist between grid points and curve t_index = np.argmin(dist, axis=-1) min_dir = direction[t_index] # directions for closest point on curve min_k = kappa[t_index] # kappas # Calculate watson spang_shape = xyz.shape[0:-1] + (util.maxl2maxj(max_l),) spang1 = spang.Spang(np.zeros(spang_shape), vox_dim=vox_dim) dot = np.einsum('ijkl,ml->ijkm', min_dir, spang1.sphere.vertices) k = min_k[...,None] watson = np.exp(k*dot**2)/(4*np.pi*hyp1f1(0.5, 1.5, k)) watson_sh = np.einsum('ijkl,lm', watson, spang1.B) watson_sh = watson_sh/watson_sh[...,None,0] # Normalize # Cylinder mask mask = min_dist < cyl_rad spang1.f = np.einsum('ijkl,ijk->ijkl', watson_sh, mask).astype(dtype) return spang1
def __init__(self, f=np.zeros((3, 3, 3, 15), dtype=np.float32), vox_dim=(1, 1, 1), sphere=get_sphere('symmetric724')): self.X = f.shape[0] self.Y = f.shape[1] self.Z = f.shape[2] # Calculate band dimensions self.lmax, mm = util.j2lm(f.shape[-1] - 1) self.J = util.maxl2maxj(self.lmax) # Fill the rest of the last l band with zeros if f.shape[-1] != self.J: temp = np.zeros((self.X, self.Y, self.Z, self.J)) temp[..., :f.shape[-1]] = f self.f = temp else: self.f = f self.vox_dim = vox_dim self.sphere = sphere self.sphere = sphere.subdivide() self.N = len(self.sphere.theta) self.calc_B()
def calc_gaunt_tensor(filename, lmax=4): jmax = myutil.maxl2maxj(lmax) G = np.zeros((jmax, jmax, jmax)) for index, g in np.ndenumerate(G): print(index) l1, m1 = myutil.j2lm(index[0]) l2, m2 = myutil.j2lm(index[1]) l3, m3 = myutil.j2lm(index[2]) G[index] = Rgaunt(l1, l2, l3, m1, m2, m3) np.save(filename, G) return G
def multiply_sh_coefficients(a, b, evaluate=True): maxl, m = myutil.j2lm(len(a) - 1) c = [0] * (myutil.maxl2maxj(maxl + 2)) for i, ai in enumerate(a): l1, m1 = myutil.j2lm(i) for j, bi in enumerate(b): l2, m2 = myutil.j2lm(j) for k, ci in enumerate(c): l3, m3 = myutil.j2lm(k) if ai != 0 and bi != 0: c[k] += ai * bi * Rgaunt( l1, l2, l3, m1, m2, m3, evaluate=evaluate) return c
def calc_sh2tensor(filename, lmax=2): jmax = myutil.maxl2maxj(lmax) H = np.zeros((6, jmax)) theta = Symbol('theta', real=True) phi = Symbol('phi', real=True) elems = [(cos(phi) * sin(theta))**2, (sin(phi) * sin(theta))**2, cos(theta)**2, cos(phi) * sin(phi) * (sin(theta)**2), sin(phi) * sin(theta) * cos(theta), cos(phi) * sin(theta) * cos(theta)] for i, elem in enumerate(elems): for j in range(jmax): l, m = myutil.j2lm(j) Znm = sh.Znm(l, m, theta, phi).expand(func=True) theta_int = integrate(sin(theta) * Znm * elem, (theta, 0, pi / 2)) final_int = integrate(expand_trig(theta_int.rewrite(cos)), (phi, 0, 2 * pi)) H[i, j] = final_int.evalf() print(i, l, m, final_int) import pdb pdb.set_trace() np.save(filename, H)