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 __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_B(self): # Calculate odf to sh matrix B = np.zeros((self.N, self.J)) for (n, j), x in np.ndenumerate(B): l, m = util.j2lm(j) B[n, j] = util.spZnm(l, m, self.sphere.theta[n], self.sphere.phi[n]) self.B = B self.Binv = np.linalg.pinv(self.B, rcond=1e-15)
def plot_spectrum(self, filename='spectrum.pdf'): print('Plotting: ' + filename) f, ax = plt.subplots(1, 1, figsize=(4, 4)) # Create image of spherical harmonic coefficients image = np.zeros((self.rmax, self.mmax)) for j, c in enumerate(self.coeffs): l, m = util.j2lm(j) image[int(l / 2), self.lmax + m] = c # Label rows and columns for l in range(self.lmax + 1): if l == 0: prepend = 'l=' else: prepend = '' if l % 2 == 0: ax.annotate(r'$' + prepend + str(l) + '$', xy=(1, 1), xytext=(-0.75, int(l / 2)), textcoords='data', ha='right', va='center') ax.annotate(r'$m=$', xy=(1, 1), xytext=(-0.75, -0.75), textcoords='data', ha='right', va='center') for m in range(2 * self.lmax + 1): ax.annotate('$' + str(m - self.lmax) + '$', xy=(1, 1), xytext=(int(m), -0.75), textcoords='data', ha='center', va='center') # Label each pixel for (y, x), value in np.ndenumerate(image): if value != 0: ax.annotate("{0:.2f}".format(value), xy=(1, 1), xytext=(x, y), textcoords='data', ha='center', va='center') ax.imshow(image, cmap='bwr', interpolation='nearest', vmin=-np.max(self.coeffs), vmax=np.max(self.coeffs)) ax.axis('off') f.savefig(filename, bbox_inches='tight')
def __init__(self, coeffs): self.lmax, mm = util.j2lm(len(coeffs) - 1) self.jmax = int(0.5 * (self.lmax + 1) * (self.lmax + 2)) self.mmax = 2 * self.lmax + 1 self.rmax = int(self.lmax / 2) + 1 # Fill the rest of the last band with zeros temp = np.zeros(self.jmax) temp[:len(coeffs)] = coeffs self.coeffs = temp
def H(self, pol=None): if pol is None: # For normalization cc = sh.SHCoeffs([1, 0, 0, -1 / np.sqrt(5), 0, 0]) / np.sqrt( 4 * np.pi) if self.optical_axis == [1, 0, 0]: # x-illumination cc = cc.rotate() return cc out = [] for j in range(6): l, m = util.j2lm(j) theta, phi = util.xyz2tp(*pol) if l == 0: cc = 1.0 else: cc = 0.4 out.append(cc * util.spZnm(l, m, theta, phi)) return sh.SHCoeffs(out)
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)
def plot_dist(self, filename='dist.png', n_pts=2500, r=1, mag=1, show=False, force_positive=True): from mayavi import mlab print('Plotting: ' + filename) # Flip sign if [1,1,1] direction is negative coeffs = self.coeffs if force_positive: test_radii = 0 for i, c in enumerate(coeffs): l, m = util.j2lm(i) test_radii += c * util.spZnm(l, m, np.pi / 4, np.pi / 4) if test_radii < 0: coeffs = -coeffs # Calculate radii tp = util.fibonacci_sphere(n_pts) xyz = util.fibonacci_sphere(n_pts, xyz=True) radii = np.zeros(tp.shape[0]) for i, c in enumerate(coeffs): l, m = util.j2lm(i) radii += c * util.spZnm(l, m, tp[:, 0], tp[:, 1]) # radii = radii/np.max(np.abs(radii)) # Handle edge cases below radii = np.nan_to_num(radii / np.max(np.abs(radii))) # Split into positive and negatives n = r * radii.clip(max=0) p = r * radii.clip(min=0) # Triangulation from scipy.spatial import ConvexHull ch = ConvexHull(xyz) triangles = ch.simplices # Create figure mlab.figure(1, bgcolor=(1, 1, 1), fgcolor=(0, 0, 0), size=(400, 400)) mlab.clf() # Plot mlab.triangular_mesh(p * xyz[:, 0], p * xyz[:, 1], p * xyz[:, 2], triangles, color=(1, 0, 0)) s = mlab.triangular_mesh(n * xyz[:, 0], n * xyz[:, 1], n * xyz[:, 2], triangles, color=(0, 0, 1)) s.scene.light_manager.light_mode = "vtk" # View and save mlab.view(azimuth=45, elevation=45, distance=5, focalpoint=None, roll=None, reset_roll=True, figure=None) mlab.savefig(filename, magnification=mag) subprocess.call( ['convert', filename, '-transparent', 'white', filename]) if show: mlab.show()