def run(self, sources, skyMap, tractInfo, patchInfo, includeDeblend=True):
        """Set is-primary and related flags on sources

        @param[in,out] sources   a SourceTable
            - reads centroid fields and an nChild field
            - writes is-patch-inner, is-tract-inner and is-primary flags
        @param[in] skyMap   sky tessellation object (subclass of lsst.skymap.BaseSkyMap)
        @param[in] tractInfo   tract object (subclass of lsst.skymap.TractInfo)
        @param[in] patchInfo   patch object (subclass of lsst.skymap.PatchInfo)
        @param[in] includeDeblend   include deblend information in isPrimary?
        """
        nChildKey = None
        if includeDeblend:
            nChildKey = self.schema.find(self.config.nChildKeyName).key

        # set inner flags for each source and set primary flags for sources with no children
        # (or all sources if deblend info not available)
        innerFloatBBox = Box2D(patchInfo.getInnerBBox())

        # When the centroider fails, we can still fall back to the peak, but we don't trust
        # that quite as much - so we use a slightly smaller box for the patch comparison.
        # That's trickier for the tract comparison, so we just use the peak without extra
        # care there.
        shrunkInnerFloatBBox = Box2D(innerFloatBBox)
        shrunkInnerFloatBBox.grow(-1)

        pseudoFilterKeys = []
        for filt in self.config.pseudoFilterList:
            try:
                pseudoFilterKeys.append(self.schema.find("merge_peak_%s" % filt).getKey())
            except Exception:
                self.log.warn("merge_peak is not set for pseudo-filter %s" % filt)

        tractId = tractInfo.getId()
        for source in sources:
            centroidPos = source.getCentroid()
            if numpy.any(numpy.isnan(centroidPos)):
                continue
            if source.getCentroidFlag():
                # Use a slightly smaller box to guard against bad centroids (see above)
                isPatchInner = shrunkInnerFloatBBox.contains(centroidPos)
            else:
                isPatchInner = innerFloatBBox.contains(centroidPos)
            source.setFlag(self.isPatchInnerKey, isPatchInner)

            skyPos = source.getCoord()
            sourceInnerTractId = skyMap.findTract(skyPos).getId()
            isTractInner = sourceInnerTractId == tractId
            source.setFlag(self.isTractInnerKey, isTractInner)

            if nChildKey is None or source.get(nChildKey) == 0:
                for pseudoFilterKey in pseudoFilterKeys:
                    if source.get(pseudoFilterKey):
                        isPseudo = True
                        break
                else:
                    isPseudo = False

                source.setFlag(self.isPrimaryKey, isPatchInner and isTractInner and not isPseudo)
Exemple #2
0
 def setUp(self):
     # Test geometry:
     #
     # -100,99                99,99
     #     +--------------------+
     #     |AAAAAAAAAACCCCCDDDDD|    A == only in epoch A
     #     |AAAAAAAAAACCCCCDDDDD|    B == only in epoch B
     #     |AAAAAAAAAACCCCCDDDDD|    C == in both epoch A and epoch B
     #     |AAAAAAAAAACCCCCDDDDD|    D == in epoch A; in B's bbox but outside its ValidPolygon
     #     |AAAAAAAAAACCCCCDDDDD|
     #     |          BBBBBBBBBB|    All WCSs have the same CRVAL and CD.
     #     |          BBBBBBBBBB|
     #     |          BBBBBBBBBB|    Coadd has CRPIX=(0, 0)
     #     |          BBBBBBBBBB|    Epoch A has CRPIX=(0, -50)
     #     |          BBBBBBBBBB|    Epoch B has CRPIX=(-50, 0)
     #     +--------------------+
     # -100,-100             99,-100
     #
     self.rng = np.random.RandomState(50)
     crval = SpherePoint(45.0, 45.0, degrees)
     cdMatrix = makeCdMatrix(scale=5E-5 * degrees, flipX=True)
     self.wcsCoadd = makeSkyWcs(crpix=Point2D(0.0, 0.0),
                                crval=crval,
                                cdMatrix=cdMatrix)
     self.wcsA = makeSkyWcs(crpix=Point2D(0.0, -50.0),
                            crval=crval,
                            cdMatrix=cdMatrix)
     self.wcsB = makeSkyWcs(crpix=Point2D(-50.0, 0.0),
                            crval=crval,
                            cdMatrix=cdMatrix)
     self.bboxCoadd = Box2I(Point2I(-100, -100), Point2I(99, 99))
     self.bboxA = Box2I(Point2I(-100, -50), Point2I(99, 49))
     self.bboxB = Box2I(Point2I(-50, -100), Point2I(49, 99))
     self.polygonA = None
     polygonD = Polygon(Box2D(Box2I(Point2I(0, 0), Point2I(49, 99))))
     self.polygonB, = polygonD.symDifference(Polygon(Box2D(self.bboxB)))
     self.curveA = makeRandomTransmissionCurve(self.rng)
     self.curveB = makeRandomTransmissionCurve(self.rng)
     self.weightA = 0.6
     self.weightB = 0.2
     schema = ExposureTable.makeMinimalSchema()
     weightKey = schema.addField("weight",
                                 type=float,
                                 doc="relative weight of image in Coadd")
     catalog = ExposureCatalog(schema)
     recordA = catalog.addNew()
     recordA[weightKey] = self.weightA
     recordA.setWcs(self.wcsA)
     recordA.setValidPolygon(self.polygonA)
     recordA.setBBox(self.bboxA)
     recordA.setTransmissionCurve(self.curveA)
     recordB = catalog.addNew()
     recordB[weightKey] = self.weightB
     recordB.setWcs(self.wcsB)
     recordB.setValidPolygon(self.polygonB)
     recordB.setBBox(self.bboxB)
     recordB.setTransmissionCurve(self.curveB)
     self.curveCoadd = makeCoaddTransmissionCurve(self.wcsCoadd, catalog)
Exemple #3
0
    def testReadOldTanFits(self):
        """Test reading a FITS file containing data for an lsst::afw::image::TanWcs

        That file was made using the same metadata follows
        (like self.metadata without the distortion)
        """
        tanMetadata = PropertyList()
        # the following was fit using CreateWcsWithSip from meas_astrom
        # and is valid over this bbox: (minimum=(0, 0), maximum=(3030, 3030))
        # This same metadata was used to create testdata/oldTanSipwWs.fits
        for name, value in (
            ("RADESYS", "ICRS"),
            ("CTYPE1", "RA---TAN"),
            ("CTYPE2", "DEC--TAN"),
            ("CRPIX1", 1531.1824767147),
            ("CRPIX2", 1531.1824767147),
            ("CRVAL1", 43.035511801383),
            ("CRVAL2", 44.305697682784),
            ("CUNIT1", "deg"),
            ("CUNIT2", "deg"),
            ("CD1_1", 0.00027493991598151),
            ("CD1_2", -3.2758487104158e-06),
            ("CD2_1", 3.2301310675830e-06),
            ("CD2_2", 0.00027493937506632),
        ):
            tanMetadata.set(name, value)

        dataDir = os.path.join(os.path.split(__file__)[0], "data")
        filePath = os.path.join(dataDir, "oldTanWcs.fits")
        wcsFromFits = SkyWcs.readFits(filePath)

        wcsFromMetadata = makeSkyWcs(tanMetadata)

        bbox = Box2D(Point2D(-1000, -1000), Extent2D(3000, 3000))
        self.assertWcsAlmostEqualOverBBox(wcsFromFits, wcsFromMetadata, bbox)
Exemple #4
0
    def checkMakeFlippedWcs(self, skyWcs, skyAtol=1e-7 * arcseconds):
        """Check makeFlippedWcs on the provided WCS
        """
        # make an arbitrary bbox, but one that includes zero in one axis
        # and does not include zero in the other axis
        # the center of the bbox is used as the center of flipping
        # and the corners of the bbox are the input positions that are tested
        bbox = Box2D(Point2D(-100, 1000), Extent2D(2000, 1501))
        # dict of (isRight, isTop): position
        minPos = bbox.getMin()
        maxPos = bbox.getMax()
        center = bbox.getCenter()
        cornerDict = {
            (False, False): minPos,
            (False, True): Point2D(minPos[0], maxPos[1]),
            (True, False): Point2D(maxPos[0], minPos[1]),
            (True, True): maxPos,
        }
        for flipLR, flipTB in itertools.product((False, True), (False, True)):
            flippedWcs = makeFlippedWcs(wcs=skyWcs,
                                        flipLR=flipLR,
                                        flipTB=flipTB,
                                        center=center)
            # the center is unchanged
            self.assertSpherePointsAlmostEqual(skyWcs.pixelToSky(center),
                                               flippedWcs.pixelToSky(center),
                                               maxSep=skyAtol)

            for isR, isT in itertools.product((False, True), (False, True)):
                origPos = cornerDict[(isR, isT)]
                flippedPos = cornerDict[(isR ^ flipLR, isT ^ flipTB)]
                self.assertSpherePointsAlmostEqual(
                    skyWcs.pixelToSky(origPos),
                    flippedWcs.pixelToSky(flippedPos),
                    maxSep=skyAtol)
Exemple #5
0
 def testAgainstAstropyWcs(self):
     skyWcs = makeSkyWcs(self.metadata, strip=False)
     header = makeLimitedFitsHeader(self.metadata)
     astropyWcs = astropy.wcs.WCS(header)
     bbox = Box2D(Point2D(-1000, -1000), Extent2D(3000, 3000))
     self.assertSkyWcsAstropyWcsAlmostEqual(skyWcs=skyWcs,
                                            astropyWcs=astropyWcs,
                                            bbox=bbox)
    def testBasics(self):
        """Test construction of a discrete sky map
        """
        butler = Butler(inputs=self.inPath,
                        outputs={
                            'root': self.outPath,
                            'mode': 'rw'
                        })
        coordList = []  # list of sky coords of all corners of all calexp
        for dataId in (
                dict(visit=1, filter="g"),
                dict(visit=2, filter="g"),
                dict(visit=3, filter="r"),
        ):
            # TODO: pybind11 remove `immediate=True` once DM-9112 is resolved
            rawImage = butler.get("raw", dataId, immediate=True)
            # fake calexp by simply copying raw data; the task just cares about its bounding box
            # (which is slightly larger for raw, but that doesn't matter for this test)
            calexp = rawImage
            butler.put(calexp, "calexp", dataId)
            calexpWcs = calexp.getWcs()
            calexpBoxD = Box2D(calexp.getBBox())
            coordList += [
                calexpWcs.pixelToSky(corner)
                for corner in calexpBoxD.getCorners()
            ]

        # use the calexp to make a sky map
        retVal = MakeDiscreteSkyMapTask.parseAndRun(
            args=[self.inPath, "--output", self.outPath, "--id", "filter=g^r"],
            config=self.config,
            doReturnResults=True,
        )
        self.assertEqual(len(retVal.resultList), 1)
        skyMap = retVal.resultList[0].result.skyMap
        self.assertEqual(type(skyMap), DiscreteSkyMap)
        self.assertEqual(len(skyMap), 1)
        tractInfo = skyMap[0]
        self.assertEqual(tractInfo.getId(), 0)
        self.assertEqual(tractInfo.getNumPatches(), Extent2I(3, 3))
        tractWcs = tractInfo.getWcs()
        tractBoxD = Box2D(tractInfo.getBBox())
        for skyPoint in coordList:
            self.assertTrue(tractBoxD.contains(tractWcs.skyToPixel(skyPoint)))
Exemple #7
0
    def makeRandomPoint(self, *args, **kwds):
        """Draw a random Point2D within a Box2I.

        All arguments are forwarded directly to the Box2I constructor, allowing
        the caller to pass a fully-constructed Box2I, a (Point2I, Point2I) pair,
        or a (Point2I, Extent2I) pair.
        """
        bboxD = Box2D(Box2I(*args, **kwds))
        return bboxD.getMin() + Extent2D(bboxD.getWidth() * self.rng.rand(),
                                         bboxD.getHeight() * self.rng.rand())
Exemple #8
0
    def testReadOldTanSipFits(self):
        """Test reading a FITS file containing data for an lsst::afw::image::TanWcs

        That file was made using the same metadata as this test
        """
        dataDir = os.path.join(os.path.split(__file__)[0], "data")
        filePath = os.path.join(dataDir, "oldTanSipWcs.fits")
        wcsFromFits = SkyWcs.readFits(filePath)

        wcsFromMetadata = makeSkyWcs(self.metadata)

        bbox = Box2D(Point2D(-1000, -1000), Extent2D(3000, 3000))
        self.assertWcsAlmostEqualOverBBox(wcsFromFits, wcsFromMetadata, bbox)
Exemple #9
0
def extractCtorArgs(md):
    wcs = makeSkyWcs(makePropertyListFromDict(md))
    kwds = {
        "pixelToIwc": getPixelToIntermediateWorldCoords(wcs),
        "bbox":
        Box2D(Box2I(Point2I(0, 0), Extent2I(md["NAXES1"], md["NAXES2"]))),
        "crpix":
        Point2D(md["CRPIX1"] - 1.0,
                md["CRPIX2"] - 1.0),  # -1 for LSST vs. FITS conventions
        "cd": np.array([[md["CD1_1"], md["CD1_2"]], [md["CD2_1"],
                                                     md["CD2_2"]]]),
    }
    return kwds
Exemple #10
0
    def __init__(self, detectorList):
        """!Construct a DetectorCollection

        @param[in] detectorList  a sequence of detectors in index order
        """
        self._idDetectorDict = dict((d.getId(), d) for d in detectorList)
        self._nameDetectorDict = dict((d.getName(), d) for d in detectorList)
        self._fpBBox = Box2D()
        for detector in detectorList:
            for corner in detector.getCorners(FOCAL_PLANE):
                self._fpBBox.include(corner)
        if len(self._idDetectorDict) < len(detectorList):
            raise RuntimeError("Detector IDs are not unique")
        if len(self._nameDetectorDict) < len(detectorList):
            raise RuntimeError("Detector names are not unique")
Exemple #11
0
def createMatchMetadata(exposure, border=0):
    """Create metadata required for unpersisting a match list

    @param[in] exposure  exposure for which to create metadata
    @param[in] border    number of pixels by which to grow the bbox in all directions

    @return metadata about the field (a daf_base PropertyList)
    """
    bboxd = Box2D(exposure.getBBox())
    bboxd.grow(border)
    wcs = getDistortedWcs(exposure.getInfo())
    ctrCoord = wcs.pixelToSky(bboxd.getCenter()).toIcrs()
    approxRadius = max(
        ctrCoord.angularSeparation(wcs.pixelToSky(pp).toIcrs())
        for pp in bboxd.getCorners())
    return MatchMetadata(ctrCoord, approxRadius,
                         exposure.getFilter().getName())
Exemple #12
0
    def assertSkyWcsAstropyWcsAlmostEqual(self,
                                          skyWcs,
                                          astropyWcs,
                                          bbox,
                                          pixAtol=1e-4,
                                          skyAtol=1e-4 * arcseconds,
                                          checkRoundTrip=True):
        """Assert that a SkyWcs and the corresponding astropy.wcs.WCS agree over a specified bounding box
        """
        bbox = Box2D(bbox)
        center = bbox.getCenter()
        xArr = bbox.getMinX(), center[0], bbox.getMaxX()
        yArr = bbox.getMinY(), center[1], bbox.getMaxY()
        pixPosList = [Point2D(x, y) for x, y in itertools.product(xArr, yArr)]

        # pixelToSky
        skyPosList = skyWcs.pixelToSky(pixPosList)
        astropySkyPosList = self.astropyPixelsToSky(astropyWcs=astropyWcs,
                                                    pixPosList=pixPosList)
        self.assertSpherePointListsAlmostEqual(skyPosList,
                                               astropySkyPosList,
                                               maxSep=skyAtol)

        if not checkRoundTrip:
            return

        # astropy round trip
        astropyPixPosRoundTrip = self.astropySkyToPixels(
            astropyWcs=astropyWcs, skyPosList=astropySkyPosList)
        self.assertPairListsAlmostEqual(pixPosList,
                                        astropyPixPosRoundTrip,
                                        maxDiff=pixAtol)

        # SkyWcs round trip
        pixPosListRoundTrip = skyWcs.skyToPixel(skyPosList)
        self.assertPairListsAlmostEqual(pixPosList,
                                        pixPosListRoundTrip,
                                        maxDiff=pixAtol)

        # skyToPixel astropy vs SkyWcs
        astropyPixPosList2 = self.astropySkyToPixels(astropyWcs=astropyWcs,
                                                     skyPosList=skyPosList)
        self.assertPairListsAlmostEqual(pixPosListRoundTrip,
                                        astropyPixPosList2,
                                        maxDiff=pixAtol)
Exemple #13
0
def makeSkyPolygonFromBBox(bbox, wcs):
    """Make an on-sky polygon from a bbox and a SkyWcs

    Parameters
    ----------
    bbox : `lsst.afw.geom.Box2I` or `lsst.afw.geom.Box2D`
        Bounding box of region, in pixel coordinates
    wcs : `lsst.afw.geom.SkyWcs`
        Celestial WCS

    Returns
    -------
    polygon : `lsst.sphgeom.ConvexPolygon`
        On-sky region
    """
    pixelPoints = Box2D(bbox).getCorners()
    skyPoints = wcs.pixelToSky(pixelPoints)
    return ConvexPolygon.convexHull([sp.getVector() for sp in skyPoints])
 def testReadV1Catalog(self):
     testDir = os.path.dirname(__file__)
     v1CatalogPath = os.path.join(
         testDir, "data", "exposure_catalog_v1.fits")
     catV1 = lsst.afw.table.ExposureCatalog.readFits(v1CatalogPath)
     self.assertEqual(self.cat[0].get(self.ka), catV1[0].get(self.ka))
     self.assertEqual(self.cat[0].get(self.kb), catV1[0].get(self.kb))
     self.comparePsfs(self.cat[0].getPsf(), catV1[0].getPsf())
     bbox = Box2D(Point2D(0, 0), Extent2D(2000, 2000))
     self.assertWcsAlmostEqualOverBBox(self.cat[0].getWcs(), catV1[0].getWcs(), bbox)
     self.assertEqual(self.cat[1].get(self.ka), catV1[1].get(self.ka))
     self.assertEqual(self.cat[1].get(self.kb), catV1[1].get(self.kb))
     self.assertEqual(self.cat[1].getWcs(), catV1[1].getWcs())
     self.assertIsNone(self.cat[1].getPsf())
     self.assertIsNone(self.cat[1].getPhotoCalib())
     self.assertEqual(self.cat[0].getPhotoCalib(), catV1[0].getPhotoCalib())
     self.assertIsNone(catV1[0].getVisitInfo())
     self.assertIsNone(catV1[1].getVisitInfo())
Exemple #15
0
 def testAgainstAstropyWcs(self):
     bbox = Box2D(Point2D(-1000, -1000), Extent2D(2000, 2000))
     for crval, orientation, flipX, projection in itertools.product(
             self.crvalList, self.orientationList, (False, True),
         ("TAN", "STG", "CEA", "AIT")):
         cdMatrix = makeCdMatrix(scale=self.scale,
                                 orientation=orientation,
                                 flipX=flipX)
         metadata = makeSimpleWcsMetadata(crpix=self.crpix,
                                          crval=crval,
                                          cdMatrix=cdMatrix,
                                          projection=projection)
         header = makeLimitedFitsHeader(metadata)
         astropyWcs = astropy.wcs.WCS(header)
         skyWcs = makeSkyWcs(crpix=self.crpix,
                             crval=crval,
                             cdMatrix=cdMatrix,
                             projection=projection)
         # Most projections only seem to agree to within 1e-4 in the round trip test
         self.assertSkyWcsAstropyWcsAlmostEqual(skyWcs=skyWcs,
                                                astropyWcs=astropyWcs,
                                                bbox=bbox)
Exemple #16
0
    def drawOnePoint(self, mask_array, dim, wcs, xy0, skyInfo):

        x = numpy.random.random() * (dim[0] - 1)
        y = numpy.random.random() * (dim[0] - 1)

        value = mask_array[y, x]

        radec = wcs.pixelToSky(x + xy0.getX(), y + xy0.getY())
        xy = wcs.skyToPixel(radec)

        # inner patch
        innerFloatBBox = Box2D(skyInfo.patchInfo.getInnerBBox())
        isPatchInner = innerFloatBBox.contains(xy)

        # inner tract
        sourceInnerTractId = skyInfo.skyMap.findTract(radec).getId()
        isTractInner = sourceInnerTractId == skyInfo.tractInfo.getId()

        ra = radec.getLongitude().asDegrees()
        dec = radec.getLatitude().asDegrees()

        return ra, dec, value, isPatchInner, isTractInner
Exemple #17
0
    def checkTanWcs(self, crval, orientation, flipX):
        """Construct a pure TAN SkyWcs and check that it operates as specified

        Parameters
        ----------
        crval : `lsst.afw.geom.SpherePoint`
            Desired reference sky position.
            Must not be at either pole.
        orientation : `lsst.afw.geom.Angle`
            Position angle of focal plane +Y, measured from N through E.
            At 0 degrees, +Y is along N and +X is along E/W if flipX false/true
            At 90 degrees, +Y is along E and +X is along S/N if flipX false/true
        flipX : `bool`
            Flip x axis? See `orientation` for details.

        Returns
        -------
        wcs : `lsst.afw.geom.SkyWcs`
            The generated pure TAN SkyWcs
        """
        cdMatrix = makeCdMatrix(scale=self.scale,
                                orientation=orientation,
                                flipX=flipX)
        wcs = makeSkyWcs(crpix=self.crpix, crval=crval, cdMatrix=cdMatrix)
        self.checkPersistence(wcs, bbox=self.bbox)
        self.checkMakeFlippedWcs(wcs)

        self.assertTrue(wcs.isFits)
        self.assertEqual(wcs.isFlipped, bool(flipX))

        xoffAng = 0 * degrees if flipX else 180 * degrees

        pixelList = [
            Point2D(self.crpix[0], self.crpix[1]),
            Point2D(self.crpix[0] + 1, self.crpix[1]),
            Point2D(self.crpix[0], self.crpix[1] + 1),
        ]
        skyList = wcs.pixelToSky(pixelList)

        # check pixels to sky
        predSkyList = [
            crval,
            crval.offset(xoffAng - orientation, self.scale),
            crval.offset(90 * degrees - orientation, self.scale),
        ]
        self.assertSpherePointListsAlmostEqual(predSkyList, skyList)
        self.assertSpherePointListsAlmostEqual(predSkyList,
                                               wcs.pixelToSky(pixelList))
        for pixel, predSky in zip(pixelList, predSkyList):
            self.assertSpherePointsAlmostEqual(predSky, wcs.pixelToSky(pixel))
            self.assertSpherePointsAlmostEqual(
                predSky, wcs.pixelToSky(pixel[0], pixel[1]))

        # check sky to pixels
        self.assertPairListsAlmostEqual(pixelList, wcs.skyToPixel(skyList))
        self.assertPairListsAlmostEqual(pixelList, wcs.skyToPixel(skyList))
        for pixel, sky in zip(pixelList, skyList):
            self.assertPairsAlmostEqual(pixel, wcs.skyToPixel(sky))
            # self.assertPairsAlmostEqual(pixel, wcs.skyToPixel(sky[0], sky[1]))

        # check CRVAL round trip
        self.assertSpherePointsAlmostEqual(wcs.getSkyOrigin(),
                                           crval,
                                           maxSep=self.tinyAngle)

        crpix = wcs.getPixelOrigin()
        self.assertPairsAlmostEqual(crpix, self.crpix, maxDiff=self.tinyPixels)

        self.assertFloatsAlmostEqual(wcs.getCdMatrix(), cdMatrix)

        pixelScale = wcs.getPixelScale()
        self.assertAnglesAlmostEqual(self.scale,
                                     pixelScale,
                                     maxDiff=self.tinyAngle)

        pixelScale = wcs.getPixelScale(self.crpix)
        self.assertAnglesAlmostEqual(self.scale,
                                     pixelScale,
                                     maxDiff=self.tinyAngle)

        # check that getFitsMetadata can operate at high precision
        # and has axis order RA, Dec
        fitsMetadata = wcs.getFitsMetadata(True)
        self.assertEqual(fitsMetadata.get("CTYPE1")[0:4], "RA--")
        self.assertEqual(fitsMetadata.get("CTYPE2")[0:4], "DEC-")

        # Compute a WCS with the pixel origin shifted by an arbitrary amount
        # The resulting sky origin should not change
        offset = Extent2D(500, -322)  # arbitrary
        shiftedWcs = wcs.copyAtShiftedPixelOrigin(offset)
        self.assertTrue(shiftedWcs.isFits)
        predShiftedPixelOrigin = self.crpix + offset
        self.assertPairsAlmostEqual(shiftedWcs.getPixelOrigin(),
                                    predShiftedPixelOrigin,
                                    maxDiff=self.tinyPixels)
        self.assertSpherePointsAlmostEqual(shiftedWcs.getSkyOrigin(),
                                           crval,
                                           maxSep=self.tinyAngle)

        shiftedPixelList = [p + offset for p in pixelList]
        shiftedSkyList = shiftedWcs.pixelToSky(shiftedPixelList)
        self.assertSpherePointListsAlmostEqual(skyList,
                                               shiftedSkyList,
                                               maxSep=self.tinyAngle)

        # Check that the shifted WCS can be round tripped as FITS metadata
        shiftedMetadata = shiftedWcs.getFitsMetadata(precise=True)
        shiftedWcsCopy = makeSkyWcs(shiftedMetadata)
        shiftedBBox = Box2D(predShiftedPixelOrigin,
                            predShiftedPixelOrigin + Extent2I(2000, 2000))
        self.assertWcsAlmostEqualOverBBox(shiftedWcs, shiftedWcsCopy,
                                          shiftedBBox)

        wcsCopy = SkyWcs.readString(wcs.writeString())
        self.assertTrue(wcsCopy.isFits)

        return wcs
Exemple #18
0
    def testSampleAt(self):
        """Test the behavior of TransmissionCurve.sampleAt on the subclass
        returned by makeCoaddTransmissionCurve.
        """
        wavelengths = np.linspace(4000, 7000, 200)

        # Points in coadd coordinates in each of the distinct regions
        point0 = self.makeRandomPoint(Point2I(-100, -100), Point2I(-1, -1))
        pointA = self.makeRandomPoint(Point2I(-100, 0), Point2I(-1, 99))
        pointB = self.makeRandomPoint(Point2I(0, -100), Point2I(99, -1))
        pointC = self.makeRandomPoint(Point2I(0, 0), Point2I(49, 99))
        pointD = self.makeRandomPoint(Point2I(50, 0), Point2I(99, 99))
        points = [point0, pointA, pointB, pointC, pointD]

        # The same points, in sky coordinates
        coords = [self.wcsCoadd.pixelToSky(point) for point in points]

        # The same points, in Epoch A's coordinates
        point0A, pointAA, pointBA, pointCA, pointDA = [
            self.wcsA.skyToPixel(coord) for coord in coords
        ]
        self.assertFalse(Box2D(self.bboxA).contains(point0A))
        self.assertTrue(Box2D(self.bboxA).contains(pointAA))
        self.assertFalse(Box2D(self.bboxA).contains(pointBA))
        self.assertTrue(Box2D(self.bboxA).contains(pointCA))
        self.assertTrue(Box2D(self.bboxA).contains(pointDA))

        # The same points, in Epoch B's coordinates
        point0B, pointAB, pointBB, pointCB, pointDB = [
            self.wcsB.skyToPixel(coord) for coord in coords
        ]
        self.assertFalse(Box2D(self.bboxB).contains(point0B))
        self.assertFalse(Box2D(self.bboxB).contains(pointAB))
        self.assertTrue(Box2D(self.bboxB).contains(pointBB))
        self.assertTrue(Box2D(self.bboxB).contains(pointCB))
        self.assertTrue(Box2D(self.bboxB).contains(pointDB))
        self.assertTrue(self.polygonB.contains(pointBB))
        self.assertTrue(self.polygonB.contains(pointCB))
        self.assertFalse(self.polygonB.contains(pointDB))

        # Test that we can't compute throughputs in region 0 (where there are no inputs)
        self.assertRaises(InvalidParameterError, self.curveCoadd.sampleAt,
                          point0, wavelengths)

        # Test throughputs in region A (only Epoch A contributes)
        throughputA1 = self.curveCoadd.sampleAt(pointA, wavelengths)
        throughputA2 = self.curveA.sampleAt(pointAA, wavelengths)
        self.assertFloatsAlmostEqual(throughputA1, throughputA2)

        # Test throughputs in region B (only Epoch B contributes)
        throughputB1 = self.curveCoadd.sampleAt(pointB, wavelengths)
        throughputB2 = self.curveB.sampleAt(pointBB, wavelengths)
        self.assertFloatsAlmostEqual(throughputB1, throughputB2)

        # Test throughputs in region C (both epochs contribute)
        throughputC1 = self.curveCoadd.sampleAt(pointC, wavelengths)
        throughputC2 = self.curveA.sampleAt(pointCA, wavelengths)
        throughputC3 = self.curveB.sampleAt(pointCB, wavelengths)
        self.assertFloatsAlmostEqual(throughputC1,
                                     throughputC2 * 0.75 + throughputC3 * 0.25)

        # Test throughputs in region D (only Epoch A contributes)
        throughputD1 = self.curveCoadd.sampleAt(pointD, wavelengths)
        throughputD2 = self.curveA.sampleAt(pointDA, wavelengths)
        self.assertFloatsAlmostEqual(throughputD1, throughputD2)
Exemple #19
0
 def setUp(self):
     metadata = PropertyList()
     # the following was fit using CreateWcsWithSip from meas_astrom
     # and is valid over this bbox: (minimum=(0, 0), maximum=(3030, 3030))
     # This same metadata was used to create testdata/oldTanSipwWs.fits
     for name, value in (
         ("RADESYS", "ICRS"),
         ("CTYPE1", "RA---TAN-SIP"),
         ("CTYPE2", "DEC--TAN-SIP"),
         ("CRPIX1", 1531.1824767147),
         ("CRPIX2", 1531.1824767147),
         ("CRVAL1", 43.035511801383),
         ("CRVAL2", 44.305697682784),
         ("CUNIT1", "deg"),
         ("CUNIT2", "deg"),
         ("CD1_1", 0.00027493991598151),
         ("CD1_2", -3.2758487104158e-06),
         ("CD2_1", 3.2301310675830e-06),
         ("CD2_2", 0.00027493937506632),
         ("A_ORDER", 5),
         ("A_0_2", -1.7769487466972e-09),
         ("A_0_3", 5.3745894718340e-13),
         ("A_0_4", -7.2921116596880e-17),
         ("A_0_5", 8.6947236956136e-21),
         ("A_1_1", 5.4246387438098e-08),
         ("A_1_2", -1.5689083084641e-12),
         ("A_1_3", 1.2424130500997e-16),
         ("A_1_4", 3.9982572658006e-20),
         ("A_2_0", 4.9268299826160e-08),
         ("A_2_1", 1.6365657558495e-12),
         ("A_2_2", 1.1976983061953e-16),
         ("A_2_3", -1.7262037266467e-19),
         ("A_3_0", -5.9235031179999e-13),
         ("A_3_1", -3.4444326387310e-16),
         ("A_3_2", 1.4377441160800e-19),
         ("A_4_0", 1.8736407845095e-16),
         ("A_4_1", 2.9213314172884e-20),
         ("A_5_0", -5.3601346091084e-20),
         ("B_ORDER", 5),
         ("B_0_2", 4.9268299822979e-08),
         ("B_0_3", -5.9235032026906e-13),
         ("B_0_4", 1.8736407776035e-16),
         ("B_0_5", -5.3601341373220e-20),
         ("B_1_1", 5.4246387435453e-08),
         ("B_1_2", 1.6365657531115e-12),
         ("B_1_3", -3.4444326228808e-16),
         ("B_1_4", 2.9213312399941e-20),
         ("B_2_0", -1.7769487494962e-09),
         ("B_2_1", -1.5689082999319e-12),
         ("B_2_2", 1.1976983393279e-16),
         ("B_2_3", 1.4377441169892e-19),
         ("B_3_0", 5.3745894237186e-13),
         ("B_3_1", 1.2424130479929e-16),
         ("B_3_2", -1.7262036838229e-19),
         ("B_4_0", -7.2921117326608e-17),
         ("B_4_1", 3.9982566975450e-20),
         ("B_5_0", 8.6947240592408e-21),
         ("AP_ORDER", 6),
         ("AP_0_0", -5.4343024221207e-11),
         ("AP_0_1", 5.5722265946666e-12),
         ("AP_0_2", 1.7769484042400e-09),
         ("AP_0_3", -5.3773609554820e-13),
         ("AP_0_4", 7.3035278852156e-17),
         ("AP_0_5", -8.7151153799062e-21),
         ("AP_0_6", 3.2535945427624e-27),
         ("AP_1_0", -3.8944805432871e-12),
         ("AP_1_1", -5.4246388067582e-08),
         ("AP_1_2", 1.5741716194971e-12),
         ("AP_1_3", -1.2447067748187e-16),
         ("AP_1_4", -3.9960260822306e-20),
         ("AP_1_5", 1.1297941471380e-26),
         ("AP_2_0", -4.9268299293185e-08),
         ("AP_2_1", -1.6256111849359e-12),
         ("AP_2_2", -1.1973373130440e-16),
         ("AP_2_3", 1.7266948205700e-19),
         ("AP_2_4", -3.7059606160753e-26),
         ("AP_3_0", 5.9710911995811e-13),
         ("AP_3_1", 3.4464427650041e-16),
         ("AP_3_2", -1.4381853884204e-19),
         ("AP_3_3", -7.6527426974322e-27),
         ("AP_4_0", -1.8748435698960e-16),
         ("AP_4_1", -2.9267280226373e-20),
         ("AP_4_2", 4.8004317051259e-26),
         ("AP_5_0", 5.3657330221120e-20),
         ("AP_5_1", -1.6904065766661e-27),
         ("AP_6_0", -1.9484495120493e-26),
         ("BP_ORDER", 6),
         ("BP_0_0", -5.4291220607725e-11),
         ("BP_0_1", -3.8944871307931e-12),
         ("BP_0_2", -4.9268299290361e-08),
         ("BP_0_3", 5.9710912831833e-13),
         ("BP_0_4", -1.8748435594265e-16),
         ("BP_0_5", 5.3657325543368e-20),
         ("BP_0_6", -1.9484577299247e-26),
         ("BP_1_0", 5.5722051513577e-12),
         ("BP_1_1", -5.4246388065000e-08),
         ("BP_1_2", -1.6256111821465e-12),
         ("BP_1_3", 3.4464427499767e-16),
         ("BP_1_4", -2.9267278448109e-20),
         ("BP_1_5", -1.6904244067295e-27),
         ("BP_2_0", 1.7769484069376e-09),
         ("BP_2_1", 1.5741716110182e-12),
         ("BP_2_2", -1.1973373446176e-16),
         ("BP_2_3", -1.4381853893526e-19),
         ("BP_2_4", 4.8004294492911e-26),
         ("BP_3_0", -5.3773609074713e-13),
         ("BP_3_1", -1.2447067726801e-16),
         ("BP_3_2", 1.7266947774875e-19),
         ("BP_3_3", -7.6527556667042e-27),
         ("BP_4_0", 7.3035279660505e-17),
         ("BP_4_1", -3.9960255158200e-20),
         ("BP_4_2", -3.7059659675039e-26),
         ("BP_5_0", -8.7151157361284e-21),
         ("BP_5_1", 1.1297944388060e-26),
         ("BP_6_0", 3.2535788867488e-27),
     ):
         metadata.set(name, value)
     self.metadata = metadata
     self.bbox = Box2D(Point2D(-1000, -1000), Extent2D(3000, 3000))