コード例 #1
0
ファイル: curvedsky.py プロジェクト: jit9/enlib
def rand_map(shape,
             wcs,
             ps,
             lmax=None,
             dtype=np.float64,
             seed=None,
             oversample=2.0,
             spin=2,
             method="auto"):
    """Generates a CMB realization with the given power spectrum for an enmap
	with the specified shape and WCS. This is identical to enlib.rand_map, except
	that it takes into account the curvature of the full sky. This makes it much
	slower and more memory-intensive. The map should not cross the poles."""
    # Ensure everything has the right dimensions and restrict to relevant dimensions
    ps = utils.atleast_3d(ps)
    assert ps.shape[0] == ps.shape[1], "ps must be [ncomp,ncomp,nl] or [nl]"
    assert len(shape) == 2 or len(
        shape) == 3, "shape must be (ncomp,ny,nx) or (ny,nx)"
    ncomp = 1 if len(shape) == 2 else shape[-3]
    ps = ps[:ncomp, :ncomp]

    ctype = np.result_type(dtype, 0j)
    alm = rand_alm(ps, lmax=lmax, seed=seed, dtype=ctype)
    map = enmap.empty((ncomp, ) + shape[-2:], wcs, dtype=dtype)
    alm2map(alm, map, spin=spin, oversample=oversample, method=method)
    if len(shape) == 2: map = map[0]
    return map
コード例 #2
0
ファイル: curvedsky.py プロジェクト: Nium14/enlib
def make_projectable_map_cyl(map, verbose=False):
    """Given an enmap in a cylindrical projection, return a map with
	the same pixelization, but extended to cover a whole band in phi
	around the sky. Also returns the slice required to recover the
	input map from the output map."""
    # First check if we need flipping. Sharp wants theta,phi increasing,
    # which means dec decreasing and ra increasing.
    flipx = map.wcs.wcs.cdelt[0] < 0
    flipy = map.wcs.wcs.cdelt[1] > 0
    if flipx: map = map[..., :, ::-1]
    if flipy: map = map[..., ::-1, :]
    # Then check if the map satisfies the lat-ring requirements
    ny, nx = map.shape[-2:]
    vy, vx = enmap.pix2sky(map.shape, map.wcs, [np.arange(ny), np.zeros(ny)])
    hy, hx = enmap.pix2sky(map.shape, map.wcs, [np.zeros(nx), np.arange(nx)])
    dx = hx[1:] - hx[:-1]
    dx = dx[np.isfinite(dx)]  # Handle overextended coordinates

    if not np.allclose(dx, dx[0]):
        raise ShapeError("Map must have constant phi spacing")
    nphi = utils.nint(2 * np.pi / dx[0])
    if not np.allclose(2 * np.pi / nphi, dx[0]):
        raise ShapeError("Pixels must evenly circumference")
    if not np.allclose(vx, vx[0]):
        raise ShapeError(
            "Different phi0 per row indicates non-cylindrical enmap")
    phi0 = vx[0]
    # Make a map with the same geometry covering a whole band around the sky
    # We can do this simply by extending it in the positive pixel dimension.
    oshape = map.shape[:-1] + (nphi, )
    owcs = map.wcs
    # Our input map could in theory cover multiple copies of the sky, which
    # would require us to copy out multiple slices.
    nslice = (nx + nphi - 1) // nphi
    islice, oslice = [], []

    def negnone(x):
        return x if x >= 0 else None

    for i in range(nslice):
        # i1:i2 is the range of pixels in the original map to use
        i1, i2 = i * nphi, min((i + 1) * nphi, nx)
        islice.append((Ellipsis, slice(i1, i2)))
        # yslice and xslice give the range of pixels in our temporary map to use.
        # This is 0:(i2-i1) if we're not flipping, but if we flip we count from
        # the opposite direction: nx-1:nx-1-(i2-i1):-1
        yslice = slice(-1, None, -1) if flipy else slice(None)
        xslice = slice(nx - 1, negnone(nx - 1 - (i2 - i1)),
                       -1) if flipx else slice(0, i2 - i1)
        oslice.append((Ellipsis, yslice, xslice))
    if verbose:
        print "Allocating shape %s dtype %s intermediate map" % (
            str(oshape), np.dtype(map.dtype).char)
    return enmap.empty(oshape, owcs, dtype=map.dtype), islice, oslice
コード例 #3
0
 def __init__(self, geometry, tiles=None, copy=True):
     try:
         self.geometry = geometry.geometry
         self.tiles = [t.copy() for t in geometry.tiles]
     except AttributeError:
         self.geometry = geometry
         if tiles is not None:
             if copy: tiles = copy = deepcopy(tiles)
             self.tiles = tiles
         else:
             self.tiles = [
                 enmap.empty(ts, tw, dtype=geometry.dtype)
                 for ts, tw in geometry.loc_geometry
             ]
コード例 #4
0
def displace_map(imap,
                 pix,
                 order=3,
                 mode="spline",
                 border="cyclic",
                 trans=False,
                 deriv=False):
    """Displace map m[{pre},ny,nx] by pix[2,ny,nx], where pix indicates the location
	in the input map each output pixel should get its value from (float). The output
	is [{pre},ny,nx]."""
    iwork = np.empty(imap.shape[-2:] + imap.shape[:-2], imap.dtype)
    if not deriv:
        out = imap.copy()
    else:
        out = enmap.empty((2, ) + imap.shape, imap.wcs, imap.dtype)
    # Why do we have to manually allocate outputs and juggle whcih is copied over here?
    # Because it is in general not possible to infer from odata what shape idata should have.
    # So the map_coordinates can't allocate the output array automatically in the transposed
    # case. But in this function we know that they will have the same shape, so we can.
    if not trans:
        iwork[:] = utils.moveaxes(imap, (-2, -1), (0, 1))
        owork = interpol.map_coordinates(iwork,
                                         pix,
                                         order=order,
                                         mode=mode,
                                         border=border,
                                         trans=trans,
                                         deriv=deriv)
        out[:] = utils.moveaxes(owork, (0, 1), (-2, -1))
    else:
        if not deriv:
            owork = iwork.copy()
        else:
            owork = np.empty(imap.shape[-2:] + (2, ) + imap.shape[:-2],
                             imap.dtype)
        owork[:] = utils.moveaxes(imap, (-2, -1), (0, 1))
        interpol.map_coordinates(iwork,
                                 pix,
                                 owork,
                                 order=order,
                                 mode=mode,
                                 border=border,
                                 trans=trans,
                                 deriv=deriv)
        out[:] = utils.moveaxes(iwork, (0, 1), (-2, -1))
    return out
コード例 #5
0
ファイル: curvedsky.py プロジェクト: Nium14/enlib
def rand_map(shape,
             wcs,
             ps,
             lmax=None,
             dtype=np.float64,
             seed=None,
             oversample=2.0,
             spin=2,
             method="auto",
             direct=False,
             verbose=False):
    """Generates a CMB realization with the given power spectrum for an enmap
	with the specified shape and WCS. This is identical to enlib.rand_map, except
	that it takes into account the curvature of the full sky. This makes it much
	slower and more memory-intensive. The map should not cross the poles."""
    # Ensure everything has the right dimensions and restrict to relevant dimensions
    ps = utils.atleast_3d(ps)
    if not ps.shape[0] == ps.shape[1]:
        raise ShapeError("ps must be [ncomp,ncomp,nl] or [nl]")
    if not (len(shape) == 2 or len(shape) == 3):
        raise ShapeError("shape must be (ncomp,ny,nx) or (ny,nx)")
    ncomp = 1 if len(shape) == 2 else shape[-3]
    ps = ps[:ncomp, :ncomp]

    ctype = np.result_type(dtype, 0j)
    if verbose:
        print "Generating alms with seed %s up to lmax=%d dtype %s" % (
            str(seed), lmax, np.dtype(ctype).char)
    alm = rand_alm_healpy(ps, lmax=lmax, seed=seed, dtype=ctype)
    if verbose:
        print "Allocating output map shape %s dtype %s" % (str(
            (ncomp, ) + shape[-2:]), np.dtype(dtype).char)
    map = enmap.empty((ncomp, ) + shape[-2:], wcs, dtype=dtype)
    alm2map(alm,
            map,
            spin=spin,
            oversample=oversample,
            method=method,
            direct=direct,
            verbose=verbose)
    if len(shape) == 2: map = map[0]
    return map
コード例 #6
0
def rand_map(shape,
             wcs,
             ps_lensinput,
             lmax=None,
             maplmax=None,
             dtype=np.float64,
             seed=None,
             oversample=2.0,
             spin=2,
             output="l",
             geodesic=True,
             verbose=False,
             delta_theta=None):
    import curvedsky, sharp
    ctype = np.result_type(dtype, 0j)
    # Restrict to target number of components
    oshape = shape[-3:]
    if len(oshape) == 2: shape = (1, ) + tuple(shape)
    # First draw a random lensing field, and use it to compute the undeflected positions
    if verbose: print("Generating alms")
    alm, ainfo = curvedsky.rand_alm(ps_lensinput,
                                    lmax=lmax,
                                    seed=seed,
                                    dtype=ctype,
                                    return_ainfo=True)
    phi_alm, cmb_alm = alm[0], alm[1:1 + shape[-3]]
    # Truncate alm if we want a smoother map. In taylens, it was necessary to truncate
    # to a lower lmax for the map than for phi, to avoid aliasing. The appropriate lmax
    # for the cmb was the one that fits the resolution. FIXME: Can't slice alm this way.
    #if maplmax: cmb_alm = cmb_alm[:,:maplmax]
    del alm
    if delta_theta is None: bsize = shape[-2]
    else:
        bsize = utils.nint(abs(delta_theta / utils.degree / wcs.wcs.cdelt[1]))
        # Adjust bsize so we don't get any tiny blocks at the end
        nblock = shape[-2] // bsize
        bsize = int(shape[-2] / (nblock + 0.5))
    # Allocate output maps
    if "p" in output: phi_map = enmap.empty(shape[-2:], wcs, dtype=dtype)
    if "k" in output:
        kappa_map = enmap.empty(shape[-2:], wcs, dtype=dtype)
        l = np.arange(ainfo.lmax + 1.0)
        kappa_alm = ainfo.lmul(phi_alm, l * (l + 1) / 2)
        for i1 in range(0, shape[-2], bsize):
            curvedsky.alm2map(kappa_alm, kappa_map[..., i1:i1 + bize, :])
        del kappa_alm
    if "a" in output:
        grad_map = enmap.empty((2, ) + shape[-2:], wcs, dtype=dtype)
    if "u" in output: cmb_raw = enmap.empty(shape, wcs, dtype=dtype)
    if "l" in output: cmb_obs = enmap.empty(shape, wcs, dtype=dtype)
    # Then loop over dec bands
    for i1 in range(0, shape[-2], bsize):
        i2 = min(i1 + bsize, shape[-2])
        lshape, lwcs = enmap.slice_geometry(shape, wcs,
                                            (slice(i1, i2), slice(None)))
        if "p" in output:
            if verbose: print("Computing phi map")
            curvedsky.alm2map(phi_alm, phi_map[..., i1:i2, :])
        if verbose: print("Computing grad map")
        if "a" in output: grad = grad_map[..., i1:i2, :]
        else: grad = enmap.zeros((2, ) + lshape[-2:], lwcs, dtype=dtype)
        curvedsky.alm2map(phi_alm, grad, deriv=True)
        if "l" not in output: continue
        if verbose: print("Computing observed coordinates")
        obs_pos = enmap.posmap(lshape, lwcs)
        if verbose: print("Computing alpha map")
        raw_pos = enmap.samewcs(
            offset_by_grad(obs_pos, grad, pol=shape[-3] > 1,
                           geodesic=geodesic), obs_pos)
        del obs_pos, grad
        if "u" in output:
            if verbose: print("Computing unlensed map")
            curvedsky.alm2map(cmb_alm, cmb_raw[..., i1:i2, :], spin=spin)
        if verbose: print("Computing lensed map")
        cmb_obs[..., i1:i2, :] = curvedsky.alm2map_pos(cmb_alm,
                                                       raw_pos[:2],
                                                       oversample=oversample,
                                                       spin=spin)
        if raw_pos.shape[0] > 2 and np.any(raw_pos[2]):
            if verbose: print("Rotating polarization")
            cmb_obs[..., i1:i2, :] = enmap.rotate_pol(cmb_obs[..., i1:i2, :],
                                                      raw_pos[2])
        del raw_pos
    del cmb_alm, phi_alm
    # Output in same order as specified in output argument
    res = []
    for c in output:
        if c == "l": res.append(cmb_obs.reshape(oshape))
        elif c == "u": res.append(cmb_raw.reshape(oshape))
        elif c == "p": res.append(phi_map)
        elif c == "k": res.append(kappa_map)
        elif c == "a": res.append(grad_map)
    return tuple(res)