Exemplo n.º 1
0
Arquivo: pmat.py Projeto: Nium14/enlib
def build_work_shift(transform, hor_box, scan_period):
    """Given a transofrmation that takes [{t,az,el},nsamp] into [{y,x,...},nsamp],
	and a bounding box [{from,to},{t,az,el}], compute the parameters for a
	per-y shift in x that makes scans roughly straight. These parameters are returned
	in the form of wbox[{from,to},{y,x'}] and wshift[{up,down},ny]. They are used in the shifted
	pmat implementation."""
    # The problem with using the real scanning profile is that it can't be adjusted to
    # cover all the detectors, and at any y, the az where a detector hits that y will
    # be different. So only one of them can faithfully follow the profile after all.
    # So I think I'll stay with the simple model I use here, and just take the travel
    # time into account, through an extra parameter.

    # Find the pixel bounds corresponding to our hor bounds
    hor_corn = utils.box2contour(hor_box, 100)
    pix_corn = transform(hor_corn.T)[:2].T
    pix_box = utils.bounding_box(pix_corn)
    pix_box = utils.widen_box(pix_box, 10, relative=False)
    # The y bounds are the most relevant. Our wshift must
    # be defined for every output y in the range.
    y0 = int(np.floor(pix_box[0, 0]))
    y1 = int(np.ceil(pix_box[1, 0])) + 1
    mean_t, mean_az, mean_el = np.mean(hor_box, 0)
    # Get a forward and backwards sweep. So index 0 is az increasing, index 1 is az decreasing
    # Divide scan period by 2 because there is a forwards and backward sweep per period.
    wshift = np.array([
        measure_sweep_pixels(transform, [mean_t, mean_t + scan_period / 2],
                             hor_box[:, 1], mean_el, [y0, y1]),
        measure_sweep_pixels(transform, [mean_t, mean_t + scan_period / 2],
                             hor_box[::-1, 1], mean_el, [y0, y1])
    ])
    # For each of these, find the pixel bounds. The total
    # bounds will be the union of these
    wboxes = []
    for wshift_single in wshift:
        # Use this shift to transform the pixel corners into shifted
        # coordinates. This wil give us the bounds of the shifted system
        shift_corn = pix_corn.copy()
        np.set_printoptions(suppress=True)
        shift_corn[:, 1] -= wshift_single[np.round(shift_corn[:, 0] -
                                                   y0).astype(int)]
        wboxes.append(utils.bounding_box(shift_corn))
    # Merge wboxes
    wbox = utils.bounding_box(wboxes)
    wbox[0] = np.floor(wbox[0])
    wbox[1] = np.ceil(wbox[1])
    wbox = wbox.astype(int)
    print "wbox"
    print wbox
    print "wshift"
    print wshift
    return wbox, wshift
Exemplo n.º 2
0
def calc_sky_bbox_scan(scan, osys, nsamp=100):
	"""Compute the bounding box of the scan in the osys coordinate system.
	Returns [{from,to},{dec,ra}]."""
	ipoints = utils.box2contour(scan.box, nsamp)
	opoints = np.array([coordinates.transform(scan.sys,osys,b[1:,None],time=scan.mjd0+b[0,None]/3600/24,site=scan.site)[::-1,0] for b in ipoints])
	# Take care of angle wrapping along the ra direction
	opoints[...,1] = utils.rewind(opoints[...,1], ref="auto")
	obox = utils.bounding_box(opoints)
	# Grow slighly to account for non-infinite nsamp
	obox = utils.widen_box(obox, 5*utils.arcmin, relative=False)
	return obox
Exemplo n.º 3
0
def classify_scanning_patterns(myscans, tol=0.5*utils.degree, comm=None):
	"""Classify scans into scanning patterns based on [az,el] bounds.
	Returns patterns[:,{ftom,to},{el,az}] and pids[len(myscans)], where
	pids contains the index of each myscan into patterns."""
	boxes = get_scan_bounds(myscans)
	rank  = np.full(len(boxes),comm.rank)
	if comm is not None:
		boxes = utils.allgatherv(boxes, comm)
		rank  = utils.allgatherv(rank,  comm)
	pids = utils.label_unique(boxes, axes=(1,2), atol=tol)
	npattern = np.max(pids)+1
	# For each scanning pattern, define a bounding box
	pboxes = np.array([utils.bounding_box(boxes[pids==pid]) for pid in xrange(npattern)])
	# Get the ids for the scans that we have
	if comm is not None:
		pids = pids[rank==comm.rank]
	return pboxes, pids
Exemplo n.º 4
0
def distribute_scans(myinds, mycosts, myboxes, comm):
    """Given the costs[nmyscan] and bounding boxes[nmyscan,2,2] of our local scans,
	compute a new scan distribution that distributes costs
	relatively evenly while keeping all scans a task owns
	in a local area of the sky. Returns the new myinds[nmyscan2] (indices into
	global scans array), mysubs[nmyscan2] (workspace index for each of my new scans),
	mybbox [nmyscan2,2,2] (bounding boxes for the new scans).

	This function does not move the scan data to the new processes. This is
	up tot he caller."""
    all_costs = np.array(comm.allreduce(mycosts))
    all_inds = np.array(comm.allreduce(myinds))
    if myboxes is None:
        myinds = all_inds[utils.equal_split(all_costs, comm.size)[comm.rank]]
        return myinds
    else:
        #hfile = h5py.File("tmp%02d.hdf" % comm.rank, "w")
        all_boxes = np.array(comm.allreduce(myboxes))
        #hfile["all1"] = all_boxes/utils.degree
        # Avoid angle wraps. We assume that the boxes are all correctly wrapped
        # individually.
        ras = all_boxes[:, :, 1]
        ra_ref = np.median(np.mean(ras, 1))
        rashift = ra_ref + (ras[:, 0] - ra_ref +
                            np.pi) % (2 * np.pi) - np.pi - ras[:, 0]
        ras += rashift[:, None]
        all_boxes[:, :, 1] = ras
        #hfile["all2"] = all_boxes/utils.degree
        myinds_old = myinds
        #hfile["myinds1"] = myinds
        # Split into nearby scans
        mygroups = dmap.split_boxes_rimwise(all_boxes, all_costs,
                                            comm.size)[comm.rank]
        myinds = [all_inds[i] for group in mygroups for i in group]
        #hfile["myinds2"] = myinds
        mysubs = [gi for gi, group in enumerate(mygroups) for i in group]
        #hfile["mysubs"] = mysubs
        #hfile["myboxes"] = np.array([all_boxes[i] for i in mygroups[0]])/utils.degree
        mybbox = [
            utils.bounding_box([all_boxes[i] for i in group])
            for group in mygroups
        ]
        #hfile["mybbox"] = mybbox[0]/utils.degree
        #hfile.close()
        return myinds, mysubs, mybbox
Exemplo n.º 5
0
		continue
	# Reorder from az,el to el,az
	boxes[ind] = [np.min(d.boresight[2:0:-1],1),np.max(d.boresight[2:0:-1],1)]
	L.info("%5d: %s" % (ind, id))
boxes = utils.allreduce(boxes, comm_world)

# Prune null boxes
usable = np.all(boxes!=0,(1,2))
moo = ids[usable]
cow = boxes[usable]

ids, boxes = ids[usable], boxes[usable]

pattern_ids = utils.label_unique(boxes, axes=(1,2), atol=tol)
npattern = np.max(pattern_ids)+1
pboxes = np.array([utils.bounding_box(boxes[pattern_ids==pid]) for pid in xrange(npattern)])
pscans = [np.where(pattern_ids==pid)[0] for pid in xrange(npattern)]

L.info("Found %d scanning patterns" % npattern)

# Build the set of tasks we should go through. This effectively
# collapses these two loops, avoiding giving rank 0 much more
# to do than the last ranks.
tasks = []
for pid, group in enumerate(pscans):
	# Start at pattern p0
	if pid < args.p0: continue
	ngroup = (len(group)+tods_per_map-1)/tods_per_map
	for gind in range(ngroup):
		tasks.append([pid,gind,group[gind*tods_per_map:(gind+1)*tods_per_map]])
Exemplo n.º 6
0
        np.max(d.boresight[2:0:-1], 1)
    ]
    L.info("%5d: %s" % (ind, id))
boxes = utils.allreduce(boxes, comm_world)

# Prune null boxes
usable = np.all(boxes != 0, (1, 2))
moo = ids[usable]
cow = boxes[usable]

ids, boxes = ids[usable], boxes[usable]

pattern_ids = utils.label_unique(boxes, axes=(1, 2), atol=tol)
npattern = np.max(pattern_ids) + 1
pboxes = np.array([
    utils.bounding_box(boxes[pattern_ids == pid]) for pid in xrange(npattern)
])
pscans = [np.where(pattern_ids == pid)[0] for pid in xrange(npattern)]

L.info("Found %d scanning patterns" % npattern)

# Build the set of tasks we should go through. This effectively
# collapses these two loops, avoiding giving rank 0 much more
# to do than the last ranks.
tasks = []
for pid, group in enumerate(pscans):
    # Start at pattern p0
    if pid < args.p0: continue
    ngroup = (len(group) + tods_per_map - 1) / tods_per_map
    for gind in range(ngroup):
        tasks.append(
Exemplo n.º 7
0
    ilayfiles = args.ifiles[1::2]

# Read in our focalplane layouts so we can define our output map bounds
dets, offs, boxes, imaps = [], [], [], []
for i in range(nfile):
    det, off = files.read_point_template(ilayfiles[i])
    imap = enmap.read_map(imapfiles[i])
    if args.slice: imap = eval("imap" + args.slice)
    # We want y,x-ordering
    off = off[:, ::-1]
    box = utils.minmax(off, 0)
    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)
Exemplo n.º 8
0
free_blocks  = np.where(block_ownership<0)[0]
nfixed = len(fixed_blocks)
nfree  = len(free_blocks)

sys.stderr.write("splitting %d:[%s] tods into %d splits via %d blocks%s" % (
	ntod, atolist(nper), nsplit, nblock, (" with %d:%d free:fixed" % (nfree,nfixed)) if nfixed > 0 else "") + "\n")

# We assume that site and pointing offsets are the same for all tods,
# so get them based on the first one
entry = filedb.data[ids[0]]
site  = actdata.read(entry, ["site"]).site

# Determine the bounding box of our selected data
bounds    = db.data["bounds"].reshape(2,-1).copy()
bounds[0] = utils.rewind(bounds[0], bounds[0,0], 360)
box = utils.widen_box(utils.bounding_box(bounds.T), 4*args.rad, relative=False)
waz, wel = box[1]-box[0]
# Use fullsky horizontally if we wrap too far
if waz <= 180:
	shape, wcs = enmap.geometry(pos=box[:,::-1]*utils.degree, res=args.res*utils.degree, proj="car", ref=(0,0))
else:
	shape, wcs = enmap.fullsky_geometry(res=args.res*utils.degree)
	y1, y2 = np.sort(enmap.sky2pix(shape, wcs, [box[:,1]*utils.degree,[0,0]])[0].astype(int))
	shape, wcs = enmap.slice_geometry(shape, wcs, (slice(y1,y2),slice(None)))

sys.stderr.write("using %s workspace with resolution %.2f deg" % (str(shape), args.res) + "\n")

# Get the hitmap for each block
hits = enmap.zeros((nblock,narray)+shape, wcs)
ndig = calc_ndig(nblock)
sys.stderr.write("estimating hitmap for block %*d/%d" % (ndig,0,nblock))
Exemplo n.º 9
0
	ilayfiles = args.ifiles[1::2]

# Read in our focalplane layouts so we can define our output map bounds
dets, offs, boxes, imaps = [], [], [], []
for i in range(nfile):
	det, off = files.read_point_template(ilayfiles[i])
	imap = enmap.read_map(imapfiles[i])
	if args.slice: imap = eval("imap"+args.slice)
	# We want y,x-ordering
	off = off[:,::-1]
	box = utils.minmax(off,0)
	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
Exemplo n.º 10
0
free_blocks  = np.where(block_ownership<0)[0]
nfixed = len(fixed_blocks)
nfree  = len(free_blocks)

sys.stderr.write("splitting %d:[%s] tods into %d splits via %d blocks%s" % (
	ntod, atolist(nper), nsplit, nblock, (" with %d:%d free:fixed" % (nfree,nfixed)) if nfixed > 0 else "") + "\n")

# We assume that site and pointing offsets are the same for all tods,
# so get them based on the first one
entry = filedb.data[ids[0]]
site  = actdata.read(entry, ["site"]).site

# Determine the bounding box of our selected data
bounds    = db.data["bounds"].reshape(2,-1).copy()
bounds[0] = utils.rewind(bounds[0], bounds[0,0], 360)
box = utils.widen_box(utils.bounding_box(bounds.T), 4*args.rad, relative=False)
waz, wel = box[1]-box[0]
# Use fullsky horizontally if we wrap too far
if waz <= 180:
	shape, wcs = enmap.geometry(pos=box[:,::-1]*utils.degree, res=args.res*utils.degree, proj="car", ref=(0,0))
else:
	shape, wcs = enmap.fullsky_geometry(res=args.res*utils.degree)
	y1, y2 = np.sort(enmap.sky2pix(shape, wcs, [box[:,1]*utils.degree,[0,0]])[0].astype(int))
	shape, wcs = enmap.slice_geometry(shape, wcs, (slice(y1,y2),slice(None)))

sys.stderr.write("using %s workspace with resolution %.2f deg" % (str(shape), args.res) + "\n")

# Get the hitmap for each block
hits = enmap.zeros((nblock,narray)+shape, wcs)
ndig = calc_ndig(nblock)
sys.stderr.write("estimating hitmap for block %*d/%d" % (ndig,0,nblock))