Ejemplo n.º 1
0
def point_in_polygon_safe(points, polygons):
    points = np.asarray(points)
    polygons = np.array(polygons)
    # Put the polygon on the same side of the sky as the points
    polygons[0] = utils.rewind(polygons[0], points[0], 360)
    # But don't allow sky wraps inside polygons
    polygons[0] = utils.rewind(polygons[0], polygons[0, 0], 360)
    return utils.point_in_polygon(points.T, polygons.T)
Ejemplo n.º 2
0
def poly_dist(points, polygons):
    points = np.asarray(points) * utils.degree
    polygons = np.array(polygons) * utils.degree
    # Put the polygon on the same side of the sky as the points
    polygons[0] = utils.rewind(polygons[0], points[0])
    # But don't allow sky wraps inside polygons
    polygons[0] = utils.rewind(polygons[0], polygons[0, 0])
    inside = utils.point_in_polygon(points.T, polygons.T)
    dists = utils.poly_edge_dist(points.T, polygons.T)
    dists = np.where(inside, 0, dists)
    return dists
Ejemplo n.º 3
0
def get_sids_in_tod(id, src_pos, bounds, ind, isids=None, src_sys="cel"):
	if isids is None: isids = list(range(src_pos.shape[-1]))
	if bounds is not None:
		poly      = bounds[:,:,ind]*utils.degree
		poly[0]   = utils.rewind(poly[0],poly[0,0])
		# bounds are defined in celestial coordinates. Must convert srcpos for comparison
		mjd       = utils.ctime2mjd(float(id.split(".")[0]))
		srccel    = coordinates.transform(src_sys, "cel", src_pos, time=mjd)
		srccel[0] = utils.rewind(srccel[0], poly[0,0])
		poly      = pad_polygon(poly.T, poly_pad).T
		accepted  = np.where(utils.point_in_polygon(srccel.T, poly.T))[0]
		sids      = [isids[i] for i in accepted]
	else:
		sids = isids
	return sids
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
def interpol_pos(from_sys, to_sys, name_or_pos, mjd, site=None, dt=10):
    """Given the name of an ephemeris object or a [ra,dec]-type position
	in radians in from_sys, compute its position in the specified coordinate system for
	each mjd. The mjds are assumed to be sampled densely enough that
	interpolation will work. For ephemeris objects, positions are
	computed in steps of 10 seconds by default (controlled by the dt argument)."""
    box = utils.widen_box([np.min(mjd), np.max(mjd)], 1e-2)
    sub_nsamp = max(3, int((box[1] - box[0]) * 24. * 3600 / dt))
    sub_mjd = np.linspace(box[0], box[1], sub_nsamp, endpoint=True)
    if isinstance(name_or_pos, basestring):
        sub_from = ephem_pos(name_or_pos, sub_mjd)
    else:
        pos = np.asarray(name_or_pos)
        assert pos.ndim == 1
        sub_from = np.zeros([2, sub_nsamp])
        sub_from[:] = np.asarray(name_or_pos)[:, None]
    sub_pos = transform_raw(from_sys,
                            to_sys,
                            sub_from,
                            time=sub_mjd,
                            site=site)
    sub_pos[1] = utils.rewind(sub_pos[1], ref="auto")
    inds = (mjd - box[0]) * (sub_nsamp - 1) / (box[1] - box[0])
    full_pos = utils.interpol(sub_pos, inds[None], order=3)
    return full_pos
Ejemplo n.º 7
0
def earth2sun(pos_earthrel, time, sundist, diff=False):
    """Compute the apparent displacement pos_sunrel - pos_earthrel for
	a source with earth-relative pointing given by pos_earthrel[{ra,dec},:] at the given time,
	and with the given distance from the sun (in AU)."""
    # Compute the position of the object relative to the earth at each time
    vec_obj_earthrel = utils.ang2rect(pos_earthrel, zenith=False)
    vec_earth_sunrel = -ephemeris.ephem_vec("Sun", time)
    # Get the object earth distance based on the sun distance, using
    # the law of sines: sin(obj_earth_sun)/obj_sun = sin(sun_obj_earth)/obj_earth.
    b = np.sum(vec_earth_sunrel**2, 0)**0.5
    c = sundist
    cosC = np.sum(-(vec_obj_earthrel.T * vec_earth_sunrel.T).T, 0) / b
    sinC = (1 - cosC**2)**0.5
    sinB = sinC * b / c
    sinA = np.sin(np.pi - np.arcsin(sinB) - np.arcsin(sinC))
    a = b * sinA / sinB
    earthdist = a
    vec_obj_earthrel *= earthdist
    # Get the relative position
    vec_obj_sunrel = (vec_obj_earthrel.T + vec_earth_sunrel.T).T
    # Translate this into an angular position
    pos_sunrel = utils.rect2ang(vec_obj_sunrel, zenith=False)
    if not diff: return pos_sunrel
    # And turn that into a displacement
    offset = pos_sunrel - pos_earthrel
    offset[1] = utils.rewind(offset[1])
    return offset
Ejemplo n.º 8
0
def transform_meta(transfun, coords, fields=["ang", "mag"], offset=5e-7):
    """Computes metadata for the coordinate transformation functor
	transfun applied to the coordinate array coords[2,...],
	such as the induced rotation, magnification.

	Currently assumes that input and output coordinates are in
	non-zenith polar coordinates. Might generalize this later.
	"""
    if "mag_brute" in fields: ntrans = 3
    elif "ang" in fields: ntrans = 2
    else: ntrans = 1
    coords = np.asarray(coords)
    offsets = np.array([[0, 0], [1, 0], [0, 1]]) * offset
    # Transform all the coordinates. We assume we aren't super-close to the poles
    # either before or after the transformation.
    ocoords = np.zeros((ntrans, 2) + coords.shape[1:])
    ocoords = None
    for i in range(ntrans):
        # Transpose to get broadcasting right
        a = transfun((coords.T + offsets[i].T).T)
        if ocoords is None:
            ocoords = np.zeros((ntrans, ) + a.shape, a.dtype)
        ocoords[i] = a

    class Result:
        pass

    res = Result()
    res.icoord = coords
    res.ocoord = ocoords[0]

    # Compute the individual properties we're interested in
    diff = utils.rewind(ocoords[1:] - ocoords[0, None])
    if "ang" in fields:
        # We only need the theta offset of this one. We started with
        # an offset in the [1,0] direction, and want to know how
        # far we have rotated away from this direction. This
        # Uses the IAU tangent plane angle convention:
        # http://healpix.jpl.nasa.gov/html/intronode12.htm
        # and assumes that both input and putput coordinates have the
        # same handedness. This is not always the case, for example
        # with horizontal to celestial coordinate transformations.
        # In these cases, the caller must correct there resulting angle
        # manually.
        phiscale = np.cos(ocoords[0, 1])
        res.ang = np.arctan2(diff[0, 1], diff[0, 0] * phiscale)
    if "mag" in fields:
        res.mag = np.cos(res.icoord[1]) / np.cos(res.ocoord[1])
    if "mag_brute" in fields:
        # Compute the ratio of the areas of the triangles
        # made up by the three point-sets in the input and
        # output coordinates. This ratio is always 1 when
        # using physical areas, so we instead compute the
        # apparent areas here.
        def tri_area(diff):
            return 0.5 * np.abs(diff[0, 0] * diff[1, 1] -
                                diff[0, 1] * diff[1, 0])

        res.mag = (tri_area(diff).T / tri_area(offsets[1:] - offsets[0]).T).T
    return res
Ejemplo n.º 9
0
 def get_templates(self, pos, irads):
     x = utils.rewind(self.pos - pos[:, None, None], 0, 2 * np.pi)
     W = np.array([[irads[0], irads[2]], [irads[2], irads[1]]])
     xWx = np.sum(np.einsum("ab,byx->ayx", W, x) * x, 0)
     profile = np.exp(-0.5 * xWx)
     bases = np.eye(self.nfreq * self.ncomp).reshape(
         self.nfreq * self.ncomp, self.nfreq, self.ncomp)
     return profile[None, None, None] * bases[:, :, :, None, None]
Ejemplo n.º 10
0
def calc_driftangle(hor, t, site):
	hor = np.atleast_2d(hor).T
	t   = np.atleast_1d(t)
	equ = coordinates.transform("hor", "equ", hor, time=utils.ctime2mjd(t), site=site)
	hor_drift = utils.rewind(coordinates.transform("equ","hor", equ, time=utils.ctime2mjd(t+1), site=site),hor,2*np.pi)
	vec_drift = hor_drift-hor
	# Compute angle between this vector and the az axis
	angle = np.arctan2(vec_drift[1],vec_drift[0]*np.cos(hor[1]))%np.pi
	return angle
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
def hor2cel(hor):
	shape = hor.shape[1:]
	hor = hor.reshape(hor.shape[0],-1)
	tmp = coordinates.transform("hor", "cel", hor[1:], time=hor[0]+t_mid, site=site, pol=True)
	res = np.zeros((4,)+tmp.shape[1:])
	res[0] = utils.rewind(tmp[0], tmp[0,0])
	res[1] = tmp[1]
	res[2] = np.cos(2*tmp[2])
	res[3] = np.sin(2*tmp[2])
	res = res.reshape(res.shape[:1]+shape)
	return res
Ejemplo n.º 13
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
Ejemplo n.º 14
0
def calc_pbox(shape, wcs, box, n=10):
    nphi = utils.nint(np.abs(360 / wcs.wcs.cdelt[0]))
    dec = np.linspace(box[0, 0], box[1, 0], n)
    ra = np.linspace(box[0, 1], box[1, 1], n)
    y = enmap.sky2pix(shape, wcs, [dec, dec * 0 + box[0, 1]])[0]
    x = enmap.sky2pix(shape, wcs, [ra * 0 + box[0, 0], ra])[1]
    x = utils.unwind(x, nphi)
    pbox = np.array([[np.min(y), np.min(x)], [np.max(y), np.max(x)]])
    xm1 = np.mean(pbox[:, 1])
    xm2 = utils.rewind(xm1, shape[-1] / 2, nphi)
    pbox[:, 1] += xm2 - xm1
    pbox = utils.nint(pbox)
    return pbox
Ejemplo n.º 15
0
def hor2cel(hor, toff):
	"""Transform from [{tsec,az,el},nsamp] to [{ra,dec,c,s},nsamp],
	where tsec is the offset from toff. Toff is given in mjd."""
	shape = hor.shape[1:]
	hor = hor.reshape(hor.shape[0],-1).astype(float)
	tmp = coordinates.transform("hor", "cel", hor[1:], time=hor[0]/24/60/60+toff, site=site, pol=True)
	res = np.zeros((4,)+tmp.shape[1:])
	res[0] = utils.rewind(tmp[0], tmp[0,0])
	res[1] = tmp[1]
	res[2] = np.cos(2*tmp[2])
	res[3] = np.sin(2*tmp[2])
	res = res.reshape(res.shape[:1]+shape)
	return res
Ejemplo n.º 16
0
def find_scan_vel(scan, ipos, aspeed, dt=0.1):
    hpos = coordinates.transform("equ",
                                 "hor",
                                 ipos,
                                 time=scan.mjd0,
                                 site=scan.site)
    hpos[0] += aspeed * dt
    opos = coordinates.transform("hor",
                                 "equ",
                                 hpos,
                                 time=scan.mjd0,
                                 site=scan.site)
    opos[0] = utils.rewind(opos[0], ipos[0])
    return (opos - ipos) / dt
Ejemplo n.º 17
0
def sun2earth(pos_sunrel, time, sundist, diff=False):
    """Compute the apparent displacement pos_earthrel - pos_sunrel for
	a source with sun-relative pointing given by pos_sunrel[{ra,dec},:] at the given time,
	and with the given distance from the sun (in AU)."""
    # Compute the position of the object relative to the earth at each time
    vec_obj_sunrel = utils.ang2rect(pos_sunrel, zenith=False) * sundist
    vec_sun_earthrel = ephemeris.ephem_vec("Sun", time)
    vec_obj_earthrel = (vec_obj_sunrel.T + vec_sun_earthrel.T).T
    # Translate this into an angular position
    pos_earthrel = utils.rect2ang(vec_obj_earthrel, zenith=False)
    if not diff: return pos_earthrel
    # And turn that into a displacement
    offset = pos_earthrel - pos_sunrel
    offset[1] = utils.rewind(offset[1])
    return offset
Ejemplo n.º 18
0
Archivo: pmat.py Proyecto: Nium14/enlib
    def __call__(self, ipos):
        """Transform ipos[{t,az,el},nsamp] into opix[{y,x,c,s},nsamp]."""
        shape = ipos.shape[1:]
        ipos = ipos.reshape(ipos.shape[0], -1)
        time = self.scan.mjd0 + ipos[0] / utils.day2sec
        # We support sidelobe mapping by passing the detector pointing "ipos" as the "boresight"
        # pointing, which is only used in boresight-relative coordinates or sidelobe mapping.
        # This actually results in a better coordinate system than if we had passed in the actual
        # boresight, since we don't really want boresight-centered coordinates, we want detector
        # centered coordinates.
        opos = coordinates.transform(self.scan.sys,
                                     self.sys,
                                     ipos[1:],
                                     time=time,
                                     site=self.scan.site,
                                     pol=True,
                                     bore=ipos[1:])
        # Parallax correction
        sundist = config.get("pmat_parallax_au")
        if sundist:
            # Transform to a sun-centered coordinate system, assuming all objects
            # are at a distance of sundist from the sun
            opos[1::-1] = parallax.earth2sun(opos[1::-1], self.scan.mjd0,
                                             sundist)

        opix = np.zeros((4, ) + ipos.shape[1:])
        if self.template is not None:
            opix[:2] = self.template.sky2pix(opos[1::-1], safe=2)
            # When mapping the full sky, angle wraps can't be hidden
            # ouside the image. We must therefore unwind along each
            # interpolation axis to avoid discontinuous interpolation
            nx = int(np.round(np.abs(360 / self.template.wcs.wcs.cdelt[0])))
            opix[1] = utils.unwind(opix[1].reshape(shape),
                                   period=nx,
                                   axes=range(len(shape))).reshape(-1)
            # Prefer positive numbers
            opix[1] -= np.floor(opix[1].reshape(-1)[0] / nx) * nx
            # but not if they put everything outside our patch
            if np.min(opix[1]) > self.template.shape[-1]:
                opix[1] -= nx
        else:
            # If we have no template, output angles instead of pixels.
            # Make sure the angles don't have any jumps in them
            opix[:2] = opos[1::-1]  # output order is dec,ra
            opix[1] = utils.rewind(opix[1], self.ref_phi)
        opix[2] = np.cos(2 * opos[2])
        opix[3] = np.sin(2 * opos[2])
        return opix.reshape((opix.shape[0], ) + shape)
Ejemplo n.º 19
0
 def apply(self, dir, tod, srcs, tmul=None, pmul=None):
     if tmul is None: tmul = self.tmul
     if pmul is None: pmul = self.pmul
     while srcs.ndim < 4: srcs = srcs[:,None]
     # Handle angle wrapping without modifying the original srcs array
     wsrcs = srcs.copy()
     wsrcs[...,:2] = utils.rewind(srcs[...,:2], self.ref) # + self.dpos
     core = get_core(tod.dtype)
     # boresight: (t, az, el)
     core.pmat_ptsrc3(dir, tmul, pmul, tod.T, wsrcs.T,
                     self.scan.boresight.T, self.scan.offsets.T, self.scan.comps.T,
                     self.rbox.T, self.nbox.T, self.yvals.T,
                     self.beam[1], self.beam[0,-1], self.rmax,
                     self.cells.T, self.ncell.T, self.cbox.T)
     # Copy out any amplitudes that may have changed
     srcs[...,2:5] = wsrcs[...,2:5]  # 2:5 -> T,Q,U in nparams
Ejemplo n.º 20
0
def hor2cel(hor):
    shape = hor.shape[1:]
    hor = hor.reshape(hor.shape[0], -1)
    tmp = coordinates.transform("hor",
                                "cel",
                                hor[1:],
                                time=hor[0] + t_mid,
                                site=site,
                                pol=True)
    res = np.zeros((4, ) + tmp.shape[1:])
    res[0] = utils.rewind(tmp[0], tmp[0, 0])
    res[1] = tmp[1]
    res[2] = np.cos(2 * tmp[2])
    res[3] = np.sin(2 * tmp[2])
    res = res.reshape(res.shape[:1] + shape)
    return res
Ejemplo n.º 21
0
Archivo: pmat.py Proyecto: jit9/enlib
 def apply(self, dir, tod, srcs, tmul=None, pmul=None):
     if tmul is None: tmul = self.tmul
     if pmul is None: pmul = self.pmul
     if srcs.ndim == 2: srcs = srcs[:, None]
     # Handle angle wrapping without modifying the original srcs array
     wsrcs = srcs.copy()
     wsrcs[:, :, :2] = utils.rewind(srcs[:, :, :2], self.ref) + self.dpos
     t1 = time.time()
     core = get_core(tod.dtype)
     core.pmat_ptsrc2(dir, tmul, pmul, tod.T, wsrcs.T,
                      self.scan.boresight.T, self.scan.offsets.T,
                      self.scan.comps.T, self.rbox.T, self.nbox.T,
                      self.yvals.T, self.scan.beam[1], self.scan.beam[0,
                                                                      -1],
                      self.rmax, self.cells.T, self.ncell.T, self.cbox.T)
     # Copy out any amplitudes that may have changed
     srcs[:, :, 2:5] = wsrcs[:, :, 2:5]
Ejemplo n.º 22
0
def calc_driftangle(hor, t, site):
    hor = np.atleast_2d(hor).T
    t = np.atleast_1d(t)
    equ = coordinates.transform("hor",
                                "equ",
                                hor,
                                time=utils.ctime2mjd(t),
                                site=site)
    hor_drift = utils.rewind(
        coordinates.transform("equ",
                              "hor",
                              equ,
                              time=utils.ctime2mjd(t + 1),
                              site=site), hor, 2 * np.pi)
    vec_drift = hor_drift - hor
    # Compute angle between this vector and the az axis
    angle = np.arctan2(vec_drift[1], vec_drift[0] * np.cos(hor[1])) % np.pi
    return angle
Ejemplo n.º 23
0
def hor2cel(hor, toff):
    """Transform from [{tsec,az,el},nsamp] to [{ra,dec,c,s},nsamp],
	where tsec is the offset from toff. Toff is given in mjd."""
    shape = hor.shape[1:]
    hor = hor.reshape(hor.shape[0], -1).astype(float)
    tmp = coordinates.transform("hor",
                                "cel",
                                hor[1:],
                                time=hor[0] / 24 / 60 / 60 + toff,
                                site=site,
                                pol=True)
    res = np.zeros((4, ) + tmp.shape[1:])
    res[0] = utils.rewind(tmp[0], tmp[0, 0])
    res[1] = tmp[1]
    res[2] = np.cos(2 * tmp[2])
    res[3] = np.sin(2 * tmp[2])
    res = res.reshape(res.shape[:1] + shape)
    return res
Ejemplo n.º 24
0
Archivo: cgrid.py Proyecto: jit9/enlib
def calc_gridinfo(shape, wcs, steps=[2, 2], nstep=[200, 200], zenith=False):
    """Return an array of line segments representing a coordinate grid
	for the given shape and wcs. the steps argument describes the
	number of points to use along each meridian."""
    steps = np.zeros([2]) + steps
    nstep = np.zeros([2], dtype=int) + nstep

    gridinfo = Gridinfo()
    if enlib.wcs.is_plain(wcs):
        box = np.sort(enmap.box(shape, wcs), 0)
        start = np.floor(box[0] / steps) * steps
        nline = np.floor(box[1] / steps) - np.floor(box[0] / steps) + 1
    else:
        box = np.array([[-90., 0.], [90., 360.]])
        start = np.array([-90., 0.])
        nline = np.array([180., 360.]) / steps + 1

    gridinfo.lon = []
    gridinfo.lat = []
    gridinfo.shape = shape[-2:]
    gridinfo.wcs = wcs
    # Draw lines of longitude
    for phi in start[1] + np.arange(nline[1]) * steps[1]:
        # Loop over theta
        pixs = np.array(
            wcs.wcs_world2pix(
                phi, np.linspace(box[0, 0], box[1, 0], nstep[0],
                                 endpoint=True), 0)).T
        if not enlib.wcs.is_plain(wcs): phi = utils.rewind(phi, 0, 360)
        gridinfo.lon.append((phi, calc_line_segs(pixs)))
    # Draw lines of latitude
    for theta in start[0] + np.arange(nline[0]) * steps[0]:
        # Loop over phi
        pixs = np.array(
            wcs.wcs_world2pix(
                np.linspace(box[0, 1],
                            box[1, 1] + 0.9,
                            nstep[1],
                            endpoint=True), theta, 0)).T
        if zenith: theta = 90 - theta
        gridinfo.lat.append((theta, calc_line_segs(pixs)))
    return gridinfo
Ejemplo n.º 25
0
def build_src_cells(cbox, srcpos, cres, unwind=False):
	# srcpos is [nsrc,...,{dec,ra}]. Reshape to 3d to keep things simple.
	# will reshape back when returning
	cbox    = np.asarray(cbox)
	srcpos  = np.asarray(srcpos)
	ishape  = srcpos.shape
	srcpos  = srcpos.reshape(ishape[0],-1,ishape[-1])

	cshape  = tuple(np.ceil(((cbox[1]-cbox[0])/cres)).astype(int))
	if unwind:
		# Make the sources' ra compatible with our area
		ref     = np.mean(cbox[:,1],0)
		srcpos[:,...,1] = utils.rewind(srcpos[:,...,1], ref)
	# How big must our cell hit array be?
	nmax = max(1,np.max(build_src_cells_helper(cbox, cshape, cres, srcpos)))
	ncell, cells = build_src_cells_helper(cbox, cshape, cres, srcpos, nmax)
	# Reshape back to original shape
	ncell = ncell.reshape(ishape[1:-1]+ncell.shape[1:])
	cells = cells.reshape(ishape[1:-1]+cells.shape[1:])
	return ncell, cells
Ejemplo n.º 26
0
def avoidance_cut(bore, det_offs, site, name_or_pos, margin):
    """Cut samples that get too close to the specified object
	(e.g. "Sun" or "Moon") or celestial position ([ra,dec] in racians).
	Margin specifies how much to avoid the object by."""
    cmargin = np.cos(margin)
    mjd = utils.ctime2mjd(bore[0])
    obj_pos = coordinates.interpol_pos("cel", "hor", name_or_pos, mjd, site)
    obj_pos[0] = utils.rewind(obj_pos[0], bore[1])
    cosel = np.cos(obj_pos[1])
    # Only cut if above horizon
    above_horizon = obj_pos[1] > 0
    null_cut = sampcut.empty(det_offs.shape[0], bore.shape[1])
    if np.all(~above_horizon): return null_cut
    # Find center of array, and radius
    arr_center = np.mean(det_offs, 0)
    arr_rad = np.max(np.sum((det_offs - arr_center)**2, 1)**0.5)

    def calc_mask(det_pos, rad, mask=slice(None)):
        offs = (det_pos - obj_pos[:, mask])
        offs[0] *= cosel[mask]
        dists2 = np.sum(offs**2, 0)
        return dists2 < rad**2

    # Find samples that could possibly be near object for any detector
    cand_mask = calc_mask(arr_center[:, None] + bore[1:], margin + arr_rad)
    cand_mask &= above_horizon
    cand_inds = np.where(cand_mask)[0]
    if len(cand_inds) == 0: return null_cut
    # Loop through all detectors and find out if each candidate actually intersects
    cuts = []
    for di, off in enumerate(det_offs):
        det_pos = bore[1:, cand_inds] + off[:, None]
        det_mask = calc_mask(det_pos, margin, cand_inds)
        # Expand mask to full set
        det_mask_full = np.zeros(bore.shape[1], bool)
        det_mask_full[cand_inds] = det_mask
        # And use this to build actual cuts
        cuts.append(sampcut.from_mask(det_mask_full))
    res = sampcut.stack(cuts)
    return res
Ejemplo n.º 27
0
def avoidance_cut(bore, det_offs, site, name_or_pos, margin):
	"""Cut samples that get too close to the specified object
	(e.g. "Sun" or "Moon") or celestial position ([ra,dec] in racians).
	Margin specifies how much to avoid the object by."""
	cmargin = np.cos(margin)
	mjd = utils.ctime2mjd(bore[0])
	obj_pos    = coordinates.interpol_pos("cel","hor",name_or_pos,mjd,site)
	obj_pos[0] = utils.rewind(obj_pos[0], bore[1])
	cosel      = np.cos(obj_pos[1])
	# Only cut if above horizon
	above_horizon = obj_pos[1]>0
	null_cut = sampcut.empty(det_offs.shape[0], bore.shape[1])
	if np.all(~above_horizon): return null_cut
	# Find center of array, and radius
	arr_center = np.mean(det_offs,0)
	arr_rad    = np.max(np.sum((det_offs-arr_center)**2,1)**0.5)
	def calc_mask(det_pos, rad, mask=slice(None)):
		offs  = (det_pos-obj_pos[:,mask])
		offs[0] *= cosel[mask]
		dists2= np.sum(offs**2,0)
		return dists2 < rad**2
	# Find samples that could possibly be near object for any detector
	cand_mask  = calc_mask(arr_center[:,None] + bore[1:], margin+arr_rad)
	cand_mask &= above_horizon
	cand_inds  = np.where(cand_mask)[0]
	if len(cand_inds) == 0: return null_cut
	# Loop through all detectors and find out if each candidate actually intersects
	cuts = []
	for di, off in enumerate(det_offs):
		det_pos  = bore[1:,cand_inds]+off[:,None]
		det_mask = calc_mask(det_pos, margin, cand_inds)
		# Expand mask to full set
		det_mask_full = np.zeros(bore.shape[1], bool)
		det_mask_full[cand_inds] = det_mask
		# And use this to build actual cuts
		cuts.append(sampcut.from_mask(det_mask_full))
	res = sampcut.stack(cuts)
	return res
Ejemplo n.º 28
0
)
parser.add_argument("--already-arcmin", action="store_true")
args = parser.parse_args()

div = enmap.read_fits(args.div)
if args.downgrade:
    div = enmap.downgrade(div, args.downgrade)
    div *= args.downgrade**2

div = div.reshape((-1, ) + div.shape[-2:])[0]
# Individual pixel area
if args.area_model == "average":
    pix_area = div * 0 + div.area() / div.size * (180 * 60 / np.pi)**2
else:
    pos = div.posmap()
    diffs = utils.rewind(pos[:, 1:, 1:] - pos[:, :-1, :-1], 0)
    pix_area = np.abs(diffs[0] * diffs[1]) * np.cos(pos[0, :-1, :-1])
    del diffs
    # Go to square arcmins
    pix_area /= utils.arcmin**2
    # Pad to recover edge pixels
    pix_area = np.concatenate([pix_area, pix_area[-1:]], 0)
    pix_area = np.concatenate([pix_area, pix_area[:, -1:]], 1)

# Flatten everything
div = div.reshape(-1)
pix_area = pix_area.reshape(-1)

with utils.nowarn():
    rms = (pix_area / div)**0.5 if not args.already_arcmin else div**-0.5
    inds = np.argsort(rms, axis=None)
Ejemplo n.º 29
0
def build_tod_stats(entry, Naz=8, Nt=2):
    """Collect summary information for the tod in the given entry, returning
	it as a bunch. If some information can't be found, then those fields will
	be set to a placeholder value (usually NaN), but the fields will still all
	be present."""
    # At the very least we need the pointing, so no try catch around this
    d = actdata.read(entry, ["boresight", "site"])
    d += actdata.read_point_offsets(entry, no_correction=True)
    d = actdata.calibrate(d, exclude=["autocut"])

    # Get the array center and radius
    acenter = np.mean(d.point_offset, 0)
    arad = np.mean((d.point_offset - acenter)**2, 0)**0.5

    t, baz, bel = 0.5 * (np.min(d.boresight, 1) + np.max(d.boresight, 1))
    #t, baz, bel = np.mean(d.boresight,1)
    az = baz + acenter[0]
    el = bel + acenter[1]
    dur, waz, wel = np.max(d.boresight, 1) - np.min(d.boresight, 1)
    if waz > 180 * utils.degree:
        print("bad waz %8.3f for %s" % (waz / utils.degree, entry.id))
    mjd = utils.ctime2mjd(t)
    hour = t / 3600. % 24
    day = hour >= day_range[0] and hour < day_range[1]
    night = not day
    jon = (t - jon_ref) / (3600 * 24)

    ra, dec = coordinates.transform(tsys, "cel", [az, el], mjd, site=d.site)
    # Get the array center bounds on the sky, assuming constant elevation
    ts = utils.ctime2mjd(t + dur / 2 * np.linspace(-1, 1, Nt))
    azs = az + waz / 2 * np.linspace(-1, 1, Naz)
    E1 = coordinates.transform(tsys,
                               "cel", [azs, [el] * Naz],
                               time=[ts[0]] * Naz,
                               site=d.site)[:, 1:]
    E2 = coordinates.transform(tsys,
                               "cel", [[azs[-1]] * Nt, [el] * Nt],
                               time=ts,
                               site=d.site)[:, 1:]
    E3 = coordinates.transform(tsys,
                               "cel", [azs[::-1], [el] * Naz],
                               time=[ts[-1]] * Naz,
                               site=d.site)[:, 1:]
    E4 = coordinates.transform(tsys,
                               "cel", [[azs[0]] * Nt, [el] * Nt],
                               time=ts[::-1],
                               site=d.site)[:, 1:]
    bounds = np.concatenate([E1, E2, E3, E4], 1)
    bounds[0] = utils.rewind(bounds[0])
    ## Grow bounds by array radius
    #bmid = np.mean(bounds,1)
    #for i in range(2):
    #	bounds[i,bounds[i]<bmid[i]] -= arad[i]
    #	bounds[i,bounds[i]>bmid[i]] += arad[i]
    tot_id = entry.id + (":" + entry.tag if entry.tag else "")
    res = bunch.Bunch(id=tot_id,
                      nsamp=d.nsamp,
                      t=t,
                      mjd=mjd,
                      jon=jon,
                      hour=hour,
                      day=day,
                      night=night,
                      dur=dur,
                      az=az / utils.degree,
                      el=el / utils.degree,
                      baz=baz / utils.degree,
                      bel=bel / utils.degree,
                      waz=waz / utils.degree,
                      wel=wel / utils.degree,
                      ra=ra / utils.degree,
                      dec=dec / utils.degree,
                      bounds=bounds / utils.degree)

    if "gseason" in entry:
        res[entry.gseason] = True

    # Planets
    for obj in [
            "Sun", "Moon", "Mercury", "Venus", "Mars", "Jupiter", "Saturn",
            "Uranus", "Neptune"
    ]:
        res[obj] = coordinates.ephem_pos(obj,
                                         utils.ctime2mjd(t)) / utils.degree

    # Get our weather information, if available
    try:
        d += actdata.read(entry, ["apex"])
        d = actdata.calibrate_apex(d)
        res["pwv"] = d.apex.pwv
        res["wx"] = d.apex.wind[0]
        res["wy"] = d.apex.wind[1]
        res["wind_speed"] = d.apex.wind_speed
        res["T"] = d.apex.temperature
    except errors.DataMissing:
        res["pwv"] = np.NaN
        res["wx"] = np.NaN
        res["wy"] = np.NaN
        res["wind_speed"] = np.NaN
        res["T"] = np.NaN

    # Try to get our cut info, so that we can select on
    # number of detectors and cut fraction
    try:
        npre = d.nsamp * d.ndet
        d += actdata.read(entry, ["cut"])
        res["ndet"] = d.ndet
        res["cut"] = 1 - d.nsamp * d.ndet / float(npre)
    except errors.DataMissing:
        res["ndet"] = 0
        res["cut"] = 1.0

    # Try to get hwp info
    res["hwp"] = False
    res["hwp_name"] = "none"
    try:
        epochs = actdata.try_read(files.read_hwp_epochs, "hwp_epochs",
                                  entry.hwp_epochs)
        t, _, ar = entry.id.split(".")
        t = float(t)
        if ar in epochs:
            for epoch in epochs[ar]:
                if t >= epoch[0] and t < epoch[1]:
                    res["hwp"] = True
                    res["hwp_name"] = epoch[2]
    except errors.DataMissing:
        pass

    return res
Ejemplo n.º 30
0
 def err(t):
     ora, odec = coordinates.transform("hor",
                                       "cel", [az, el],
                                       time=t,
                                       site=site)
     return utils.rewind(ra - ora, 0)
Ejemplo n.º 31
0
	allowed &= set(selected)

f = open(args.odir + "/fits_%03d.txt" % comm.rank, "w")

# Iterate over tods
for ind in range(comm.rank, len(ids), comm.size):
	id    = ids[ind]
	oid   = id.replace(":","_")

	# Check if we hit any of the sources. We first make sure
	# there's no angle wraps in the bounds, and then move the sources
	# to the same side of the sky. bounds are pretty approximate, so
	# might not actually hit all these sources
	if bounds is not None:
		poly      = bounds[:,:,ind]*utils.degree
		poly[0]   = utils.rewind(poly[0],poly[0,0])
		# bounds are defined in celestial coordinates. Must convert srcpos for comparison
		mjd       = utils.ctime2mjd(float(id.split(".")[0]))
		srccel    = coordinates.transform(src_sys, "cel", srcpos, time=mjd)
		srccel[0] = utils.rewind(srccel[0], poly[0,0])
		poly      = pad_polygon(poly.T, poly_pad).T
		sids      = np.where(utils.point_in_polygon(srccel.T, poly.T))[0]
		sids      = sorted(list(set(sids)&allowed))
	else:
		sids = sorted(list(allowed))
	if len(sids) == 0:
		print("%s has 0 srcs: skipping" % id)
		continue
	try:
		nsrc = len(sids)
		print("%s has %d srcs: %s" % (id,nsrc,", ".join(["%d (%.1f)" % (i,a) for i,a in zip(sids,amps[sids])])))
Ejemplo n.º 32
0
utils.mkdir(args.odir)

# Read in lines with format [id, az, el]
# Compute drift angle and assign each id to a bin in angle.
nbin = int(np.ceil(360 / args.binwidth))
with open(args.odir + "/bins.txt", "w") as f:
    for bi in range(nbin):
        f.write("%8.3f %8.3f\n" % (bi * args.binwidth,
                                   (bi + 1) * args.binwidth))
bfiles = [None for i in range(nbin)]
site = None
for line in open(args.todinfo, "r"):
    toks = line.split()
    id = toks[0]
    entry = db[id]

    az = utils.rewind(float(toks[1]), 0, 360)
    el = float(toks[2])
    t = float(id[:id.index(".")])
    if site is None: site = files.read_site(entry.site)

    angle = calc_driftangle([az * np.pi / 180, el * np.pi / 180], t,
                            site) * 180 / np.pi
    if not np.isfinite(angle): continue
    # Assign bin
    bi = int(angle / args.binwidth)
    if bfiles[bi] is None:
        bfiles[bi] = open(args.odir + "/ang%03d.txt" % bi, "w")
    bfiles[bi].write("%s %8.2f\n" % (id, angle))
    print "%s %8.2f %8.2f %8.2f %3d" % (id, az, el, angle, bi)
Ejemplo n.º 33
0
def find_scan_vel(scan, ipos, aspeed, dt=0.1):
	hpos  = coordinates.transform("equ","hor", ipos, time=scan.mjd0, site=scan.site)
	hpos[0] += aspeed*dt
	opos  = coordinates.transform("hor","equ", hpos, time=scan.mjd0, site=scan.site)
	opos[0] = utils.rewind(opos[0],ipos[0])
	return (opos-ipos)/dt
Ejemplo n.º 34
0
 def __init__(self, scan, area, dets):
     abox = area.box()[:, 1]
     self.scan, self.az0, self.daz = scan, abox[0], (
         abox[1] - abox[0]) / area.shape[-1]
     self.az, self.dets = utils.rewind(self.scan.boresight[:, 1], 0), dets
Ejemplo n.º 35
0
parser.add_argument("-t", "--thin", type=int, default=1000)
parser.add_argument("-A", "--area-model", type=str, default="exact", help="How to model pixel area. exact: Compute shape of each pixel. average: Use a single average number for all")
args = parser.parse_args()

div = enmap.read_fits(args.div)
if args.downgrade:
	div  = enmap.downgrade(div, args.downgrade)
	div *= args.downgrade**2

div = div.reshape((-1,)+div.shape[-2:])[0]
# Individual pixel area
if args.area_model == "average":
	pix_area = div*0 + div.area()/div.size*(180*60/np.pi)**2
else:
	pos   = div.posmap()
	diffs = utils.rewind(pos[:,1:,1:]-pos[:,:-1,:-1],0)
	pix_area = np.abs(diffs[0]*diffs[1])*np.cos(pos[0,:-1,:-1])
	del diffs
	# Go to square arcmins
	pix_area /= utils.arcmin**2
	# Pad to recover edge pixels
	pix_area = np.concatenate([pix_area,pix_area[-1:]],0)
	pix_area = np.concatenate([pix_area,pix_area[:,-1:]],1)

# Flatten everything
div = div.reshape(-1)
pix_area = pix_area.reshape(-1)

with utils.nowarn():
	rms  = (pix_area/div)**0.5
	inds = np.argsort(rms, axis=None)
Ejemplo n.º 36
0
filedb.init()
db = filedb.data
utils.mkdir(args.odir)

# Read in lines with format [id, az, el]
# Compute drift angle and assign each id to a bin in angle.
nbin = int(np.ceil(360/args.binwidth))
with open(args.odir + "/bins.txt","w") as f:
	for bi in range(nbin):
		f.write("%8.3f %8.3f\n" % (bi*args.binwidth, (bi+1)*args.binwidth))
bfiles = [None for i in range(nbin)]
site = None
for line in open(args.todinfo,"r"):
	toks = line.split()
	id = toks[0]
	entry = db[id]

	az = utils.rewind(float(toks[1]),0,360)
	el = float(toks[2])
	t  = float(id[:id.index(".")])
	if site is None: site = files.read_site(entry.site[0])

	angle = calc_driftangle([az*np.pi/180,el*np.pi/180],t,site)*180/np.pi
	if not np.isfinite(angle): continue
	# Assign bin
	bi = int(angle/args.binwidth)
	if bfiles[bi] is None:
		bfiles[bi] = open(args.odir + "/ang%03d.txt"%bi,"w")
	bfiles[bi].write("%s %8.2f\n" % (id, angle))
	print "%s %8.2f %8.2f %8.2f %3d" % (id, az, el, angle, bi)
Ejemplo n.º 37
0
	def foc2cel(self, dfoc):
		foc = self.ref_foc + dfoc
		cel = foc2cel(foc, self.site, self.mjd, self.bore)
		dcel = utils.rewind(cel-self.ref_cel)
		return dcel
Ejemplo n.º 38
0
	def cel2foc(self, dcel):
		cel = self.ref_cel + dcel
		foc = cel2foc(cel, self.site, self.mjd, self.bore)
		dfoc = utils.rewind(foc-self.ref_foc)
		return dfoc
Ejemplo n.º 39
0
    selected = [int(w) for w in args.restrict.split(",")]
    allowed &= set(selected)

for ind in range(comm.rank, len(ids), comm.size):
    id = ids[ind]
    oid = id.replace(":", "_")
    oname = "%s/%s.hdf" % (args.odir, oid)
    if args.cont and os.path.exists(oname):
        print "%s is done: skipping" % id
        continue

    # Check if we hit any of the sources. We first make sure
    # there's no angle wraps in the bounds, and then move the sources
    # to the same side of the sky.
    poly = bounds[:, :, ind] * utils.degree
    poly[0] = utils.rewind(poly[0], poly[0, 0])
    srcpos = srcpos.copy()
    srcpos[0] = utils.rewind(srcpos[0], poly[0, 0])
    sids = np.where(utils.point_in_polygon(srcpos.T, poly.T))[0]
    sids = sorted(list(set(sids) & allowed))
    if len(sids) == 0:
        print "%s has 0 srcs: skipping" % id
        continue
    nsrc = len(sids)
    print "%s has %d srcs: %s" % (id, nsrc, ", ".join(
        ["%d (%.1f)" % (i, a) for i, a in zip(sids, amps[sids])]))

    entry = filedb.data[id]
    try:
        with bench.mark("read"):
            d = actdata.read(entry)
Ejemplo n.º 40
0
	oid   = id.replace(":","_")
	oname = "%s/%s.fits" % (args.odir, oid)
	ename = oname + ".empty"
	if args.cont:
		if os.path.exists(oname):
			print "%5d/%d %s is done: skipping" % (ind+1, len(ids), id)
			continue
		if os.path.exists(ename):
			print "%5d/%d %s already failed: skipping" % (ind+1, len(ids), id)
			continue

	# Check if we hit any of the sources. We first make sure
	# there's no angle wraps in the bounds, and then move the sources
	# to the same side of the sky.
	poly      = bounds[:,:,ind]*utils.degree
	poly[0]   = utils.rewind(poly[0],poly[0,0])
	srcpos    = srcpos.copy()
	srcpos[0] = utils.rewind(srcpos[0], poly[0,0])
	sids      = np.where(utils.point_in_polygon(srcpos.T, poly.T))[0]
	sids      = np.array(sorted(list(set(sids)&allowed)))
	if len(sids) == 0:
		print "%5d/%d %s has 0 srcs: skipping" % (ind+1, len(ids), id)
		continue
	nsrc = len(sids)
	print "%5d/%d %s has %d srcs: %s" % (ind+1, len(ids), id,nsrc,", ".join(["%d (%.1f)" % (i,a) for i,a in zip(sids,amps[sids])]))

	def skip(msg):
		print "%s skipped: %s" % (id, msg)
		with open(ename, "w")  as f:
			f.write(msg + "\n")
Ejemplo n.º 41
0
	def err(t):
		ora, odec = coordinates.transform("hor","cel",[az,el],time=t,site=site)
		return utils.rewind(ra-ora, 0)
Ejemplo n.º 42
0
# Find out which sources are hit by each tod
db = filedb.scans.select(filedb.scans[args.sel])
tod_srcs = {}
for sid, src in enumerate(srcs):
    if args.src is not None and sid != args.src: continue
    if src.type == "planet":
        # This is a bit hacky, but sometimes the "t" member is unavailable
        # in the database. This also ignores the planet movement during the
        # TOD. We will take that into account in the final step in the mapping, though.
        t = np.char.partition(db.ids, ".")[:, 0].astype(float) + 300
        ra, dec = ephemeris.ephem_pos(src.name, utils.ctime2mjd(t), dt=0)[:2]
    else:
        ra, dec = src.ra, src.dec
    points = np.array([ra, dec])
    polys = db.data["bounds"] * utils.degree
    polys[0] = utils.rewind(polys[0], points[0])
    polys[0] = utils.rewind(polys[0], polys[0, 0])
    inside = utils.point_in_polygon(points.T, polys.T)
    dists = utils.poly_edge_dist(points.T, polys.T)
    dists = np.where(inside, 0, dists)
    hit = np.where(dists < args.hit_tol * utils.degree)[0]
    for id in db.ids[hit]:
        if not id in tod_srcs: tod_srcs[id] = []
        tod_srcs[id].append(sid)

# Prune those those that are done
if args.cont:
    good = []
    for id in tod_srcs:
        bid = id.replace(":", "_")
        ndone = 0
Ejemplo n.º 43
0
filedb.init()
ids    = filedb.scans[args.sel]
db     = filedb.scans.select(ids)
ntod   = len(db)
nsplit = args.nsplit
nopt   = args.nopt if nsplit > 1 else 0
optimize_subsets = (args.mode == "crosslink" or args.mode=="scanpat")
utils.mkdir(args.odir)

# Determine which arrays we have. We can't process arrays independently,
# as they in principle have correlated noise. But we also want to distinguish
# between them
pre, _, anames = np.char.rpartition(ids,".").T
if args.mode == "crosslink":
	# Treat rising and setting as separate arrays"
	rise = utils.rewind(db.data["baz"],0,360) > 0
	anames[rise]  = np.char.add(anames[rise], "r")
	anames[~rise] = np.char.add(anames[~rise],"s")
elif args.mode == "scanpat":
	# Treat each scanning pattern as a different array
	patterns = np.array([db.data["baz"],db.data["bel"],db.data["waz"]]).T
	pids     = utils.label_unique(patterns, axes=(1,), atol=1.0)
	npat     = np.max(pids)+1
	for pid in range(npat):
		anames[pids==pid] = np.char.add(anames[pids==pid], "p%d" % pid)

def ids2ctimes(ids): return np.char.partition(ids,".").T[0].astype(int)
arrays, ais, nper = np.unique(anames, return_counts=True, return_inverse=True)
narray = len(arrays)
ctime  = ids2ctimes(pre)
sys.stderr.write("found arrays " + " ".join(arrays) + "\n")
Ejemplo n.º 44
0
	def calc_profile(self, pos):
		dpos = self.posmap[::-1] - pos[:,None,None]
		if np.abs(dpos[0,0,0]) > np.pi:
			dpos[0] = utils.rewind(dpos[0])
		return self.beam.eval(dpos)
Ejemplo n.º 45
0
# Find out which sources are hit by each tod
db = filedb.scans.select(filedb.scans[args.sel])
tod_srcs = {}
for sid, src in enumerate(srcs):
	if args.src is not None and sid != args.src: continue
	if src.type == "planet":
		# This is a bit hacky, but sometimes the "t" member is unavailable
		# in the database. This also ignores the planet movement during the
		# TOD. We will take that into account in the final step in the mapping, though.
		t = np.char.partition(db.ids,".")[:,0].astype(float)+300
		ra, dec = ephemeris.ephem_pos(src.name, utils.ctime2mjd(t), dt=0)[:2]
	else: ra, dec = src.ra, src.dec
	points = np.array([ra, dec])
	polys  = db.data["bounds"]*utils.degree
	polys[0] = utils.rewind(polys[0], points[0])
	polys[0] = utils.rewind(polys[0], polys[0,0])
	inside   = utils.point_in_polygon(points.T, polys.T)
	dists    = utils.poly_edge_dist(points.T, polys.T)
	dists    = np.where(inside, 0, dists)
	hit      = np.where(dists < args.hit_tol*utils.degree)[0]
	for id in db.ids[hit]:
		if not id in tod_srcs: tod_srcs[id] = []
		tod_srcs[id].append(sid)

# Prune those those that are done
if args.cont:
	good = []
	for id in tod_srcs:
		bid = id.replace(":","_")
		ndone = 0
Ejemplo n.º 46
0
db     = filedb.scans.select(ids)
ntod   = len(db)
nsplit = args.nsplit
nopt   = args.nopt if nsplit > 1 else 0
optimize_subsets = (args.mode == "crosslink" or args.mode=="scanpat")
detdir = args.odir + "/details"
utils.mkdir(args.odir)
utils.mkdir(detdir)

# Determine which arrays we have. We can't process arrays independently,
# as they in principle have correlated noise. But we also want to distinguish
# between them
pre, _, anames = np.char.rpartition(ids,".").T
if args.mode == "crosslink":
	# Treat rising and setting as separate arrays"
	rise = utils.rewind(db.data["baz"],0,360) > 0
	anames[rise]  = np.char.add(anames[rise], "r")
	anames[~rise] = np.char.add(anames[~rise],"s")
elif args.mode == "scanpat":
	# Treat each scanning pattern as a different array
	patterns = np.array([db.data["baz"],db.data["bel"],db.data["waz"]]).T
	pids     = utils.label_unique(patterns, axes=(1,), atol=1.0)
	npat     = np.max(pids)+1
	for pid in range(npat):
		anames[pids==pid] = np.char.add(anames[pids==pid], "p%d" % pid)

def ids2ctimes(ids): return np.char.partition(ids,".").T[0].astype(int)
def fix_aname(aname): return aname.replace("ar","pa").replace(":","_")
anames = np.array([fix_aname(aname) for aname in anames])
arrays, ais, nper = np.unique(anames, return_counts=True, return_inverse=True)
narray = len(arrays)