Пример #1
0
    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 = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.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.matcher.sourceSelector.config.minSnr = 0
 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())
Пример #3
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())
Пример #4
0
    def testClone(self):
        """Test copying an exposure with an attached Blob.
        """
        im = ExposureF(10, 10)
        # Extra components must be ALL CAPS for fits storage.
        im.getInfo().setComponent("BLOB", self.blob)

        im2 = im.clone()
        im3 = copy.deepcopy(im)
        im4 = ExposureF(im, deep=False)
        im5 = ExposureF(im, deep=True)

        for i in [im2, im3, im4, im5]:
            self.assertEqual(i.getInfo().getComponent("BLOB"), self.blob)
Пример #5
0
    def testPersistence(self):
        """Test persisting an exposure with an attached Blob.
        """
        im = ExposureF(10, 10)
        # Extra components must be ALL CAPS for fits storage.
        im.getInfo().setComponent("BLOB", self.blob)
        with lsst.utils.tests.getTempFilePath(".fits") as tmpFile:
            im.writeFits(tmpFile)

            newIm = ExposureF(tmpFile)
            self.assertEqual(newIm.getInfo().getComponent("BLOB"), self.blob)

            reader = ExposureFitsReader(tmpFile)
            newBlob = reader.readComponent("BLOB")
            self.assertEqual(newBlob, self.blob)
Пример #6
0
    def test_solve(self):
        exposure = ExposureF(1000, 1000)
        psfConfig = InstallGaussianPsfConfig()
        psfConfig.fwhm = 4
        psfTask = InstallGaussianPsfTask(config=psfConfig)
        psfTask.run(exposure=exposure)

        variance_image = exposure.getMaskedImage().getVariance()
        variance_image += 50

        add_psf_image(exposure, 200.0, 400.0, 600.0)
        add_psf_image(exposure, 210.0, 210.0, 300.0)
        # These last two are to catch edge effects.
        add_psf_image(exposure, 5.0, 210.0, 400.0)
        add_psf_image(exposure, 300.0, 5.0, 500.0)

        matrix = CrowdedFieldMatrix(exposure,
                                    np.array([200.0, 210.0, 5.0, 300.0]),
                                    np.array([400.0, 210.0, 210.0, 5.0]))
        status = matrix.solve()
        self.assertEqual(status, matrix.SUCCESS)
        result = matrix.result()

        self.assertFloatsAlmostEqual(result,
                                     np.array([600.0, 300.0, 400.0, 500.0]),
                                     atol=1e-3)
Пример #7
0
    def test_reject_maskedpixels(self):
        exposure = ExposureF(1000, 1000)
        psfConfig = InstallGaussianPsfConfig()
        psfConfig.fwhm = 4
        psfTask = InstallGaussianPsfTask(config=psfConfig)
        psfTask.run(exposure=exposure)

        variance_image = exposure.getMaskedImage().getVariance()
        variance_image += 50

        add_psf_image(exposure, 200.0, 400.0, 600.0)
        add_psf_image(exposure, 210.0, 210.0, 300.0)

        exposure.getMaskedImage().getImage()[200, 400] += 10000
        mask_dict = exposure.getMaskedImage().getMask().getMaskPlaneDict()
        exposure.getMaskedImage().getMask()[200, 400] |= mask_dict['SAT']

        matrix = CrowdedFieldMatrix(exposure, np.array([200.0, 210.0]),
                                    np.array([400.0, 210.0]))
        status = matrix.solve()
        self.assertEqual(status, matrix.SUCCESS)
        result = matrix.result()

        self.assertFloatsAlmostEqual(result,
                                     np.array([600.0, 300.0]),
                                     atol=1e-3)
Пример #8
0
    def test_solve_catalog(self):
        exposure = ExposureF(1000, 1000)
        psfConfig = InstallGaussianPsfConfig()
        psfConfig.fwhm = 4
        psfTask = InstallGaussianPsfTask(config=psfConfig)
        psfTask.run(exposure=exposure)

        variance_image = exposure.getMaskedImage().getVariance()
        variance_image += 50

        add_psf_image(exposure, 200.0, 400.0, 600.0)
        add_psf_image(exposure, 210.0, 210.0, 300.0)

        schema = afwTable.SourceTable.makeMinimalSchema()
        schema.addField("centroid_x", type=np.float64)
        schema.addField("centroid_y", type=np.float64)
        flux_key = schema.addField("flux_flux", type=np.float64)
        schema.getAliasMap().set("slot_Centroid", "centroid")
        testCatalog = afwTable.SourceCatalog(schema)
        for x, y in zip([200.0, 210.0], [400.0, 210]):
            r = testCatalog.addNew()
            r["centroid_x"] = x
            r["centroid_y"] = y

        matrix = CrowdedFieldMatrix(exposure, testCatalog, flux_key)
        result = matrix.solve()

        self.assertFloatsAlmostEqual(testCatalog["flux_flux"],
                                     np.array([600.0, 300.0]),
                                     atol=1e-3)
Пример #9
0
    def setUp(self):
        self.exposure = ExposureF(1000, 1000)
        psfConfig = InstallGaussianPsfConfig()
        psfConfig.fwhm = 4
        psfTask = InstallGaussianPsfTask(config=psfConfig)
        psfTask.run(exposure=self.exposure)

        variance_image = self.exposure.getMaskedImage().getVariance()
        variance_image += 50
Пример #10
0
    def test_solve_centroid(self):
        exposure = ExposureF(400, 400)
        psfConfig = InstallGaussianPsfConfig()
        psfConfig.fwhm = 4
        psfTask = InstallGaussianPsfTask(config=psfConfig)
        psfTask.run(exposure=exposure)

        variance_image = exposure.getMaskedImage().getVariance()
        variance_image += 100

        exposure.getMaskedImage().getVariance().getArray()[203, 203] = np.nan

        add_psf_image(exposure, 200.0, 200.0, 600.0)
        # exposure.image.array += 20*np.random.randn(*exposure.image.array.shape)

        schema = afwTable.SourceTable.makeMinimalSchema()
        simultaneousPsfFlux_key = schema.addField(
            "crowd_psfFlux_flux_instFlux",
            type=np.float64,
            doc="PSF Flux from simultaneous fitting")
        afwTable.Point2DKey.addFields(schema, "coarse_centroid",
                                      "Detection peak", "pixels")
        centroid_key = afwTable.Point2DKey.addFields(
            schema, "new_centroid", "Measurement of centroid", "pixels")
        schema.getAliasMap().set("slot_Centroid", "coarse_centroid")
        schema.getAliasMap().set("slot_PsfFlux", "crowd_psfFlux_flux")
        source_catalog = afwTable.SourceCatalog(schema)
        child = source_catalog.addNew()
        child['coarse_centroid_x'] = 200.0
        child['coarse_centroid_y'] = 200.5

        # Fit once with fixed positions to get the fluxes
        matrix = CrowdedFieldMatrix(exposure,
                                    source_catalog,
                                    simultaneousPsfFlux_key,
                                    fitCentroids=False,
                                    centroidKey=centroid_key)
        matrix.solve()

        # Now that we have rough fluxes, re-fit and allow
        # centroids to move.
        matrix = CrowdedFieldMatrix(exposure,
                                    source_catalog,
                                    simultaneousPsfFlux_key,
                                    fitCentroids=True,
                                    centroidKey=centroid_key)

        result = matrix.solve()

        self.assertFloatsAlmostEqual(source_catalog[0]['new_centroid_x'],
                                     200.0,
                                     atol=5e-2)
        self.assertFloatsAlmostEqual(source_catalog[0]['new_centroid_y'],
                                     200.0,
                                     atol=5e-2)
Пример #11
0
    def readFits(cls, path):
        """Read an external detrended image and create an LSST Exposure object
        from it.

        Any significant processing (e.g. pixel interpolation) should probably
        be done in a ExternalIsrTask instead of here so it can be done once and
        saved, instead of being done every time the image is loaded.

        THIS METHOD IS INCOMPLETE; IT MUST BE MODIFIED ACCORDING TO THE
        FORMAT OF THE DATA BEING LOADED.
        """
        directory, filename = os.path.split(path)
        match = cls.EXTERNAL_REGEX.match(filename)
        camera = cls.getCameraFromVisit(match.group("visit"))

        # Customize the code below based on the camera determined above.
        # To support more than one camera it may be useful to delegate
        # to other methods that are specific to certain cameras.

        # Read the actual image in from the given path using e.g. astropy,
        # and use it to fill in various arrays below.

        bbox = Box2I(Point2I(0, 0), Extent2I(..., ...))  # width, height
        result = ExposureF(bbox)
        # main image, as a [y, x] numpy.float32 array
        result.image.array = ...
        # variance image, as a [y, x] numpy.float32 array
        result.variance.array = ...

        # This example includes masking NaN pixels as NO_DATA and pixels above
        # 1E5 counts as SAT.  External information about where bad pixels
        # should be preferred when available, and obviously that saturation
        # threshold is just an example (saturation should actually be
        # determined before flat-fielding, of course).
        # Interpolating these bad pixels is handled by ExternalIsrTask.
        noDataBitMask = result.mask.getPlaneBitMask("NO_DATA")
        satBitMask = result.mask.getPlaneBitMask("SAT")
        result.mask.array |= noDataBitMask * np.isnan(result.image.array)
        result.mask.array |= satBitMask * (result.image.array > 1E5)

        # If you have a better guess at the PSF, we can find a way to use it.
        # But it'd be a good idea to at least put this in with a guess at the
        # seeing (RMS in pixels).
        result.setPsf(SingleGaussianPsf(seeingRMS))

        # Add a guess for the WCS, in this case assuming it's in the FITS
        # header of the first HDU.  Need to have something here, even if it
        # isn't very good (e.g. whatever comes from the telescope).
        metadata = readMetadata(filename)
        wcs = SkyWcs(metadata)
        result.setWcs(wcs)

        return result
Пример #12
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)
Пример #13
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))
 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)
Пример #15
0
    def adaptArgsAndRun(self, inputData, inputDataIds, outputDataIds, butler):
        """Operate on in-memory data.

        Returns
        -------
        `Struct` instance with produced result.
        """
        # calexps = inputData["calexp"]
        calexpDataIds = inputDataIds["calexp"]
        coaddDataIds = outputDataIds["coadd"]
        _LOG.info("executing %s: calexp=%s coadd=%s", self.getName(),
                  calexpDataIds, coaddDataIds)

        # output data, scalar in this case
        data = ExposureF(100, 100)

        # attribute name of struct is the same as a config field name
        return Struct(coadd=data)
    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)
Пример #17
0
    def test31035(self):
        """Test that illegal values in the header can be round-tripped."""
        with lsst.utils.tests.getTempFilePath(".fits") as fileName:
            exp = ExposureF(width=100, height=100)
            md = exp.getMetadata()
            md['BORE-RA'] = 'NaN'
            md['BORE-DEC'] = 'NaN'
            md['BORE-AZ'] = 'NaN'
            md['BORE-ALT'] = 'NaN'
            md['BORE-AIRMASS'] = 'NaN'
            md['BORE-ROTANG'] = 'NaN'
            md['OBS-LONG'] = 'NaN'
            md['OBS-LAT'] = 'NaN'
            md['OBS-ELEV'] = 'NaN'
            md['AIRTEMP'] = 'NaN'
            md['AIRPRESS'] = 'NaN'
            md['HUMIDITY'] = 'NaN'

            exp.writeFits(fileName)

            _ = ExposureF.readFits(fileName)
    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)
Пример #19
0
    def setUp(self):
        self.camera = CameraWrapper().camera
        self.detector = DetectorWrapper().detector
        self.crpix = lsst.geom.Point2D(50, 100)
        self.crval = lsst.geom.SpherePoint(36, 71, lsst.geom.degrees)
        scale = 1.0 * lsst.geom.arcseconds
        self.cdMatrix = afwGeom.makeCdMatrix(scale=scale)
        self.wcs = afwGeom.makeSkyWcs(crpix=self.crpix,
                                      crval=self.crval,
                                      cdMatrix=self.cdMatrix)
        self.bbox = lsst.geom.Box2I(lsst.geom.Point2I(-10, 10),
                                    lsst.geom.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)
Пример #20
0
    def run(self, calexp):
        """Operate on in-memory data.

        Returns
        -------
        `Struct` instance with produced result.
        """
        _LOG.info("executing %s: calexp=%s", self.getName(), calexp)

        # To test lsstDebug function make a debug.py file with this contents
        # somewhere in PYTHONPATH and run `pipetask` with --debug option:
        #
        #    import lsstDebug
        #    lsstDebug.Info('lsst.ctrl.mpexec.examples.calexpToCoaddTask').display = True
        #
        if lsstDebug.Info(__name__).display:
            _LOG.info("%s: display enabled", __name__)

        # output data, scalar in this case
        data = ExposureF(100, 100)

        # attribute name of struct is the same as a config field name
        return Struct(coadd=data)
Пример #21
0
    def run(self, input):
        """Operate on in-memory data.

        With default implementation of `runQuantum()` keyword arguments
        correspond to field names in a config.

        Parameters
        ----------
        input : `list`
            List of input data objects

        Returns
        -------
        `Struct` instance with produced result.
        """

        _LOG.info("executing %s: input=%s", self.getName(), input)

        # result, scalar in this case, just create 100x100 image
        data = ExposureF(100, 100)

        # attribute name of struct is the same as a config field name
        return Struct(output=data)
Пример #22
0
def displayAstrometry(refCat=None,
                      sourceCat=None,
                      distortedCentroidKey=None,
                      bbox=None,
                      exposure=None,
                      matches=None,
                      frame=1,
                      title="",
                      pause=True):
    """Show an astrometry debug image.

    Parameters
    ----------
    refCat : `lsst.afw.table.SimpleCatalog`
        reference object catalog; must have fields "centroid_x" an
        "centroid_y"
    sourceCat : `lsst.afw.table.SourceCatalg`
        source catalog; must have field "slot_Centroid_x" and "slot_Centroid_y"
    distortedCentroidKey : `lsst.afw.table.Key`
        key for sourceCat with field to use for distorted positions
    exposure : `lsst.afw.image.Exposure`
        exposure to display
    bbox : `lsst.geom.Box2I`
        bounding box of exposure; Used if the exposure is `None`
    matches : `list` of `lsst.afw.table.ReferenceMatch`
        List of matched objects
    frame : `int`
        frame number for display
    title : `str`
        title for display
    pause : `bool`
        pause for inspection of display? This is done by dropping into pdb.

    Notes
    -----

    - reference objects in refCat are shown as red X
    - sources in sourceCat are shown as green +
    - distorted sources in sourceCat (position given by distortedCentroidKey)
      are shown as green o
    - matches are shown as a yellow circle around the source and a yellow line
      connecting the reference object and source
    - if both exposure and bbox are `None`, no image is displayed

    """
    disp = afwDisplay.getDisplay(frame=frame)

    if exposure is not None:
        disp.mtv(exposure, title=title)
    elif bbox is not None:
        disp.mtv(exposure=ExposureF(bbox), title=title)

    with disp.Buffering():
        if refCat is not None:
            refCentroidKey = Point2DKey(refCat.schema["centroid"])
            for refObj in refCat:
                rx, ry = refObj.get(refCentroidKey)
                disp.dot("x", rx, ry, size=10, ctype=afwDisplay.RED)

        if sourceCat is not None:
            sourceCentroidKey = Point2DKey(sourceCat.schema["slot_Centroid"])
            for source in sourceCat:
                sx, sy = source.get(sourceCentroidKey)
                disp.dot("+", sx, sy, size=10, ctype=afwDisplay.GREEN)
                if distortedCentroidKey is not None:
                    dx, dy = source.get(distortedCentroidKey)
                    disp.dot("o", dx, dy, size=10, ctype=afwDisplay.GREEN)
                    disp.line([(sx, sy), (dx, dy)], ctype=afwDisplay.GREEN)

        if matches is not None:
            refCentroidKey = Point2DKey(matches[0].first.schema["centroid"])
            sourceCentroidKey = Point2DKey(
                matches[0].second.schema["slot_Centroid"])
            radArr = np.ndarray(len(matches))

            for i, m in enumerate(matches):
                refCentroid = m.first.get(refCentroidKey)
                sourceCentroid = m.second.get(sourceCentroidKey)
                radArr[i] = math.hypot(*(refCentroid - sourceCentroid))
                sx, sy = sourceCentroid
                disp.dot("o", sx, sy, size=10, ctype=afwDisplay.YELLOW)
                disp.line([refCentroid, sourceCentroid],
                          ctype=afwDisplay.YELLOW)

            print("<match radius> = %.4g +- %.4g [%d matches]" %
                  (radArr.mean(), radArr.std(), len(matches)))

    if pause:
        print(
            "Dropping into debugger to allow inspection of display. Type 'continue' when done."
        )
        import pdb
        pdb.set_trace()
Пример #23
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
Пример #24
0
def displayAstrometry(refCat=None,
                      sourceCat=None,
                      distortedCentroidKey=None,
                      bbox=None,
                      exposure=None,
                      matches=None,
                      frame=1,
                      title="",
                      pause=True):
    """Show an astrometry debug image

    - reference objects in refCat are shown as red X
    - sources in sourceCat are shown as green +
    - distorted sources in sourceCat (position given by distortedCentroidKey) are shown as green o
    - matches are shown as a yellow circle around the source and a yellow line
        connecting the reference object and source
    - if both exposure and bbox are None, no image is displayed

    @param[in] refCat  reference object catalog; must have fields "centroid_x" and "centroid_y"
    @param[in] sourceCat  source catalog; must have field "slot_Centroid_x" and "slot_Centroid_y"
    @param[in] distortedCentroidKey  key for sourceCat with field to use for distorted positions, or None
    @param[in] exposure  exposure to display, or None for a blank exposure
    @param[in] bbox  bounding box of exposure; used if exposure is None for a blank image
    @param[in] matches  a list of lsst.afw.table.ReferenceMatch, or None
    @param[in] frame  frame number for ds9 display
    @param[in] title  title for ds9 display
    @param[in] pause  pause for inspection of display? This is done by dropping into pdb.
    """
    disp = afwDisplay.getDisplay(frame)

    if exposure is not None:
        disp.mtv(exposure, title=title)
    elif bbox is not None:
        disp.mtv(exposure=ExposureF(bbox), title=title)

    with disp.Buffering():
        if refCat is not None:
            refCentroidKey = Point2DKey(refCat.schema["centroid"])
            for refObj in refCat:
                rx, ry = refObj.get(refCentroidKey)
                disp.dot("x", rx, ry, size=10, ctype=afwDisplay.RED)

        if sourceCat is not None:
            sourceCentroidKey = Point2DKey(sourceCat.schema["slot_Centroid"])
            for source in sourceCat:
                sx, sy = source.get(sourceCentroidKey)
                disp.dot("+", sx, sy, size=10, ctype=afwDisplay.GREEN)
                if distortedCentroidKey is not None:
                    dx, dy = source.get(distortedCentroidKey)
                    disp.dot("o", dx, dy, size=10, ctype=afwDisplay.GREEN)
                    disp.line([(sx, sy), (dx, dy)], ctype=afwDisplay.GREEN)

        if matches is not None:
            refCentroidKey = Point2DKey(matches[0].first.schema["centroid"])
            sourceCentroidKey = Point2DKey(
                matches[0].second.schema["slot_Centroid"])
            radArr = np.ndarray(len(matches))

            for i, m in enumerate(matches):
                refCentroid = m.first.get(refCentroidKey)
                sourceCentroid = m.second.get(sourceCentroidKey)
                radArr[i] = math.hypot(*(refCentroid - sourceCentroid))
                sx, sy = sourceCentroid
                disp.dot("o", sx, sy, size=10, ctype=afwDisplay.YELLOW)
                disp.line([refCentroid, sourceCentroid],
                          ctype=afwDisplay.YELLOW)

            print("<match radius> = %.4g +- %.4g [%d matches]" %
                  (radArr.mean(), radArr.std(), len(matches)))

    if pause:
        print(
            "Dropping into debugger to allow inspection of display. Type 'continue' when done."
        )
        import pdb
        pdb.set_trace()
Пример #25
0
    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
        amp1 = makeAmplifier("left", target1, image1, overscan1, gain,
                             readNoise, saturation)
        amp2 = makeAmplifier("right", target2, image2, overscan2, gain,
                             readNoise, saturation)
        ccdBox = Box2I(Point2I(0, 0),
                       Extent2I(image1.getWidth() + image2.getWidth(), height))
        camBuilder = cameraGeom.Camera.Builder("fakeCam")
        detBuilder = camBuilder.add("detector", 1)
        detBuilder.setSerial("det1")
        detBuilder.setBBox(ccdBox)
        detBuilder.setPixelSize(Extent2D(1.0, 1.0))
        detBuilder.setOrientation(cameraGeom.Orientation())
        detBuilder.append(amp1)
        detBuilder.append(amp2)
        cam = camBuilder.finish()
        exposure.setDetector(cam.get('detector'))

        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.doWrite = False
        self.config.expectWcs = False
        self.config.doLinearize = False
        self.config.doCrosstalk = False
        self.config.doBrighterFatter = False
        self.config.doAttachTransmissionCurve = False
        self.config.doAssembleCcd = False
        self.config.doNanMasking = False
        self.config.doInterpolate = False

        self.config.maskNegativeVariance = False  # This runs on mocks.
        # Set the things that match our test setup
        self.config.overscan.fitType = "CHEB"
        self.config.overscan.order = 1
        self.config.doEmpiricalReadNoise = True

        self.task = IsrTask(config=self.config)