def disp3D(img, phi, theta, dmode='abs', cmap='jet'): """Display 3D, equal in phi and theta (Driscoll and Healy mapping) image img: 2D array of complex flux values phi: 2D array of phi values theta: 2D array of theta values img, phi, theta are of the same shape, they are the output of swht.make3Dimage() dmode: string, data mode (abs, real, imaginary, phase) cmap: string, matplotlib colormap name """ if dmode.startswith('abs'): img = np.abs(img) elif dmode.startswith('real'): img = img.real elif dmode.startswith('imag'): img = img.imag elif dmode.startswith('phase'): img = np.angle(img) else: print 'WARNING: Unknown data mode, defaulting to absolute value' img = np.abs(img) #X = np.cos(theta-(np.pi/2.)) * np.cos(phi) #Y = np.cos(theta-(np.pi/2.)) * np.sin(phi) #Z = np.sin(theta-(np.pi/2.)) X, Y, Z = util.sph2cart(theta, phi) # North-South Flip #Z *= -1. #http://stackoverflow.com/questions/22175533/what-is-the-equivalent-of-matlabs-surfx-y-z-c-in-matplotlib from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm from matplotlib.colors import Normalize fig = plt.figure(figsize=(10, 8)) ax = fig.gca(projection='3d') imin = img.min() imax = img.max() scalarMap = cm.ScalarMappable(norm=Normalize(vmin=imin, vmax=imax), cmap=plt.get_cmap(cmap)) #scalarMap = cm.ScalarMappable(norm=Normalize(vmin=imin, vmax=imax), cmap=cm.jet) #scalarMap = cm.ScalarMappable(norm=Normalize(vmin=imin, vmax=imax), cmap=cm.gist_earth_r) scalarMap.set_array(img) C = scalarMap.to_rgba(img) surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, facecolors=C, antialiased=True, linewidth=1) #wire = ax.plot_wireframe(1.01*X, 1.01*Y, 1.01*Z, rstride=5, cstride=5, color='black') # RA/Dec grid fig.colorbar(scalarMap, shrink=0.7) ax.set_axis_off() ax.set_xlim(-0.75, 0.75) ax.set_ylim(-0.75, 0.75) ax.set_zlim(-0.75, 0.75) ax.set_aspect('auto') return fig, ax
def disp3D(img, phi, theta, dmode='abs', cmap='jet'): """Display 3D, equal in phi and theta (Driscoll and Healy mapping) image img: 2D array of complex flux values phi: 2D array of phi values theta: 2D array of theta values img, phi, theta are of the same shape, they are the output of swht.make3Dimage() dmode: string, data mode (abs, real, imaginary, phase) cmap: string, matplotlib colormap name """ if dmode.startswith('abs'): img = np.abs(img) elif dmode.startswith('real'): img = img.real elif dmode.startswith('imag'): img = img.imag elif dmode.startswith('phase'): img = np.angle(img) else: print 'WARNING: Unknown data mode, defaulting to absolute value' img = np.abs(img) #X = np.cos(theta-(np.pi/2.)) * np.cos(phi) #Y = np.cos(theta-(np.pi/2.)) * np.sin(phi) #Z = np.sin(theta-(np.pi/2.)) X, Y, Z = util.sph2cart(theta, phi) # North-South Flip #Z *= -1. #http://stackoverflow.com/questions/22175533/what-is-the-equivalent-of-matlabs-surfx-y-z-c-in-matplotlib from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm from matplotlib.colors import Normalize fig = plt.figure() ax = fig.gca(projection='3d') imin = img.min() imax = img.max() scalarMap = cm.ScalarMappable(norm=Normalize(vmin=imin, vmax=imax), cmap=plt.get_cmap(cmap)) #scalarMap = cm.ScalarMappable(norm=Normalize(vmin=imin, vmax=imax), cmap=cm.jet) #scalarMap = cm.ScalarMappable(norm=Normalize(vmin=imin, vmax=imax), cmap=cm.gist_earth_r) scalarMap.set_array(img) C = scalarMap.to_rgba(img) surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, facecolors=C, antialiased=True) #wire = ax.plot_wireframe(1.05*X, 1.05*Y, 1.05*Z, rstride=10, cstride=10, color='black') # RA/Dec grid fig.colorbar(scalarMap) return fig, ax
def make2Dimage(coeffs, res, px=[64, 64], phs=[0., 0.]): """Make a flat image of a single hemisphere from SWHT image coefficients coeffs: SWHT brightness coefficients px: [int, int], number of pixels, note these are equivalent to the l,m coordinates in FT imaging res: float, resolution of the central pixel in radians phs: [float, float], RA and Dec (radians) position at the center of the image """ start_time = time.time() #start from a regular Cartesian grid lrange = np.linspace(-1.*px[0]*res/2., px[0]*res/2., num=px[0], endpoint=True)/(np.pi/2.) #m range (-1,1) mrange = np.linspace(-1.*px[1]*res/2., px[1]*res/2., num=px[1], endpoint=True)/(np.pi/2.) #l range (-1,1) xx,yy = np.meshgrid(lrange, mrange) #xx,yy = np.meshgrid(np.linspace(-1., 1., num=px[0]), np.linspace(-1., 1., num=px[1])) #Full hemisphere, no FoV control img = np.zeros(xx.shape, dtype='complex') #convert to polar positions r = np.sqrt(xx**2. + yy**2.) phi = np.arctan2(yy, xx) # zero out undefined regions of the image where r>0 # overly tedious steps for something that should be much easier to do rflat = r.flatten() phiflat = phi.flatten() maxRcond = r.flatten() > 1 idx = np.argwhere(maxRcond) rflat[idx] = 0. phiflat[idx] = 0. r = np.reshape(rflat, r.shape) phi = np.reshape(phiflat, phi.shape) #convert to unit sphere coordinates thetap = np.arccos(r) - np.pi/2. #north pole is at 0 in spherical coordinates phip = np.pi - phi #azimuth range [-pi, pi] -> [2pi, 0] #Determine the theta, phi coordinates for a hemisphere at the snapshot zenith X, Y, Z = util.sph2cart(thetap, phip) ra = phs[0] raRotation = np.array([[np.cos(ra), -1.*np.sin(ra), 0.], [np.sin(ra), np.cos(ra), 0.], [ 0., 0., 1.]]) #rotate about the z-axis dec = np.pi - phs[1] #adjust relative to the north pole at -pi/2 print 'dec', dec, 'phs', phs[1] # TODO: might need to do a transpose to apply the inverse rotation decRotation = np.array([[1.,0.,0.], [0., np.cos(dec), -1.*np.sin(dec)], [0., np.sin(dec), np.cos(dec)]]) #rotate about the x-axis XYZ = np.vstack((X.flatten(), Y.flatten(), Z.flatten())) rotMatrix = np.dot(decRotation, raRotation) XYZ0 = np.dot(rotMatrix, XYZ) #order of rotation is important #XYZ0 = np.dot(np.dot(raRotation, decRotation), XYZ) #order of rotation is important r0, phi0, theta0 = util.cart2sph(XYZ0[0,:], XYZ0[1,:], XYZ0[2,:]) r0 = r0.reshape(thetap.shape) #not used, should all be nearly 1 phi0 = phi0.reshape(thetap.shape) #rotated phi values theta0 = theta0.reshape(thetap.shape) #rotated theta values lmax = coeffs.shape[0] print 'L:', for l in np.arange(lmax): print l, sys.stdout.flush() for m in np.arange(-1*l, l+1): img += coeffs[l, l+m] * Ylm.Ylm(l, m, phi0, theta0) #TODO: a slow call print 'done' print 'Run time: %f s'%(time.time() - start_time) return np.ma.array(img, mask=maxRcond)
def make2Dimage(coeffs, res, px=[64, 64], phs=[0., 0.]): """Make a flat image of a single hemisphere from SWHT image coefficients coeffs: SWHT brightness coefficients px: [int, int], number of pixels, note these are equivalent to the l,m coordinates in FT imaging res: float, resolution of the central pixel in radians phs: [float, float], RA and Dec (radians) position at the center of the image """ start_time = time.time() #start from a regular Cartesian grid lrange = np.linspace( -1. * px[0] * res / 2., px[0] * res / 2., num=px[0], endpoint=True) / ( np.pi / 2.) #m range (-1,1) mrange = np.linspace( -1. * px[1] * res / 2., px[1] * res / 2., num=px[1], endpoint=True) / ( np.pi / 2.) #l range (-1,1) xx, yy = np.meshgrid(lrange, mrange) #xx,yy = np.meshgrid(np.linspace(-1., 1., num=px[0]), np.linspace(-1., 1., num=px[1])) #Full hemisphere, no FoV control img = np.zeros(xx.shape, dtype='complex') #convert to polar positions r = np.sqrt(xx**2. + yy**2.) phi = np.arctan2(yy, xx) # zero out undefined regions of the image where r>0 # overly tedious steps for something that should be much easier to do rflat = r.flatten() phiflat = phi.flatten() maxRcond = r.flatten() > 1 idx = np.argwhere(maxRcond) rflat[idx] = 0. phiflat[idx] = 0. r = np.reshape(rflat, r.shape) phi = np.reshape(phiflat, phi.shape) #convert to unit sphere coordinates thetap = np.arccos( r) - np.pi / 2. #north pole is at 0 in spherical coordinates phip = np.pi - phi #azimuth range [-pi, pi] -> [2pi, 0] #Determine the theta, phi coordinates for a hemisphere at the snapshot zenith X, Y, Z = util.sph2cart(thetap, phip) ra = phs[0] raRotation = np.array([[np.cos(ra), -1. * np.sin(ra), 0.], [np.sin(ra), np.cos(ra), 0.], [0., 0., 1.]]) #rotate about the z-axis dec = np.pi - phs[1] #adjust relative to the north pole at -pi/2 print 'dec', dec, 'phs', phs[1] # TODO: might need to do a transpose to apply the inverse rotation decRotation = np.array([[1., 0., 0.], [0., np.cos(dec), -1. * np.sin(dec)], [0., np.sin(dec), np.cos(dec)]]) #rotate about the x-axis XYZ = np.vstack((X.flatten(), Y.flatten(), Z.flatten())) rotMatrix = np.dot(decRotation, raRotation) XYZ0 = np.dot(rotMatrix, XYZ) #order of rotation is important #XYZ0 = np.dot(np.dot(raRotation, decRotation), XYZ) #order of rotation is important r0, phi0, theta0 = util.cart2sph(XYZ0[0, :], XYZ0[1, :], XYZ0[2, :]) r0 = r0.reshape(thetap.shape) #not used, should all be nearly 1 phi0 = phi0.reshape(thetap.shape) #rotated phi values theta0 = theta0.reshape(thetap.shape) #rotated theta values lmax = coeffs.shape[0] print 'L:', for l in np.arange(lmax): print l, sys.stdout.flush() for m in np.arange(-1 * l, l + 1): img += coeffs[l, l + m] * Ylm.Ylm(l, m, phi0, theta0) #TODO: a slow call print 'done' print 'Run time: %f s' % (time.time() - start_time) return np.ma.array(img, mask=maxRcond)