Esempio n. 1
0
    def __signal_postprocessing__(self,
                                  patch,
                                  signal_idx,
                                  alm_patch,
                                  save_map,
                                  oshape,
                                  owcs,
                                  apply_window=True):
        signal = self.get_template(patch, shape=oshape, wcs=owcs)
        signal = signal if len(alm_patch.shape) > 1 else signal[0, ...]
        curvedsky.alm2map(alm_patch, signal, spin=[0, 2], verbose=True)

        if apply_window:
            print('apply window')
            axes = [-2, -1]
            for idx in range(signal.shape[0]):
                kmap = pfft.fft(signal[idx], axes=axes)
                wy, wx = enmap.calc_window(kmap.shape)
                wind = wy[:, None]**1 * wx[None, :]**1
                kmap *= wind

                signal[idx] = (pfft.ifft(kmap, axes=axes, normalize=True)).real
                del kmap

        if save_map:
            self.signals[signal_idx] = signal.copy()
            self.manage_cache(self.signals, self.max_cached)
        return signal
Esempio n. 2
0
        maps = d["maps_%s_%s" % (sv, ar)]
        nsplit[sv] = len(maps)

        cal = d["cal_%s_%s" % (sv, ar)]
        print("%s split of survey: %s, array %s" % (nsplit[sv], sv, ar))

        if deconvolve_pixwin:
            # ok so this is a bit overcomplicated because we need to take into account CAR and HEALPIX
            # for CAR the pixel window function deconvolution is done in Fourier space and take into account
            # the anisotropy if the pixwin
            # In HEALPIX it's a simple 1d function in multipole space
            # we also need to take account the case where we have projected Planck into a CAR pixellisation since
            # the native pixel window function of Planck need to be deconvolved
            if win_T.pixel == "CAR":
                wy, wx = enmap.calc_window(win_T.data.shape)
                inv_pixwin_lxly = (wy[:, None] * wx[None, :])**(-1)
                pixwin_l[sv] = np.ones(2 * lmax)
                if sv == "Planck":
                    print("Deconvolve Planck pixel window function")
                    # we include this special case for Planck projected in CAR taking into account the Planck native pixellisation
                    # we should check if the projection doesn't include an extra pixel window
                    inv_pixwin_lxly = None
                    pixwin_l[sv] = hp.pixwin(2048)

            elif win_T.pixel == "HEALPIX":
                pixwin_l[sv] = hp.pixwin(win_T.nside)

        else:
            inv_pixwin_lxly = None
Esempio n. 3
0
def getActpolCmbFgSim(beamfileDict,
                      shape, wcs,
                      iterationNum, cmbDir, freqs, psa,
                      cmbSet = 0, \
                      doBeam = True, applyWindow = True, verbose = True, cmbMaptype = 'LensedCMB',
                      foregroundSeed = 0, simType = 'cmb', foregroundPowerFile = None, applyModulation = True):

    nTQUs = len('TQU')
    firstTime = True

    output = enmap.empty((
        len(freqs),
        nTQUs,
    ) + shape[-2:], wcs)

    if simType == 'cmb':

        filename = cmbDir + "/fullsky%s_alm_set%02d_%05d.fits" % (
            cmbMaptype, cmbSet, iterationNum)
        if verbose:
            print('getActpolCmbFgSim(): loading CMB a_lms from %s' % filename)
        import healpy
        almTebFullskyOnecopy = np.complex128(
            healpy.fitsfunc.read_alm(filename, hdu=(1, 2, 3)))

        #Now tile the same for all the frequencies requested (i.e. CMB is same at all frequencies).
        #The beam convolution happens below.
        almTebFullsky = np.tile(almTebFullskyOnecopy, (len(freqs), 1, 1))

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

    elif simType == 'foregrounds':
        outputFreqs = ['f090', 'f150']

        foregroundPowers \
            = powspec.read_spectrum(os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                                 '../data/',
                                                 foregroundPowerFile),
                                ncol = 3,
                                expand = 'row')

        if verbose:
            print('getActpolCmbFgSim(): getting foreground a_lms')
        almTFullsky90and150 = curvedsky.rand_alm(foregroundPowers,
                                                 seed=foregroundSeed)

        almTebFullsky = np.zeros((
            len(freqs),
            nTQUs,
        ) + (len(almTFullsky90and150[-1]), ),
                                 dtype=np.complex128)

        for fi, freq in enumerate(freqs):
            if freq in outputFreqs:
                almTebFullsky[fi, 'TQU'.index('T'), :]  \
                    = almTFullsky90and150[outputFreqs.index(freq), :]

    #Convolve with beam on full sky
    for fi, freq in enumerate(freqs):
        if doBeam:
            beamFile = beamfileDict[psa + '_' + freq]
            if verbose:
                print('getActpolCmbFgSim(): applying beam from %s' % beamFile)
            beamData = (np.loadtxt(beamFile))[:, 1]
        else:
            if verbose:
                print('getActpolCmbFgSim(): not convolving with beam')
            beamData = np.repeat(1., almTebFullsky.shape[-1])

        import healpy

        #couldn't quickly figure out how to vectorize this so loop from 0 to 2.
        for tqui in range(nTQUs):
            almTebFullsky[fi, tqui] = healpy.sphtfunc.almxfl(
                almTebFullsky[fi, tqui].copy(), beamData)

        #These lines stolen from curvedsky.rand_map
        #doing all freqs at once gives error:
        #sharp.pyx in sharp.execute_dp (cython/sharp.c:12118)()
        #ValueError: ndarray is not C-contiguous
        #so loop over all freqs once for now.

    curvedsky.alm2map(almTebFullsky, output, spin=[0, 2], verbose=True)

    # outputThisfreq   = enmap.empty(( nTQUs,)+shape[-2:], wcs)
    # curvedsky.alm2map(almTebFullsky[fi,:,:], outputThisfreq, spin = [0,2],  verbose = True)
    # output[fi,...] = outputThisfreq

    # curvedsky.alm2map(almTebFullsky[fi,:,:], output[fi,:,:,:], spin = [0,2],  verbose = True)

    if applyModulation:
        from pixell import aberration
        for fi, freq in enumerate(freqs):

            print('applying modulation for frequency %s' % freq)
            output, A = aberration.boost_map(output,
                                             aberration.dir_equ,
                                             aberration.beta,
                                             return_modulation=True,
                                             aberrate=False,
                                             freq=freqStrToValGhz[freq] * 1e9)

    if applyWindow:
        from pixell import fft

        #The axes along which to FFT
        axes = [-2, -1]
        if verbose:
            print('getActpolCmbFgSim(): applying pixel window function')

        nfreq = len(freqs)
        for idx in range(nfreq):
            fd = fft.fft(output[idx], axes=axes)
            wy, wx = enmap.calc_window(fd.shape)
            twoDWindow = wy[:, None]**1 * wx[None, :]**1

            #Careful, this is quietly multiplying an array with shape [N_freq, N_TQU, N_y, N_x] with one of shape [N_y, N_x]
            fd *= twoDWindow

            output[idx] = (fft.ifft(fd, axes=axes, normalize=True)).real
            del fd
        if verbose:
            print('getActpolCmbFgSim(): done')

    return enmap.ndmap(output, wcs)
Esempio n. 4
0
def read_data(fnames,
              sel=None,
              pixbox=None,
              box=None,
              geometry=None,
              comp=0,
              split=0,
              unit="flux",
              dtype=np.float32,
              beam_rmax=5 * utils.degree,
              beam_res=2 * utils.arcsec,
              deconv_pixwin=True,
              apod=15 * utils.arcmin,
              mask=None,
              ivscale=[1, 0.5, 0.5]):
    """Read multi-frequency data for a single split of a single component, preparing it for
	analysis."""
    # Read in our data files and harmonize
    br = np.arange(0, beam_rmax, beam_res)
    data = bunch.Bunch(maps=[],
                       ivars=[],
                       beams=[],
                       freqs=[],
                       l=None,
                       bls=[],
                       names=[],
                       beam_profiles=[])
    for ifile in fnames:
        d = mapdata.read(ifile,
                         sel=sel,
                         pixbox=pixbox,
                         box=box,
                         geometry=geometry)
        # The 0 here is just selecting the first split. That is, we don't support splits
        data.maps.append(d.maps[split].astype(dtype)[comp])
        data.ivars.append(d.ivars[split].astype(dtype) * ivscale[comp])
        data.freqs.append(d.freq)
        if data.l is None: data.l = d.maps[0].modlmap()
        data.beams.append(
            enmap.ndmap(
                np.interp(data.l, np.arange(len(d.beam)),
                          d.beam / np.max(d.beam)),
                d.maps[0].wcs).astype(dtype))
        data.names.append(".".join(os.path.basename(ifile).split(".")[:-1]))
        data.bls.append(d.beam)
        data.beam_profiles.append(
            np.array([br, curvedsky.harm2profile(d.beam, br)]).astype(dtype))

    data.maps = enmap.enmap(data.maps)
    data.ivars = enmap.enmap(data.ivars)
    data.beams = enmap.enmap(data.beams)
    data.freqs = np.array(data.freqs)
    if unit == "uK":
        data.fconvs = np.full(len(data.freqs), 1.0, dtype)
    elif unit == "flux":
        data.fconvs = (utils.dplanck(data.freqs * 1e9, utils.T_cmb) /
                       1e3).astype(dtype)  # uK -> mJy/sr
    else:
        raise ValueError("Unrecognized unit '%s'" % str(unit))
    data.n = len(data.freqs)

    # Apply the unit
    data.maps *= data.fconvs[:, None, None]
    data.ivars /= data.fconvs[:, None, None]**2

    if mask is not None:
        mask_map = 1 - enmap.read_map(mask, sel=sel, pixbox=pixbox, box=box)
        data.ivars *= mask_map
        del mask_map

    # Should generalize this to handle internal map edges and frequency differences
    mask = enmap.shrink_mask(enmap.grow_mask(data.ivars > 0, 1 * utils.arcmin),
                             1 * utils.arcmin)
    apod_map = enmap.apod_mask(mask, apod)
    data.apod = apod_map
    data.fapod = np.mean(apod_map**2)
    data.maps *= apod_map
    data.ivars *= apod_map**2

    # Get the pixel window and optionall deconvolve it
    data.wy, data.wx = [
        w.astype(dtype) for w in enmap.calc_window(data.maps.shape)
    ]
    if deconv_pixwin:
        data.maps = enmap.ifft(
            enmap.fft(data.maps) / data.wy[:, None] / data.wx[None, :]).real

    return data
Esempio n. 5
0
def kfilter_map(m, apo, kx_cut, ky_cut, unpixwin=True, legacy_steve=False):
    r"""Apply a k-space filter on a map.

    By default, we do not reproduce the output of Steve's code. We do offer
    this functionality: set the optional flag `legacy_steve=True` to offset
    the mask and the map by one pixel in each dimension.

    You should filter both in temperature and polarization.

    Parameters
    ----------
    m : enmap
        Input map which this function will filter.
    apo : enmap
        This map is a smooth tapering of the edges of the map, to be multiplied
        into the map prior to filtering. The filtered map is divided by the
        nonzero pixels of this map at the end. This is required because
        maps of actual data are unlikely to be periodic, which will induce
        ringing when one applies a k-space filter. To solve this, we taper the
        edges of the map to zero prior to filtering.

        See :py:func:`nawrapper.ps.rectangular_apodization`
    kx_cut : float
        We cut modes with wavenumber :math:`|k_x| < k_x^{\mathrm{cut}}`.
    ky_cut : float
        We cut modes with wavenumber :math:`|k_y| < k_y^{\mathrm{cut}}`.
    unpixwin : bool
        Correct for the CAR pixel window if True.
    legacy_steve : bool
        Use a slightly different filter if True, to reproduce Steve's pipeline.
        Steve's k-space filter as of June 2019 had a bug where two k-space
        modes (the most positive cut mode in x and most negative cut mode in y)
        were not cut. This has a very small effect on the spectrum, but for
        reproducibility purposes we offer this behavior. By default we do not
        use this. To reproduce Steve's code behavior you should set `legacy_steve=True`.

    Returns
    -------
    result : enmap
        The map with the specified k-space filter applied.

    """
    alm = enmap.fft(m * apo, normalize=True)

    if unpixwin:  # remove pixel window in Fourier space
        wy, wx = enmap.calc_window(m.shape)
        alm /= wy[:, np.newaxis]
        alm /= wx[np.newaxis, :]

    ly, lx = enmap.lmap(alm.shape, alm.wcs)
    kfilter_x = np.abs(lx) >= kx_cut
    kfilter_y = np.abs(ly) >= ky_cut

    if legacy_steve:  # Steve's kspace filter appears to do this
        cut_x_k = np.unique(lx[(np.abs(lx) <= kx_cut)])
        cut_y_k = np.unique(ly[(np.abs(ly) <= ky_cut)])
        # keep most negative kx and most positive ky
        kfilter_x[np.isclose(lx, cut_x_k[0])] = True
        kfilter_y[np.isclose(ly, cut_y_k[-1])] = True

    result = enmap.ifft(alm * kfilter_x * kfilter_y, normalize=True).real
    result[apo > 0.0] = result[apo > 0.0] / apo[apo > 0.0]
    return result
Esempio n. 6
0
def get_pixwin(shape):
    wy, wx = enmap.calc_window(shape)
    wind = wy[:, None] * wx[None, :]
    return wind
Esempio n. 7
0
        maps = d["maps_%s_%s" % (sv, ar)]
        nsplit[sv] = len(maps)

        cal = d["cal_%s_%s" % (sv, ar)]

        print("%s split of survey: %s, array %s" % (nsplit[sv], sv, ar))

        if deconvolve_pixwin:
            # ok so this is a bit overcomplicated because we need to take into account CAR and HEALPIX
            # for CAR the pixel window function deconvolution is done in Fourier space and take into account
            # the anisotropy if the pixwin
            # In HEALPIX it's a simple 1d function in multipole space
            # we also need to take account the case where we have projected Planck into a CAR pixellisation since
            # the native pixel window function of Planck need to be deconvolved
            if window_tuple[0].pixel == "CAR":
                wy, wx = enmap.calc_window(window_tuple[0].data.shape)
                inv_pixwin_lxly = (wy[:, None] * wx[None, :])**(-1)
                inv_pixwin_lxly = inv_pixwin_lxly.astype(np.float32)
                pixwin_l[sv] = np.ones(2 * lmax)
                if sv == "Planck":
                    print("Deconvolve Planck pixel window function")
                    # we include this special case for Planck projected in CAR taking into account the Planck native pixellisation
                    # we should check if the projection doesn't include an extra pixel window
                    inv_pixwin_lxly = None
                    pixwin_l[sv] = hp.pixwin(2048)

            elif window_tuple[0].pixel == "HEALPIX":
                pixwin_l[sv] = hp.pixwin(window_tuple[0].nside)

        else:
            inv_pixwin_lxly = None