def qe_m4(px,mlmax,Talm=None,fTalm=None): """ px is a pixelization object, initialized like this: px = pixelization(shape=shape,wcs=wcs) # for CAR px = pixelization(nside=nside) # for healpix output: curved sky multipole=4 estimator """ ells = np.arange(mlmax) #prepare temperature map rmapT=px.alm2map(np.stack((Talm,Talm)),spin=0,ncomp=1,mlmax=mlmax)[0] #find tbarf t_alm=cs.almxfl(fTalm,np.sqrt((ells-3.)*(ells-2.)*(ells-1.)*ells*(ells+1.)*(ells+2.)*(ells+3.)*(ells+4.))) alms=np.stack((t_alm,t_alm)) rmap=px.alm2map_spin(alms,0,4,ncomp=2,mlmax=mlmax) #multiply the two fields together rmap=np.nan_to_num(rmap) prodmap=rmap*rmapT prodmap=np.nan_to_num(prodmap) if not(px.hpix): prodmap=enmap.enmap(prodmap,px.wcs) realsp2=prodmap[0] #spin +4 real space real space field if not(px.hpix): realsp2 = enmap.enmap(realsp2,px.wcs) #convert the above spin4 fields to spin pm 4 alms res1 = px.map2alm_spin(realsp2,mlmax,4,4) #will return pm4 #spin 4 ylm ttalmsp2=rot2dalm(res1,4)[0] #pick up the spin 4 alm of the first one ttalmsm2=rot2dalm(res1,4)[1] #pick up the spin -4 alm of the second one m4_alm=ttalmsp2+ttalmsm2 return m4_alm
def qe_shear(px,mlmax,Talm=None,fTalm=None): """ px is a pixelization object, initialized like this: px = pixelization(shape=shape,wcs=wcs) # for CAR px = pixelization(nside=nside) # for healpix output: curved sky shear estimator """ ells = np.arange(mlmax) #prepare temperature map rmapT=px.alm2map(np.stack((Talm,Talm)),spin=0,ncomp=1,mlmax=mlmax)[0] #find tbarf t_alm=cs.almxfl(fTalm,np.sqrt((ells-1.)*ells*(ells+1.)*(ells+2.))) alms=np.stack((t_alm,t_alm)) rmap=px.alm2map_spin(alms,0,2,ncomp=2,mlmax=mlmax) #same as 2 2 #multiply the two fields together prodmap=rmap*rmapT if not(px.hpix): prodmap=enmap.enmap(prodmap,px.wcs) realsp2=prodmap[0] #spin +2 real space real space field realsm2=prodmap[1] #spin -2 real space real space field if not(px.hpix): realsp2 = enmap.enmap(realsp2,px.wcs) realsm2=enmap.enmap(realsm2,px.wcs) #convert the above spin2 fields to spin pm 2 alms res1 = px.map2alm_spin(realsp2,mlmax,2,2) #will return pm2 res2= px.map2alm_spin(realsm2,mlmax,-2,2) #will return pm2 #spin 2 ylm ttalmsp2=rot2dalm(res1,2)[0] #pick up the spin 2 alm of the first one ttalmsm2=rot2dalm(res1,2)[1] #pick up the spin -2 alm of the second one shear_alm=ttalmsp2+ttalmsm2 return shear_alm
def filter_alms(alms,filt,lmin=None,lmax=None): """ Filter the alms with transfer function specified by filt (indexed starting at ell=0). """ mlmax = get_mlmax(alms) ls = np.arange(filt.size) if lmax is not None: assert lmax<=ls.max() assert lmax<=mlmax if lmin is not None: filt[ls<lmin] = 0 if lmax is not None: filt[ls>lmax] = 0 return cs.almxfl(alms.copy(),filt)
def qe_source(px,mlmax,fTalm,profile=None,xfTalm=None): """generalised source estimator Args: px (object): pixelization object mlmax (int): maximum ell to perform alm2map transforms profile (narray): profile of reconstructed source in ell space. If none is provided, defaults to point source hardening fTalm (narray): inverse filtered temperature map xfTalm (narray, optional): inverse filtered temperature map. Defaults to None Returns: narray: profile reconstruction """ if profile is not None: #filter the first map with the source profile fTalm = cs.almxfl(fTalm, profile) #If we don't provide a second map, #copy the first (which is already filtered) if xfTalm is None: xfTalm = fTalm.copy() else: #otherwise, we still need to filter #the second map if profile is not None: xfTalm = cs.almxfl(xfTalm, profile) rmap1 = px.alm2map(fTalm,spin=0,ncomp=1,mlmax=mlmax)[0] rmap2 = px.alm2map(xfTalm,spin=0,ncomp=1,mlmax=mlmax)[0] #multiply the two fields together prodmap=rmap1*rmap2 if not(px.hpix): prodmap=enmap.enmap(prodmap,px.wcs) #spin +0 real space field res=px.map2alm_spin(prodmap,mlmax,0,0) #spin 0 salm salm=0.5*res[0] if profile is not None: salm=cs.almxfl(salm,1./profile) return salm
def test_almxfl(self): import healpy as hp for lmax in [100, 400, 500, 1000]: ainfo = sharp.alm_info(lmax) alms = hp.synalm(np.ones(lmax + 1), lmax=lmax) filtering = np.ones(lmax + 1) alms0 = ainfo.lmul(alms.copy(), filtering) assert np.all(np.isclose(alms0, alms)) for lmax in [100, 400, 500, 1000]: ainfo = sharp.alm_info(lmax) alms = hp.synalm(np.ones(lmax + 1), lmax=lmax) alms0 = curvedsky.almxfl(alms.copy(), lambda x: np.ones(x.shape)) assert np.all(np.isclose(alms0, alms))
for ar_id, ar in enumerate(arrays): win_T = so_map.read_map(d["window_T_%s_%s" % (sv, ar)]) win_pol = so_map.read_map(d["window_pol_%s_%s" % (sv, ar)]) window_tuple = (win_T, win_pol) del win_T, win_pol # we add fg alms to cmb alms in temperature alms_beamed = alms.copy() alms_beamed[0] += fglms[id_freq[d["nu_eff_%s_%s" % (sv, ar)]]] # we convolve signal + foreground with the beam of the array l, bl = pspy_utils.read_beam_file(d["beam_%s_%s" % (sv, ar)]) alms_beamed = curvedsky.almxfl(alms_beamed, bl) if scenario == "noE": alms_beamed[1] *= 0 if scenario == "noB": alms_beamed[2] *= 0 # generate our signal only sim split = sph_tools.alm2map(alms_beamed, template[sv]) # compute the alms of the sim master_alms[sv, ar, "nofilter"] = sph_tools.get_alms( split, window_tuple, niter, lmax, dtype=sim_alm_dtype) # apply the k-space filter binary = so_map.read_map("%s/binary_%s_%s.fits" %
def almxfl(alm,fl): alm = np.asarray(alm) ncomp = alm.shape[0] assert ncomp in [1,2,3] res = cs.almxfl(alm,fl) return res