Exemple #1
0
    def test_plain_wcs(self):
        # Test area and box for a small Cartesian geometry
        shape,wcs = enmap.geometry(res=np.deg2rad(1./60.),shape=(600,600),pos=(0,0),proj='plain')
        box = np.rad2deg(enmap.box(shape,wcs))
        area = np.rad2deg(np.rad2deg(enmap.area(shape,wcs)))
        assert np.all(np.isclose(box,np.array([[-5,-5],[5,5]])))
        assert np.isclose(area,100.)

        # and for an artifical Cartesian geometry with area>4pi
        shape,wcs = enmap.geometry(res=np.deg2rad(10),shape=(100,100),pos=(0,0),proj='plain')
        box = np.rad2deg(enmap.box(shape,wcs))
        area = np.rad2deg(np.rad2deg(enmap.area(shape,wcs)))
        assert np.all(np.isclose(box,np.array([[-500,-500],[500,500]])))
        assert np.isclose(area,1000000)
Exemple #2
0
    def test_area(self):
        """Test that map area is computed accurately."""
        test_patches = []
        # Small CAR patch
        DELT = 0.01
        patch = Patch.centered_at(-52., -38., 12. + DELT, 12.0 + DELT)
        shape, w = enmap.geometry(pos=patch.pos(),
                                  res=DELT*DEG,
                                  proj='car',
                                  ref=(0, 0))
        exact_area = (np.dot(patch.ra_range*DEG, [-1,1]) *
                      np.dot(np.sin(patch.dec_range*DEG), [1,-1]))

        test_patches.append((shape, w, exact_area))
        # Full sky CAR patch
        shape, w = enmap.fullsky_geometry(res=0.01*DEG, proj='car')
        exact_area = 4*np.pi
        test_patches.append((shape, w, exact_area))
        # Small ZEA patch at pole
        shape, w = enmap.geometry(pos=[90*DEG,0], res=DELT*DEG, proj='zea', shape=[100,100])
        exact_area = 1*DEG**2
        test_patches.append((shape, w, exact_area))

        for shape, w, exact_area in test_patches:
            ratio = enmap.area(shape, w)/exact_area
            print(ratio)
            assert(abs(ratio-1) < 1e-6)
Exemple #3
0
def wfactor(n, mask, sht=True, pmap=None, equal_area=False):
    """
    Approximate correction to an n-point function for the loss of power
    due to the application of a mask.

    For an n-point function using SHTs, this is the ratio of 
    area weighted by the nth power of the mask to the full sky area 4 pi.
    This simplifies to mean(mask**n) for equal area pixelizations like
    healpix. For SHTs on CAR, it is sum(mask**n * pixel_area_map) / 4pi.
    When using FFTs, it is the area weighted by the nth power normalized
    to the area of the map. This also simplifies to mean(mask**n)
    for equal area pixels. For CAR, it is sum(mask**n * pixel_area_map) 
    / sum(pixel_area_map).

    If not, it does an expensive calculation of the map of pixel areas. If this has
    been pre-calculated, it can be provided as the pmap argument.
    
    """
    assert mask.ndim == 1 or mask.ndim == 2
    if pmap is None:
        if equal_area:
            npix = mask.size
            pmap = 4 * np.pi / npix if sht else enmap.area(
                mask.shape, mask.wcs) / npix
        else:
            pmap = enmap.pixsizemap(mask.shape, mask.wcs)
    return np.sum((mask**n) * pmap) / np.pi / 4. if sht else np.sum(
        (mask**n) * pmap) / np.sum(pmap)
Exemple #4
0
 def test_fullsky_geometry(self):
     # Tests whether number of pixels and area of a full-sky 0.5 arcminute resolution map are correct
     print("Testing full sky geometry...")
     test_res_arcmin = 0.5
     shape,wcs = enmap.fullsky_geometry(res=np.deg2rad(test_res_arcmin/60.),proj='car')
     assert shape[0]==21601 and shape[1]==43200
     assert abs(enmap.area(shape,wcs) - 4*np.pi) < 1e-6
Exemple #5
0
 def _counts(self):
     cts = self.counts.copy()
     cts[self.mask < 0.9] = np.nan
     self.ngals = np.nansum(cts)
     self.nmean = np.nanmean(cts)
     if self.curved:
         area_sqdeg = 4. * np.pi * (180. / np.pi)**2.
     else:
         area_sqdeg = enmap.area(self.shape, self.wcs) * (180. / np.pi)**2.
     self.frac = self.mask.sum() * 1. / self.mask.size
     self.area_sqdeg = self.frac * area_sqdeg
     self.ngal_per_arcminsq = self.ngals / (self.area_sqdeg * 60. * 60.)
Exemple #6
0
def fcov_to_rcorr(shape,wcs,p2d,N):
    """Convert a 2D PS into a pix-pix covariance
    """
    ncomp = p2d.shape[0]
    p2d *= np.prod(shape[-2:])/enmap.area(shape,wcs)
    ocorr = enmap.zeros((ncomp,ncomp,N*N,N*N),wcs)
    for i in range(ncomp):
        for j in range(i,ncomp):
            dcorr = ps2d_to_mat(p2d[i,j].copy(), N).reshape((N*N,N*N))
            ocorr[i,j] = dcorr.copy()
            if i!=j: ocorr[j,i] = dcorr.copy()
    return ocorr
Exemple #7
0
def test_fullsky_geometry():
    # Tests whether number of pixels and area of a full-sky 0.5 arcminute resolution map are correct
    test_res_arcmin = 0.5
    shape,wcs = enmap.fullsky_geometry(res=np.deg2rad(test_res_arcmin/60.),proj='car')
    assert shape[0]==21601 and shape[1]==43200
    assert 50000 < (enmap.area(shape,wcs)*(180./np.pi)**2.) < 51000
Exemple #8
0
    def get_poisson_srcs_alms(self, set_idx, sim_num, patch, alm_shape, oshape,
                              owcs):
        def deltaTOverTcmbToJyPerSr(freqGHz, T0=2.726):
            """
            @brief the function name is self-eplanatory
            @return the converstion factor
            stolen from Flipper -- van engelen
            """
            kB = 1.380658e-16
            h = 6.6260755e-27
            c = 29979245800.
            nu = freqGHz * 1.e9
            x = h * nu / (kB * T0)
            cNu = 2 * (kB * T0)**3 / (h**2 *
                                      c**2) * x**4 / (4 * (np.sinh(x / 2.))**2)
            cNu *= 1e23
            return cNu

        TCMB_uk = 2.72e6

        if oshape[0] > 3:
            #then this is a multichroic array, and sadly we only have this at 150 GHz for now
            raise Exception('get_poisson_srcs_alms only implemented for 150 GHz so far ' \
                            + '(that is the model we currently have for radio sources) ')
        else:
            freq_ghz = 148

        #ideally this RNG stuff would be defined in a central place to
        #avoid RNG collisions.  Old version is currently commented out at top of
        #simgen.py
        templ = self.get_template(patch, shape=oshape, wcs=owcs)

        templ[:] = 0
        seed = seedgen.get_poisson_seed(set_idx, sim_num)
        np.random.seed(seed=seed)

        #Wasn't sure how to codify this stuff outside this routine - hardcoded for now
        S_min_Jy = .001
        S_max_Jy = .015

        tucci = np.loadtxt(
            os.path.join(os.path.dirname(os.path.abspath(__file__)),
                         '../data/ns_148GHz_modC2Ex.dat'))

        S = tucci[:, 0]
        dS = S[1:] - S[0:-1]
        dS = np.append(dS, [0.])
        dNdS = tucci[:, 1]

        mean_numbers_per_patch = dNdS * enmap.area(templ.shape, templ.wcs) * dS

        numbers_per_fluxbin = np.random.poisson(mean_numbers_per_patch)

        #note pixel areas not constant for pixell maps
        pixel_areas = enmap.pixsizemap(templ.shape, templ.wcs)

        for si, fluxval in enumerate(S[S <= S_max_Jy]):
            xlocs = np.random.randint(templ.shape[-1],
                                      size=numbers_per_fluxbin[si])
            ylocs = np.random.randint(templ.shape[-2],
                                      size=numbers_per_fluxbin[si])

            #add the value in jy / sr, i.e. divide by the solid angle of a pixel.
            templ[0, ylocs, xlocs] += fluxval / pixel_areas[ylocs, xlocs]

        map_factor = TCMB_uk / deltaTOverTcmbToJyPerSr(freq_ghz)
        templ *= map_factor

        #GET ALMs
        output = curvedsky.map2alm(templ[0], lmax=hp.Alm.getlmax(alm_shape[0]))

        return output
Exemple #9
0
def get_covariance(window,
                   lmax,
                   spec_name_list,
                   ps_dict,
                   binning_file,
                   error_method="master",
                   spectra=None,
                   l_thres=None,
                   l_toep=None,
                   mbb_inv=None,
                   compute_T_only=False):
    """Compute the covariance matrix of the power spectrum in the patch

    Parameters
    ----------

    window: so_map
      the window function of the patch
    lmax: integer
      the maximum multipole to consider for the spectra computation
    spec_name_list:  list
      the list of  power spectra
      For example : [split0xsplit0,split0xsplit1,split1xsplit1]
      note that for computing the error on PS(split0xsplit1) we need PS(split0xsplit0), PS(split0xsplit1), PS(split1xsplit1)
    ps_dict: dict
      a dict containing all power spectra
    binning_file: text file
      a binning file with three columns bin low, bin high, bin mean
      note that either binning_file or bin_size should be provided
    error_method: string
      the method for the computation of error
      can be "master" or "knox" for now
   approx_coupling: dict
   mbb_inv: 2d array
     the inverse mode coupling matrix, not in use for 2dflat
   compute_T_only: boolean
     True to compute only T spectra

    """

    bin_lo, bin_hi, bin_c, bin_size = pspy_utils.read_binning_file(
        binning_file, lmax)
    n_bins = len(bin_hi)

    fsky = enmap.area(window.data.shape, window.data.wcs) / 4. / np.pi
    fsky *= np.mean(window.data)

    cov_dict = {}

    if error_method == "Knox":
        for name in spec_name_list:
            m1, m2 = name.split("x")
            cov_dict[name] = {}
            for spec in spectra:
                X, Y = spec
                prefac = 1 / ((2 * bin_c + 1) * fsky * bin_size)
                cov_dict[name][X + Y] = np.diag(
                    prefac *
                    (ps_dict["%sx%s" %
                             (m1, m1)][X + X] * ps_dict["%sx%s" %
                                                        (m2, m2)][Y + Y] +
                     ps_dict["%sx%s" % (m1, m2)][X + Y]**2))

    elif error_method == "master":
        print("compute master error")
        if mbb_inv is None:
            raise ValueError("Missing 'mbb_inv' argument")
        if not compute_T_only:
            mbb_inv = mbb_inv["spin0xspin0"]
        coupling_dict = so_cov.cov_coupling_spin0(window,
                                                  lmax,
                                                  niter=0,
                                                  l_thres=l_thres,
                                                  l_toep=l_toep)
        coupling = so_cov.bin_mat(coupling_dict["TaTcTbTd"], binning_file,
                                  lmax)

        for name in spec_name_list:
            m1, m2 = name.split("x")
            cov_dict[name] = {}
            for spec in spectra:
                X, Y = spec
                cov_dict[name][X + Y] = so_cov.symmetrize(
                    ps_dict["%sx%s" % (m1, m1)][X + X]) * so_cov.symmetrize(
                        ps_dict["%sx%s" % (m2, m2)][Y + Y])
                cov_dict[name][X + Y] += so_cov.symmetrize(
                    ps_dict["%sx%s" % (m1, m2)][X + Y]**2)
                cov_dict[name][X + Y] *= coupling
                cov_dict[name][X + Y] = np.dot(
                    np.dot(mbb_inv, cov_dict[name][X + Y]), mbb_inv.T)

    else:
        cov_dict = None

    return cov_dict
Exemple #10
0
def compute_mode_coupling(window,
                          type,
                          lmax,
                          binning_file,
                          ps_method="master",
                          beam=None,
                          lmax_pad=None,
                          l_thres=None,
                          l_toep=None,
                          compute_T_only=False):
    """Compute the mode coupling corresponding the the window function

    Parameters
    ----------

    window: so_map
        the window function of the patch
    type: string
        the type of binning, either bin Cl or bin Dl
    lmax : integer
        the maximum multipole to consider for the spectra computation
    binning_file: text file
      a binning file with three columns bin low, bin high, bin mean
      note that either binning_file or bin_size should be provided
    ps_method: string
        the method for the computation of the power spectrum
        can be "master", "pseudo", or "2dflat" for now
    beam: text file
        file describing the beam of the map, expect bl to be the second column and start at l=0 (standard is : l,bl, ...)
    lmax_pad: integer
        the maximum multipole to consider for the mcm computation (optional)
        lmax_pad should always be greater than lmax
    compute_T_only: boolean
        True to compute only T spectra
    """

    bin_lo, bin_hi, bin_c, bin_size = pspy_utils.read_binning_file(
        binning_file, lmax)
    n_bins = len(bin_hi)

    fsky = enmap.area(window.data.shape, window.data.wcs) / 4. / np.pi
    fsky *= np.mean(window.data)

    if beam is not None:
        beam_data = np.loadtxt(beam)
        if compute_T_only:
            beam = beam_data[:, 1]
        else:
            beam = (beam_data[:, 1], beam_data[:, 1])

    if compute_T_only:
        if ps_method == "master":
            mbb_inv, Bbl = so_mcm.mcm_and_bbl_spin0(window,
                                                    binning_file,
                                                    bl1=beam,
                                                    lmax=lmax,
                                                    type=type,
                                                    niter=0,
                                                    lmax_pad=lmax_pad,
                                                    l_thres=l_thres,
                                                    l_toep=l_toep)

        elif ps_method == "pseudo":
            mbb_inv = np.identity(n_bins)
            mbb_inv *= 1 / fsky
    else:
        window = (window, window)
        if ps_method == "master":
            print("compute master MCM")
            mbb_inv, Bbl = so_mcm.mcm_and_bbl_spin0and2(window,
                                                        binning_file,
                                                        bl1=beam,
                                                        lmax=lmax,
                                                        type=type,
                                                        niter=0,
                                                        lmax_pad=lmax_pad,
                                                        l_thres=l_thres,
                                                        l_toep=l_toep)

        elif ps_method == "pseudo":
            mbb_inv = {}
            spin_list = ["spin0xspin0", "spin0xspin2", "spin2xspin0"]
            for spin in spin_list:
                mbb_inv[spin] = np.identity(n_bins)
                mbb_inv[spin] *= 1 / fsky
            mbb_inv["spin2xspin2"] = np.identity(4 * n_bins)
            mbb_inv["spin2xspin2"] *= 1 / fsky

    if ps_method == "2dflat":
        mbb_inv = None

    return mbb_inv
Exemple #11
0
def getActpolNoiseSim(noiseSeed,
                      psa,
                      noisePsdDir,
                      freqs,
                      verbose=True,
                      useCovSqrt=True,
                      killFactor=30.,
                      fillValue=0.,
                      noiseDiagsOnly=False,
                      splitWanted=None):
    #return array of T, Q, U
    #to-do: these are currently using numpy.FFT and are slow; switch to FFTW if installed.

    #Could also have an alternative version of this using enlib tools.

    if useCovSqrt:
        #in this case it was the CovSqrt's that were saved.  This is based on Mat's code in orphics.
        if verbose:
            print(
                'getActpolNoiseSim(): getting weight maps; assuming I for all')

        iqu = 'I'  #FOR NOW

        # stackOfMaskMaps = [enmap.read_map(noisePsdDir + 'totalWeightMap' \
        #                                                 + iqu + '_' + psa + '_' + freq  + '_fromenlib.fits') \
        #                                  for freq in freqs ]

        if splitWanted is None:

            stackOfMaskMaps = [enmap.read_map(noisePsdDir + 'totalWeightMap'\
                                              + iqu + '_' + psa + '_' + freq  + '_fromenlib.fits') \
                               for freq in freqs ]
        else:
            stackOfMaskMaps = [enmap.read_map(noisePsdDir + 'weightMap_split' + str(splitWanted) \
                                              + iqu + '_' + psa + '_' + freq  + '_fromenlib.fits') \
                               for freq in freqs ]

        thisWcs = stackOfMaskMaps[0].wcs

        maskMaps = enmap.enmap(np.stack(stackOfMaskMaps), thisWcs)

        #first one is for IXI, QxQ, UXU only
        print("loading")
        if False:
            print('loading ' + noisePsdDir +
                  '/bigMatrixNoisePsdsCovSqrtDiags_' + psa + '.fits HACKING')
            covsqrt = enmap.read_fits(noisePsdDir +
                                      '/bigMatrixNoisePsdsCovSqrtDiags_' +
                                      psa + '.fits')
        if False:
            print('loading ' + noisePsdDir + '/bigMatrixNoisePsdsCovSqrt_' +
                  psa + '.fits')
            covsqrt = enmap.read_fits(noisePsdDir +
                                      '/bigMatrixNoisePsdsCovSqrt_' + psa +
                                      '.fits')

        if noiseDiagsOnly:
            print('loading ' + noisePsdDir +
                  '/noisePsds_flattened_covSqrtDiags_' + psa + '.fits')
            covsqrt = enmap.read_fits(noisePsdDir +
                                      '/noisePsds_flattened_covSqrtDiags_' +
                                      psa + '.fits')
        elif True:
            print('loading ' + noisePsdDir + '/noisePsds_flattened_covSqrt_' +
                  psa + '.fits')
            covsqrt = enmap.read_fits(noisePsdDir +
                                      '/noisePsds_flattened_covSqrt_' + psa +
                                      '.fits')
        print("loading done")

        if verbose:
            print('getActpolNoiseSim(): running map_mul to make random phases')

        #get the right normalization
        covsqrt *= np.sqrt(
            np.prod(covsqrt.shape[-2:]) /
            enmap.area(covsqrt.shape[-2:], thisWcs))

        np.random.seed(noiseSeed)
        print("randmap")
        rmap = enmap.rand_gauss_harm(
            (covsqrt.shape[0], covsqrt.shape[-2:][0], covsqrt.shape[-2:][1]),
            thisWcs)
        print("randmap done")
        print("map_mul")
        kmap = enmap.map_mul(covsqrt, rmap)
        print("map_mul done")

        #old way:
        # kmapReshape = kmap.reshape((4, kmap.shape[-2:][0], kmap.shape[-2:][1]))
        # outMaps = enmap.ifft(kmapReshape).real
        # kmap /= sqrt(mask)

        if verbose:
            print('getActpolNoiseSim(): inverse transforming')
            print('you are transforming %d maps' % kmap.shape[0])
        spin = np.repeat([0], kmap.shape[0])
        print("fft")
        outMaps = enmap.harm2map(kmap, iau=False, spin=spin)
        print("fft done")
        #now reshape to have shape [nfreqs, 3, Ny, Nx]
        #The "order = 'F' (row vs. column ordering) is due to the ordering that is done
        #in makeNoisePsds.py for the dichroic arrays,
        #namely I90, Q90, U90, I150, Q150, U150.

        outMaps = outMaps.reshape(len(freqs),
                                  outMaps.shape[0] / len(freqs),
                                  outMaps.shape[-2],
                                  outMaps.shape[-1],
                                  order='F')

        for fi, freq in enumerate(freqs):
            #Note each frequency has its own maskmap, so this loop is important
            thisMaskMap = np.squeeze(maskMaps[fi])
            outMaps[fi, :, :, :] /= np.sqrt(thisMaskMap)

            #Loop over T,Q,U.  Couldn't think of clever way to vectorize this part..
            for z in range(outMaps.shape[-3]):
                outMaps[fi, z][thisMaskMap < thisMaskMap[np.where(np.isfinite(thisMaskMap))].max() / killFactor] \
                    = fillValue

        if verbose:
            print('getActpolNoiseSim(): done ')

        return outMaps

    else:
        raise ValueError('older ways of getting the noise maps are deprecated')
Exemple #12
0
def get_covariance(
    window,
    lmax,
    spec_name_list,
    ps_dict,
    binning_file,
    error_method="master",
    spectra=None,
    l_exact=None,
    l_band=None,
    l_toep=None,
    mbb_inv=None,
    compute_T_only=False,
    transfer_function=None,
):
    """Compute the covariance matrix of the power spectrum in the patch

     Parameters
     ----------

     window: so_map
       the window function of the patch
     lmax: integer
       the maximum multipole to consider for the spectra computation
     spec_name_list:  list
       the list of  power spectra
       For example : [split0xsplit0,split0xsplit1,split1xsplit1]
       note that for computing the error on PS(split0xsplit1) we need PS(split0xsplit0), PS(split0xsplit1), PS(split1xsplit1)
     ps_dict: dict
       a dict containing all power spectra
     binning_file: text file
       a binning file with three columns bin low, bin high, bin mean
       note that either binning_file or bin_size should be provided
     error_method: string
       the method for the computation of error
       can be "master" or "knox" for now
    approx_coupling: dict
    mbb_inv: 2d array
      the inverse mode coupling matrix, not in use for 2dflat
    compute_T_only: boolean
      True to compute only T spectra
    transfer_function: str
      the path to the transfer function
    """
    timer.start("Compute {} error...".format(error_method))

    bin_lo, bin_hi, bin_c, bin_size = pspy_utils.read_binning_file(
        binning_file, lmax)

    fsky = enmap.area(window.data.shape, window.data.wcs) / 4.0 / np.pi
    fsky *= np.mean(window.data)

    cov_dict = {}

    if error_method == "knox":
        for name in spec_name_list:
            m1, m2 = name.split("x")
            cov_dict[name] = {}
            for spec in spectra:
                X, Y = spec
                prefac = 1 / ((2 * bin_c + 1) * fsky * bin_size)
                # fmt: off
                cov_dict[name][X + Y] = np.diag(
                    prefac *
                    (ps_dict["%sx%s" %
                             (m1, m1)][X + X] * ps_dict["%sx%s" %
                                                        (m2, m2)][Y + Y] +
                     ps_dict["%sx%s" % (m1, m2)][X + Y]**2))
                # fmt: on

    elif error_method == "master":

        if not compute_T_only:
            mbb_inv = mbb_inv["spin0xspin0"]

        coupling_dict = so_cov.cov_coupling_spin0(window,
                                                  lmax,
                                                  niter=0,
                                                  l_band=l_band,
                                                  l_toep=l_toep,
                                                  l_exact=l_exact)
        coupling = so_cov.bin_mat(coupling_dict["TaTcTbTd"], binning_file,
                                  lmax)

        for name in spec_name_list:
            m1, m2 = name.split("x")
            cov_dict[name] = {}
            for spec in spectra:
                X, Y = spec
                cov_dict[name][X + Y] = so_cov.symmetrize(
                    ps_dict["%sx%s" % (m1, m1)][X + X]) * so_cov.symmetrize(
                        ps_dict["%sx%s" % (m2, m2)][Y + Y])
                cov_dict[name][X + Y] += so_cov.symmetrize(
                    ps_dict["%sx%s" % (m1, m2)][X + Y]**2)
                cov_dict[name][X + Y] *= coupling
                cov_dict[name][X + Y] = np.dot(
                    np.dot(mbb_inv, cov_dict[name][X + Y]), mbb_inv.T)
                if transfer_function is not None:
                    _, _, tf, _ = np.loadtxt(transfer_function, unpack=True)
                    tf = tf[:len(bin_c)]
                    cov_dict[name][X + Y] /= np.outer(np.sqrt(tf), np.sqrt(tf))

    else:
        cov_dict = None

    timer.stop()
    return cov_dict