def swhtImageCoeffs(vis, uvw, freqs, lmax, lmin=0): """Generate brightness coefficients by transforming visibilities with the SWHT vis: complex array [Q, F], Q observed visibilities at F frequencies, can be size [Q] if only using 1 frequency uvw: float array [Q, 3, F], meters, has a F frequency axis because of the time steps in LOFAR station obsevrations changes uvw with respect to the frequency freqs: float array [F, 1] or [F], observing frequencies in Hz lmax: positive int, maximum spherical harmonic l number lmin: positive int, minimum spherical harmonic l number, usually 0 """ start_time = time.time() #single subband cases if vis.ndim==1: vis = vis[np.newaxis].T if uvw.ndim==2: uvw = uvw.reshape(uvw.shape[0], uvw.shape[1], 1) if freqs.ndim==1: freqs = freqs[np.newaxis].T k = 2. * np.pi * freqs/cc #obs freq/c #convert u,v,w to r,phi,theta r, phi, theta = util.cart2sph(uvw[:,0], uvw[:,1], uvw[:,2]) if r.ndim==1: #make arrays 2D r = r[np.newaxis].T phi = phi[np.newaxis].T theta = theta[np.newaxis].T phi = phi - np.pi #make range -pi to pi theta = np.pi - theta #flip theta values #from matplotlib import pyplot as plt #from mpl_toolkits.mplot3d import Axes3D #fig = plt.figure() #ax = fig.add_subplot(111, projection='3d') #ax.scatter(uvw[:,0], uvw[:,1], uvw[:,2], c=r, alpha=0.5, edgecolors='none') #plt.show() #exit() #r = np.sqrt(uvw[:,0]**2. + uvw[:,1]**2. + uvw[:,2]**2.)[np.newaxis].T #phi = np.arctan2(uvw[:,1], uvw[:,0])[np.newaxis].T #theta = (np.pi/2.) - np.arctan2(uvw[:,2], np.sqrt(uvw[:,0]**2. + uvw[:,1]**2.))[np.newaxis].T #make range -pi/2 to pi/2 #compute the SWHT visibility coefficients vislm = computeVislm(lmax, k, r, theta, phi, vis, lmin=lmin) #compute the SWHT brightness coefficients blm = computeblm(vislm) print 'Run time: %f s'%(time.time() - start_time) return blm
def swhtImageCoeffs(vis, uvw, freqs, lmax, lmin=0): """Generate brightness coefficients by transforming visibilities with the SWHT vis: complex array [Q, F], Q observed visibilities at F frequencies, can be size [Q] if only using 1 frequency uvw: float array [Q, 3, F], meters, has a F frequency axis because of the time steps in LOFAR station obsevrations changes uvw with respect to the frequency freqs: float array [F, 1] or [F], observing frequencies in Hz lmax: positive int, maximum spherical harmonic l number lmin: positive int, minimum spherical harmonic l number, usually 0 """ start_time = time.time() #single subband cases if vis.ndim == 1: vis = vis[np.newaxis].T if uvw.ndim == 2: uvw = uvw.reshape(uvw.shape[0], uvw.shape[1], 1) if freqs.ndim == 1: freqs = freqs[np.newaxis].T k = 2. * np.pi * freqs / cc #obs freq/c #convert u,v,w to r,phi,theta r, phi, theta = util.cart2sph(uvw[:, 0], uvw[:, 1], uvw[:, 2]) if r.ndim == 1: #make arrays 2D r = r[np.newaxis].T phi = phi[np.newaxis].T theta = theta[np.newaxis].T phi = phi - np.pi #make range -pi to pi theta = np.pi - theta #flip theta values #from matplotlib import pyplot as plt #from mpl_toolkits.mplot3d import Axes3D #fig = plt.figure() #ax = fig.add_subplot(111, projection='3d') #ax.scatter(uvw[:,0], uvw[:,1], uvw[:,2], c=r, alpha=0.5, edgecolors='none') #plt.show() #exit() #r = np.sqrt(uvw[:,0]**2. + uvw[:,1]**2. + uvw[:,2]**2.)[np.newaxis].T #phi = np.arctan2(uvw[:,1], uvw[:,0])[np.newaxis].T #theta = (np.pi/2.) - np.arctan2(uvw[:,2], np.sqrt(uvw[:,0]**2. + uvw[:,1]**2.))[np.newaxis].T #make range -pi/2 to pi/2 #compute the SWHT visibility coefficients vislm = computeVislm(lmax, k, r, theta, phi, vis, lmin=lmin) #compute the SWHT brightness coefficients blm = computeblm(vislm) print 'Run time: %f s' % (time.time() - start_time) return blm
def iswhtVisibilities(blm, uvw, freqs): """Generate visibilities by inverse transforming brightness coefficients with the iSWHT blm: [LMAX+1, 2*LMAX + 1] array, brightness coefficients uvw: float array [Q, 3, F], meters, has a F frequency axis because of the time steps in LOFAR station obsevrations changes uvw with respect to the frequency freqs: float array [F, 1] or [F], observing frequencies in Hz """ start_time = time.time() #Convert brightness coefficients into visibility coefficients vislm = computeblm(blm, reverse=True) #single subband cases if uvw.ndim==2: uvw = uvw.reshape(uvw.shape[0], uvw.shape[1], 1) if freqs.ndim==1: freqs = freqs[np.newaxis].T k = 2. * np.pi * freqs/cc #obs freq/c #from matplotlib import pyplot as plt #from mpl_toolkits.mplot3d import Axes3D #fig = plt.figure() #ax = fig.add_subplot(111, projection='3d') #ax.scatter(uvw[:,0], uvw[:,1], uvw[:,2]) #plt.show() #exit() #convert u,v,w to r,phi,theta r, phi, theta = util.cart2sph(uvw[:,0], uvw[:,1], uvw[:,2]) if r.ndim==1: #make arrays 2D r = r[np.newaxis].T phi = phi[np.newaxis].T theta = theta[np.newaxis].T phi = phi - np.pi #make range -pi to pi theta = np.pi - theta #flip theta values #compute visibilities vis = computeVisSamples(vislm, k, r, theta, phi) print 'Run time: %f s'%(time.time() - start_time) return vis
def iswhtVisibilities(blm, uvw, freqs): """Generate visibilities by inverse transforming brightness coefficients with the iSWHT blm: [LMAX+1, 2*LMAX + 1] array, brightness coefficients uvw: float array [Q, 3, F], meters, has a F frequency axis because of the time steps in LOFAR station obsevrations changes uvw with respect to the frequency freqs: float array [F, 1] or [F], observing frequencies in Hz """ start_time = time.time() #Convert brightness coefficients into visibility coefficients vislm = computeblm(blm, reverse=True) #single subband cases if uvw.ndim == 2: uvw = uvw.reshape(uvw.shape[0], uvw.shape[1], 1) if freqs.ndim == 1: freqs = freqs[np.newaxis].T k = 2. * np.pi * freqs / cc #obs freq/c #from matplotlib import pyplot as plt #from mpl_toolkits.mplot3d import Axes3D #fig = plt.figure() #ax = fig.add_subplot(111, projection='3d') #ax.scatter(uvw[:,0], uvw[:,1], uvw[:,2]) #plt.show() #exit() #convert u,v,w to r,phi,theta r, phi, theta = util.cart2sph(uvw[:, 0], uvw[:, 1], uvw[:, 2]) if r.ndim == 1: #make arrays 2D r = r[np.newaxis].T phi = phi[np.newaxis].T theta = theta[np.newaxis].T phi = phi - np.pi #make range -pi to pi theta = np.pi - theta #flip theta values #compute visibilities vis = computeVisSamples(vislm, k, r, theta, phi) print 'Run time: %f s' % (time.time() - start_time) return vis
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)