def testNoPsf(self):
     """Test InstallGaussianPsfTask when the input exposure has no PSF."""
     for width in (21, 25):
         for fwhm in (2.8, 7.1):
             config = InstallGaussianPsfTask.ConfigClass()
             config.width = width
             config.fwhm = fwhm
             task = InstallGaussianPsfTask(config=config)
             exposure = ExposureF(100, 100)
             task.run(exposure=exposure)
             self.assertTrue(exposure.hasPsf())
             psf = exposure.getPsf()
             psfIm = psf.computeImage()
             self.assertEqual(psfIm.getWidth(), width)
             self.assertEqual(psfIm.getHeight(), width)
             measFwhm = psf.computeShape().getDeterminantRadius()*FwhmPerSigma
             self.assertAlmostEqual(measFwhm, fwhm, delta=1e-3)
    def testMatchSingleGaussianPsf(self):
        """Test InstallGaussianPsfTask when the input exposure has a single Gaussian PSF."""
        config = InstallGaussianPsfTask.ConfigClass()
        task = InstallGaussianPsfTask(config=config)

        for desWidth, desHeight, desSigma in (
            (21, 23, 1.2),
            (23, 25, 3.5),
        ):
            exposure = ExposureF(100, 100)
            inPsf = SingleGaussianPsf(desWidth, desHeight, desSigma)
            exposure.setPsf(inPsf)
            task.run(exposure=exposure)
            self.assertTrue(exposure.hasPsf())
            psf = exposure.getPsf()
            psfIm = psf.computeImage()
            self.assertEqual(psfIm.getWidth(), desWidth)
            self.assertEqual(psfIm.getHeight(), desHeight)
            self.assertAlmostEqual(psf.computeShape().getDeterminantRadius(), desSigma, delta=1e-3)
    def testMatchDoubleGaussianPsf(self):
        """Test InstallGaussianPsfTask when the input exposure has a DoubleGaussian PSF."""
        config = InstallGaussianPsfTask.ConfigClass()
        task = InstallGaussianPsfTask(config=config)

        for doubleGaussParms in (
            # width, height, inner sigma, outer sigma, outer/inner peak amplitude
            (21, 23, 1.2, 3.5, 0.02),
            (23, 25, 3.5, 9.0, 0.02),
        ):
            exposure = ExposureF(100, 100)
            inPsf = DoubleGaussianPsf(*doubleGaussParms)
            exposure.setPsf(inPsf)
            desWidth, desHeight, innerSigma = doubleGaussParms[0:3]
            task.run(exposure=exposure)
            self.assertTrue(exposure.hasPsf())
            psf = exposure.getPsf()
            psfIm = psf.computeImage()
            self.assertEqual(psfIm.getWidth(), desWidth)
            self.assertEqual(psfIm.getHeight(), desHeight)
            self.assertAlmostEqual(psf.computeShape().getDeterminantRadius(), innerSigma, delta=0.1)
    def setUp(self):
        # Load sample input from disk
        testDir = os.path.dirname(__file__)

        self.srcSet = SourceCatalog.readFits(os.path.join(testDir, "v695833-e0-c000.xy.fits"))

        self.bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(2048, 4612))  # approximate
        # create an exposure with the right metadata; the closest thing we have is
        # apparently v695833-e0-c000-a00.sci.fits, which is much too small
        smallExposure = ExposureF(os.path.join(testDir, "v695833-e0-c000-a00.sci.fits"))
        self.exposure = ExposureF(self.bbox)
        self.exposure.setWcs(smallExposure.getWcs())
        self.exposure.setFilter(smallExposure.getFilter())
        # copy the pixels we can, in case the user wants a debug display
        mi = self.exposure.getMaskedImage()
        mi.assign(smallExposure.getMaskedImage(), smallExposure.getBBox())

        logLevel = Log.INFO
        refCatDir = os.path.join(testDir, "data", "sdssrefcat")
        butler = Butler(refCatDir)
        refObjLoader = LoadIndexedReferenceObjectsTask(butler=butler)
        astrometryConfig = AstrometryTask.ConfigClass()
        self.astrom = AstrometryTask(config=astrometryConfig, refObjLoader=refObjLoader)
        self.astrom.log.setLevel(logLevel)
        # Since our sourceSelector is a registry object we have to wait for it to be created
        # before setting default values.
        self.astrom.sourceSelector.config.minSnr = 0
    def setUp(self):
        self.camera = CameraWrapper().camera
        self.detector = DetectorWrapper().detector
        self.crpix = afwGeom.Point2D(50, 100)
        self.crval = afwGeom.SpherePoint(36, 71, afwGeom.degrees)
        scale = 1.0*afwGeom.arcseconds
        self.cdMatrix = afwGeom.makeCdMatrix(scale=scale)
        self.wcs = afwGeom.makeSkyWcs(crpix=self.crpix, crval=self.crval, cdMatrix=self.cdMatrix)
        self.bbox = afwGeom.Box2I(afwGeom.Point2I(-10, 10), afwGeom.Extent2I(1000, 1022))
        self.exposure = ExposureF(self.bbox)

        # set the few items of ExposureInfo needed by IsrTask.run
        # when only adding a distortion model
        exposureInfo = ExposureInfo(photoCalib=PhotoCalib(1.0),
                                    detector=self.detector,
                                    visitInfo=VisitInfo(exposureTime=1.0),
                                    wcs=self.wcs)

        self.exposure.setInfo(exposureInfo)
    def setUp(self):
        """Constructs a CCD with two amplifiers and prepares for ISR"""
        np.random.seed(12345)
        baseValue = 100.0
        gain = 1.0
        readNoise = 123456789.0
        saturation = 987654321.0
        height = 234
        imageSize = Extent2I(123, height)
        overscanSize = Extent2I(16, height)
        self.sigma = 1.234

        # Set up the various regions
        overscan1 = Box2I(Point2I(0, 0), overscanSize)
        image1 = Box2I(Point2I(overscanSize[0], 0), imageSize)
        image2 = Box2I(Point2I(overscanSize[0] + imageSize[0], 0), imageSize)
        overscan2 = Box2I(Point2I(overscanSize[0] + 2*imageSize[0], 0), overscanSize)

        leftBox = Box2I(overscan1.getMin(), Extent2I(overscan1.getWidth() + image1.getWidth(), height))
        rightBox = Box2I(image2.getMin(), Extent2I(image2.getWidth() + overscan2.getWidth(), height))

        target1 = Box2I(Point2I(0, 0), imageSize)
        target2 = Box2I(Point2I(image1.getWidth(), 0), imageSize)

        # Set the pixels
        exposure = ExposureF(Box2I(Point2I(0, 0), Extent2I(imageSize[0]*2 + overscanSize[0]*2, height)))
        yy = np.arange(0, height, 1, dtype=np.float32)
        leftImage = ExposureF(exposure, leftBox)
        leftImage.image.array[:] = baseValue + yy[:, np.newaxis]
        rightImage = ExposureF(exposure, rightBox)
        rightImage.image.array[:] = baseValue - yy[:, np.newaxis]

        leftOverscan = ExposureF(exposure, overscan1)
        leftOverscan.image.array += np.random.normal(0.0, self.sigma, leftOverscan.image.array.shape)
        rightOverscan = ExposureF(exposure, overscan2)
        rightOverscan.image.array += np.random.normal(0.0, self.sigma, leftOverscan.image.array.shape)
        exposure.mask.array[:] = 0.0
        exposure.variance.array[:] = np.nan

        # Construct the detectors
        amps = AmpInfoCatalog(AmpInfoTable.makeMinimalSchema())
        makeAmplifier(amps, "left", target1, image1, overscan1, gain, readNoise, saturation)
        makeAmplifier(amps, "right", target2, image2, overscan2, gain, readNoise, saturation)
        ccdBox = Box2I(Point2I(0, 0), Extent2I(image1.getWidth() + image2.getWidth(), height))
        ccd = Detector("detector", 1, SCIENCE, "det1", ccdBox, amps, Orientation(), Extent2D(1.0, 1.0), {})
        exposure.setDetector(ccd)
        header = PropertyList()
        header.add("EXPTIME", 0.0)
        exposure.getInfo().setVisitInfo(VisitInfo(header))

        self.exposure = exposure
        self.config = IsrTask.ConfigClass()

        # Disable everything we don't care about
        self.config.doBias = False
        self.config.doDark = False
        self.config.doFlat = False
        self.config.doFringe = False
        self.config.doDefect = False
        self.config.doAddDistortionModel = False
        self.config.doWrite = False
        self.config.expectWcs = False
        self.config.doLinearize = False
        self.config.doCrosstalk = False
        self.config.doBrighterFatter = False
        self.config.doAttachTransmissionCurve = False

        # Set the things that match our test setup
        self.config.overscanFitType = "CHEB"
        self.config.overscanOrder = 1
        self.config.doEmpiricalReadNoise = True

        self.task = IsrTask(config=self.config)
class ApplyLookupTableTestCase(lsst.utils.tests.TestCase):
    """Test IsrTask.addDistortionModel
    """

    def setUp(self):
        self.camera = CameraWrapper().camera
        self.detector = DetectorWrapper().detector
        self.crpix = afwGeom.Point2D(50, 100)
        self.crval = afwGeom.SpherePoint(36, 71, afwGeom.degrees)
        scale = 1.0*afwGeom.arcseconds
        self.cdMatrix = afwGeom.makeCdMatrix(scale=scale)
        self.wcs = afwGeom.makeSkyWcs(crpix=self.crpix, crval=self.crval, cdMatrix=self.cdMatrix)
        self.bbox = afwGeom.Box2I(afwGeom.Point2I(-10, 10), afwGeom.Extent2I(1000, 1022))
        self.exposure = ExposureF(self.bbox)

        # set the few items of ExposureInfo needed by IsrTask.run
        # when only adding a distortion model
        exposureInfo = ExposureInfo(photoCalib=PhotoCalib(1.0),
                                    detector=self.detector,
                                    visitInfo=VisitInfo(exposureTime=1.0),
                                    wcs=self.wcs)

        self.exposure.setInfo(exposureInfo)

    def tearDown(self):
        self.detector = None
        self.exposure = None

    def testAddDistortionMethod(self):
        """Call IsrTask.addDistortionModel directly"""
        isrFunctions.addDistortionModel(self.exposure, self.camera)
        self.assertFalse(wcsAlmostEqualOverBBox(self.wcs, self.exposure.getWcs(), self.bbox))

        desiredWcs = self.makeDesiredDistortedWcs()
        self.assertWcsAlmostEqualOverBBox(desiredWcs, self.exposure.getWcs(), self.bbox)

    def makeMinimalIsrConfig(self):
        """Return an IsrConfig with all boolean flags disabled"""
        isrConfig = IsrTask.ConfigClass()
        for name in isrConfig:
            if name.startswith("do"):
                setattr(isrConfig, name, False)
        return isrConfig

    def makeDesiredDistortedWcs(self):
        """Make the expected distorted WCS"""
        pixelToFocalPlane = self.detector.getTransform(PIXELS, FOCAL_PLANE)
        focalPlaneToFieldAngle = self.camera.getTransformMap().getTransform(FOCAL_PLANE, FIELD_ANGLE)
        return makeDistortedTanWcs(self.wcs, pixelToFocalPlane, focalPlaneToFieldAngle)

    def testRunWithAddDistortionModel(self):
        """Test IsrTask.run with config.doAddDistortionModel true"""
        isrConfig = self.makeMinimalIsrConfig()
        isrConfig.doAddDistortionModel = True
        isrTask = IsrTask(config=isrConfig)
        with self.assertRaises(RuntimeError):
            # the camera argument is required
            isrTask.run(ccdExposure=self.exposure)
        exposure = isrTask.run(ccdExposure=self.exposure, camera=self.camera).exposure
        desiredWcs = self.makeDesiredDistortedWcs()
        self.assertWcsAlmostEqualOverBBox(desiredWcs, exposure.getWcs(), self.bbox)

    def testRunWithoutAddDistortionModel(self):
        """Test IsrTask.run with config.doAddDistortionModel false"""
        isrConfig = self.makeMinimalIsrConfig()
        isrTask = IsrTask(config=isrConfig)

        # the camera argument is not needed
        exposure = isrTask.run(ccdExposure=self.exposure).exposure
        self.assertEqual(self.wcs, exposure.getWcs())

        # and the camera argument is ignored if provided
        exposure2 = isrTask.run(ccdExposure=self.exposure, camera=self.camera).exposure
        self.assertEqual(self.wcs, exposure2.getWcs())
class JoinMatchListWithCatalogTestCase(unittest.TestCase):

    def setUp(self):
        # Load sample input from disk
        testDir = os.path.dirname(__file__)

        self.srcSet = SourceCatalog.readFits(os.path.join(testDir, "v695833-e0-c000.xy.fits"))

        self.bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(2048, 4612))  # approximate
        # create an exposure with the right metadata; the closest thing we have is
        # apparently v695833-e0-c000-a00.sci.fits, which is much too small
        smallExposure = ExposureF(os.path.join(testDir, "v695833-e0-c000-a00.sci.fits"))
        self.exposure = ExposureF(self.bbox)
        self.exposure.setWcs(smallExposure.getWcs())
        self.exposure.setFilter(smallExposure.getFilter())
        # copy the pixels we can, in case the user wants a debug display
        mi = self.exposure.getMaskedImage()
        mi.assign(smallExposure.getMaskedImage(), smallExposure.getBBox())

        logLevel = Log.INFO
        refCatDir = os.path.join(testDir, "data", "sdssrefcat")
        butler = Butler(refCatDir)
        refObjLoader = LoadIndexedReferenceObjectsTask(butler=butler)
        astrometryConfig = AstrometryTask.ConfigClass()
        self.astrom = AstrometryTask(config=astrometryConfig, refObjLoader=refObjLoader)
        self.astrom.log.setLevel(logLevel)
        # Since our sourceSelector is a registry object we have to wait for it to be created
        # before setting default values.
        self.astrom.sourceSelector.config.minSnr = 0

    def tearDown(self):
        del self.srcSet
        del self.bbox
        del self.exposure
        del self.astrom

    def getAstrometrySolution(self):
        return self.astrom.solve(exposure=self.exposure, sourceCat=self.srcSet)

    def testJoin(self):
        res = self.getAstrometrySolution()

        matches = res.matches
        matchmeta = res.matchMeta

        normalized = packMatches(matches)
        normalized.table.setMetadata(matchmeta)

        matches2 = self.astrom.refObjLoader.joinMatchListWithCatalog(normalized, self.srcSet)

        self.assertEqual(len(matches2), len(matches))
        for i in range(len(matches)):
            self.assertEqual(matches2[i].second.table, matches[i].second.table)
            self.assertEqual(matches2[i].second.getId(), matches[i].second.getId())
            self.assertEqual(matches2[i].second, matches[i].second)  # no deep copying, so we can compare ptrs
            self.assertEqual(matches2[i].first.getId(), matches[i].first.getId())
            self.assertEqual(matches2[i].first.getRa().asDegrees(), matches[i].first.getRa().asDegrees())
            self.assertEqual(matches2[i].first.getDec().asDegrees(), matches[i].first.getDec().asDegrees())
            self.assertEqual(matches2[i].first.get("i_flux"), matches[i].first.get("i_flux"))

    def testJoinAllFluxes(self):
        """Test that we can read all the fluxes from a reference catalog"""
        res = self.getAstrometrySolution()

        matches = res.matches
        matchmeta = res.matchMeta

        normalized = packMatches(matches)
        normalized.table.setMetadata(matchmeta)

        matches2 = self.astrom.refObjLoader.joinMatchListWithCatalog(normalized, self.srcSet)
        self.assertGreater(len(matches2), 0)
        ref = matches2[0][0]

        refSchema = ref.getSchema()
        for b in ("u", "g", "r", "i", "z"):
            self.assertIn("%s_flux" % (b,), refSchema)
            self.assertIn("%s_fluxErr" % (b,), refSchema)
Пример #9
0
 def testPersistence(self):
     for pgp in self.pgps:
         assert cppLib.isPersistable(pgp)
         im = ExposureF(10, 10)
         im.setPsf(pgp)
         self.assertEqual(im.getPsf(), pgp)
         with lsst.utils.tests.getTempFilePath(".fits") as tmpFile:
             im.writeFits(tmpFile)
             newIm = ExposureF(tmpFile)
             self.assertEqual(newIm.getPsf(), im.getPsf())
Пример #10
0
from lsst.afw.image import ExposureF
from lsst.meas.algorithms.installGaussianPsf import InstallGaussianPsfTask, FwhmPerSigma

exposure = ExposureF(100, 100)
task = InstallGaussianPsfTask()
task.run(exposure=exposure)

# This particular exposure had no PSF model to begin with, so the new PSF model
# uses the config's FWHM. However, measured FWHM is based on the truncated
# PSF image, so it does not exactly match the input
measFwhm = exposure.getPsf().computeShape().getDeterminantRadius() * FwhmPerSigma
assert abs(measFwhm - task.config.fwhm) < 1e-3
 def testPersistence(self):
     im = ExposureF(10, 10)
     im.setPsf(self.psf)
     self.assertEqual(im.getPsf(), self.psf)
     with lsst.utils.tests.getTempFilePath(".fits") as tmpFile:
         im.writeFits(tmpFile)
         newIm = ExposureF(tmpFile)
         self.assertEqual(newIm.getPsf(), im.getPsf())