Пример #1
0
	def __call__(self, ipos, time):
		opos = coordinates.transform(self.isys, self.osys, ipos, time=time, site=self.site)
		x, y = self.wcs.wcs_world2pix(opos[0]/utils.degree,opos[1]/utils.degree,0)
		nx = int(np.abs(360.0/self.wcs.wcs.cdelt[0]))
		x = utils.unwind(x, nx, ref=nx/2)
		opos[0] = utils.unwind(opos[0])
		return np.array([opos[0],opos[1],x,y])
Пример #2
0
 def __call__(self, ipos, time):
     opos = coordinates.transform(self.isys,
                                  self.osys,
                                  ipos,
                                  time=time,
                                  site=self.site)
     x, y = self.wcs.wcs_world2pix(opos[0] / utils.degree,
                                   opos[1] / utils.degree, 0)
     nx = int(np.abs(360.0 / self.wcs.wcs.cdelt[0]))
     x = utils.unwind(x, nx, ref=nx / 2)
     opos[0] = utils.unwind(opos[0])
     return np.array([opos[0], opos[1], x, y])
Пример #3
0
def get_moby_pointing(entry, bore, dets, downgrade=1):
    # Set up moby2
    import moby2
    moby2.pointing.set_bulletin_A()
    params = {
        "detector_offsets": {
            "format": "fp_file",
            "filename": entry.point_template
        },
        "pol_source": {
            "source": "file",
            "filename": entry.polangle,
            "format": "ascii",
            "fail_value": -1
        },
        "shift_generator": {
            "source": "file",
            "filename": entry.point_offsets,
            "columns": [0, 5, 6],
            "rescale_degrees": 180 / np.pi
        },
    }
    bore = np.ascontiguousarray(bore[::downgrade].T)
    fplane = moby2.scripting.get_focal_plane(params,
                                             det_uid=dets,
                                             tod=entry.id)
    res = fplane.get_coords(bore[0],
                            bore[1],
                            bore[2],
                            fields=['ra', 'dec', 'cos_2gamma', 'sin_2gamma'])
    res[0][:] = utils.unwind(res[0])
    return np.array(res)
Пример #4
0
def calc_az_sweep(pattern, offset, site, pad=2.0, subsample=1.0):
    """Helper function. Given a pattern and mean focalplane offset,
	computes the shape of an azimuth sweep on the sky."""
    el1 = pattern[0] + offset[0]
    az1 = pattern[1] + offset[1] - pad
    az2 = pattern[2] + offset[1] + pad
    daz = rhs.pixshape()[0] / np.cos(el1) / subsample
    naz = int(np.ceil((az2 - az1) / daz))
    naz = fft.fft_len(naz, "above", [2, 3, 5, 7])
    # Simulate a single sweep at arbitrary time
    sweep_az = np.arange(naz) * daz + az1
    sweep_el = np.full(naz, el1)
    sweep_cel = coordinates.transform("hor",
                                      "cel",
                                      np.array([sweep_az, sweep_el]),
                                      time=ref_time,
                                      site=site)
    # Make ra safe
    sweep_cel = utils.unwind(sweep_cel)
    return bunch.Bunch(sweep_cel=sweep_cel,
                       sweep_hor=np.array([sweep_az, sweep_el]),
                       el=el1,
                       az1=az1,
                       az2=az2,
                       naz=naz,
                       daz=daz)
Пример #5
0
def ephem_pos(objname, mjd, dt=10):
    """Computes the earth-relative angular position and radius [{ra,dec,r},ntime]
	for the given object. Uses interpolation in steps dt (seconds) to sepeed
	things up. Set dt to 0 to disable this. r has units of AU."""
    # Get low-res [ra,dec,r]
    sub_time, inds = define_subsamples(mjd, dt=dt / (24. * 3600))
    sub_pos = ephem_raw(objname, sub_time)
    # Avoid angle wraps, as they will mess up the interpolation
    sub_pos[0] = utils.unwind(sub_pos[0])
    # Interpolate to target resolution
    full_pos = utils.interpol(sub_pos, inds[None])
    return full_pos
Пример #6
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
Пример #7
0
	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
		opos  = coordinates.transform("hor", "cel", ipos[1:], time=time, site=self.scan.site, pol=True)
		opix  = np.zeros((4,)+ipos.shape[1:])
		opix[:2] = self.wcs.wcs_world2pix(*tuple(opos[:2]/utils.degree)+(0,))[::-1]
		nx    = int(np.abs(360/self.wcs.wcs.cdelt[0]))
		opix[1]  = utils.unwind(opix[1], period=nx, ref=nx/2)
		opix[2]  = np.cos(2*opos[2])
		opix[3]  = np.sin(2*opos[2])
		return opix.reshape((opix.shape[0],)+shape)
Пример #8
0
	def resample(self, mapping):
		res = cpy.deepcopy(self)
		res.boresight = np.ascontiguousarray(utils.interpol(res.boresight.T, mapping.oimap[None], order=1).T)
		res.hwp       = utils.interpol(utils.unwind(res.hwp), mapping.oimap[None], order=1)
		res.hwp_phase = np.ascontiguousarray(utils.interpol(res.hwp_phase.T, mapping.oimap[None], order=1).T)
		try:
			res.dark_tod = utils.interpol(res.dark_tod, mapping.oimap[None])
			res.dark_cut = resample_cut(res.dark_cut, mapping)
		except AttributeError as e: pass
		res.cut          = resample_cut(res.cut,          mapping)
		res.cut_noiseest = resample_cut(res.cut_noiseest, mapping)
		res.noise        = res.noise.resample(mapping)
		res.mapping      = mapping
		return res
Пример #9
0
    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)
Пример #10
0
def calc_az_sweep(pattern, offset, site, pad=2.0, subsample=1.0):
	"""Helper function. Given a pattern and mean focalplane offset,
	computes the shape of an azimuth sweep on the sky."""
	el1 = pattern[0] + offset[0]
	az1 = pattern[1] + offset[1] - pad
	az2 = pattern[2] + offset[1] + pad
	daz = rhs.pixshape()[0]/np.cos(el1)/subsample
	naz  = int(np.ceil((az2-az1)/daz))
	naz  = fft.fft_len(naz, "above", [2,3,5,7])
	# Simulate a single sweep at arbitrary time
	sweep_az = np.arange(naz)*daz + az1
	sweep_el = np.full(naz,el1)
	sweep_cel = coordinates.transform("hor","cel", np.array([sweep_az,sweep_el]),time=ref_time,site=site)
	# Make ra safe
	sweep_cel = utils.unwind(sweep_cel)
	return bunch.Bunch(sweep_cel=sweep_cel, sweep_hor=np.array([sweep_az,sweep_el]),
			el=el1, az1=az1, az2=az2, naz=naz, daz=daz)
Пример #11
0
 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
     opos = coordinates.transform("hor",
                                  "cel",
                                  ipos[1:],
                                  time=time,
                                  site=self.scan.site,
                                  pol=True)
     opix = np.zeros((4, ) + ipos.shape[1:])
     opix[:2] = self.wcs.wcs_world2pix(*tuple(opos[:2] / utils.degree) +
                                       (0, ))[::-1]
     nx = int(np.abs(360 / self.wcs.wcs.cdelt[0]))
     opix[1] = utils.unwind(opix[1], period=nx, ref=nx / 2)
     opix[2] = np.cos(2 * opos[2])
     opix[3] = np.sin(2 * opos[2])
     return opix.reshape((opix.shape[0], ) + shape)
Пример #12
0
def build_hwp_sample_mapping(hwp, quantile=0.1):
	"""Given a HWP angle, return an array with shape [nout] containing
	the original sample index (float) corresponding to each sample in the
	remapped array, along with the resulting hwp sample rate.
	The remapping also truncates the end to ensure that
	there is an integer number of HWP rotations in the data."""
	# Make sure there are no angle wraps in the hwp
	hwp = utils.unwind(hwp)
	# interp requires hwp to be monotonically increasing. In practice
	# it could be monotonically decreasing too, but our final result
	# does not depend on the direction of rotation, so we simply flip it here
	# if necessary
	hwp = np.abs(hwp)
	# Find the target hwp speed
	speed = np.percentile(hwp[1:]-hwp[:-1], 100*quantile)
	# We want a whole number of samples per revolution, and
	# a whole number of revolutions in the whole tod
	a    = hwp - hwp[0]
	nrev = int(np.floor(a[-1]/(2*np.pi)))
	nper = utils.nint(2*np.pi/speed)
	# Make each of these numbers fourier-friendly
	nrev = fft.fft_len(nrev, "below")
	nper = fft.fft_len(nper, "above")
	# Set up our output samples
	speed = 2*np.pi/nper
	nout  = nrev*nper
	ohwp  = hwp[0] + np.arange(nout)*speed
	# Find the input sample for each output sample
	res = bunch.Bunch()
	res.oimap = np.interp(ohwp, hwp, np.arange(len(hwp)))
	# Find the output sampe for each input sample too. Because of
	# cropping, the last of these will be invalid
	res.iomap = np.interp(np.arange(len(hwp)), res.oimap, np.arange(len(res.oimap)))
	# Find the average sampling rate change fsamp_rel = fsamp_out/fsamp_in
	res.fsamp_rel = 1/np.mean(res.oimap[1:]-res.oimap[:-1])
	res.insamp = len(hwp)
	res.onsamp = nout
	res.nrev   = nrev
	res.nper   = nper
	return res
Пример #13
0
	subdets = None
	absdets = None
	if args.absdets is not None:
		absdets = [int(w) for w in args.absdets.split(",")]
	elif args.dets is not None:
		subdets = [int(w) for w in args.dets.split(",")]

	fields = ["gain","tconst","cut","tod","boresight"]
	if args.fields: fields = args.fields.split(",")
	d = actdata.read(entry, fields=fields)
	if absdets: d.restrict(dets=absdets)
	if subdets: d.restrict(dets=d.dets[subdets])
	if args.calib: d = actdata.calibrate(d, exclude=["autocut"])
	elif args.manual_calib:
		ops = args.manual_calib.split(",")
		if "safe" in ops: d.boresight[1:] = utils.unwind(d.boresight[1:], period=360)
		if "rad" in ops: d.boresight[1:] *= np.pi/180
		if "bgap" in ops:
			bad = (d.flags!=0)*(d.flags!=0x10)
			for b in d.boresight: gapfill.gapfill_linear(b, bad, inplace=True)
		if "gain" in ops: d.tod *= d.gain[:,None]
		if "tgap" in ops: 
			gapfiller = {"copy":gapfill.gapfill_copy, "linear":gapfill.gapfill_linear}[config.get("gapfill")]
			gapfiller(d.tod, d.cut, inplace=True)
		if "slope" in ops:
			utils.deslope(d.tod, w=8, inplace=True)
		if "deconv" in ops:
			d = actdata.calibrate(d, operations=["tod_fourier"])
	if args.bin > 1:
		d.tod = resample.downsample_bin(d.tod, steps=[args.bin])
		d.boresight = resample.downsample_bin(d.boresight, steps=[args.bin])
Пример #14
0
def fixx(yx, nphi):
	yx    = np.array(yx)
	yx[1] = utils.unwind(yx[1], nphi)
	return yx
Пример #15
0
    absdets = None
    if args.absdets is not None:
        absdets = [int(w) for w in args.absdets.split(",")]
    elif args.dets is not None:
        subdets = [int(w) for w in args.dets.split(",")]

    fields = ["gain", "tconst", "cut", "tod", "boresight"]
    if args.fields: fields = args.fields.split(",")
    d = actdata.read(entry, fields=fields)
    if absdets: d.restrict(dets=absdets)
    if subdets: d.restrict(dets=d.dets[subdets])
    if args.calib: d = actdata.calibrate(d, exclude=["autocut"])
    elif args.manual_calib:
        ops = args.manual_calib.split(",")
        if "safe" in ops:
            d.boresight[1:] = utils.unwind(d.boresight[1:], period=360)
        if "rad" in ops: d.boresight[1:] *= np.pi / 180
        if "bgap" in ops:
            bad = (d.flags != 0) * (d.flags != 0x10)
            for b in d.boresight:
                gapfill.gapfill_linear(b, bad, inplace=True)
        if "gain" in ops: d.tod *= d.gain[:, None]
        if "tgap" in ops:
            gapfiller = {
                "copy": gapfill.gapfill_copy,
                "linear": gapfill.gapfill_linear
            }[config.get("gapfill")]
            gapfiller(d.tod, d.cut, inplace=True)
        if "slope" in ops:
            utils.deslope(d.tod, w=8, inplace=True)
        if "deconv" in ops: