def make_maps(tod, data, pos, ncomp, radius, resolution): tod = tod.copy() pos = np.array(pos) # Handle angle wrapping pos = utils.rewind(pos, data.ref) nsrc= len(pos) dbox= np.array([[-1,-1],[1,1]])*radius shape, wcs = enmap.geometry(pos=dbox, res=resolution) # Set up pixels n = int(np.round(2*radius/resolution)) boxes = np.array([[p-radius,p+radius] for p in pos]) # Set up output maps rhs = enmap.zeros((nsrc,ncomp) +shape, wcs, dtype=dtype) div = enmap.zeros((ncomp,nsrc,ncomp)+shape, wcs, dtype=dtype) # Build rhs ptsrc_data.nmat_basis(tod, data) pmat_thumbs(-1, tod, rhs, boxes, data) # Build div for c in range(ncomp): idiv = div[0].copy(); idiv[:,c] = 1 wtod = data.tod.astype(dtype,copy=True); wtod[...] = 0 pmat_thumbs( 1, wtod, idiv, boxes, data) ptsrc_data.nmat_basis(wtod, data, white=True) pmat_thumbs(-1, wtod, div[c], boxes, data) div = np.rollaxis(div,1) mask = div[:,0] != 0 bin = rhs.copy() bin[mask] = rhs[mask]/div[:,0][mask] # Fixme: only works for ncomp == 1 return bin, rhs, div
def project_tod_on_workspace(scan, tod, wgeo): """Compute the tod onto a map using the pixelization defined in the workspace, and return it along with a [TQU,TQU] hitmap and a hits-by-detector-by-y array.""" rhs = enmap.zeros(wgeo.shape, wgeo.lwcs, wgeo.dtype) hdiv = enmap.zeros((rhs.shape[:1]+rhs.shape),rhs.wcs, rhs.dtype) # Project it onto the workspace pcut = pmat.PmatCut(scan) pmap = PmatWorkspaceTOD(scan, wgeo) pix, phase = pmap.get_pix_phase() # Build rhs junk = np.zeros(pcut.njunk,dtype=rhs.dtype) pcut.backward(tod, junk) pmap.backward(tod, rhs, pix, phase) # Build div tmp = hdiv[0].copy() for i in range(ncomp): tmp[:] = np.eye(ncomp)[i,:,None,None] pmap.forward(tod, tmp, pix, phase) pcut.backward(tod, junk) pmap.backward(tod, hdiv[i], pix, phase) # Find each detector's hits by wy. Some detectors have # sufficient residual curvature that they hit every wy. yhits = np.zeros([scan.ndet, rhs.shape[-2]],dtype=np.int32) core = pmat.get_core(dtype) core.bincount_flat(yhits.T, pix.T, rhs.shape[-2:], 0) return rhs, hdiv, yhits
def project_tod_on_workspace(scan, tod, wgeo): """Compute the tod onto a map using the pixelization defined in the workspace, and return it along with a [TQU,TQU] hitmap and a hits-by-detector-by-y array.""" rhs = enmap.zeros(wgeo.shape, wgeo.lwcs, wgeo.dtype) hdiv = enmap.zeros((rhs.shape[:1] + rhs.shape), rhs.wcs, rhs.dtype) # Project it onto the workspace pcut = pmat.PmatCut(scan) pmap = PmatWorkspaceTOD(scan, wgeo) pix, phase = pmap.get_pix_phase() # Build rhs junk = np.zeros(pcut.njunk, dtype=rhs.dtype) pcut.backward(tod, junk) pmap.backward(tod, rhs, pix, phase) # Build div tmp = hdiv[0].copy() for i in range(ncomp): tmp[:] = np.eye(ncomp)[i, :, None, None] pmap.forward(tod, tmp, pix, phase) pcut.backward(tod, junk) pmap.backward(tod, hdiv[i], pix, phase) # Find each detector's hits by wy. Some detectors have # sufficient residual curvature that they hit every wy. yhits = np.zeros([scan.ndet, rhs.shape[-2]], dtype=np.int32) core = pmat.get_core(dtype) core.bincount_flat(yhits.T, pix.T, rhs.shape[-2:], 0) return rhs, hdiv, yhits
def make_maps(tod, data, pos, ncomp, radius, resolution): tod = tod.copy() pos = np.array(pos) # Handle angle wrapping pos = utils.rewind(pos, data.ref) nsrc = len(pos) dbox = np.array([[-1, -1], [1, 1]]) * radius shape, wcs = enmap.geometry(pos=dbox, res=resolution) # Set up pixels n = int(np.round(2 * radius / resolution)) boxes = np.array([[p - radius, p + radius] for p in pos]) # Set up output maps rhs = enmap.zeros((nsrc, ncomp) + shape, wcs, dtype=dtype) div = enmap.zeros((ncomp, nsrc, ncomp) + shape, wcs, dtype=dtype) # Build rhs ptsrc_data.nmat_basis(tod, data) pmat_thumbs(-1, tod, rhs, boxes, data) # Build div for c in range(ncomp): idiv = div[0].copy() idiv[:, c] = 1 wtod = data.tod.astype(dtype, copy=True) wtod[...] = 0 pmat_thumbs(1, wtod, idiv, boxes, data) ptsrc_data.nmat_basis(wtod, data, white=True) pmat_thumbs(-1, wtod, div[c], boxes, data) div = np.rollaxis(div, 1) mask = div[:, 0] != 0 bin = rhs.copy() bin[mask] = rhs[mask] / div[:, 0][mask] # Fixme: only works for ncomp == 1 return bin, rhs, div
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): ctype = np.result_type(dtype, 0j) # First draw a random lensing field, and use it to compute the undeflected positions if verbose: print "Computing observed coordinates" obs_pos = enmap.posmap(shape, wcs) if verbose: print "Generating alms" alm = curvedsky.rand_alm(ps_lensinput, lmax=lmax, seed=seed, dtype=ctype) phi_alm, cmb_alm = alm[0], alm[1:] # 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 "p" in output: if verbose: print "Computing phi map" phi_map = curvedsky.alm2map(phi_alm, enmap.zeros(shape[-2:], wcs, dtype=dtype)) if verbose: print "Computing grad map" grad = curvedsky.alm2map(phi_alm, enmap.zeros((2, ) + shape[-2:], wcs, dtype=dtype), deriv=True) if verbose: print "Computing alpha map" raw_pos = enmap.samewcs( offset_by_grad(obs_pos, grad, pol=True, geodesic=geodesic), obs_pos) del obs_pos, phi_alm if "a" not in output: del grad if "u" in output: if verbose: print "Computing unlensed map" cmb_raw = curvedsky.alm2map(cmb_alm, enmap.zeros(shape, wcs, dtype=dtype), spin=spin) if verbose: print "Computing lensed map" cmb_obs = 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 = enmap.rotate_pol(cmb_obs, raw_pos[2]) del cmb_alm, raw_pos # Output in same order as specified in output argument res = [] for c in output: if c == "l": res.append(cmb_obs) elif c == "u": res.append(cmb_raw) elif c == "p": res.append(phi_map) elif c == "a": res.append(grad) return tuple(res)
def make_dummy_tile(shape, wcs, box, pad=0): pbox = calc_pbox(shape, wcs, box) if pad: pbox[0] -= pad pbox[1] += pad shape2, wcs2 = enmap.slice_wcs( shape, wcs, (slice(pbox[0, 0], pbox[1, 0]), slice(pbox[0, 1], pbox[1, 1]))) shape2 = tuple(pbox[1] - pbox[0]) map = enmap.zeros(shape2, wcs2, dtype) div = enmap.zeros(shape2[-2:], wcs2, dtype) return bunch.Bunch(map=map, div=div)
def __init__(self, scans, pids, patterns, array_shape, res, dtype, comm, cuts=None, name="phase", ofmt="{name}_{pid:02}_{az0:.0f}_{az1:.0f}_{el:.0f}", output=True, ext="fits", col_major=True, hysteresis=True): Signal.__init__(self, name, ofmt, output, ext) nrow, ncol = array_shape ndet = nrow * ncol self.pids = pids self.patterns = patterns self.comm = comm self.dtype = dtype self.col_major = col_major self.cuts = cuts self.data = {} self.areas = [] # Set up an area for each scanning pattern. We assume that these are constant # elevation scans, so only azimuth matters. This setup is ugly and would be # nicer if passed in, but then the ugliness would only be moved to the calling # code instead. for pattern in patterns: az0, az1 = utils.widen_box(pattern)[:, 1] naz = int(np.ceil((az1 - az0) / res)) az1 = az0 + naz * res det_unit = nrow if col_major else ncol shape, wcs = enmap.geometry( pos=[[0, az0], [ndet / det_unit * utils.degree, az1]], shape=(ndet, naz), proj="car") if hysteresis: area = enmap.zeros((2, ) + shape, wcs, dtype=dtype) else: area = enmap.zeros(shape, wcs, dtype=dtype) self.areas.append(area) for pid, scan in zip(pids, scans): dets = scan.dets if col_major: dets = utils.transpose_inds(dets, nrow, ncol) mat = pmat.PmatScan(scan, self.areas[pid], dets) self.data[scan] = [pid, mat] self.dof = zipper.MultiZipper( [zipper.ArrayZipper(area, comm=comm) for area in self.areas], comm=comm)
def __init__(self, geometry, rhs=None, hdiv=None, wfilter=None, ids=[]): if rhs is None: dtype = geometry.dtype if rhs is None: rhs = enmap.zeros(geometry.shape, geometry.lwcs, dtype) if hdiv is None: hdiv = enmap.zeros((geometry.ncomp,) + geometry.shape, geometry.lwcs, dtype) if wfilter is None: wfilter = np.zeros([geometry.shape[-2],geometry.num_az_freq],dtype=dtype) self.geometry = geometry self.rhs = rhs self.hdiv = hdiv self.wfilter = wfilter self.ids = list(ids)
def __init__(self, geometry, rhs=None, hdiv=None, wfilter=None, ids=[]): if rhs is None: dtype = geometry.dtype if rhs is None: rhs = enmap.zeros(geometry.shape, geometry.lwcs, dtype) if hdiv is None: hdiv = enmap.zeros((geometry.ncomp, ) + geometry.shape, geometry.lwcs, dtype) if wfilter is None: wfilter = np.zeros([geometry.shape[-2], geometry.num_az_freq], dtype=dtype) self.geometry = geometry self.rhs = rhs self.hdiv = hdiv self.wfilter = wfilter self.ids = list(ids)
def hwexpand(mflat, nrow=-1, ncol=-1, transpose=False): """Stack the maps in mflat[n,ny,nx] into a single flat map mflat[nrow,ncol,ny,nx]""" n, ny, nx = mflat.shape if nrow < 0 and ncol < 0: ncol = int(np.ceil(n**0.5)) if nrow < 0: nrow = (n+ncol-1)/ncol if ncol < 0: ncol = (n+nrow-1)/nrow if not transpose: omap = enmap.zeros([nrow,ncol,ny,nx],mflat.wcs,mflat.dtype) omap.reshape(-1,ny,nx)[:n] = mflat else: omap = enmap.zeros([ncol,nrow,ny,nx],mflat.wcs,mflat.dtype) omap.reshape(-1,ny,nx)[:n] = mflat omap = np.transpose(omap,(1,0,2,3)) return omap
def calc_cmode_corrfun(ushape, uwcs, offset_upos, sigma, nsigma=10): """Compute the real-space correlation function for the atmospheric common mode in unskewed coordinates. The result has an arbitrary overall scaling.""" res = enmap.zeros(ushape, uwcs) # Generate corrfun around center of map upos = offset_upos + np.mean(res.box(), 0)[:, None] # We will work on a smaller cutout to speed things up pad = sigma * nsigma box = np.array([np.min(upos, 1) - pad, np.max(upos, 1) + pad]) pixbox = res.sky2pix(box.T).T work = res[pixbox[0, 0]:pixbox[1, 0], pixbox[0, 1]:pixbox[1, 1]] posmap = work.posmap() # Generate each part of the corrfun as a gaussian in real space. # Could do this in fourier space, but easier to get subpixel precision this way # (not that that is very important, though) for p in upos.T: r2 = np.sum((posmap - p[:, None, None])**2, 0) work += np.exp(-0.5 * r2 / sigma**2) # Convolute with itself mirrored to get the actual correlation function fres = fft.rfft(res, axes=[-2, -1]) fres *= np.conj(fres) fft.ifft(fres, res, axes=[-2, -1]) res /= np.max(res) return res
def monolithic(idir, ofile, verbose=True, slice=None, dtype=None): # Find the range of input tiles ipathfmt = idir + "/tile%(y)03d_%(x)03d.fits" itile1, itile2 = find_tile_range(ipathfmt) def read(fname): m = enmap.read_map(fname) if slice: m = eval("m" + slice) return m # Read the first and last tile to get the total dimensions m1 = read(ipathfmt % {"y": itile1[0], "x": itile1[1]}) m2 = read(ipathfmt % {"y": itile2[0] - 1, "x": itile2[1] - 1}) wy, wx = m1.shape[-2:] oshape = tuple( np.array(m1.shape[-2:]) * (itile2 - itile1 - 1) + np.array(m2.shape[-2:])) if dtype is None: dtype = m1.dtype omap = enmap.zeros(m1.shape[:-2] + oshape, m1.wcs, dtype) del m1, m2 # Now loop through all tiles and copy them in to the correct position for ty in range(itile1[0], itile2[0]): for tx in range(itile1[1], itile2[1]): m = read(ipathfmt % {"y": ty, "x": tx}) oy = ty - itile1[0] ox = tx - itile1[1] omap[..., oy * wy:(oy + 1) * wy, ox * wx:(ox + 1) * wx] = m if verbose: print ipathfmt % {"y": ty, "x": tx} enmap.write_map(ofile, omap)
def eval_srcs_loop(posmap, poss, amps, beam, cres, nhit, cell_srcs): # Loop through each cell ncy, ncx = nhit.shape model = enmap.zeros(amps.shape[-1:] + posmap.shape[-2:], posmap.wcs, amps.dtype) for cy in range(ncy): for cx in range(ncx): nsrc = nhit[cy, cx] if nsrc == 0: continue srcs = cell_srcs[cy, cx, :nsrc] y1, y2 = (cy + 0) * cres[0], (cy + 1) * cres[0] x1, x2 = (cx + 0) * cres[1], (cx + 1) * cres[1] pixpos = posmap[:, y1:y2, x1:x2] srcpos = poss[srcs].T # [2,nsrc] srcamp = amps[srcs].T # [ncomp,nsrc] diff = pixpos[:, None, :, :] - srcpos[:, :, None, None] r = (diff[0]**2 + (diff[1] * np.cos(pixpos[0, None, :, :]))**2)**0.5 bpix = (r - beam[0, 0]) / (beam[0, 1] - beam[0, 0]) # Evaluate the beam at these locations bval = utils.interpol(beam[1], bpix[None], mode="constant", order=1) # [nsrc,ry,rx] cmodel = srcamp[:, :, None, None] * bval cmodel = np.sum(cmodel, -3) model[:, y1:y2, x1:x2] += cmodel return model
def project_maps(imaps, pos, shape, wcs): pos = np.asarray(pos) omaps = enmap.zeros((len(imaps),)+imaps[0].shape[:-2]+shape, wcs, imaps[0].dtype) pmap = omaps.posmap() for i, imap in enumerate(imaps): omaps[i] = imaps[i].at(pmap+pos[i,::-1,None,None]) return omaps
def calc_cmode_corrfun(ushape, uwcs, offset_upos, sigma, nsigma=10): """Compute the real-space correlation function for the atmospheric common mode in unskewed coordinates. The result has an arbitrary overall scaling.""" res = enmap.zeros(ushape, uwcs) # Generate corrfun around center of map upos = offset_upos + np.mean(res.box(),0)[:,None] # We will work on a smaller cutout to speed things up pad = sigma*nsigma box = np.array([np.min(upos,1)-pad,np.max(upos,1)+pad]) pixbox = res.sky2pix(box.T).T work = res[pixbox[0,0]:pixbox[1,0],pixbox[0,1]:pixbox[1,1]] posmap = work.posmap() # Generate each part of the corrfun as a gaussian in real space. # Could do this in fourier space, but easier to get subpixel precision this way # (not that that is very important, though) for p in upos.T: r2 = np.sum((posmap-p[:,None,None])**2,0) work += np.exp(-0.5*r2/sigma**2) # Convolute with itself mirrored to get the actual correlation function fres = fft.rfft(res, axes=[-2,-1]) fres *= np.conj(fres) fft.ifft(fres, res, axes=[-2,-1]) res /= np.max(res) return res
def corr_to_mat(corr, n): res = enmap.zeros([n, n, n, n], dtype=corr.dtype) for i in range(n): tmp = np.roll(corr, i, 0)[:n, :] for j in range(n): res[i, j] = np.roll(tmp, j, 1)[:, :n] return res
def __init__(self, signal, signal_cut, scans, weights, noise=True, hits=True): """Binned preconditioner: (P'W"P)", where W" is a white nosie approximation of N". If noise=False, instead computes (P'P)". If hits=True, also computes a hitcount map.""" ncomp = signal.area.shape[0] self.div = enmap.zeros((ncomp, ) + signal.area.shape, signal.area.wcs, signal.area.dtype) calc_div_map(self.div, signal, signal_cut, scans, weights, noise=noise) self.idiv = array_ops.svdpow(self.div, -1, axes=[0, 1], lim=config.get("eig_limit")) #self.idiv[:] = np.eye(3)[:,:,None,None] if hits: # Build hitcount map too self.hits = signal.area.copy() self.hits = calc_hits_map(self.hits, signal, signal_cut, scans) else: self.hits = None self.signal = signal
def zeros(geometry): """Return a new Dmap with the specified geometry, filled with zeros.""" tiles = [ enmap.zeros(ts, tw, dtype=geometry.dtype) for ts, tw in geometry.loc_geometry ] return Dmap(geometry, tiles, copy=False)
def read_div(fname, shape=None, wcs=None, ncomp=3): m = nonan(read_helper(fname, shape, wcs))*1.0 if ncomp == 0: return m.preflat[0] #return m.preflat[:1][None] if m.ndim == 2: res = enmap.zeros((ncomp,ncomp)+m.shape[-2:], m.wcs, m.dtype) for i in range(ncomp): res[i,i] = m return res elif m.ndim == 3: res = enmap.zeros((ncomp,ncomp)+m.shape[-2:], m.wcs, m.dtype) for i in range(ncomp): res[i,i] = m[i] return res elif m.ndim == 4: return m else: raise ValueError("Wrong number of dimensions in div %s" % fname)
def rand_map_flat(shape, wcs, ps, lmax=None, lens=True, aberrate=True, beta=None, dir=None, seed=None, dtype=None, verbose=False, recenter=False, pad=0): """Simulate a random flat-sky map. The input spectrum should be [{phi,T,E,B},{phi,T,E,b},nl] of lens is True, and just [{T,E,B},{T,E,B},nl] otherwise.""" if dtype is None: dtype = np.float64 if dir is None: dir = aberration.dir_equ if beta is None: beta = aberration.beta ctype = np.result_type(dtype, 0j) if verbose: print "Generating unlensed cmb" # No position calculation necessary if we're not lensing or aberrating. if not lens and not aberrate: return enmap.rand_map(shape, wcs, ps, seed=seed) # Otherwise we must deal with various displacements if aberrate: pad += np.pi * beta * 1.2 pad_pix = int(pad / enmap.pixsize(shape, wcs)**0.5) if pad_pix > 0: if verbose: print "Padding" template = enmap.zeros(shape, wcs, np.int16) template, pslice = enmap.pad(template, pad_pix, return_slice=True) pshape, pwcs = template.shape, template.wcs else: pshape, pwcs = shape, wcs # Simulate (padded) lensing map if lens: maps = enmap.rand_map((ps.shape[0], ) + pshape[-2:], pwcs, ps) phi, unlensed = maps[0], maps[1:] if verbose: print "Lensing" m = lensing.lens_map_flat(unlensed, phi) else: m = enmap.rand_map((ps.shape[0], ) + pshape[-2:], pwcs, ps) # Then handle aberration if necessary if aberrate: if verbose: print "Computing aberration displacement" pos = m.posmap() pos = enmap.samewcs( aberration.remap(pos[1::-1], dir=dir, beta=beta, recenter=recenter), pos) amp = pos[3] pos = pos[1::-1] if verbose: print "Interpolating aberration" m = enmap.samewcs(m.at(pos, mask_nan=False), m) if verbose: print "Applying modulation" m *= amp if pad_pix > 0: if verbose: print "Unpadding" m = m[pslice] return m
def map_likelihood(likfun, rmax=5*utils.arcmin, res=0.7*utils.arcmin): shape, wcs = enmap.geometry(np.array([[-1,-1],[1,1]])*rmax, res=res, proj="car") map = enmap.zeros(shape, wcs) pos = map.posmap() for y in range(map.shape[0]): for x in range(map.shape[1]): map[y,x] = likfun(pos[:,y,x]/utils.arcmin) return map
def add_missing_comps(map, ncomp, rms_factor=1e3): map = map.preflat if len(map) == ncomp: return map omap = enmap.zeros((ncomp, ) + map.shape[-2:], map.wcs, map.dtype) omap[:len(map)] = map omap[len(map):] = np.random.standard_normal( (len(map), ) + map.shape[-2:]) * np.std(map) * rms_factor return omap
def project_maps(imaps, pos, shape, wcs): pos = np.asarray(pos) omaps = enmap.zeros((len(imaps), ) + imaps[0].shape[:-2] + shape, wcs, imaps[0].dtype) pmap = omaps.posmap() for i, imap in enumerate(imaps): omaps[i] = imaps[i].at(pmap + pos[i, ::-1, None, None]) return omaps
def read_area(ipathfmt, opix, itile1=(None,None), itile2=(None,None), verbose=False, cache=None, slice=None): """Given a set of tiles on disk with locations ipathfmt % {"y":...,"x":...}, read the data corresponding to the pixel range opix[{from,to],{y,x}] in the full map.""" opix = np.asarray(opix) # Find the range of input tiles itile1, itile2 = find_tile_range(ipathfmt, itile1, itile2) # To fill in the rest of the information we need to know more # about the input tiling, so read the first tile if cache is None or cache[2] is None: geo = read_tileset_geometry(ipathfmt, itile1=itile1, itile2=itile2) else: geo = cache[2] if cache is not None: cache[2] = geo isize = geo.tshape osize = opix[1]-opix[0] omap = enmap.zeros(geo.shape[:-2]+tuple(osize), geo.wcs, geo.dtype) # Find out which input tiles overlap with this output tile. # Our tile stretches from opix1:opix2 relative to the global input pixels it1 = opix[0]/isize it2 = (opix[1]-1)/isize+1 noverlap = 0 for ity in range(it1[0],it2[0]): if ity < itile1[0] or ity >= itile2[0]: continue # Start/end of this tile in global input pixels ipy1, ipy2 = ity*isize[0], (ity+1)*isize[0] overlap = range_overlap(opix[:,0],[ipy1,ipy2]) oy1,oy2 = overlap-opix[0,0] iy1,iy2 = overlap-ipy1 for itx in range(it1[1],it2[1]): if itx < itile1[1] or itx >= itile2[1]: continue ipx1, ipx2 = itx*isize[1], (itx+1)*isize[1] overlap = range_overlap(opix[:,1],[ipx1,ipx2]) ox1,ox2 = overlap-opix[0,1] ix1,ix2 = overlap-ipx1 # Read the input tile and copy over iname = ipathfmt % {"y":ity,"x":itx} if cache is None or cache[0] != iname: imap = enmap.read_map(iname) if slice: imap = eval("imap"+slice) else: imap = cache[1] if cache is not None: cache[0], cache[1] = iname, imap if verbose: print iname # Edge input tiles may be smaller than the standard # size. ysub = isize[0]-imap.shape[-2] xsub = isize[1]-imap.shape[-1] # If the input map is too small, there may actually be # zero overlap. if oy2-ysub <= oy1 or ox2-xsub <= ox1: continue omap[...,oy1:oy2-ysub,ox1:ox2-xsub] = imap[...,iy1:iy2-ysub,ix1:ix2-xsub] noverlap += 1 if noverlap == 0: raise IOError("No tiles for tiling %s in range %s" % (ipathfmt, ",".join([":".join([str(p) for p in r]) for r in opix.T]))) # Set up the wcs for the output tile omap.wcs.wcs.crpix -= opix[0,::-1] return omap
def likgrid(self, R, n, super=1, marg=False, verbose=False): shape, wcs = enmap.geometry(pos=np.array([[-R,-R],[R,R]]), shape=(n,n), proj="car") dchisqs = enmap.zeros(shape, wcs) amps = enmap.zeros((self.nsrc,)+shape, wcs) pos = dchisqs.posmap() for i,p in enumerate(pos.reshape(2,-1).T): if np.sum(p**2)**0.5 > R: continue L = self.lik.eval(p) if verbose: print "%6d %7.3f %7.3f %15.7f" % (i, p[0]/utils.arcmin, p[1]/utils.arcmin, L.chisq0-L.chisq) dchisqs.reshape(-1)[i] = L.chisq0-L.chisq amps.reshape(self.nsrc,-1)[:,i] = L.amps if super > 1: # Use bicubic spline interpolation to upscale shape2, wcs2 = enmap.geometry(pos=np.array([[-R,-R],[R,R]]), shape=(n*super,n*super), proj="car") dchisqs = dchisqs.project(shape2, wcs2, mode="constant") amps = amps.project(shape2, wcs2, mode="constant") return dchisqs, amps
def map(self, tod): junk = np.zeros(self.pcut.njunk,tod.dtype) rhs = enmap.zeros(self.pthumb.shape, self.pthumb.wcs, tod.dtype) #self.nmat.white(tod) self.nmat.apply(tod) self.pcut.backward(tod, junk) self.pthumb.backward(tod, rhs) rhs *= self.idiv[:,None] return rhs
def measure_corr(pmaps, nmat, divs, tod_work, ref_pixs): ref_pixs = np.array(ref_pixs) tod_work[:] = 0 map_work = enmap.zeros((3,)+divs.shape[-2:], divs.wcs, divs.dtype) corrs = enmap.zeros(divs.shape, divs.wcs, divs.dtype) for i, pmap in enumerate(pmaps): map_work[:] = 0 map_work[0,ref_pixs[i,0],ref_pixs[i,1]] = 1 pmap.forward(tod_work, map_work, tmul=1) nmat.apply(tod_work) for i, pmap in enumerate(pmaps): pmap.backward(tod_work, map_work, mmul=0) corrs[i] = map_work[0] norm = (divs[i,ref_pixs[i,0],ref_pixs[i,1]] * divs[i])**0.5 corrs[i,norm>0] /= norm[norm>0] corrs[i] = np.roll(np.roll(corrs[i], -ref_pixs[i,0], -2), -ref_pixs[i,1], -1) # Shift center to corner, so the result is the correlation relative to # corner pixel return corrs
def read_map(fname, shape=None, wcs=None, ncomp=3): m = nonan(read_helper(fname, shape, wcs)) #return m.preflat[:1] m = m.reshape(-1, m.shape[-2], m.shape[-1]) if ncomp == 0: return m[0] if len(m) == 1: res = enmap.zeros((ncomp,)+m.shape[1:],m.wcs,m.dtype) res[0] = m return res else: return m
def read_div(fname): m = nonan(enmap.read_map(fname))*1.0 return m #return m.preflat[:1][None] if m.ndim == 2: res = enmap.zeros((padlen,padlen)+m.shape[-2:], m.wcs, m.dtype) for i in range(padlen): res[i,i] = m return res elif m.ndim == 4: return m else: raise ValueError("Wrong number of dimensions in div %s" % fname)
def sim_srcs(shape, wcs, srcs, beam, omap=None, dtype=None, nsigma=5, rmax=None, method="loop", mmul=1, return_padded=False): """Simulate a point source map in the geometry given by shape, wcs for the given srcs[nsrc,{dec,ra,T...}], using the beam[{r,val},npoint], which must be equispaced. If omap is specified, the sources will be added to it in place. All angles are in radians. The beam is only evaluated up to the point where it reaches exp(-0.5*nsigma**2) unless rmax is specified, in which case this gives the maximum radius. mmul gives a factor to multiply the resulting source model by. This is mostly useful in conction with omap. method can be "loop" or "vectorized", but "loop" is both faster and uses less memory, so there's no point in using the latter. The source simulation is sped up by using a source lookup grid. """ if omap is None: omap = enmap.zeros(shape, wcs, dtype) ishape = omap.shape omap = omap.preflat ncomp = omap.shape[0] # In keeping with the rest of the functions here, srcs is [nsrc,{dec,ra,T,Q,U}]. # The beam parameters are ignored - the beam argument is used instead amps = srcs[:,2:2+ncomp] poss = srcs[:,:2].copy() # Rewind positions to let us use flat-sky approximation for distance calculations #wcs = enmap.enlib.wcs.fix_wcs(wcs) ref = np.mean(enmap.box(shape, wcs, corner=False)[:,1]) poss[:,1] = utils.rewind(poss[:,1], ref) beam = expand_beam(beam, nsigma, rmax) rmax = nsigma2rmax(beam, nsigma) # Pad our map by rmax, so we get the contribution from sources # just ourside our area. We will later split our map into cells of size cres. Let's # adjust the padding so we have a whole number of cells cres = utils.nint(rmax/omap.pixshape()) epix = cres-(omap.shape[-2:]+2*cres)%cres padding = [cres,cres+epix] wmap, wslice = enmap.pad(omap, padding, return_slice=True) # Overall we will have this many grid cells cshape = wmap.shape[-2:]/cres # Find out which sources matter for which cells srcpix = wmap.sky2pix(poss.T).T pixbox= np.array([[0,0],wmap.shape[-2:]],int) nhit, cell_srcs = build_src_cells(pixbox, srcpix, cres) posmap = wmap.posmap() model = eval_srcs_loop(posmap, poss, amps, beam, cres, nhit, cell_srcs) # Update our work map, through our view if mmul != 1: model *= mmul wmap += model if not return_padded: # Copy out omap[:] = wmap[wslice] # Restore shape omap = omap.reshape(ishape) return omap else: return wmap.reshape(ishape[:-2]+wmap.shape[-2:]), wslice
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
def sim_scan(imap, sigma, sshape, rad): w = enmap.zeros(imap.shape, imap.wcs) + (np.array([1, 0.5, 0.5]) / sigma ** 2)[:, None, None] m = imap + np.random.standard_normal(imap.shape) * w ** -0.5 # Draw random center pos r, phi = np.random.uniform(0, rad), np.random.uniform(0, 2 * np.pi) y, x = (np.array(imap.shape[-2:]) / 2 + np.array([r * np.cos(phi), r * np.sin(phi)])).astype(int) H, W = sshape mask = np.zeros(imap.shape) + 1 mask[:, : y - H / 2, :] = 0 mask[:, y + H / 2 :, :] = 0 mask[:, :, : x - W / 2] = 0 mask[:, :, x + W / 2 :] = 0 return m * mask, w * mask
def init_geometry(ishape,iwcs): modlmap = enmap.modlmap(ishape,iwcs) bin_edges = np.arange(args.kellmin,args.kellmax,args.dell) binner = stats.bin2D(modlmap,bin_edges) if args.beam<1e-5: kbeam = None else: kbeam = maps.gauss_beam(modlmap,args.beam) lmax = modlmap.max() ells = np.arange(2,lmax,1) wnoise_TT = ells*0.+(args.noise*(np.pi/180./60.))**2. wnoise_PP = 2.*wnoise_TT nT = modlmap*0.+(args.noise*(np.pi/180./60.))**2. nP = 2.*nT ncomp = 3 if pol else 1 ps = np.zeros((ncomp,ncomp,ells.size)) ps[0,0] = wnoise_TT if pol: ps[1,1] = wnoise_PP ps[2,2] = wnoise_PP oshape = (3,)+ishape if pol else ishape if not(args.flat) and args.noise_pad>1.e-5: # Pad noise sim geometry pad_width_deg = args.noise_pad pad_width = pad_width_deg * np.pi/180. res = maps.resolution(oshape[-2:],iwcs) pad_pixels = int(pad_width/res) template = enmap.zeros(oshape,iwcs) btemplate = enmap.pad(template,pad_pixels) bshape,bwcs = btemplate.shape,btemplate.wcs del template del btemplate ngen = maps.MapGen(bshape,bwcs,ps) else: ngen = maps.MapGen(oshape,iwcs,ps) tmask = maps.mask_kspace(ishape,iwcs,lmin=args.tellmin,lmax=args.tellmax) pmask = maps.mask_kspace(ishape,iwcs,lmin=args.pellmin,lmax=args.pellmax) kmask = maps.mask_kspace(ishape,iwcs,lmin=args.kellmin,lmax=args.kellmax) qest = lensing.qest(ishape,iwcs,theory,noise2d=nT,beam2d=kbeam,kmask=tmask,noise2d_P=nP,kmask_P=pmask,kmask_K=kmask,pol=pol,grad_cut=None,unlensed_equals_lensed=True) taper,w2 = maps.get_taper_deg(ishape,iwcs,taper_width_degrees = args.taper_width,pad_width_degrees = args.pad_width) fc = maps.FourierCalc(oshape,iwcs,iau=args.iau) purifier = maps.Purify(ishape,iwcs,taper) if args.purify else None return qest,ngen,kbeam,binner,taper,fc,purifier
def __init__(self, data, srcpos, pcut, nmat, perdet=False): pthumb = PmatThumbs(data, srcpos, perdet=perdet) twork = np.full(data.tod.shape, 1.0, data.tod.dtype) nmat.white(twork) div = enmap.zeros(pthumb.shape, pthumb.wcs, data.tod.dtype) junk = np.zeros(pcut.njunk,data.tod.dtype) pcut.backward(twork, junk) pthumb.backward(twork, div) div = div[:,0] self.pthumb, self.pcut, self.nmat = pthumb, pcut, nmat self.div = div with utils.nowarn(): self.idiv = 1/self.div self.idiv[~np.isfinite(self.idiv)] = 0
def grid_pos(d, params, box=np.array([[-1,-1],[1,1]])*pos_rel_max, shape=(10,10)): # Build the pos grid p = params.copy() shape, wcs = enmap.geometry(pos=box, shape=shape, proj="car") probs = enmap.zeros(shape, wcs) pos_rel = probs.posmap() best = -np.inf for iy in range(shape[0]): for ix in range(shape[1]): p.pos_rel = pos_rel[:,iy,ix] P_s, P_w, adist_strong = calc_marginal_amps_strong(d, p) probs[iy,ix] = P_s + P_w best = max(best,probs[iy,ix]) print "%4d %4d %6.2f %6.2f %9.3f %9.3f %9.3f %s" % ((iy,ix)+tuple(pos_rel[:,iy,ix]/m2r)+(probs[iy,ix],P_s,P_w) + ("*" if probs[iy,ix]>=best else "",)) return probs
def likgrid(self, R, n, super=1, marg=False, verbose=False): shape, wcs = enmap.geometry(pos=np.array([[-R, -R], [R, R]]), shape=(n, n), proj="car") dchisqs = enmap.zeros(shape, wcs) amps = enmap.zeros((self.nsrc, ) + shape, wcs) pos = dchisqs.posmap() for i, p in enumerate(pos.reshape(2, -1).T): if np.sum(p**2)**0.5 > R: continue L = self.lik.eval(p) if verbose: print "%6d %7.3f %7.3f %15.7f" % (i, p[0] / utils.arcmin, p[1] / utils.arcmin, L.chisq0 - L.chisq) dchisqs.reshape(-1)[i] = L.chisq0 - L.chisq amps.reshape(self.nsrc, -1)[:, i] = L.amps if super > 1: # Use bicubic spline interpolation to upscale shape2, wcs2 = enmap.geometry(pos=np.array([[-R, -R], [R, R]]), shape=(n * super, n * super), proj="car") dchisqs = dchisqs.project(shape2, wcs2, mode="constant") amps = amps.project(shape2, wcs2, mode="constant") return dchisqs, amps
def calc_precon(self): datasets = self.datasets # Build the preconditioner self.tot_div = enmap.ndmap( np.sum([ split.data.div for dataset in datasets for split in dataset.splits ], 0), self.wcs) self.tot_idiv = self.tot_div.copy() self.tot_idiv[self.tot_idiv > 0] **= -1 # Find the part of the sky hit by high-res data self.highres_mask = enmap.zeros(self.shape[-2:], self.wcs, np.bool) for dataset in datasets: if dataset.lowres: continue for split in dataset.splits: if split.data.empty or not split.active: continue self.highres_mask |= split.data.div > 0
def calc_rhs(self): # Build the right-hand side. The right-hand side is sum(HNHm) rhs = enmap.zeros(self.shape, self.wcs, self.dtype) for dataset in self.datasets: #print "moo", dataset.name, "iN" in dataset, id(dataset) for split in dataset.splits: if split.data.empty or not split.active: continue w = split.data.H * split.data.map fw = map_fft(w) #print dataset.name fw *= dataset.iN if self.mode == "filter": fw *= dataset.filter w = map_ifft(fw) * split.data.H rhs += w # Apply resolution mask rhs *= self.highres_mask self.rhs = rhs
def A(self, x): map = self.dof.unzip(x) res = map*0 for work in self.workspaces: # This is normall P'N"P. In our case wmap = enmap.zeros(work.geometry.shape, work.geometry.lwcs, work.geometry.dtype) work.pmat.forward(wmap, map) #wmap[:] = array_ops.matmul(work.hdiv_norm_sqrt, wmap, [0,1]) wmap *= work.hdiv_norm_sqrt ft = fft.rfft(wmap) ft *= work.wfilter fft.ifft(ft, wmap, normalize=True) wmap *= work.hdiv_norm_sqrt # Noise weighting would go here. No weighting for now #wmap[:] = array_ops.matmul(np.rollaxis(work.hdiv_norm_sqrt,1), wmap, [0,1]) work.pmat.backward(wmap, res) res = utils.allreduce(res, self.comm) return self.dof.zip(res)
def output_tile(prefix, tpos, info): shape = info.model.shape[-2:] tname = "tile%(y)03d_%(x)03d.fits" % {"y":tpos,"x":tpos[1]} ffpad_slice = (Ellipsis,slice(0,shape[0]-info.ffpad[0]),slice(0,shape[1]-info.ffpad[1])) for maptypename, mapgroup in [("snmap",info.snmaps),("snresid",info.snresid)]: for srctypename, map in mapgroups: write_padtile("%s%s_%s/%s" % (prefix, srctypename, maptypename, tname), map[ffpad_slice]) if not args.output_full_model: if len(info.model) > 0: model = info.model[0] else: model = enmap.zeros(info.model.shape[-2:], info.model.wcs, info.model.dtype) write_padtile(prefix + "model" + tname, model[ffpad_slice]) else: write_padtile(prefix + "model" + tname, info.model[ffpad_slice]) # Output total catalogue apod_slice = (slice(args.apod_edge,-args.apod_edge), slice(args.apod_edge,-args.apod_edge)) shape, wcs = enmap.slice_geometry(info.model.shape, info.model.wcs, ffpad_slice[-2:]) shape, wcs = enmap.slice_geometry(shape, wcs, apod_slice) box = enmap.box(shape, wcs) jointmap.write_catalogue(prefix + "catalogue" + tname, info.catalogue, box)
def __init__(self, workspaces, template, comm=None): """Initialize a FastmapSolver for the equation system given by the workspace list workspaces. The template argument specifies the output coordinate system. This enmap have a wcs which is pixel-compatible with that used to build the workspaces.""" if comm is None: comm = mpi.COMM_WORLD # Find the global coordinate offset needed to match our # global wcs with the template wcs corner = template.pix2sky([0,0]) gwcs, offset = offset_wcs(workspaces[0].geometry.gwcs, corner) # Prepare workspaces for solving in these coordinates self.workspaces = [] for work in workspaces: work = work.copy() with utils.nowarn(): hdiv_norm = work.hdiv / np.sum(work.hdiv[0,0],-1)[None,None,:,None] hdiv_norm[~np.isfinite(hdiv_norm)] = 0 work.hdiv_norm_sqrt = hdiv_norm[0,0]**0.5 # array_ops.eigpow(hdiv_norm, 0.5, [0,1]) # Update the global wcs and pixel coordinates work.geometry.gwcs = gwcs work.geometry.y0 -= offset[0] work.geometry.xshifts -= offset[1] # Set up our ponting matrix work.pmat = PmatWorkspaceMap(work.geometry) self.workspaces.append(work) # Update our template to match the geometry we're actually using. # If the original template was compatible, this will be a NOP geometry-wise template = enmap.zeros((work.geometry.ncomp,)+template.shape[-2:], work.geometry.gwcs, work.geometry.dtype) # Build a simple binned preconditioner # FIXME: This just makes things worse #idiv = enmap.zeros((work.geometry.ncomp,work.geometry.ncomp)+template.shape[-2:], work.geometry.gwcs, work.geometry.dtype) #for work in self.workspaces: # wmap = enmap.zeros(work.geometry.shape, work.geometry.lwcs, work.geometry.dtype) # for i in range(work.geometry.ncomp): # tmp = idiv[0]*0 # tmp[i] = 1 # work.pmat.forward(wmap, tmp) # wmap[:] = array_ops.matmul(work.hdiv, wmap, [0,1]) # wmap[:] = array_ops.matmul(np.rollaxis(work.hdiv,1), wmap, [0,1]) # work.pmat.backward(wmap, idiv[i]) #self.prec = array_ops.eigpow(idiv, -1, axes=[0,1]) self.dof = zipper.ArrayZipper(template) self.comm = comm
def __init__(self, data, srcpos, res=0.25*utils.arcmin, rad=20*utils.arcmin, perdet=False, detoff=10*utils.arcmin): scan = actscan.ACTScan(data.entry, d=data) if perdet: # Offset each detector's pointing so that we produce a grid of images, one per detector. gside = int(np.ceil(data.ndet**0.5)) goffs = np.mgrid[:gside,:gside] - (gside-1)/2.0 goffs = goffs.reshape(2,-1).T[:data.ndet]*detoff scan.offsets = scan.offsets.copy() scan.offsets[:,1:] += goffs rad = rad + np.max(np.abs(goffs)) # Build geometry for each source shape, wcs = enmap.geometry(pos=[[-rad,-rad],[rad,rad]], res=res, proj="car") area = enmap.zeros((3,)+shape, wcs, dtype=data.tod.dtype) self.pmats = [] for i, pos in enumerate(srcpos.T): if planet: sys = src_sys else: sys = ["icrs",[np.array([[pos[0]],[pos[1]],[0],[0]]),False]] with config.override("pmat_accuracy", 10): self.pmats.append(pmat.PmatMap(scan, area, sys=sys)) self.shape = (len(srcpos.T),3)+shape self.wcs = wcs
import numpy as np, argparse, os, sys from enlib import enmap, pmat, config from enact import filedb, data parser = config.ArgumentParser(os.environ["HOME"] + "/.enkirc") parser.add_argument("id") parser.add_argument("area") parser.add_argument("--di", type=int, default=0, help="Index into array of accepted detectors to use.") args = parser.parse_args() dtype = np.float64 eqsys = config.get("map_eqsys") area = enmap.read_map(args.area).astype(dtype) area = enmap.zeros((3,)+area.shape[-2:], area.wcs, dtype) entry = filedb.data[args.id] # First get the raw samples d = data.read(entry, subdets=[args.di]) raw_tod = d.tod[0,d.sample_offset:d.cutafter].copy() raw_bore = d.boresight[:,d.sample_offset:d.cutafter].T # Then some calibrated samples d = data.calibrate(d) cal_tod = d.tod[0] cal_bore = d.boresight.T # Apply fourier-truncation to raw data raw_tod = raw_tod[:cal_tod.shape[0]] raw_bore = raw_bore[:cal_bore.shape[0]] # And a proper ACTScan scan = data.ACTScan(entry, subdets=[args.di]) # Detector pointing
tod -= model del model tod = tod.astype(dtype, copy=False) # Should now be reasonably clean of correlated noise, so we can from now on use # a white noise model. with bench.show("pmat"): P = PmatTot(scan, srcpos, sys=sys) N = NmatWhite(ivar) with bench.show("pmat"): pmap = pmat.PmatMap(scan, area, sys=sys) pcut = pmat.PmatCut(scan) rhs = enmap.zeros((ncomp,)+shape, area.wcs, dtype) div = enmap.zeros((ncomp,ncomp)+shape, area.wcs, dtype) junk = np.zeros(pcut.njunk, dtype) with bench.show("rhs"): tod *= ivar[:,None] pcut.backward(tod, junk) pmap.backward(tod, rhs) with bench.show("hits"): for i in range(ncomp): div[i,i] = 1 pmap.forward(tod, div[i]) tod *= ivar[:,None] pcut.backward(tod, junk) div[i] = 0 pmap.backward(tod, div[i]) with bench.show("map"):
# This program computes a simple estimation of the amount of distortion the # flat-sky approximation involves import numpy as np, argparse from enlib import enmap parser = argparse.ArgumentParser() parser.add_argument("omap") parser.add_argument("-D", "--diameter", type=float, default=30) parser.add_argument("-n", "--npix", type=int, default=800) parser.add_argument("--proj", type=str, default="cea") args = parser.parse_args() r = args.diameter*np.pi/180/2 shape, wcs = enmap.geometry(pos=[[-r,-r],[r,r]], shape=(args.npix, args.npix), proj=args.proj) def linpos(n,b): return b[0] + (np.arange(n)+0.5)*(b[1]-b[0])/n alpha = enmap.zeros((2,)+shape, wcs) pos = enmap.posmap(shape, wcs) # I'm not sure how to compute this in general, so here's a specialization # for cylindrical projections if args.proj == "cea" or args.proj =="car": dec = pos[0,:,0] ra = pos[1,0,:] lindec= linpos(shape[0],enmap.box(shape,wcs)[:,0]) scale = 1/np.cos(dec)-1 alpha[0] = (lindec-dec)[:,None] alpha[1] = ra[None,:]*scale[:,None] enmap.write_map(args.omap, alpha*180*60/np.pi)
# Read the input maps L.info("Reading " + args.ihealmap) imap = np.atleast_2d(healpy.read_map(args.ihealmap, field=tuple(range(args.first,args.first+ncomp)))) nside = healpy.npix2nside(imap.shape[-1]) mask = imap < -1e20 dtype = imap.dtype bsize = 100 if args.unit != 1: imap[~mask]/= args.unit # Read the template shape, wcs = enmap.read_map_geometry(args.template) shape = (args.ncomp,)+shape[-2:] # Allocate our output map omap = enmap.zeros(shape, wcs, dtype) nblock = (omap.shape[-2]+bsize-1)//bsize for bi in range(nblock): r1 = bi*bsize r2 = (bi+1)*bsize print "Processing row %5d/%d" % (r1, omap.shape[-2]) # Output map coordinates osub = omap[...,r1:r2,:] pmap = osub.posmap() # Coordinate transformation if args.rot: s1,s2 = args.rot.split(",") opos = coordinates.transform(s2, s1, pmap[::-1], pol=ncomp==3) pmap[...] = opos[1::-1]
parser.add_argument("prefix",nargs="?") parser.add_argument("--ndet", type=int, default=0, help="Max number of detectors") args = parser.parse_args() filedb.init() utils.mkdir(args.odir) root = args.odir + "/" + (args.prefix + "_" if args.prefix else "") log_level = log.verbosity2level(config.get("verbosity")) dtype = np.float32 if config.get("map_bits") == 32 else np.float64 area = enmap.read_map(args.area) comm = mpi.COMM_WORLD ids = filedb.scans[args.sel] L = log.init(level=log_level, rank=comm.rank) # Set up our output map. osig = enmap.zeros((1,)+area.shape[-2:], area.wcs, dtype) odiv = osig*0 sig_all = np.zeros(len(ids)) sig_med = sig_all*0 div_all, div_med = sig_all*0, sig_med*0 # Read in all our scans for ind in range(comm.rank, len(ids), comm.size): id = ids[ind] entry = filedb.data[id] try: d = actscan.ACTScan(entry) if d.ndet == 0 or d.nsamp == 0: raise errors.DataMissing("Tod contains no valid data") except errors.DataMissing as e: L.debug("Skipped %s (%s)" % (str(id), e.message))
aspeed = np.median(np.abs(d.boresight[1,1:]-d.boresight[1,:-1])[::10])*d.srate tref = d.boresight[0,d.nsamp/2] # Build a small, high-res map around each source sdata = [] with bench.mark("scan"): scan = actscan.ACTScan(entry, d=d) pcut = pmat.PmatCut(scan) junk = np.zeros(pcut.njunk, dtype) pcut.backward(tod, junk) #wtod = apply_bivar(tod*0+1,bivar,bsize_ivar,inplace=True) wtod = tod*0+ivar[:,None] pcut.backward(wtod, junk) for sid in sids: shape, wcs = enmap.geometry(pos=[srcpos[::-1,sid]-R,srcpos[::-1,sid]+R], res=res, proj="car") area = enmap.zeros(shape, wcs, dtype) with bench.mark("pmap"): pmap = pmat.PmatMap(scan, area) rhs = enmap.zeros((3,)+shape, wcs, dtype) div = rhs*0 with bench.mark("rhs"): pmap.backward(tod, rhs) with bench.mark("div"): pmap.backward(wtod,div) div = div[0] map = rhs.copy() map[:,div>0] /= div[div>0] map = map[0] # Crop the outermost pixel, where outside hits will have accumulated map, div, area = [m[...,1:-1,1:-1] for m in [map,div,area]] # Find the local scanning velocity at the source position
if args.rot and ncomp==3: L.debug("Rotating polarization vectors") res[1:3] = enmap.rotate_pol(res[1:3], psi) else: # We will project directly onto target map if possible if args.rot: L.debug("Rotating alms") s1,s2 = args.rot.split(",") if s1 != s2: # Note: rotate_alm does not actually modify alm # if it is single precision alm = alm.astype(np.complex128,copy=False) if s1 == "gal" and (s2 == "equ" or s2 == "cel"): healpy.rotate_alm(alm, euler[0], euler[1], euler[2]) elif s2 == "gal" and (s1 == "equ" or s1 == "cel"): healpy.rotate_alm(alm,-euler[2],-euler[1],-euler[0]) else: raise NotImplementedError alm = alm.astype(ctype,copy=False) L.debug("Projecting") res = enmap.zeros((len(alm),)+shape[-2:], wcs, dtype) res = curvedsky.alm2map(alm, res) if len(args.templates) > 1: oname = args.odir + "/" + os.path.basename(tfile) else: oname = args.ofile if args.oslice: res = eval("res"+args.oslice) L.info("Writing " + oname) enmap.write_map(oname, res)
print "alm -> P" sht.alm2map(alm[1:], field.map[1:].reshape(2,-1), spin=2) # Reapply spline filter print "Prefilter" field.pmap = utils.interpol_prefilter(field.map, order=field.order) print "Beam done" phi = np.full(args.nsamp, args.phi, dtype=float) theta = np.arange(args.nsamp)*2*np.pi/args.nsamp phi [theta> np.pi/2] = phi[theta > np.pi/2] + np.pi theta[theta> np.pi/2] = np.pi - theta[theta> np.pi/2] phi [theta<-np.pi/2] = phi[theta <-np.pi/2] - np.pi theta[theta<-np.pi/2] = -np.pi - theta[theta<-np.pi/2] pos = np.array([theta,phi]) res = enmap.zeros((len(freqs),3,args.nsamp)) for field in fields: vals = field.pmap.at(pos, order=field.order, prefilter=False, mask_nan=False, safe=False, mode="wrap") res += field.spec(freqs, vals[...,None])[...,0] if args.apply_beam: # Apply frequency part of beam too res *= scatter[:,None,None] with h5py.File(args.ofile, "w") as hfile: hfile["data"] = res hfile["freq"] = freqs #maps = [field.project(shape, wcs)(freqs) for field in fields] #maps.insert(0, np.sum(maps,0)) #maps = enmap.samewcs(np.array(maps), maps[1])
parser.add_argument("area") parser.add_argument("sel") parser.add_argument("odir") parser.add_argument("-n", "--nstep", type=int, default=50) parser.add_argument("-m", "--method",type=str, default="messenger") parser.add_argument( "--ndet", type=int, default=None) parser.add_argument("-p", "--precompute", action="store_true") parser.add_argument("-o", "--ostep", type=int, default=10) args = parser.parse_args() utils.mkdir(args.odir) comm = mpi.COMM_WORLD dtype = np.float32 ncomp = 3 area = enmap.read_map(args.area) area = enmap.zeros((ncomp,)+area.shape[-2:],area.wcs,dtype) Tscale = 0.9 nstep = args.nstep downsample = config.get("downsample") filedb.init() ids = filedb.scans[args.sel] # Was 1e7 cooldown = sum([[10**j]*5 for j in range(6,0,-1)],[])+[1] # Read my scans njunk_tot = 0 cg_rhs = area*0 cg_rjunk = [] if args.precompute: prec_NNmap = {lam: area*0 for lam in np.unique(cooldown)}
# Construct our output coordinates, a zea system. My standard # constructor doesn't handle pole crossing, so do it manually. with dprint("construct omap"): R = args.radius*deg2rad res = args.res*min2rad wo = wcsutils.WCS(naxis=2) wo.wcs.ctype = ["RA---ZEA","DEC--ZEA"] wo.wcs.crval = [0,90] wo.wcs.cdelt = [res/deg2rad, res/deg2rad] wo.wcs.crpix = [1,1] x, y = wo.wcs_world2pix(0,90-R/deg2rad,1) y = int(np.ceil(y)) n = 2*y-1 wo.wcs.crpix = [y,y] omap = enmap.zeros((n,n),wo) # Construct our projection coordinates this is a CAR system in order # to make interpolation easy. with dprint("construct imap"): ires = np.array([1,1./np.sin(R)])*res/args.supersample shape, wi = enmap.geometry(pos=[[np.pi/2-R,-np.pi],[np.pi/2,np.pi]], res=ires, proj="car") imap = enmap.zeros((ncomp,)+shape, wi) # Define SHT for interpolation pixels with dprint("construct sht"): minfo = curvedsky.map2minfo(imap) lmax_ideal = np.pi/res ps = ps[:,:,:lmax_ideal] lmax = ps.shape[-1] # We do not need all ms when centered on the pole. To reach 1e-10 relative
comm = mpi.COMM_WORLD dtype= np.float32 nref = args.nref min_accuracy = 1.0 # 1 pixel utils.mkdir(args.odir) src_cols = [int(w) for w in args.cols.split(":")] # Set up thumbnail geometry res = args.res*utils.arcmin pad = args.pad*utils.arcmin box = np.array([[float(w) for w in dim.split(":")] for dim in args.box.split(",")]).T*utils.arcmin box[0] -= pad box[1] += pad shape, wcs = enmap.geometry(pos=box, res=res, proj="car") area = enmap.zeros(shape, wcs, dtype) def read_srcs(fname, cols=(0,1,2)): if fname.endswith(".fits"): data = fits.open(fname)[1].data return np.array([data.ra*utils.degree,data.dec*utils.degree,data.sn]) else: data = np.loadtxt(fname, usecols=cols).T data[:2] *= utils.degree return data def find_ref_pixs(divs, rcost=1.0, dcost=1.0): """rcost is cost per pixel away from center dcost is cost per dB change in div value avay from median""" # Find median nonzero div per map ref_val = np.asarray(np.median(np.ma.array(divs, mask=divs==0),(-2,-1)))
import numpy as np, argparse from enlib import enmap from scipy import ndimage parser = argparse.ArgumentParser() parser.add_argument("pos") parser.add_argument("template") parser.add_argument("ofile") parser.add_argument("-r", "--radius", type=float, default=3) parser.add_argument("-c", "--columns", type=str, default="3,5,2") parser.add_argument("-t", "--threshold", type=float, default=0) args = parser.parse_args() cols = [int(w) for w in args.columns.split(",")] srcinfo = np.loadtxt(args.pos)[:,cols] pos = srcinfo[np.abs(srcinfo[:,2])>=args.threshold][:,:2] * np.pi/180 map = enmap.read_map(args.template) pix = map.sky2pix(pos.T).T.astype(int) pixrad = (map.area()/map.npix)**0.5 mrad = args.radius*np.pi/180/60/pixrad mask = enmap.zeros(map.shape[-2:], map.wcs)+1 mask[pix[:,0],pix[:,1]] = 0 mask = enmap.enmap(1.0*(ndimage.distance_transform_edt(mask) > mrad), map.wcs) enmap.write_map(args.ofile, mask)
dets.append(det) offs.append(off) boxes.append(box) imaps.append(imap) box = utils.bounding_box(boxes) box = utils.widen_box(box, rad*5, relative=False) # We assume that the two maps have the same pixelization imaps = enmap.samewcs(np.array(imaps), imaps[0]) # Downsample by averaging imaps = enmap.downgrade(imaps, (1,args.step)) naz = imaps.shape[-1] # Ok, build our output geometry shape, wcs = enmap.geometry(pos=box, res=args.res*utils.arcmin, proj="car", pre=(naz,)) omap = enmap.zeros(shape, wcs, dtype=dtype) # Normalization norm = enmap.zeros(shape[-2:],wcs) norm[0,0] = 1 norm = enmap.smooth_gauss(norm, rad)[0,0] # Loop through slices and populate bazs = [] for iaz in range(naz): # Get our boresight az bazs.append(imaps.pix2sky([0,iaz])[1]) vals = [] for i in range(nfile): # Go from detectors to y-pixel in input maps ypix = utils.transpose_inds(dets[i], nrow, ncol)