def jones2celestial_basis(jones, z0_cza=None): if z0_cza is None: z0_cza = np.radians(120.7215) npix = jones.shape[0] nside = hp.npix2nside(npix) hpxidx = np.arange(npix) cza, ra = hp.pix2ang(nside, hpxidx) z0 = irf.r_hat_cart(z0_cza, 0.) RotAxis = np.cross(z0, np.array([0, 0, 1.])) RotAxis /= np.sqrt(np.dot(RotAxis, RotAxis)) RotAngle = np.arccos(np.dot(z0, [0, 0, 1.])) R_z0 = irf.rotation_matrix(RotAxis, RotAngle) ### New jones_b = transform_basis(nside, jones, z0_cza, R_z0.T) rot = [0., -z0_cza, 0.] jones_out = irf.unitary_rotate_jones(jones_b, rot, multiway=True) return jones_out
def horizon_mask(jones, z0_cza): npix = jones.shape[0] nside = hp.npix2nside(npix) hpxidx = np.arange(npix) cza, ra = hp.pix2ang(nside, hpxidx) if z0_cza == 0.: tb, pb = cza, ra else: z0 = irf.r_hat_cart(z0_cza, 0.) RotAxis = np.cross(z0, np.array([0,0,1.])) RotAxis /= np.sqrt(np.dot(RotAxis,RotAxis)) RotAngle = np.arccos(np.dot(z0, [0,0,1.])) R_z0 = irf.rotation_matrix(RotAxis, RotAngle) tb, pb = irf.rotate_sphr_coords(R_z0, cza, ra) hm = np.zeros((npix,2,2)) hm[np.where(tb < np.pi/2.)] = 1. return hm
def jones2celestial_basis(jones, z0_cza=None): if z0_cza is None: z0_cza = np.radians(120.7215) npix = jones.shape[0] nside = hp.npix2nside(npix) hpxidx = np.arange(npix) cza, ra = hp.pix2ang(nside, hpxidx) z0 = irf.r_hat_cart(z0_cza, 0.) RotAxis = np.cross(z0, np.array([0,0,1.])) RotAxis /= np.sqrt(np.dot(RotAxis,RotAxis)) RotAngle = np.arccos(np.dot(z0, [0,0,1.])) R_z0 = irf.rotation_matrix(RotAxis, RotAngle) jones_b = transform_basis(nside, jones, z0_cza, R_z0.T) rot = [0., -z0_cza, 0.] jones_out = irf.unitary_rotate_jones(jones_b, rot, multiway=True) return jones_out
def horizon_mask(jones, z0_cza): npix = jones.shape[0] nside = hp.npix2nside(npix) hpxidx = np.arange(npix) cza, ra = hp.pix2ang(nside, hpxidx) if z0_cza == 0.: tb, pb = cza, ra else: z0 = irf.r_hat_cart(z0_cza, 0.) RotAxis = np.cross(z0, np.array([0, 0, 1.])) RotAxis /= np.sqrt(np.dot(RotAxis, RotAxis)) RotAngle = np.arccos(np.dot(z0, [0, 0, 1.])) R_z0 = irf.rotation_matrix(RotAxis, RotAngle) tb, pb = irf.rotate_sphr_coords(R_z0, cza, ra) hm = np.zeros((npix, 2, 2)) hm[np.where(tb < np.pi / 2.)] = 1. return hm
def instrument_setup(z0_cza, freqs): """ This is the CST simulation using the efield basis of z' = -x, y' = -y, x' = -z frequencies are every 10MHz, from 100-200 Each file contains 8 columns which are ordered as: (Re(xt),Re(xp),Re(yt),Re(yp),Im(xt),Im(xp),Im(yt),Im(yp)). Each column is a healpix map with resolution nside = 2**8 """ nu0 = str(int(p.nu_axis[0] / 1e6)) nuf = str(int(p.nu_axis[-1] / 1e6)) band_str = nu0 + "-" + nuf # restore_name = p.interp_type + "_" + "band_" + band_str + "mhz_nfreq" + str(p.nfreq)+ "_nside" + str(p.nside) + ".npy" # # if os.path.exists('jones_save/' + restore_name) == True: # return np.load('jones_save/' + restore_name) # local_jones0_file = 'local_jones0/nside' + str( p.nside) + '_band' + band_str + '_Jdata.npy' if os.path.exists(local_jones0_file) == True: return np.load(local_jones0_file) fbase = '/data4/paper/zionos/HERA_jones_data/HERA_Jones_healpix_' # fbase = '/home/zmart/radcos/polskysim/IonRIME/HERA_jones_data/HERA_Jones_healpix_' nside_in = 2**8 fnames = [fbase + str(int(f / 1e6)) + 'MHz.txt' for f in freqs] nfreq_nodes = len(freqs) npix = hp.nside2npix(nside_in) hpxidx = np.arange(npix) cza, ra = hp.pix2ang(nside_in, hpxidx) z0 = irf.r_hat_cart(z0_cza, 0.) RotAxis = np.cross(z0, np.array([0, 0, 1.])) RotAxis /= np.sqrt(np.dot(RotAxis, RotAxis)) RotAngle = np.arccos(np.dot(z0, [0, 0, 1.])) R_z0 = irf.rotation_matrix(RotAxis, RotAngle) t0, p0 = irf.rotate_sphr_coords(R_z0, cza, ra) hm = np.zeros(npix) hm[np.where(cza < (np.pi / 2. + np.pi / 20.) )] = 1 # Horizon mask; is 0 below the local horizon. # added some padding. Idea being to allow for some interpolation near the horizon. Questionable. npix_out = hp.nside2npix(p.nside) Jdata = np.zeros((nfreq_nodes, npix_out, 2, 2), dtype='complex128') for i, f in enumerate(fnames): J_f = np.loadtxt(f) # J_f.shape = (npix_in, 8) J_f = J_f * np.tile(hm, 8).reshape(8, npix).transpose( 1, 0) # Apply horizon mask # Could future "rotation" of these zeroed-maps have small errors at the # edges of the horizon? due to the way healpy interpolates. # Unlikely to be important. # Comment update: Yep, it turns out this happens, BUT it is approximately # power-preserving. The pixels at the edges of the rotated mask are not # identically 1, but the sum over the mask is maintained to about a part # in 1e-5 # Perform a scalar rotation of each component so that the instrument's boresight # is pointed toward (z0_cza, 0), the location of the instrument on the # earth in the Current-Epoch-RA/Dec coordinate frame. J_f = irf.rotate_jones(J_f, R_z0, multiway=False) if p.nside != nside_in: # Change the map resolution as needed. #d = lambda m: hp.ud_grade(m, nside=p.nside, power=-2.) # I think these two ended up being (roughly) the same? # The apparent normalization problem was really becuase of an freq. interpolation problem. # irf.harmonic_ud_grade is probably better for increasing resolution, but hp.ud_grade is # faster because it's just averaging/tiling instead of doing SHT's d = lambda m: irf.harmonic_ud_grade(m, nside_in, p.nside) J_f = (np.asarray(map(d, J_f.T))).T # The inner transpose is so that correct dimension is map()'ed over, # and then the outer transpose returns the array to its original shape. J_f = irf.inverse_flatten_jones( J_f) # Change shape to (nfreq,npix,2,2), complex-valued J_f = transform_basis( p.nside, J_f, z0_cza, R_z0 ) # right-multiply by the basis transformation matrix from RA/CZA to the Local CST basis. # Note that CZA = pi/2 - Dec! So this is not quite the RA/Dec basis. But the difference # in the Stoke parameters between the two is only U -> -U Jdata[i, :, :, :] = J_f print i # If the model at the current nside hasn't been generated before, save it for future reuse. if os.path.exists(local_jones0_file) == False: np.save(local_jones0_file, Jdata) return Jdata
def instrument_setup(z0_cza, freqs): """ This is the CST simulation using the efield basis of z' = -x, y' = -y, x' = -z frequencies are every 10MHz, from 100-200 Each file contains 8 columns which are ordered as: (Re(xt),Re(xp),Re(yt),Re(yp),Im(xt),Im(xp),Im(yt),Im(yp)). Each column is a healpix map with resolution nside = 2**8 """ nu0 = str(int(p.nu_axis[0] / 1e6)) nuf = str(int(p.nu_axis[-1] / 1e6)) band_str = nu0 + "-" + nuf # restore_name = p.interp_type + "_" + "band_" + band_str + "mhz_nfreq" + str(p.nfreq)+ "_nside" + str(p.nside) + ".npy" # # if os.path.exists('jones_save/' + restore_name) == True: # return np.load('jones_save/' + restore_name) # local_jones0_file = 'local_jones0/nside' + str(p.nside) + '_band' + band_str + '_Jdata.npy' if os.path.exists(local_jones0_file) == True: return np.load(local_jones0_file) fbase = '/data4/paper/zionos/HERA_jones_data/HERA_Jones_healpix_' # fbase = '/home/zmart/radcos/polskysim/IonRIME/HERA_jones_data/HERA_Jones_healpix_' nside_in = 2**8 fnames = [fbase + str(int(f / 1e6)) + 'MHz.txt' for f in freqs] nfreq_nodes = len(freqs) npix = hp.nside2npix(nside_in) hpxidx = np.arange(npix) cza, ra = hp.pix2ang(nside_in, hpxidx) z0 = irf.r_hat_cart(z0_cza, 0.) RotAxis = np.cross(z0, np.array([0,0,1.])) RotAxis /= np.sqrt(np.dot(RotAxis,RotAxis)) RotAngle = np.arccos(np.dot(z0, [0,0,1.])) R_z0 = irf.rotation_matrix(RotAxis, RotAngle) t0, p0 = irf.rotate_sphr_coords(R_z0, cza, ra) hm = np.zeros(npix) hm[np.where(cza < (np.pi / 2. + np.pi / 20.))] = 1 # Horizon mask; is 0 below the local horizon. # added some padding. Idea being to allow for some interpolation near the horizon. Questionable. npix_out = hp.nside2npix(p.nside) Jdata = np.zeros((nfreq_nodes,npix_out,2,2),dtype='complex128') for i,f in enumerate(fnames): J_f = np.loadtxt(f) # J_f.shape = (npix_in, 8) J_f = J_f * np.tile(hm, 8).reshape(8, npix).transpose(1,0) # Apply horizon mask # Could future "rotation" of these zeroed-maps have small errors at the # edges of the horizon? due to the way healpy interpolates. # Unlikely to be important. # Comment update: Yep, it turns out this happens, BUT it is approximately # power-preserving. The pixels at the edges of the rotated mask are not # identically 1, but the sum over the mask is maintained to about a part # in 1e-5 # Perform a scalar rotation of each component so that the instrument's boresight # is pointed toward (z0_cza, 0), the location of the instrument on the # earth in the Current-Epoch-RA/Dec coordinate frame. J_f = irf.rotate_jones(J_f, R_z0, multiway=False) if p.nside != nside_in: # Change the map resolution as needed. #d = lambda m: hp.ud_grade(m, nside=p.nside, power=-2.) # I think these two ended up being (roughly) the same? # The apparent normalization problem was really becuase of an freq. interpolation problem. # irf.harmonic_ud_grade is probably better for increasing resolution, but hp.ud_grade is # faster because it's just averaging/tiling instead of doing SHT's d = lambda m: irf.harmonic_ud_grade(m, nside_in, p.nside) J_f = (np.asarray(map(d, J_f.T))).T # The inner transpose is so that correct dimension is map()'ed over, # and then the outer transpose returns the array to its original shape. J_f = irf.inverse_flatten_jones(J_f) # Change shape to (nfreq,npix,2,2), complex-valued J_f = transform_basis(p.nside, J_f, z0_cza, R_z0) # right-multiply by the basis transformation matrix from RA/CZA to the Local CST basis. # Note that CZA = pi/2 - Dec! So this is not quite the RA/Dec basis. But the difference # in the Stoke parameters between the two is only U -> -U Jdata[i,:,:,:] = J_f print i # If the model at the current nside hasn't been generated before, save it for future reuse. if os.path.exists(local_jones0_file) == False: np.save(local_jones0_file, Jdata) return Jdata
def jones2celestial_basis(jones, z0_cza=None): if z0_cza is None: z0_cza = np.radians(120.7215) npix = jones.shape[0] nside = hp.npix2nside(npix) hpxidx = np.arange(npix) cza, ra = hp.pix2ang(nside, hpxidx) z0 = irf.r_hat_cart(z0_cza, 0.) RotAxis = np.cross(z0, np.array([0,0,1.])) RotAxis /= np.sqrt(np.dot(RotAxis,RotAxis)) RotAngle = np.arccos(np.dot(z0, [0,0,1.])) R_z0 = irf.rotation_matrix(RotAxis, RotAngle) R_jones = irf.rotate_jones(jones, R_z0, multiway=True) # beams are now pointed at -31 deg latitude jones_out = np.zeros((npix, 2,2), dtype=np.complex128) ######## ## This next bit is a routine to patch the topological hole by grabbing pixel ## data from a neighborhood of the corrupted pixels. ## It uses the crucial assumption that in the ra/cza basis the dipoles ## are orthogonal at zenith. This means that for the diagonal components, ## the zenith pixels should be a local maximum, while for the off-diagonal ## components the zenith pixels should be a local minimum (in absolute value). ## Using this assumption, we can cover the corrupted pixel(s) in the ## zenith neighborhood by the maximum pixel of the neighborhood ## for the diagonal, and the minimum of the neighborhood for the off-diagonal. ## As long as the function is relatively flat in this neighborhood, this should ## be a good fix jones_b = transform_basis(nside, R_jones, z0_cza, R_z0) cf = [np.real,np.imag] u = [1.,1.j] z0pix = hp.vec2pix(nside, z0[0],z0[1],z0[2]) if nside < 128: z0_nhbrs = hp.get_all_neighbours(nside, z0_cza, phi=0.) else: z0_nhbrs = neighbors_of_neighbors(nside, z0_cza, phi=0.) jones_c = np.zeros((npix,2,2,2), dtype=np.float64) for k in range(2): jones_c[:,:,:,k] = cf[k](jones_b) for i in range(2): for j in range(2): for k in range(2): z0_nbhd = jones_c[z0_nhbrs,i,j,k] if i == j: fill_val_pix = np.argmax(abs(z0_nbhd)) fill_val = z0_nbhd[fill_val_pix] else: fill_val_pix = np.argmin(abs(z0_nbhd)) fill_val = z0_nbhd[fill_val_pix] jones_c[z0_nhbrs,i,j,k] = fill_val jones_c[z0pix,i,j,k] = fill_val jones_out = jones_c[:,:,:,0] + 1j*jones_c[:,:,:,1] return jones_out