Esempio n. 1
0
    def testTicket2441(self):
        """Test ticket 2441: warpExposure sometimes mishandles zero-extent dest exposures"""
        fromWcs = makeWcs(
            pixelScale=afwGeom.Angle(1.0e-8, afwGeom.degrees),
            projection="TAN",
            crPixPos=(0, 0),
            crValCoord=afwCoord.IcrsCoord(afwGeom.Point2D(359, 0),
                                          afwGeom.degrees),
        )
        fromExp = afwImage.ExposureF(afwImage.MaskedImageF(10, 10), fromWcs)

        toWcs = makeWcs(
            pixelScale=afwGeom.Angle(0.00011, afwGeom.degrees),
            projection="CEA",
            crPixPos=(410000.0, 11441.0),
            crValCoord=afwCoord.IcrsCoord(afwGeom.Point2D(45, 0),
                                          afwGeom.degrees),
            doFlipX=True,
        )
        toExp = afwImage.ExposureF(afwImage.MaskedImageF(0, 0), toWcs)

        warpControl = afwMath.WarpingControl("lanczos3")
        # if a bug described in ticket #2441 is present, this will raise an
        # exception:
        numGoodPix = afwMath.warpExposure(toExp, fromExp, warpControl)
        self.assertEqual(numGoodPix, 0)
Esempio n. 2
0
    def testSmallSrc(self):
        """Verify that a source image that is too small will not raise an exception

        This tests another bug that was fixed in ticket #2441
        """
        fromWcs = makeWcs(
            pixelScale=afwGeom.Angle(1.0e-8, afwGeom.degrees),
            projection="TAN",
            crPixPos=(0, 0),
            crValCoord=afwCoord.IcrsCoord(afwGeom.Point2D(359, 0),
                                          afwGeom.degrees),
        )
        fromExp = afwImage.ExposureF(afwImage.MaskedImageF(1, 1), fromWcs)

        toWcs = makeWcs(
            pixelScale=afwGeom.Angle(1.1e-8, afwGeom.degrees),
            projection="TAN",
            crPixPos=(0, 0),
            crValCoord=afwCoord.IcrsCoord(afwGeom.Point2D(358, 0),
                                          afwGeom.degrees),
        )
        toExp = afwImage.ExposureF(afwImage.MaskedImageF(10, 10), toWcs)

        warpControl = afwMath.WarpingControl("lanczos3")
        # if a bug described in ticket #2441 is present, this will raise an
        # exception:
        numGoodPix = afwMath.warpExposure(toExp, fromExp, warpControl)
        self.assertEqual(numGoodPix, 0)
        imArr, maskArr, varArr = toExp.getMaskedImage().getArrays()
        self.assertTrue(np.all(np.isnan(imArr)))
        self.assertTrue(np.all(np.isinf(varArr)))
        noDataBitMask = afwImage.Mask.getPlaneBitMask("NO_DATA")
        self.assertTrue(np.all(maskArr == noDataBitMask))
Esempio n. 3
0
    def __call__(self, gc, band, max_mag):
        # Retrieve the desired columns and filter on magnitude values.
        bandname = 'mag_true_{}_lsst'.format(band)
        filter_ = '{} < {}'.format(bandname, max_mag)
        print(filter_)
        gc_cols = gc.get_quantities(
            ['galaxy_id', 'ra_true', 'dec_true', bandname], filters=[filter_])
        print(len(gc_cols[bandname]))
        # Rotate to the Run1.2p field.
        gc_ra_rot, gc_dec_rot \
            = self.field_rotator.transform(gc_cols['ra_true'],
                                           gc_cols['dec_true'])

        # Select the galaxies within the patch.
        index = np.where((gc_ra_rot > self.ra_range[0])
                         & (gc_ra_rot < self.ra_range[1])
                         & (gc_dec_rot > self.dec_range[0])
                         & (gc_dec_rot < self.dec_range[1]))
        galaxy_id = gc_cols['galaxy_id'][index]
        gc_ra = gc_ra_rot[index]
        gc_dec = gc_dec_rot[index]
        gc_mag = gc_cols[bandname][index]
        print(len(galaxy_id))

        # Create a SourceCatalog with the galaxy_ids, coordinates, magnitudes
        galaxy_catalog = make_SourceCatalog(mag_cols((band, )))
        for id_, ra, dec, mag in zip(galaxy_id, gc_ra, gc_dec, gc_mag):
            record = galaxy_catalog.addNew()
            record.set('id', id_)
            record.set('coord_ra', afw_geom.Angle(ra, afw_geom.degrees))
            record.set('coord_dec', afw_geom.Angle(dec, afw_geom.degrees))
            record.set('mag_{}'.format(band), mag)
        return galaxy_catalog
Esempio n. 4
0
    def __init__(self, config=None):
        """Construct a DodecaSkyMap

        @param[in] config: an instance of self.ConfigClass; if None the default config is used
        """
        BaseSkyMap.__init__(self, config)
        self._dodecahedron = detail.Dodecahedron(
            withFacesOnPoles=self.config.withTractsOnPoles)

        tractOverlap = afwGeom.Angle(self.config.tractOverlap, afwGeom.degrees)

        for id in range(12):
            tractVec = self._dodecahedron.getFaceCtr(id)
            tractCoord = detail.coordFromVec(tractVec, defRA=afwGeom.Angle(0))
            tractRA = tractCoord.getLongitude()
            vertexVecList = self._dodecahedron.getVertices(id)

            # make initial WCS; don't worry about crPixPos because TractInfo will shift it as required
            wcs = self._wcsFactory.makeWcs(crPixPos=afwGeom.Point2D(0, 0),
                                           crValCoord=tractCoord)

            self._tractInfoList.append(
                TractInfo(
                    id=id,
                    patchInnerDimensions=self.config.patchInnerDimensions,
                    patchBorder=self.config.patchBorder,
                    ctrCoord=tractCoord,
                    vertexCoordList=[
                        detail.coordFromVec(vec, defRA=tractRA)
                        for vec in vertexVecList
                    ],
                    tractOverlap=tractOverlap,
                    wcs=wcs,
                ))
    def __init__(self, result):
        """Set exposure information based on a query result from a db connection
        """
        self._ind = -1

        dataId = dict(
            run=result[self._nextInd],
            rerun=result[self._nextInd],
            camcol=result[self._nextInd],
            field=result[self._nextInd],
            filter=result[self._nextInd],
        )
        coordList = []
        for i in range(4):
            coordList.append(
                IcrsCoord(
                    afwGeom.Angle(result[self._nextInd], afwGeom.degrees),
                    afwGeom.Angle(result[self._nextInd], afwGeom.degrees),
                ))
        BaseExposureInfo.__init__(self, dataId, coordList)

        self.strip = result[self._nextInd]
        self.fwhm = result[self._nextInd]
        self.sky = result[self._nextInd]
        self.airmass = result[self._nextInd]
        self.quality = result[self._nextInd]
        self.isBlacklisted = result[self._nextInd]

        # compute RHL quality factors
        self.q = self.sky * (self.fwhm**2)
        self.qscore = None  # not known yet
Esempio n. 6
0
    def testFlatFocalPlane(self):
        """Test an undistorted focal plane (with rectangular pixels)
        """
        bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(1000, 1000))
        pixelSizeMm = afwGeom.Extent2D(0.02, 0.03)
        plateScale = 25.0   # arcsec/mm
        yaw = afwGeom.Angle(20, afwGeom.degrees)
        fpPosition = afwGeom.Point2D(50, 25)  # focal-plane position of ref position on detector (mm)
        refPoint = afwGeom.Point2D(-0.5, -0.5)  # ref position on detector (pos of lower left corner)
        orientation = cameraGeom.Orientation(
            fpPosition,
            refPoint,
            yaw,
        )
        plateScaleRad = afwGeom.Angle(plateScale, afwGeom.arcseconds).asRadians()
        focalPlaneToPupil = afwGeom.RadialXYTransform((0.0, plateScaleRad))

        pixelToTanPixel = makePixelToTanPixel(
            bbox=bbox,
            orientation=orientation,
            focalPlaneToPupil=focalPlaneToPupil,
            pixelSizeMm=pixelSizeMm,
        )

        # with no distortion, this should be a unity transform
        for pointPix in (
            afwGeom.Point2D(0, 0),
            afwGeom.Point2D(1000, 2000),
            afwGeom.Point2D(-100.5, 27.23),
        ):
            pointTanPix = pixelToTanPixel.forwardTransform(pointPix)
            self.assertPairsNearlyEqual(pointTanPix, pointPix)
Esempio n. 7
0
 def _bbox_for_coords(self, wcs, center_coord, width, height, units):
     """Returns a Box2I object representing the bounding box in pixels
     of the target region.
     @wcs: WCS object for the target region.
     @center_coord: ICRS RA and Dec coordinate for the center of the target region.
     @width: Width of the target region with units indicated by 'units' below.
     @height: Height of the target region with units indicated by 'units' below.
     @units: Units for height and width. 'pixel' or 'arcsecond'
     """
     if units == "arcsec":
         # center_coord center, RA and Dec with width and height in arcseconds
         width_half_a = afw_geom.Angle((width / 2.0), afw_geom.arcseconds)
         height_half_a = afw_geom.Angle((height / 2.0), afw_geom.arcseconds)
         min_ra = center_coord.getLongitude() - width_half_a
         min_dec = center_coord.getLatitude() - height_half_a
         max_ra = center_coord.getLongitude() + width_half_a
         max_dec = center_coord.getLatitude() + height_half_a
         ll_coord = afw_geom.SpherePoint(min_ra, min_dec)
         ll_coord_pix = wcs.skyToPixel(ll_coord)
         ur_coord = afw_geom.SpherePoint(max_ra, max_dec)
         ur_coord_pix = wcs.skyToPixel(ur_coord)
         p2i_min = afw_geom.Point2I(ll_coord_pix)
         p2i_max = afw_geom.Point2I(ur_coord_pix)
         bbox = afw_geom.Box2I(p2i_min, p2i_max)
     elif units == "pixel":
         # center_coord center, RA and Dec with width and height in pixels
         ctr_coord_pix = wcs.skyToPixel(center_coord)
         min_ra_pix = int(ctr_coord_pix.getX() - width // 2)
         min_dec_pix = int(ctr_coord_pix.getY() - height // 2)
         p2i = afw_geom.Point2I(min_ra_pix, min_dec_pix)
         bbox = afw_geom.Box2I(p2i, afw_geom.Extent2I(width, height))
     else:
         raise Exception("invalid units {}".format(units))
     return bbox
Esempio n. 8
0
def averageRaDec(ra, dec):
    """Calculate average RA, Dec from input lists using spherical geometry.

    Parameters
    ----------
    ra : list of float
        RA in [radians]
    dec : list of float
        Dec in [radians]

    Returns
    -------
    float, float
       meanRa, meanDec -- Tuple of average RA, Dec [radians]
    """
    assert (len(ra) == len(dec))

    angleRa = [afwGeom.Angle(r, afwGeom.radians) for r in ra]
    angleDec = [afwGeom.Angle(d, afwGeom.radians) for d in dec]
    coords = [
        afwGeom.SpherePoint(ar, ad, afwGeom.radians)
        for (ar, ad) in zip(angleRa, angleDec)
    ]

    meanRa, meanDec = afwGeom.averageSpherePoint(coords)

    return meanRa.asRadians(), meanDec.asRadians()
Esempio n. 9
0
    def testCurvedFocalPlane(self):
        """Test a curved focal plane (with rectangular pixels)
        """
        bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0),
                             afwGeom.Extent2I(1000, 1000))
        pixelSizeMm = afwGeom.Extent2D(0.02, 0.03)
        plateScale = 25.0  # arcsec/mm
        yaw = afwGeom.Angle(20, afwGeom.degrees)
        fpPosition = afwGeom.Point2D(
            50, 25)  # focal-plane position of ref position on detector (mm)
        refPoint = afwGeom.Point2D(
            -0.5, -0.5)  # ref position on detector (pos of lower left corner)
        orientation = cameraGeom.Orientation(
            fpPosition,
            refPoint,
            yaw,
        )
        plateScaleRad = afwGeom.Angle(plateScale,
                                      afwGeom.arcseconds).asRadians()
        focalPlaneToPupil = afwGeom.RadialXYTransform(
            (0.0, plateScaleRad, 0.0, 0.001 * plateScaleRad))

        pixelToTanPixel = makePixelToTanPixel(
            bbox=bbox,
            orientation=orientation,
            focalPlaneToPupil=focalPlaneToPupil,
            pixelSizeMm=pixelSizeMm,
            plateScale=plateScale,
        )

        # the center point of the detector should not move
        ctrPointPix = afwGeom.Box2D(bbox).getCenter()
        ctrPointTanPix = pixelToTanPixel.forwardTransform(ctrPointPix)
        for i in range(2):
            self.assertAlmostEquals(ctrPointTanPix[i], ctrPointPix[i])

        # two points separated by x pixels in tan pixels coordinates
        # should be separated x * rad/tanPix in pupil coordinates,
        # where rad/tanPix = plate scale in rad/MM * mean pixel size in mm
        radPerTanPixel = plateScaleRad * (pixelSizeMm[0] +
                                          pixelSizeMm[1]) / 2.0
        pixelToFocalPlane = orientation.makePixelFpTransform(pixelSizeMm)
        pixelToPupil = afwGeom.MultiXYTransform(
            (pixelToFocalPlane, focalPlaneToPupil))
        prevPointPupil = None
        prevPointTanPix = None
        for pointPix in (
                afwGeom.Point2D(0, 0),
                afwGeom.Point2D(1000, 2000),
                afwGeom.Point2D(-100.5, 27.23),
                afwGeom.Point2D(-95.3, 0.0),
        ):
            pointPupil = pixelToPupil.forwardTransform(pointPix)
            pointTanPix = pixelToTanPixel.forwardTransform(pointPix)
            if prevPointPupil:
                pupilSep = numpy.linalg.norm(pointPupil - prevPointPupil)
                tanPixSep = numpy.linalg.norm(pointTanPix - prevPointTanPix)
                self.assertAlmostEquals(tanPixSep * radPerTanPixel, pupilSep)
            prevPointPupil = pointPupil
            prevPointTanPix = pointTanPix
Esempio n. 10
0
    def run(self, dataRef):
        """Report tracts and patches that are within a given region of a skymap

        @param dataRef: data reference for sky map.
        @return: a pipeBase.Struct with fields:
        - ccdInfoSetDict: a dict of (tractId, patchIndex): set of CcdExposureInfo
        """
        skyMap = dataRef.get(self.config.coaddName + "Coadd_skyMap")

        # make coords in the correct order to form an enclosed space
        raRange = (self.config.raDecRange[0], self.config.raDecRange[2])
        decRange = (self.config.raDecRange[1], self.config.raDecRange[3])
        raDecList = [
            (raRange[0], decRange[0]),
            (raRange[1], decRange[0]),
            (raRange[1], decRange[1]),
            (raRange[0], decRange[1]),
        ]
        coordList = [
            afwCoord.IcrsCoord(afwGeom.Angle(ra, afwGeom.degrees),
                               afwGeom.Angle(dec, afwGeom.degrees))
            for ra, dec in raDecList
        ]
        tractPatchList = skyMap.findTractPatchList(coordList)
        for tractInfo, patchInfoList in tractPatchList:
            for patchInfo in patchInfoList:
                patchIndex = patchInfo.getIndex()
                print("tract=%d patch=%d,%d" %
                      (tractInfo.getId(), patchIndex[0], patchIndex[1]))
Esempio n. 11
0
 def makeHSCExposure(self, galData, psfData, pixScale, variance):
     ny, nx = galData.shape
     exposure = afwImg.ExposureF(nx, ny)
     exposure.getMaskedImage().getImage().getArray()[:, :] = galData
     exposure.getMaskedImage().getVariance().getArray()[:, :] = variance
     #Set the PSF
     ngridPsf = psfData.shape[0]
     psfLsst = afwImg.ImageF(ngridPsf, ngridPsf)
     psfLsst.getArray()[:, :] = psfData
     psfLsst = psfLsst.convertD()
     kernel = afwMath.FixedKernel(psfLsst)
     kernelPSF = meaAlg.KernelPsf(kernel)
     exposure.setPsf(kernelPSF)
     #prepare the wcs
     #Rotation
     cdelt = (pixScale * afwGeom.arcseconds)
     CD = afwGeom.makeCdMatrix(cdelt, afwGeom.Angle(0.))  #no rotation
     #wcs
     crval = afwGeom.SpherePoint(afwGeom.Angle(0., afwGeom.degrees),
                                 afwGeom.Angle(0., afwGeom.degrees))
     #crval   =   afwCoord.IcrsCoord(0.*afwGeom.degrees, 0.*afwGeom.degrees) # hscpipe6
     crpix = afwGeom.Point2D(0.0, 0.0)
     dataWcs = afwGeom.makeSkyWcs(crpix, crval, CD)
     exposure.setWcs(dataWcs)
     #prepare the frc
     dataCalib = afwImg.makePhotoCalibFromCalibZeroPoint(63095734448.0194)
     exposure.setPhotoCalib(dataCalib)
     return exposure
Esempio n. 12
0
def makeWcs(pixScale, nx, ny, rotation=0., raCen=180.0, decCen=0.0):
    """Create a TAN WCS with pixScale/nx/ny, plus rotation (degrees) and RA/Dec center (degrees). """
    #Hardcoding TAN projection since this application is for focal plane size at most
    wcsFactory = WcsFactory(pixScale, 'TAN', rotation=rotation*afwGeom.radians)
    crpix_x = float(nx-1)/2.
    crpix_y = float(ny-1)/2.
    crval = afwCoord.Coord(afwGeom.Angle(raCen*afwGeom.degrees), afwGeom.Angle(decCen*afwGeom.degrees))
    return wcsFactory.makeWcs(afwGeom.Point2D(crpix_x, crpix_y), crval)
Esempio n. 13
0
 def pixel(wcs, ra, dec):
     """
     Use the Wcs object, wcs, to return the Pixel object corresponding
     to ra, dec, both in degrees.
     """
     ra_angle = afwGeom.Angle(ra, afwGeom.degrees)
     dec_angle = afwGeom.Angle(dec, afwGeom.degrees)
     return wcs.skyToPixel(ra_angle, dec_angle)
Esempio n. 14
0
    def testCurvedFocalPlane(self):
        """Test a curved focal plane (with rectangular pixels)
        """
        bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0),
                             afwGeom.Extent2I(1000, 1000))
        pixelSizeMm = afwGeom.Extent2D(0.02, 0.03)
        plateScale = 25.0  # arcsec/mm
        yaw = afwGeom.Angle(20, afwGeom.degrees)
        # focal-plane position of ref position on detector (mm)
        fpPosition = afwGeom.Point2D(50, 25)
        # ref position on detector (pos of lower left corner)
        refPoint = afwGeom.Point2D(-0.5, -0.5)
        orientation = cameraGeom.Orientation(
            fpPosition,
            refPoint,
            yaw,
        )
        pixelToFocalPlane = orientation.makePixelFpTransform(pixelSizeMm)
        plateScaleRad = afwGeom.Angle(plateScale,
                                      afwGeom.arcseconds).asRadians()
        focalPlaneToField = afwGeom.makeRadialTransform(
            (0.0, plateScaleRad, 0.0, 0.001 * plateScaleRad))
        pixelToField = pixelToFocalPlane.then(focalPlaneToField)

        pixelToTanPixel = makePixelToTanPixel(
            bbox=bbox,
            orientation=orientation,
            focalPlaneToField=focalPlaneToField,
            pixelSizeMm=pixelSizeMm,
        )

        # the center point of the field angle frame should not move
        pixAtFieldCtr = pixelToField.applyInverse(afwGeom.Point2D(0, 0))
        tanPixAtFieldCr = pixelToTanPixel.applyForward(pixAtFieldCtr)
        self.assertPairsAlmostEqual(pixAtFieldCtr, tanPixAtFieldCr)

        # build same camera geometry transforms without optical distortion
        focalPlaneToFieldNoDistortion = afwGeom.makeRadialTransform(
            (0.0, plateScaleRad))
        pixelToFieldNoDistortion = pixelToFocalPlane.then(
            focalPlaneToFieldNoDistortion)

        for x in (100, 200, 1000):
            for y in (100, 500, 800):
                pixPos = afwGeom.Point2D(x, y)
                tanPixPos = pixelToTanPixel.applyForward(pixPos)

                # for a given field angle (which, together with a pointing, gives a position on the sky):
                # - field angle to pixels gives pixPos
                # - undistorted field angle to pixels gives tanPixPos
                fieldPos = pixelToField.applyForward(pixPos)
                desTanPixPos = pixelToFieldNoDistortion.applyInverse(fieldPos)
                # use a degraded accuracy because small Jacobian errors accumulate this far from the center
                self.assertPairsAlmostEqual(desTanPixPos,
                                            tanPixPos,
                                            maxDiff=1e-5)
Esempio n. 15
0
    def testCtor(self):
        self.assertEqual(self.pi, math.pi)
        self.assertEqual(self.pi, afwGeom.Angle(math.pi))
        self.assertEqual(self.pi, self.d)

        dd = afwGeom.Angle(180, afwGeom.degrees)
        self.assertEqual(self.d, dd)
        dd = afwGeom.Angle(60*180, afwGeom.arcminutes)
        self.assertEqual(self.d, dd)
        dd = afwGeom.Angle(60*60*180, afwGeom.arcseconds)
        self.assertEqual(self.d, dd)
Esempio n. 16
0
def makeOrientation(detectorConfig):
    """!Make an Orientation instance from a detector config

    @param detectorConfig  config for this detector (an lsst.pex.config.Config)
    @return orientation (an lsst.afw.cameraGeom.Orientation)
    """
    offset = afwGeom.Point2D(detectorConfig.offset_x, detectorConfig.offset_y)
    refPos = afwGeom.Point2D(detectorConfig.refpos_x, detectorConfig.refpos_y)
    yaw = afwGeom.Angle(detectorConfig.yawDeg, afwGeom.degrees)
    pitch = afwGeom.Angle(detectorConfig.pitchDeg, afwGeom.degrees)
    roll = afwGeom.Angle(detectorConfig.rollDeg, afwGeom.degrees)
    return Orientation(offset, refPos, yaw, pitch, roll)
Esempio n. 17
0
 def __init__(self,
     fpPosition = afwGeom.Point2D(0, 0),
     refPoint = afwGeom.Point2D(-0.5, -0.5),
     yaw = afwGeom.Angle(0),
     pitch = afwGeom.Angle(0),
     roll = afwGeom.Angle(0),
 ):
     self.fpPosition = fpPosition
     self.refPoint = refPoint
     self.yaw = yaw
     self.pitch = pitch
     self.roll = roll
     self.orient = Orientation(fpPosition, refPoint, yaw, pitch, roll)
Esempio n. 18
0
    def checkResults(self, fitRes, catsUpdated):
        """Check results

        @param[in] fitRes  a object with two fields:
            - wcs  fit TAN-SIP WCS, an lsst.afw.image.TanWcs
            - scatterOnSky  median on-sky scatter, an lsst.afw.geom.Angle
        @param[in] catsUpdated  if True then coord field of self.sourceCat and centroid fields of self.refCat
            have been updated
        """
        self.assertLess(fitRes.scatterOnSky.asArcseconds(), 0.001)
        tanSipWcs = fitRes.wcs
        maxAngSep = afwGeom.Angle(0)
        maxPixSep = 0
        refCoordKey = afwTable.CoordKey(self.refCat.schema["coord"])
        if catsUpdated:
            refCentroidKey = afwTable.Point2DKey(
                self.refCat.schema["centroid"])
        maxDistErr = afwGeom.Angle(0)
        for refObj, src, distRad in self.matches:
            srcPixPos = src.get(self.srcCentroidKey)
            refCoord = refObj.get(refCoordKey)
            if catsUpdated:
                refPixPos = refObj.get(refCentroidKey)
                srcCoord = src.get(self.srcCoordKey)
            else:
                refPixPos = tanSipWcs.skyToPixel(refCoord)
                srcCoord = tanSipWcs.pixelToSky(srcPixPos)

            angSep = refCoord.angularSeparation(srcCoord)
            dist = distRad * afwGeom.radians
            distErr = abs(dist - angSep)
            maxDistErr = max(maxDistErr, distErr)
            maxAngSep = max(maxAngSep, angSep)
            self.assertLess(angSep.asArcseconds(), 0.001)

            pixSep = math.hypot(*(srcPixPos - refPixPos))
            maxPixSep = max(maxPixSep, pixSep)
            self.assertLess(pixSep, 0.001)

        print("max angular separation = %0.4f arcsec" %
              (maxAngSep.asArcseconds(), ))
        print("max pixel separation = %0.3f" % (maxPixSep, ))
        if catsUpdated:
            allowedDistErr = 1e-7
        else:
            allowedDistErr = 0.001
        self.assertLess(
            maxDistErr.asArcseconds(), allowedDistErr,
            "Computed distance in match list is off by %s arcsec" %
            (maxDistErr.asArcseconds(), ))
Esempio n. 19
0
def get_hsc_regions(box_coords, butler=None):
    """
    Get hsc regions within a polygonal region (box) of the sky. Here, 
    hsc regions means the tracts and patches within the 'skybox'. 

    Parameters
    ----------
    box_coords : list of tuples
        The four coordinates for the box corners. This is the 
        output of the skybox function. If only one coordinate
        is given, will return a single tract and patch. 
    butler : Butler object, optional
        If None, then a will be created in this function.
        Default is None.

    Returns
    -------
    regions : structured ndarray
        The tracts and patches within the skybox. The columns of 
        the array are 'tract' and 'patch'.

    Note
    ----
    This may give incorrect answers on regions that are larger than a tract, 
    which is ~1.5 degree = 90 arcminute.
    """
    import lsst.afw.coord as afwCoord
    import lsst.afw.geom as afwGeom
    if butler is None:
        import lsst.daf.persistence
        from myPipe import dataDIR
        butler = lsst.daf.persistence.Butler(dataDIR)
    if len(box_coords)==4:
        from toolbox.astro import angsep
        (ra1, dec1), (ra2, dec2) = box_coords[0], box_coords[2]
        if angsep(ra1, dec1, ra2, dec2, sepunits='arcmin') > 90.0:
            print('\n********* WARNING *********')
            print('Region larger than a tract')
            print('***************************\n')
    skymap = butler.get('deepCoadd_skyMap', immediate=True)
    coordList = [afwCoord.IcrsCoord(afwGeom.Angle(ra, afwGeom.degrees),\
                 afwGeom.Angle(dec, afwGeom.degrees)) for ra, dec in box_coords]
    tractPatchList = skymap.findClosestTractPatchList(coordList)
    regions = []
    for tractInfo, patchInfoList in tractPatchList:
        for patchInfo in patchInfoList:
            patchIndex = patchInfo.getIndex()
            regions.append((tractInfo.getId(), str(patchIndex[0])+','+str(patchIndex[1])))
    return np.array(regions, dtype=[('tract', int), ('patch', 'S4')])
Esempio n. 20
0
    def _minimumBoundingBox(self, wcs):
        """Calculate the minimum bounding box for the tract, given the WCS

        The bounding box is created in the frame of the supplied WCS,
        so that it's OK if the coordinates are negative.

        We compute the bounding box that holds all the vertices and the
        desired overlap.
        """
        minBBoxD = afwGeom.Box2D()
        halfOverlap = self._tractOverlap / 2.0
        for vertexCoord in self._vertexCoordList:
            vertexDeg = vertexCoord.getPosition(afwGeom.degrees)
            if self._tractOverlap == 0:
                minBBoxD.include(wcs.skyToPixel(vertexCoord))
            else:
                numAngles = 24
                angleIncr = afwGeom.Angle(360.0,
                                          afwGeom.degrees) / float(numAngles)
                for i in range(numAngles):
                    offAngle = angleIncr * i
                    offCoord = vertexCoord.clone()
                    offCoord.offset(offAngle, halfOverlap)
                    pixPos = wcs.skyToPixel(offCoord)
                    minBBoxD.include(pixPos)
        return minBBoxD
Esempio n. 21
0
    def testAngleAliases(self):
        with self.assertWarns(FutureWarning):
            self.assertEqual(afwGeom.Angle(1), lsst.geom.Angle(1))

        self.assertIs(afwGeom.radians, lsst.geom.radians)
        self.assertIs(afwGeom.degrees, lsst.geom.degrees)
        self.assertIs(afwGeom.hours, lsst.geom.hours)
        self.assertIs(afwGeom.arcminutes, lsst.geom.arcminutes)
        self.assertIs(afwGeom.arcseconds, lsst.geom.arcseconds)

        self.assertIs(afwGeom.PI, lsst.geom.PI)
        self.assertIs(afwGeom.TWOPI, lsst.geom.TWOPI)
        self.assertIs(afwGeom.HALFPI, lsst.geom.HALFPI)
        self.assertIs(afwGeom.ONE_OVER_PI, lsst.geom.ONE_OVER_PI)
        self.assertIs(afwGeom.SQRTPI, lsst.geom.SQRTPI)
        self.assertIs(afwGeom.INVSQRTPI, lsst.geom.INVSQRTPI)
        self.assertIs(afwGeom.ROOT2, lsst.geom.ROOT2)

        with self.assertWarns(FutureWarning):
            self.assertEqual(afwGeom.degToRad(1), lsst.geom.degToRad(1))
        with self.assertWarns(FutureWarning):
            self.assertEqual(afwGeom.radToDeg(1), lsst.geom.radToDeg(1))
        with self.assertWarns(FutureWarning):
            self.assertEqual(afwGeom.radToArcsec(1), lsst.geom.radToArcsec(1))
        with self.assertWarns(FutureWarning):
            self.assertEqual(afwGeom.radToMas(1), lsst.geom.radToMas(1))
        with self.assertWarns(FutureWarning):
            self.assertEqual(afwGeom.arcsecToRad(1), lsst.geom.arcsecToRad(1))
        with self.assertWarns(FutureWarning):
            self.assertEqual(afwGeom.masToRad(1), lsst.geom.masToRad(1))
Esempio n. 22
0
    def __init__(self, result):
        """Set exposure information based on a query result from a db connection
        """
        result = list(result)
        dataId = dict(
            run=result.pop(0),
            camcol=result.pop(0),
            field=result.pop(0),
            filter=result.pop(0),
        )
        coordList = [IcrsCoord(afwGeom.Angle(result.pop(0), afwGeom.degrees),
                               afwGeom.Angle(result.pop(0), afwGeom.degrees)) for i in range(4)]

        BaseExposureInfo.__init__(self, dataId=dataId, coordList=coordList)
        self.fluxMag0 = result.pop(0)
        self.fluxMag0Sigma = result.pop(0)
Esempio n. 23
0
 def testGetters(self):
     """Test getters
     """
     ow = OrientationWrapper(
         fpPosition = afwGeom.Point2D(0.1, -0.2),
         refPoint = afwGeom.Point2D(-5.7, 42.3),
         yaw = afwGeom.Angle(-0.53),
         pitch = afwGeom.Angle(0.234),
         roll = afwGeom.Angle(1.2),
     )
     for i in range(2):
         self.assertAlmostEquals(ow.fpPosition[i], ow.orient.getFpPosition()[i])
         self.assertAlmostEquals(ow.refPoint[i], ow.orient.getReferencePoint()[i])
     self.assertAlmostEquals(ow.yaw, ow.orient.getYaw())
     self.assertAlmostEquals(ow.roll, ow.orient.getRoll())
     self.assertAlmostEquals(ow.pitch, ow.orient.getPitch())
Esempio n. 24
0
 def setUp(self):
     self._NumTracts = 12  # Number of tracts to expect
     self._NeighborAngularSeparation = afwGeom.Angle(180.0, afwGeom.degrees) \
         - _DihedralAngle  # Tract separation
     self._SkyMapClass = DodecaSkyMap  # Class of SkyMap to test
     self._SkyMapName = "dodeca"  # Name of SkyMap class to test
     self._numNeighbors = 6  # Number of neighbours
def build_matched_dataset(repo,
                          dataIds,
                          matchRadius=None,
                          safeSnr=50.,
                          useJointCal=False,
                          skipTEx=False):
    blob = Blob('MatchedMultiVisitDataset')

    if not matchRadius:
        matchRadius = afwGeom.Angle(1, afwGeom.arcseconds)

    # Extract single filter
    blob['filterName'] = Datum(quantity=set([dId['filter']
                                             for dId in dataIds]).pop(),
                               description='Filter name')

    # Record important configuration
    blob['useJointCal'] = Datum(
        quantity=useJointCal,
        description='Whether jointcal/meas_mosaic calibrations were used')

    # Match catalogs across visits
    blob._catalog, blob._matchedCatalog = \
        _loadAndMatchCatalogs(repo, dataIds, matchRadius,
                                   useJointCal=useJointCal, skipTEx=False)

    blob.magKey = blob._matchedCatalog.schema.find("base_PsfFlux_mag").key
    # Reduce catalogs into summary statistics.
    # These are the serialiable attributes of this class.
    _reduceStars(blob, blob._matchedCatalog, safeSnr)
    return blob
Esempio n. 26
0
    def __init__(self, config=None):
        """Construct a BaseSkyMap

        @param[in] config: an instance of self.ConfigClass; if None the default config is used
        """
        if config is None:
            config = self.ConfigClass()
        config.freeze()  # just to be sure, e.g. for pickling
        self.config = config
        self._tractInfoList = []
        self._wcsFactory = detail.WcsFactory(
            pixelScale=afwGeom.Angle(self.config.pixelScale,
                                     afwGeom.arcseconds),
            projection=self.config.projection,
            rotation=afwGeom.Angle(self.config.rotation, afwGeom.degrees),
        )
Esempio n. 27
0
    def testCurvedFocalPlane(self):
        """Test a curved focal plane (with rectangular pixels)
        """
        bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(1000, 1000))
        pixelSizeMm = afwGeom.Extent2D(0.02, 0.03)
        plateScale = 25.0   # arcsec/mm
        yaw = afwGeom.Angle(20, afwGeom.degrees)
        fpPosition = afwGeom.Point2D(50, 25)  # focal-plane position of ref position on detector (mm)
        refPoint = afwGeom.Point2D(-0.5, -0.5)  # ref position on detector (pos of lower left corner)
        orientation = cameraGeom.Orientation(
            fpPosition,
            refPoint,
            yaw,
        )
        pixelToFocalPlane = orientation.makePixelFpTransform(pixelSizeMm)
        plateScaleRad = afwGeom.Angle(plateScale, afwGeom.arcseconds).asRadians()
        focalPlaneToPupil = afwGeom.RadialXYTransform((0.0, plateScaleRad, 0.0, 0.001 * plateScaleRad))
        pixelToPupil = afwGeom.MultiXYTransform((pixelToFocalPlane, focalPlaneToPupil))

        pixelToTanPixel = makePixelToTanPixel(
            bbox=bbox,
            orientation=orientation,
            focalPlaneToPupil=focalPlaneToPupil,
            pixelSizeMm=pixelSizeMm,
        )

        # the center point of the pupil frame should not move
        pixAtPupilCtr = pixelToPupil.reverseTransform(afwGeom.Point2D(0, 0))
        tanPixAtPupilCr = pixelToTanPixel.forwardTransform(pixAtPupilCtr)
        self.assertPairsNearlyEqual(pixAtPupilCtr, tanPixAtPupilCr)

        # build same camera geometry transforms without optical distortion
        focalPlaneToPupilNoDistortion = afwGeom.RadialXYTransform((0.0, plateScaleRad))
        pixelToPupilNoDistortion = afwGeom.MultiXYTransform(
            (pixelToFocalPlane, focalPlaneToPupilNoDistortion))

        for x in (100, 200, 1000):
            for y in (100, 500, 800):
                pixPos = afwGeom.Point2D(x, y)
                tanPixPos = pixelToTanPixel.forwardTransform(pixPos)

                # for a given pupil position (which, together with a pointing, gives a position on the sky):
                # - pupil to pixels gives pixPos
                # - undistorted pupil to pixels gives tanPixPos
                pupilPos = pixelToPupil.forwardTransform(pixPos)
                desTanPixPos = pixelToPupilNoDistortion.reverseTransform(pupilPos)
                self.assertPairsNearlyEqual(desTanPixPos, tanPixPos)
Esempio n. 28
0
 def __init__(self, result):
     """Set exposure information based on a query result from a db connection
     """
     self._ind = -1
     dataId = dict(raft=result[self._nextInd],
                   visit=result[self._nextInd],
                   sensor=result[self._nextInd],
                   filter=result[self._nextInd])
     coordList = []
     for i in range(4):
         coordList.append(
             IcrsCoord(
                 afwGeom.Angle(result[self._nextInd], afwGeom.degrees),
                 afwGeom.Angle(result[self._nextInd], afwGeom.degrees),
             ))
     self.fwhm = result[self._nextInd]
     BaseExposureInfo.__init__(self, dataId, coordList)
Esempio n. 29
0
def makeWcs(pixelScale=0.2 * afwGeom.arcseconds,
            crPixPos=(2000.0, 1520.5),
            crValDeg=(27.53, 87.123),
            posAng=afwGeom.Angle(0.0),
            doFlipX=False,
            projection="TAN",
            coordSys=afwCoord.ICRS,
            equinox=2000):
    """Make an simple TAN WCS with sensible defaults

    @param[in] pixelScale: desired scale, as sky/pixel, an afwGeom.Angle
    @param[in] crPixPos: crPix for WCS, using the LSST standard; a pair of floats
    @param[in] crValDeg: crVal for WCS, in degrees; a pair of floats
    @param[in] posAng: position angle (afwGeom.Angle)
    @param[in] doFlipX: flip X axis?
    @param[in] projection: WCS projection (e.g. "TAN" or "STG")
    @param[in] coordSys: coordinate system enum
    @param[in] equinox: date of equinox; should be 2000 for ICRS or GALACTIC
    """
    if len(projection) != 3:
        raise RuntimeError("projection=%r; must have length 3" %
                           (projection, ))

    csysPrefixes, radesys = {
        afwCoord.ICRS: (("RA", "DEC"), "ICRS"),
        afwCoord.FK5: (("RA", "DEC"), "FK5"),
        afwCoord.ECLIPTIC: (("ELON", "ELAT"), None),
        afwCoord.GALACTIC: (("GLON", "GLAT"), None),
    }[coordSys]

    ctypeList = [
        ("%-4s-%3s" % (csysPrefixes[i], projection)).replace(" ", "-")
        for i in range(2)
    ]
    ps = dafBase.PropertySet()
    # convert pix position to FITS standard
    crPixFits = [ind + 1.0 for ind in crPixPos]
    posAngRad = posAng.asRadians()
    pixelScaleDeg = pixelScale.asDegrees()
    cdMat = np.array(
        [[math.cos(posAngRad), math.sin(posAngRad)],
         [-math.sin(posAngRad), math.cos(posAngRad)]],
        dtype=float) * pixelScaleDeg
    if doFlipX:
        cdMat[:, 0] = -cdMat[:, 0]
    for i in range(2):
        ip1 = i + 1
        ps.add("CTYPE%1d" % (ip1, ), ctypeList[i])
        ps.add("CRPIX%1d" % (ip1, ), crPixFits[i])
        ps.add("CRVAL%1d" % (ip1, ), crValDeg[i])
    if radesys:
        ps.add("RADESYS", radesys)
    ps.add("EQUINOX", equinox)
    ps.add("CD1_1", cdMat[0, 0])
    ps.add("CD2_1", cdMat[1, 0])
    ps.add("CD1_2", cdMat[0, 1])
    ps.add("CD2_2", cdMat[1, 1])
    return afwImage.makeWcs(ps)
Esempio n. 30
0
    def testSimpleCurvedFocalPlane(self):
        """Test a trivial curved focal plane with square pixels

        The CCD's lower left pixel is centered on the boresight
        pupil center = focal plane center
        CCD x is along focal plane x
        """
        bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(1000, 1000))
        pixelSizeMm = afwGeom.Extent2D(0.02, 0.02)
        plateScale = 25.0   # arcsec/mm
        yaw = 0 * afwGeom.degrees
        fpPosition = afwGeom.Point2D(0, 0)  # focal-plane position of ref position on detector (mm)
        refPoint = afwGeom.Point2D(0, 0)  # ref position on detector (pos of lower left corner)
        orientation = cameraGeom.Orientation(
            fpPosition,
            refPoint,
            yaw,
        )
        pixelToFocalPlane = orientation.makePixelFpTransform(pixelSizeMm)
        plateScaleRad = afwGeom.Angle(plateScale, afwGeom.arcseconds).asRadians()
        focalPlaneToPupil = afwGeom.RadialXYTransform((0.0, plateScaleRad, 0.0, 0.001 * plateScaleRad))
        pixelToPupil = afwGeom.MultiXYTransform((pixelToFocalPlane, focalPlaneToPupil))

        pixelToTanPixel = makePixelToTanPixel(
            bbox=bbox,
            orientation=orientation,
            focalPlaneToPupil=focalPlaneToPupil,
            pixelSizeMm=pixelSizeMm,
        )

        # pupil center should be pixel position 0, 0 and tan pixel position 0, 0
        pixAtPupilCtr = pixelToPupil.reverseTransform(afwGeom.Point2D(0, 0))
        self.assertPairsNearlyEqual(pixAtPupilCtr, [0, 0])
        tanPixAtPupilCr = pixelToTanPixel.forwardTransform(pixAtPupilCtr)
        self.assertPairsNearlyEqual(tanPixAtPupilCr, [0, 0])

        # build same camera geometry transforms without optical distortion
        focalPlaneToPupilNoDistortion = afwGeom.RadialXYTransform((0.0, plateScaleRad))
        pixelToPupilNoDistortion = afwGeom.MultiXYTransform(
            (pixelToFocalPlane, focalPlaneToPupilNoDistortion))

        for x in (100, 200, 1000):
            for y in (100, 500, 800):
                pixPos = afwGeom.Point2D(x, y)
                tanPixPos = pixelToTanPixel.forwardTransform(pixPos)
                # pix to tan pix should be radial
                self.assertAlmostEqual(
                    math.atan2(pixPos[1], pixPos[0]),
                    math.atan2(tanPixPos[1], tanPixPos[0]),
                )

                # for a given pupil angle (which, together with a pointing, gives a position on the sky):
                # - pupil to pixels gives pixPos
                # - undistorted pupil to pixels gives tanPixPos
                pupilPos = pixelToPupil.forwardTransform(pixPos)
                desTanPixPos = pixelToPupilNoDistortion.reverseTransform(pupilPos)
                self.assertPairsNearlyEqual(desTanPixPos, tanPixPos)