예제 #1
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)
예제 #2
0
    def setUp(self):
        SkyWcsBaseTestCase.setUp(self)
        crpix = Point2D(100, 100)
        crvalList = [
            SpherePoint(0 * degrees, 45 * degrees),
            SpherePoint(0.00001 * degrees, 45 * degrees),
            SpherePoint(359.99999 * degrees, 45 * degrees),
            SpherePoint(30 * degrees, 89.99999 * degrees),
        ]
        orientationList = [
            0 * degrees,
            0.00001 * degrees,
            -0.00001 * degrees,
            -45 * degrees,
            90 * degrees,
        ]
        scale = 1.0 * arcseconds

        self.wcsList = []
        for crval in crvalList:
            for orientation in orientationList:
                cd = makeCdMatrix(scale=scale, orientation=orientation)
                self.wcsList.append(
                    makeSkyWcs(crpix=crpix, crval=crval, cdMatrix=cd))
        self.pixelPoints = [
            Point2D(x, y)
            for x, y in itertools.product((0.0, -2.0, 42.5,
                                           1042.3), (27.6, -0.1, 0.0, 196.0))
        ]
예제 #3
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)
예제 #4
0
    def setUp(self):
        # Set up a Coadd with CoaddInputs tables that have blank filter columns to be filled
        # in by later test code.
        self.coadd = ExposureF(30, 90)
        # WCS is arbitrary, since it'll be the same for all images
        wcs = makeSkyWcs(crpix=Point2D(0, 0),
                         crval=SpherePoint(45.0, 45.0, degrees),
                         cdMatrix=makeCdMatrix(scale=0.17 * degrees))
        self.coadd.setWcs(wcs)
        schema = ExposureCatalog.Table.makeMinimalSchema()
        self.filterKey = schema.addField("filter", type=str, doc="", size=16)
        weightKey = schema.addField("weight", type=float, doc="")
        # First input image covers the first 2/3, second covers the last 2/3, so they
        # overlap in the middle 1/3.
        inputs = ExposureCatalog(schema)
        self.input1 = inputs.addNew()
        self.input1.setId(1)
        self.input1.setBBox(Box2I(Point2I(0, 0), Point2I(29, 59)))
        self.input1.setWcs(wcs)
        self.input1.set(weightKey, 2.0)
        self.input2 = inputs.addNew()
        self.input2.setId(2)
        self.input2.setBBox(Box2I(Point2I(0, 30), Point2I(29, 89)))
        self.input2.setWcs(wcs)
        self.input2.set(weightKey, 3.0)
        # Use the same catalog for visits and CCDs since the algorithm we're testing only cares
        # about CCDs.
        self.coadd.getInfo().setCoaddInputs(CoaddInputs(inputs, inputs))

        # Set up a catalog with centroids and a FilterFraction plugin.
        # We have one record in each region (first input only, both inputs, second input only)
        schema = SourceCatalog.Table.makeMinimalSchema()
        centroidKey = Point2DKey.addFields(schema,
                                           "centroid",
                                           doc="position",
                                           unit="pixel")
        schema.getAliasMap().set("slot_Centroid", "centroid")
        self.plugin = FilterFractionPlugin(
            config=FilterFractionPlugin.ConfigClass(),
            schema=schema,
            name="subaru_FilterFraction",
            metadata=PropertyList())
        catalog = SourceCatalog(schema)
        self.record1 = catalog.addNew()
        self.record1.set(centroidKey, Point2D(14.0, 14.0))
        self.record12 = catalog.addNew()
        self.record12.set(centroidKey, Point2D(14.0, 44.0))
        self.record2 = catalog.addNew()
        self.record2.set(centroidKey, Point2D(14.0, 74.0))
예제 #5
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)
예제 #6
0
    def testMakeTanSipWcs(self):
        referenceWcs = makeSkyWcs(self.metadata, strip=False)

        crpix = Point2D(
            self.metadata.get("CRPIX1") - 1,
            self.metadata.get("CRPIX2") - 1)
        crval = SpherePoint(
            self.metadata.get("CRVAL1") * degrees,
            self.metadata.get("CRVAL2") * degrees)
        cdMatrix = getCdMatrixFromMetadata(self.metadata)
        sipA = getSipMatrixFromMetadata(self.metadata, "A")
        sipB = getSipMatrixFromMetadata(self.metadata, "B")
        sipAp = getSipMatrixFromMetadata(self.metadata, "AP")
        sipBp = getSipMatrixFromMetadata(self.metadata, "BP")
        skyWcs1 = makeTanSipWcs(crpix=crpix,
                                crval=crval,
                                cdMatrix=cdMatrix,
                                sipA=sipA,
                                sipB=sipB)
        skyWcs2 = makeTanSipWcs(crpix=crpix,
                                crval=crval,
                                cdMatrix=cdMatrix,
                                sipA=sipA,
                                sipB=sipB,
                                sipAp=sipAp,
                                sipBp=sipBp)

        self.assertWcsAlmostEqualOverBBox(referenceWcs, skyWcs1, self.bbox)
        self.assertWcsAlmostEqualOverBBox(referenceWcs, skyWcs2, self.bbox)
        self.checkMakeFlippedWcs(skyWcs1)
        self.checkMakeFlippedWcs(skyWcs2)
예제 #7
0
 def getCrpix(self, metadata):
     """Get CRPIX from metadata using the LSST convention: 0-based in parent coordinates
     """
     return Point2D(   # zero-based, hence the - 1
         metadata.get("CRPIX1") + metadata.get("CRVAL1A") - 1,
         metadata.get("CRPIX2") + metadata.get("CRVAL2A") - 1,
     )
예제 #8
0
    def __init__(self,
                 n=5,
                 chips=['R00_S22', 'R04_S20', 'R40_S02', 'R44_S00'],
                 mag=17,
                 sed='../sky/sed_500.txt'):
        super().__init__()

        # lazy imports
        from lsst.obs.lsst.phosim import PhosimMapper
        from lsst.afw.cameraGeom import PIXELS, FIELD_ANGLE
        from lsst.afw.geom import Point2D

        camera = PhosimMapper().camera

        for chip in chips:
            det = camera[chip]
            cornersPix = [Point2D(x) for x in det.getBBox().getCorners()]
            pixels2Field = camera.getTransform(det.makeCameraSys(PIXELS),
                                               FIELD_ANGLE)
            corners = pixels2Field.applyForward(cornersPix)
            ras = np.rad2deg([c.getX() for c in corners])
            decs = np.rad2deg([c.getY() for c in corners])

            for ra in np.linspace(min(ras), max(ras), n + 2)[1:-1]:
                for dec in np.linspace(min(decs), max(decs), n + 2)[1:-1]:
                    self.addSource(ra, dec, mag, sed)
예제 #9
0
 def testFullAffine(self):
     """Test affine = AffineXYTransform with just linear coefficients
     """
     affineClass = xyTransformRegistry["affine"]
     affineConfig = affineClass.ConfigClass()
     affineConfig.translation = (-2.1, 3.4)
     rotAng = 0.832  # radians
     xScale = 3.7
     yScale = 45.3
     affineConfig.linear = (
         math.cos(rotAng) * xScale, math.sin(rotAng) * yScale,
         -math.sin(rotAng) * xScale, math.cos(rotAng) * yScale,
     )
     with lsst.utils.tests.getTempFilePath(".py") as filePath:
         self.checkConfig(affineClass, affineConfig, filePath)
         affine = affineClass(affineConfig)
         for fromPoint in self.fromIter():
             toPoint = affine.forwardTransform(fromPoint)
             predToPoint = Point2D(
                 affineConfig.linear[0] * fromPoint[0] + affineConfig.linear[1] * fromPoint[1],
                 affineConfig.linear[2] * fromPoint[0] + affineConfig.linear[3] * fromPoint[1],
             )
             predToPoint = predToPoint + Extent2D(*affineConfig.translation)
             for i in range(2):
                 self.assertAlmostEqual(toPoint[i], predToPoint[i])
예제 #10
0
 def testRadial(self):
     """Test radial = RadialXYTransform
     """
     radialClass = xyTransformRegistry["radial"]
     radialConfig = radialClass.ConfigClass()
     radialConfig.coeffs = (0, 1.05, 0.1)
     with lsst.utils.tests.getTempFilePath(".py") as filePath:
         self.checkConfig(radialClass, radialConfig, filePath)
         radial = radialClass(radialConfig)
         self.assertEquals(type(radial), RadialXYTransform)
         self.assertEquals(len(radial.getCoeffs()),
                           len(radialConfig.coeffs))
         for coeff, predCoeff in itertools.izip(radial.getCoeffs(),
                                                radialConfig.coeffs):
             self.assertAlmostEqual(coeff, predCoeff)
         self.checkBasics(radial)
         for fromPoint in self.fromIter():
             fromRadius = math.hypot(fromPoint[0], fromPoint[1])
             fromAngle = math.atan2(fromPoint[1], fromPoint[0])
             predToRadius = fromRadius * (
                 radialConfig.coeffs[2] * fromRadius +
                 radialConfig.coeffs[1])
             predToPoint = Point2D(predToRadius * math.cos(fromAngle),
                                   predToRadius * math.sin(fromAngle))
             toPoint = radial.forwardTransform(fromPoint)
             for i in range(2):
                 self.assertAlmostEqual(toPoint[i], predToPoint[i])
    def testFilters(self):
        wavelengths = np.linspace(3000, 12000, 1000)
        point = Point2D(1000, -500)

        def check(curve, central, w1, w2):
            # check that throughput within w1 of central is strictly greater
            # than throughput outside w2 of central
            throughput = curve.sampleAt(point, wavelengths)
            mid = np.logical_and(wavelengths > central - w1,
                                 wavelengths < central + w1)
            outer = np.logical_or(wavelengths < central - w2,
                                  wavelengths > central + w2)
            self.assertGreater(throughput[mid].min(), throughput[outer].max())

        for curves in makeTransmissionCurves.getFilterTransmission().values():
            check(curves["NB0387"], 3870, 50, 100)
            check(curves["NB0816"], 8160, 50, 100)
            check(curves["NB0921"], 9210, 50, 100)
            check(curves["HSC-G"], 4730, 500, 1500)
            check(curves["HSC-R"], 6230, 500, 1500)
            check(curves["HSC-R2"], 6230, 500, 1500)
            check(curves["HSC-I"], 7750, 500, 1500)
            check(curves["HSC-I2"], 7750, 500, 1500)
            check(curves["HSC-Z"], 8923, 500, 1500)
            check(curves["HSC-Y"], 10030, 500, 1500)
예제 #12
0
    def testNormalizationFk5(self):
        """Test that readLsstSkyWcs correctly normalizes FK5 1975 to ICRS
        """
        equinox = 1975.0
        metadata = self.metadata

        metadata.set("RADESYS", "FK5")
        metadata.set("EQUINOX", equinox)
        crpix = Point2D(metadata.get("CRPIX1") - 1, metadata.get("CRPIX2") - 1)
        # record the original CRVAL before reading and stripping metadata
        crvalFk5Deg = (metadata.get("CRVAL1"), metadata.get("CRVAL2"))

        # create the wcs and retrieve crval
        skyWcs = makeSkyWcs(metadata)
        crval = skyWcs.getSkyOrigin()

        # compare to computed crval
        computedCrval = skyWcs.pixelToSky(crpix)
        self.assertSpherePointsAlmostEqual(crval, computedCrval)

        # get predicted crval by converting with astropy
        crvalFk5 = astropy.coordinates.SkyCoord(crvalFk5Deg[0],
                                                crvalFk5Deg[1],
                                                frame="fk5",
                                                equinox="J%f" % (equinox, ),
                                                unit="deg")
        predictedCrvalIcrs = crvalFk5.icrs
        predictedCrval = SpherePoint(predictedCrvalIcrs.ra.radian * radians,
                                     predictedCrvalIcrs.dec.radian * radians)
        self.assertSpherePointsAlmostEqual(crval,
                                           predictedCrval,
                                           maxSep=0.002 * arcseconds)
예제 #13
0
    def testNormalizationDecRa(self):
        """Test that a Dec, RA WCS is normalized to RA, Dec
        """
        crpix = Point2D(
            self.metadata.get("CRPIX1") - 1,
            self.metadata.get("CRPIX2") - 1)

        # swap RA, Decaxes in metadata
        crvalIn = SpherePoint(
            self.metadata.get("CRVAL1") * degrees,
            self.metadata.get("CRVAL2") * degrees)
        self.metadata.set("CRVAL1", crvalIn[1].asDegrees())
        self.metadata.set("CRVAL2", crvalIn[0].asDegrees())
        self.metadata.set("CTYPE1", "DEC--TAN")
        self.metadata.set("CTYPE2", "RA---TAN")

        # create the wcs
        skyWcs = makeSkyWcs(self.metadata)

        # compare pixel origin to input crval
        crval = skyWcs.getSkyOrigin()
        self.assertSpherePointsAlmostEqual(crval, crvalIn)

        # compare to computed crval
        computedCrval = skyWcs.pixelToSky(crpix)
        self.assertSpherePointsAlmostEqual(crval, computedCrval)
예제 #14
0
 def testMakeSimpleWcsMetadata(self):
     crpix = Point2D(111.1, 222.2)
     crval = SpherePoint(45.6 * degrees, 12.3 * degrees)
     scale = 1 * arcseconds
     for orientation in (0 * degrees, 21 * degrees):
         cdMatrix = makeCdMatrix(scale=scale, orientation=orientation)
         for projection in ("TAN", "STG"):
             metadata = makeSimpleWcsMetadata(crpix=crpix, crval=crval,
                                              cdMatrix=cdMatrix, projection=projection)
             desiredLength = 12 if orientation == 0 * degrees else 14
             self.assertEqual(len(metadata.names()), desiredLength)
             self.assertEqual(metadata.get("RADESYS"), "ICRS")
             self.assertAlmostEqual(metadata.get("EQUINOX"), 2000.0)
             self.assertEqual(metadata.get("CTYPE1"), "RA---" + projection)
             self.assertEqual(metadata.get("CTYPE2"), "DEC--" + projection)
             for i in range(2):
                 self.assertAlmostEqual(metadata.get("CRPIX%d" % (i + 1,)), crpix[i] + 1)
                 self.assertAlmostEqual(metadata.get("CRVAL%d" % (i + 1,)), crval[i].asDegrees())
                 self.assertEqual(metadata.get("CUNIT%d" % (i + 1,)), "deg")
             for i in range(2):
                 for j in range(2):
                     name = "CD%d_%d" % (i + 1, j + 1)
                     if cdMatrix[i, j] != 0:
                         self.assertAlmostEqual(metadata.get(name), cdMatrix[i, j])
                     else:
                         self.assertFalse(metadata.exists(name))
예제 #15
0
    def testCD_PC(self):
        """Test that we can read a FITS file with both CD and PC keys (like early Suprimecam files)"""
        md = PropertyList()
        for k, v in (
            ("EQUINOX", 2000.0),
            ("RADESYS", "ICRS"),
            ("CRPIX1", 5353.0),
            ("CRPIX2", -35.0),
            ("CD1_1", 0.0),
            ("CD1_2", -5.611E-05),
            ("CD2_1", -5.611E-05),
            ("CD2_2", -0.0),
            ("CRVAL1", 4.5789875),
            ("CRVAL2", 16.30004444),
            ("CUNIT1", "deg"),
            ("CUNIT2", "deg"),
            ("CTYPE1", "RA---TAN"),
            ("CTYPE2", "DEC--TAN"),
            ("CDELT1", -5.611E-05),
            ("CDELT2", 5.611E-05),
        ):
            md.set(k, v)

        wcs = makeSkyWcs(md, strip=False)

        pixPos = Point2D(1000, 2000)
        pred_skyPos = SpherePoint(4.459815023498577 * degrees,
                                  16.544199850984768 * degrees)

        skyPos = wcs.pixelToSky(pixPos)
        self.assertSpherePointsAlmostEqual(skyPos, pred_skyPos)

        for badPC in (False, True):
            for k, v in (
                ("PC001001", 0.0),
                ("PC001002", -1.0 if badPC else 1.0),
                ("PC002001", 1.0 if badPC else -1.0),
                ("PC002002", 0.0),
            ):
                md.set(k, v)

            # Check Greisen and Calabretta A&A 395 1061 (2002), Eq. 3
            if not badPC:
                for i in (
                        1,
                        2,
                ):
                    for j in (
                            1,
                            2,
                    ):
                        self.assertEqual(
                            md.get("CD%d_%d" % (i, j)),
                            md.get("CDELT%d" % i) * md.get("PC00%d00%d" %
                                                           (i, j)))

            wcs2 = makeSkyWcs(md, strip=False)
            skyPos2 = wcs2.pixelToSky(pixPos)
            self.assertSpherePointsAlmostEqual(skyPos2, pred_skyPos)
예제 #16
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 testOptics(self):
     wavelengths = np.linspace(4000, 10000, 100)
     point = Point2D(1000, -500)
     for curve in makeTransmissionCurves.getOpticsTransmission().values():
         if curve is None:
             continue
         throughputs = curve.sampleAt(point, wavelengths)
         self.assertTrue((throughputs > 0.70).all())
예제 #18
0
    def testMakeModifiedWcsNoActualPixels(self):
        """Test makeModifiedWcs on a SkyWcs that has no ACTUAL_PIXELS frame
        """
        cdMatrix = makeCdMatrix(scale=self.scale)
        originalWcs = makeSkyWcs(crpix=self.crpix,
                                 crval=self.crvalList[0],
                                 cdMatrix=cdMatrix)
        originalFrameDict = originalWcs.getFrameDict()

        # make an arbitrary but reasonable transform to insert using makeModifiedWcs
        pixelTransform = makeRadialTransform([0.0, 1.0, 0.0, 0.0011])
        # the result of the insertion should be as follows
        desiredPixelsToSky = pixelTransform.then(originalWcs.getTransform())

        pixPointList = (  # arbitrary but reasonable
            Point2D(0.0, 0.0),
            Point2D(1000.0, 0.0),
            Point2D(0.0, 2000.0),
            Point2D(-1111.0, -2222.0),
        )
        for modifyActualPixels in (False, True):
            modifiedWcs = makeModifiedWcs(
                pixelTransform=pixelTransform,
                wcs=originalWcs,
                modifyActualPixels=modifyActualPixels)
            modifiedFrameDict = modifiedWcs.getFrameDict()
            skyList = modifiedWcs.pixelToSky(pixPointList)

            # compare pixels to sky
            desiredSkyList = desiredPixelsToSky.applyForward(pixPointList)
            self.assertSpherePointListsAlmostEqual(skyList, desiredSkyList)

            # compare pixels to IWC
            pixelsToIwc = TransformPoint2ToPoint2(
                modifiedFrameDict.getMapping("PIXELS", "IWC"))
            desiredPixelsToIwc = TransformPoint2ToPoint2(
                pixelTransform.getMapping().then(
                    originalFrameDict.getMapping("PIXELS", "IWC")))
            self.assertPairListsAlmostEqual(
                pixelsToIwc.applyForward(pixPointList),
                desiredPixelsToIwc.applyForward(pixPointList))

            self.checkNonFitsWcs(modifiedWcs)
 def testSensors(self):
     wavelengths = np.linspace(4000, 12000, 100)
     point = Point2D(200, 10)
     for sensors in makeTransmissionCurves.getSensorTransmission().values():
         for i in range(112):
             curve = sensors[i]
             throughputs = curve.sampleAt(point, wavelengths)
             siliconTransparent = wavelengths > 11000
             self.assertTrue((throughputs[siliconTransparent] < 0.01).all())
             midR = np.logical_and(wavelengths > 6000, wavelengths < 6300)
             self.assertTrue((throughputs[midR] > 0.9).all())
예제 #20
0
    def checkPersistence(self, skyWcs, bbox):
        """Check persistence of a SkyWcs
        """
        className = "SkyWcs"

        # check writeString and readString
        skyWcsStr = skyWcs.writeString()
        serialVersion, serialClassName, serialRest = skyWcsStr.split(" ", 2)
        self.assertEqual(int(serialVersion), 1)
        self.assertEqual(serialClassName, className)
        badStr1 = " ".join(["2", serialClassName, serialRest])
        with self.assertRaises(lsst.pex.exceptions.TypeError):
            skyWcs.readString(badStr1)
        badClassName = "x" + serialClassName
        badStr2 = " ".join(["1", badClassName, serialRest])
        with self.assertRaises(lsst.pex.exceptions.TypeError):
            skyWcs.readString(badStr2)
        skyWcsFromStr1 = skyWcs.readString(skyWcsStr)
        self.assertEqual(skyWcs, skyWcsFromStr1)
        self.assertEqual(type(skyWcs), type(skyWcsFromStr1))
        self.assertEqual(skyWcs.getFrameDict(), skyWcsFromStr1.getFrameDict())

        pixelPoints = [
            Point2D(0, 0),
            Point2D(1000, 0),
            Point2D(0, 1000),
            Point2D(-50, -50),
        ]
        skyPoints = skyWcs.pixelToSky(pixelPoints)
        pixelPoints2 = skyWcs.skyToPixel(skyPoints)
        assert_allclose(pixelPoints, pixelPoints2, atol=1e-7)

        # check that WCS is properly saved as part of an exposure FITS file
        exposure = ExposureF(100, 100, skyWcs)
        with lsst.utils.tests.getTempFilePath(".fits") as outFile:
            exposure.writeFits(outFile)
            exposureRoundTrip = ExposureF(outFile)
        wcsFromExposure = exposureRoundTrip.getWcs()
        self.assertWcsAlmostEqualOverBBox(skyWcs, wcsFromExposure, bbox)
예제 #21
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
예제 #22
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)
 def testAtmosphere(self):
     wavelengths = np.linspace(4000, 12000, 100)
     point = Point2D(1000, -500)
     for curve in makeTransmissionCurves.getAtmosphereTransmission().values(
     ):
         if curve is None:
             continue
         throughputs = curve.sampleAt(point, wavelengths)
         ohAbsorption = np.logical_and(wavelengths > 11315,
                                       wavelengths < 11397)
         midR = np.logical_and(wavelengths > 6000, wavelengths < 6300)
         self.assertTrue(
             (throughputs[ohAbsorption] < throughputs[midR]).all())
예제 #24
0
    def setUp(self):
        xy0 = Point2I(12345, 67890)  # xy0 for image
        dims = Extent2I(2345, 2345)  # Dimensions of image
        box = Box2I(xy0, dims)  # Bounding box of image
        sigma = 3.21  # PSF sigma
        buffer = 4.0  # Buffer for star centers around edge
        nSigmaForKernel = 5.0  # Number of PSF sigmas for kernel
        sky = 12345.6  # Sky level
        numStars = 100  # Number of stars
        noise = np.sqrt(sky) * np.pi * sigma**2  # Poisson noise per PSF
        faint = 1.0 * noise  # Faintest level for star fluxes
        bright = 100.0 * noise  # Brightest level for star fluxes
        starBox = Box2I(box)  # Area on image in which we can put star centers
        starBox.grow(-int(buffer * sigma))
        scale = 1.0e-5 * degrees  # Pixel scale

        np.random.seed(12345)
        stars = [(xx, yy, ff, sigma) for xx, yy, ff in zip(
            np.random.uniform(starBox.getMinX(), starBox.getMaxX(), numStars),
            np.random.uniform(starBox.getMinY(), starBox.getMaxY(), numStars),
            np.linspace(faint, bright, numStars))]
        self.exposure = plantSources(box, 2 * int(nSigmaForKernel * sigma) + 1,
                                     sky, stars, True)
        self.exposure.setWcs(
            makeSkyWcs(crpix=Point2D(0, 0),
                       crval=SpherePoint(0, 0, degrees),
                       cdMatrix=makeCdMatrix(scale=scale)))

        # Make a large area of extra background; we should be robust against it
        # Unfortunately, some tuning is required here to get something challenging but not impossible:
        # * A very large box will cause failures because the "extra" and the "normal" are reversed.
        # * A small box will not be challenging because it's simple to clip out.
        # * A large value will cause failures because it produces large edges in background-subtrction that
        #     broaden flux distributions.
        # * A small value will not be challenging because it has little effect.
        extraBox = Box2I(xy0 + Extent2I(345, 456),
                         Extent2I(1234, 1234))  # Box for extra background
        extraValue = 0.5 * noise  # Extra background value to add in
        self.exposure.image[extraBox, PARENT] += extraValue

        self.config = DynamicDetectionTask.ConfigClass()
        self.config.skyObjects.nSources = 300
        self.config.reEstimateBackground = False
        self.config.doTempWideBackground = True
        self.config.thresholdType = "pixel_stdev"

        # Relative tolerance for tweak factor
        # Not sure why this isn't smaller; maybe due to use of Poisson instead of Gaussian noise?
        self.rtol = 0.1
예제 #25
0
    def testGetIntermediateWorldCoordsToSky(self):
        """Test getIntermediateWorldCoordsToSky and getPixelToIntermediateWorldCoords
        """
        crpix = Extent2D(
            self.metadata.get("CRPIX1") - 1,
            self.metadata.get("CRPIX2") - 1)
        skyWcs = makeSkyWcs(self.metadata, strip=False)
        for simplify in (False, True):
            pixelToIwc = getPixelToIntermediateWorldCoords(skyWcs, simplify)
            iwcToSky = getIntermediateWorldCoordsToSky(skyWcs, simplify)
            self.assertTrue(isinstance(pixelToIwc, TransformPoint2ToPoint2))
            self.assertTrue(isinstance(iwcToSky, TransformPoint2ToSpherePoint))
            if simplify:
                self.assertTrue(pixelToIwc.getMapping().isSimple)
                self.assertTrue(iwcToSky.getMapping().isSimple)
            # else the mapping may have already been simplified inside the WCS,
            # so don't assert isSimple is false

            # check that the chained transforms produce the same results as the WCS
            # in the forward and inverse direction
            pixPosList = []
            for dx in (0, 1000):
                for dy in (0, 1000):
                    pixPosList.append(Point2D(dx, dy) + crpix)
            iwcPosList = pixelToIwc.applyForward(pixPosList)
            skyPosList = iwcToSky.applyForward(iwcPosList)
            self.assertSpherePointListsAlmostEqual(
                skyPosList, skyWcs.pixelToSky(pixPosList))
            self.assertPairListsAlmostEqual(
                pixelToIwc.applyInverse(iwcToSky.applyInverse(skyPosList)),
                skyWcs.skyToPixel(skyPosList))

            self.assertPairListsAlmostEqual(iwcPosList,
                                            iwcToSky.applyInverse(skyPosList))
            self.assertPairListsAlmostEqual(
                pixPosList, pixelToIwc.applyInverse(iwcPosList))

            # compare extracted pixelToIwc to a version of pixelToIwc computed directly from the metadata
            ourPixelToIwc = makeSipPixelToIwc(self.metadata)
            self.assertPairListsAlmostEqual(
                pixelToIwc.applyForward(pixPosList),
                ourPixelToIwc.applyForward(pixPosList))

            # compare extracted iwcToPixel to a version of iwcToPixel computed directly from the metadata
            ourIwcToPixel = makeSipIwcToPixel(self.metadata)
            self.assertPairListsAlmostEqual(
                pixelToIwc.applyInverse(iwcPosList),
                ourIwcToPixel.applyForward(iwcPosList))
예제 #26
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)
예제 #27
0
 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())
예제 #28
0
 def setUp(self):
     TransformTestBaseClass.setUp(self)
     self.crpix = Point2D(100, 100)
     self.crvalList = [
         IcrsCoord(0 * degrees, 45 * degrees),
         IcrsCoord(0.00001 * degrees, 45 * degrees),
         IcrsCoord(359.99999 * degrees, 45 * degrees),
         IcrsCoord(30 * degrees, 89.99999 * degrees),
         IcrsCoord(30 * degrees, -89.99999 * degrees),
     ]
     self.orientationList = [
         0 * degrees,
         0.00001 * degrees,
         -0.00001 * degrees,
         -45 * degrees,
         90 * degrees,
     ]
     self.scale = 1.0 * arcseconds
     self.tinyPixels = 10 * sys.float_info.epsilon
     self.tinyAngle = 10 * sys.float_info.epsilon * radians
예제 #29
0
 def setUp(self):
     self.crpix = Point2D(100, 100)
     self.crvalList = [
         SpherePoint(0 * degrees, 45 * degrees),
         SpherePoint(0.00001 * degrees, 45 * degrees),
         SpherePoint(359.99999 * degrees, 45 * degrees),
         SpherePoint(30 * degrees, 89.99999 * degrees),
         SpherePoint(30 * degrees, -89.99999 * degrees),
     ]
     self.orientationList = [
         0 * degrees,
         0.00001 * degrees,
         -0.00001 * degrees,
         -45 * degrees,
         90 * degrees,
     ]
     self.scale = 1.0 * arcseconds
     self.tinyPixels = 1.0e-10
     self.tinyAngle = 1.0e-10 * radians
     self.bbox = Box2I(Point2I(-1000, -1000),
                       Extent2I(2000, 2000))  # arbitrary but reasonable
예제 #30
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)