def check(self, expectFactor):
        schema = SourceTable.makeMinimalSchema()
        task = DynamicDetectionTask(config=self.config, schema=schema)
        table = SourceTable.make(schema)

        results = task.run(table, self.exposure, expId=12345)
        self.assertFloatsAlmostEqual(results.factor, expectFactor, rtol=self.rtol)
示例#2
0
    def __init__(self, butler=None, refObjLoader=None, schema=None, **kwargs):
        """!Construct a CharacterizeImageTask

        @param[in] butler  A butler object is passed to the refObjLoader constructor in case
            it is needed to load catalogs.  May be None if a catalog-based star selector is
            not used, if the reference object loader constructor does not require a butler,
            or if a reference object loader is passed directly via the refObjLoader argument.
        @param[in] refObjLoader  An instance of LoadReferenceObjectsTasks that supplies an
            external reference catalog to a catalog-based star selector.  May be None if a
            catalog star selector is not used or the loader can be constructed from the
            butler argument.
        @param[in,out] schema  initial schema (an lsst.afw.table.SourceTable), or None
        @param[in,out] kwargs  other keyword arguments for lsst.pipe.base.CmdLineTask
        """
        pipeBase.CmdLineTask.__init__(self, **kwargs)
        if schema is None:
            schema = SourceTable.makeMinimalSchema()
        self.schema = schema
        self.makeSubtask("background")
        self.makeSubtask("installSimplePsf")
        self.makeSubtask("repair")
        self.makeSubtask("measurePsf", schema=self.schema)
        if self.config.doMeasurePsf and self.measurePsf.usesMatches:
            if not refObjLoader:
                self.makeSubtask('refObjLoader', butler=butler)
                refObjLoader = self.refObjLoader
            self.makeSubtask("astrometry", refObjLoader=refObjLoader)
        self.makeSubtask("detectAndMeasure", schema=self.schema)
        self._initialFrame = getDebugFrame(self._display, "frame") or 1
        self._frame = self._initialFrame
        self.schema.checkUnits(parse_strict=self.config.checkUnitsParseStrict)
    def __init__(self, *args, **kwargs):
        """Constructor

        Besides the usual initialisation of configurables, we also set up
        the forced measurement which is deliberately not represented in
        this Task's configuration parameters because we're using it as part
        of the algorithm and we don't want to allow it to be modified.
        """
        SourceDetectionTask.__init__(self, *args, **kwargs)
        self.makeSubtask("skyObjects")

        # Set up forced measurement.
        config = ForcedMeasurementTask.ConfigClass()
        config.plugins.names = [
            'base_TransformedCentroid', 'base_PsfFlux', 'base_LocalBackground'
        ]
        # We'll need the "centroid" and "psfFlux" slots
        for slot in ("shape", "psfShape", "apFlux", "modelFlux",
                     "gaussianFlux", "calibFlux"):
            setattr(config.slots, slot, None)
        config.copyColumns = {}
        self.skySchema = SourceTable.makeMinimalSchema()
        self.skyMeasurement = ForcedMeasurementTask(config=config,
                                                    name="skyMeasurement",
                                                    parentTask=self,
                                                    refSchema=self.skySchema)
示例#4
0
    def check(self, expectFactor):
        schema = SourceTable.makeMinimalSchema()
        task = DynamicDetectionTask(config=self.config, schema=schema)
        table = SourceTable.make(schema)

        results = task.run(table, self.exposure, expId=12345)
        self.assertFloatsAlmostEqual(results.factor,
                                     expectFactor,
                                     rtol=self.rtol)
示例#5
0
    def __init__(self, schema=None, butler=None, **kwargs):
        """Initalize things! This should go above in the class docstring
        """

        super().__init__(**kwargs)

        if schema is None:
            schema = SourceTable.makeMinimalSchema()
        self.schema = schema
        self.makeSubtask("insertFakes")
        self.makeSubtask("calibrate")
    def testNoPsfUsed(self):
        """Test that the "calib_psfUsed" is required to measure aperture correction

        I hope someday DetectAndMeasureTask can determine for itself
        which sources are suitable for measuring aperture correction,
        at which point I expect this test to be deleted.
        """
        schema = SourceTable.makeMinimalSchema()
        config = DetectAndMeasureTask.ConfigClass()
        config.doMeasureApCorr = True
        with self.assertRaises(Exception):
            DetectAndMeasureTask(config=config, schema=schema)
    def testNoPsfUsed(self):
        """Test that the "calib_psfUsed" is required to measure aperture correction

        I hope someday DetectAndMeasureTask can determine for itself
        which sources are suitable for measuring aperture correction,
        at which point I expect this test to be deleted.
        """
        schema = SourceTable.makeMinimalSchema()
        config = DetectAndMeasureTask.ConfigClass()
        config.doMeasureApCorr = True
        with self.assertRaises(Exception):
            DetectAndMeasureTask(config=config, schema=schema)
    def testBasics(self):
        """Test detection and measurement on simple synthesized data
        """
        bbox = Box2I(Point2I(256, 100), Extent2I(128, 127))
        minCounts = 5000
        maxCounts = 50000
        starSigma = 1.5
        numX = 5
        numY = 5
        coordList = self.makeCoordList(
            bbox=bbox,
            numX=numX,
            numY=numY,
            minCounts=minCounts,
            maxCounts=maxCounts,
            sigma=starSigma,
        )
        kwid = 11  # kernel width
        sky = 2000
        # create an exposure without a Wcs; add the Wcs later
        exposure = plantSources(bbox=bbox,
                                kwid=kwid,
                                sky=sky,
                                coordList=coordList,
                                addPoissonNoise=True)

        schema = SourceTable.makeMinimalSchema()

        config = DetectAndMeasureTask.ConfigClass()
        task = DetectAndMeasureTask(config=config, schema=schema)

        butler = Butler(root=InputDir)
        dataRef = butler.dataRef("calexp", dataId=dict(visit=1))
        wcs = dataRef.get("raw").getWcs()
        exposure.setWcs(wcs)
        exposureIdInfo = dataRef.get("expIdInfo")
        taskRes = task.run(exposure=exposure, exposureIdInfo=exposureIdInfo)
        self.assertEqual(len(taskRes.sourceCat), numX * numY)
        schema = taskRes.sourceCat.schema
        centroidFlagKey = schema.find("slot_Centroid_flag").getKey()
        parentKey = schema.find("parent").getKey()
        psfFluxFlagKey = schema.find("slot_PsfFlux_flag").getKey()
        psfFluxKey = schema.find("slot_PsfFlux_flux").getKey()
        for src in taskRes.sourceCat:
            self.assertFalse(src.get(centroidFlagKey))  # centroid found
            self.assertEqual(src.get(parentKey), 0)  # not debelended
            self.assertFalse(src.get(psfFluxFlagKey))  # flux measured
            self.assertGreater(src.get(psfFluxKey), 4000)  # flux sane
示例#9
0
    def __init__(self, butler=None, refObjLoader=None, schema=None, **kwargs):
        """!Construct a CharacterizeImageTask

        @param[in] butler  A butler object is passed to the refObjLoader constructor in case
            it is needed to load catalogs.  May be None if a catalog-based star selector is
            not used, if the reference object loader constructor does not require a butler,
            or if a reference object loader is passed directly via the refObjLoader argument.
        # TODO DM-34769: remove rebObjLoader kwarg here.
        @param[in] refObjLoader  An instance of LoadReferenceObjectsTasks that supplies an
            external reference catalog to a catalog-based star selector.  May be None if a
            catalog star selector is not used or the loader can be constructed from the
            butler argument.
        @param[in,out] schema  initial schema (an lsst.afw.table.SourceTable), or None
        @param[in,out] kwargs  other keyword arguments for lsst.pipe.base.CmdLineTask
        """
        super().__init__(**kwargs)

        if schema is None:
            schema = SourceTable.makeMinimalSchema()
        self.schema = schema
        self.makeSubtask("background")
        self.makeSubtask("installSimplePsf")
        self.makeSubtask("repair")
        self.makeSubtask("measurePsf", schema=self.schema)
        # TODO DM-34769: remove this `if` block
        if self.config.doMeasurePsf and self.measurePsf.usesMatches:
            if not refObjLoader:
                self.makeSubtask('refObjLoader', butler=butler)
                refObjLoader = self.refObjLoader
            self.makeSubtask("ref_match", refObjLoader=refObjLoader)
        self.algMetadata = dafBase.PropertyList()
        self.makeSubtask('detection', schema=self.schema)
        if self.config.doDeblend:
            self.makeSubtask("deblend", schema=self.schema)
        self.makeSubtask('measurement',
                         schema=self.schema,
                         algMetadata=self.algMetadata)
        if self.config.doApCorr:
            self.makeSubtask('measureApCorr', schema=self.schema)
            self.makeSubtask('applyApCorr', schema=self.schema)
        self.makeSubtask('catalogCalculation', schema=self.schema)
        self._initialFrame = getDebugFrame(self._display, "frame") or 1
        self._frame = self._initialFrame
        self.schema.checkUnits(parse_strict=self.config.checkUnitsParseStrict)
        self.outputSchema = afwTable.SourceCatalog(self.schema)
    def __init__(self, schema=None, **kwargs):
        """!Construct a CharacterizeImageTask

        @param[in,out] schema  initial schema (an lsst.afw.table.SourceTable), or None
        @param[in,out] kwargs  other keyword arguments for lsst.pipe.base.CmdLineTask
        """
        pipeBase.CmdLineTask.__init__(self, **kwargs)
        if schema is None:
            schema = SourceTable.makeMinimalSchema()
        self.schema = schema
        self.makeSubtask("installSimplePsf")
        self.makeSubtask("repair")
        self.makeSubtask("measurePsf", schema=self.schema)
        if self.config.doMeasurePsf and self.measurePsf.usesMatches:
            self.makeSubtask("astrometry")
        self.makeSubtask("detectAndMeasure", schema=self.schema)
        self._initialFrame = getDebugFrame(self._display, "frame") or 1
        self._frame = self._initialFrame
    def __init__(self, schema=None, butler=None, **kwargs):
        """Initalize things! This should go above in the class docstring
        """

        super().__init__(**kwargs)

        if schema is None:
            schema = SourceTable.makeMinimalSchema()
        self.schema = schema
        self.makeSubtask("insertFakes")
        self.algMetadata = dafBase.PropertyList()
        self.makeSubtask("detection", schema=self.schema)
        self.makeSubtask("deblend", schema=self.schema)
        self.makeSubtask("measurement",
                         schema=self.schema,
                         algMetadata=self.algMetadata)
        self.makeSubtask("applyApCorr", schema=self.schema)
        self.makeSubtask("catalogCalculation", schema=self.schema)
示例#12
0
    def __init__(self, schema=None, **kwargs):
        """!Construct a CharacterizeImageTask

        @param[in,out] schema  initial schema (an lsst.afw.table.SourceTable), or None
        @param[in,out] kwargs  other keyword arguments for lsst.pipe.base.CmdLineTask
        """
        pipeBase.CmdLineTask.__init__(self, **kwargs)
        if schema is None:
            schema = SourceTable.makeMinimalSchema()
        self.schema = schema
        self.makeSubtask("installSimplePsf")
        self.makeSubtask("repair")
        self.makeSubtask("measurePsf", schema=self.schema)
        if self.config.doMeasurePsf and self.measurePsf.usesMatches:
            self.makeSubtask("astrometry")
        self.makeSubtask("detectAndMeasure", schema=self.schema)
        self._initialFrame = getDebugFrame(self._display, "frame") or 1
        self._frame = self._initialFrame
    def testBasics(self):
        """Test detection and measurement on simple synthesized data
        """
        bbox = Box2I(Point2I(256, 100), Extent2I(128, 127))
        minCounts = 5000
        maxCounts = 50000
        starSigma = 1.5
        numX = 5
        numY = 5
        coordList = self.makeCoordList(
            bbox=bbox,
            numX=numX,
            numY=numY,
            minCounts=minCounts,
            maxCounts=maxCounts,
            sigma=starSigma,
        )
        kwid = 11  # kernel width
        sky = 2000
        # create an exposure without a Wcs; add the Wcs later
        exposure = plantSources(bbox=bbox, kwid=kwid, sky=sky, coordList=coordList, addPoissonNoise=True)

        schema = SourceTable.makeMinimalSchema()

        config = DetectAndMeasureTask.ConfigClass()
        task = DetectAndMeasureTask(config=config, schema=schema)

        butler = Butler(root=InputDir)
        dataRef = butler.dataRef("calexp", dataId=dict(visit=1))
        wcs = dataRef.get("raw").getWcs()
        exposure.setWcs(wcs)
        exposureIdInfo = dataRef.get("expIdInfo")
        taskRes = task.run(exposure=exposure, exposureIdInfo=exposureIdInfo)
        self.assertEqual(len(taskRes.sourceCat), numX * numY)
        schema = taskRes.sourceCat.schema
        centroidFlagKey = schema.find("slot_Centroid_flag").getKey()
        parentKey = schema.find("parent").getKey()
        psfFluxFlagKey = schema.find("slot_PsfFlux_flag").getKey()
        psfFluxKey = schema.find("slot_PsfFlux_flux").getKey()
        for src in taskRes.sourceCat:
            self.assertFalse(src.get(centroidFlagKey))  # centroid found
            self.assertEqual(src.get(parentKey), 0)     # not debelended
            self.assertFalse(src.get(psfFluxFlagKey))   # flux measured
            self.assertGreater(src.get(psfFluxKey), 4000)  # flux sane
示例#14
0
    def __init__(self, *args, **kwargs):

        SourceDetectionTask.__init__(self, *args, **kwargs)
        self.makeSubtask("skyObjects")

        # Set up forced measurement.
        config = ForcedMeasurementTask.ConfigClass()
        config.plugins.names = [
            'base_TransformedCentroid', 'base_PsfFlux', 'base_LocalBackground'
        ]
        # We'll need the "centroid" and "psfFlux" slots
        for slot in ("shape", "psfShape", "apFlux", "modelFlux",
                     "gaussianFlux", "calibFlux"):
            setattr(config.slots, slot, None)
        config.copyColumns = {}
        self.skySchema = SourceTable.makeMinimalSchema()
        self.skyMeasurement = ForcedMeasurementTask(config=config,
                                                    name="skyMeasurement",
                                                    parentTask=self,
                                                    refSchema=self.skySchema)
    def __init__(self, *args, **kwargs):
        """Constructor

        Besides the usual initialisation of configurables, we also set up
        the forced measurement which is deliberately not represented in
        this Task's configuration parameters because we're using it as part
        of the algorithm and we don't want to allow it to be modified.
        """
        SourceDetectionTask.__init__(self, *args, **kwargs)
        self.makeSubtask("skyObjects")

        # Set up forced measurement.
        config = ForcedMeasurementTask.ConfigClass()
        config.plugins.names = ['base_TransformedCentroid', 'base_PsfFlux', 'base_LocalBackground']
        # We'll need the "centroid" and "psfFlux" slots
        for slot in ("shape", "psfShape", "apFlux", "modelFlux", "gaussianFlux", "calibFlux"):
            setattr(config.slots, slot, None)
        config.copyColumns = {}
        self.skySchema = SourceTable.makeMinimalSchema()
        self.skyMeasurement = ForcedMeasurementTask(config=config, name="skyMeasurement", parentTask=self,
                                                    refSchema=self.skySchema)
示例#16
0
    def __init__(self, dataPrefix="", schema=None, **kwargs):
        """Construct a DetectAndMeasureTask

        Arguments in addition to the standard Task arguments:
        @param[in] dataPrefix  prefix for name of source tables;
            - for calexp use the default of ""
            - for coadds use coaddName + "Coadd"
        @param[in,out] schema  schema for sources; if None then one is constructed
        """
        pipeBase.Task.__init__(self, **kwargs)
        self.dataPrefix = dataPrefix
        self.algMetadata = dafBase.PropertyList()
        if schema is None:
            schema = SourceTable.makeMinimalSchema()
        self.schema = schema
        self.makeSubtask("detection", schema=self.schema)
        if self.config.doDeblend:
            self.makeSubtask("deblend", schema=self.schema)
        self.makeSubtask("measurement", schema=self.schema, algMetadata=self.algMetadata)
        if self.config.doMeasureApCorr:
            # add field to flag stars useful for measuring aperture correction
            self.makeSubtask("measureApCorr", schema=schema)
示例#17
0
    def __init__(self, butler=None, schema=None, **kwargs):
        """!Construct a CharacterizeSpotsTask
        @param[in] butler  A butler object is passed to the refObjLoader constructor in case
            it is needed to load catalogs.  May be None if a catalog-based star selector is
            not used, if the reference object loader constructor does not require a butler,
            or if a reference object loader is passed directly via the refObjLoader argument.
        @param[in,out] schema  initial schema (an lsst.afw.table.SourceTable), or None
        @param[in,out] kwargs  other keyword arguments for lsst.pipe.base.CmdLineTask
        """
        super().__init__(**kwargs)

        if schema is None:
            schema = SourceTable.makeMinimalSchema()
        self.schema = schema
        self.makeSubtask("installSimplePsf")
        self.makeSubtask("repair")
        self.algMetadata = dafBase.PropertyList()
        self.makeSubtask('measurement', schema=self.schema, algMetadata=self.algMetadata)
        self.makeSubtask('catalogCalculation', schema=self.schema)
        self._initialFrame = getDebugFrame(self._display, "frame") or 1
        self._frame = self._initialFrame
        self.schema.checkUnits(parse_strict=self.config.checkUnitsParseStrict)
        self.outputSchema = afwTable.SourceCatalog(self.schema)
示例#18
0
    def __init__(self, dataPrefix="", schema=None, **kwargs):
        """Construct a DetectAndMeasureTask

        Arguments in addition to the standard Task arguments:
        @param[in] dataPrefix  prefix for name of source tables;
            - for calexp use the default of ""
            - for coadds use coaddName + "Coadd"
        @param[in,out] schema  schema for sources; if None then one is constructed
        """
        pipeBase.Task.__init__(self, **kwargs)
        self.dataPrefix = dataPrefix
        self.algMetadata = dafBase.PropertyList()
        if schema is None:
            schema = SourceTable.makeMinimalSchema()
        self.schema = schema
        self.makeSubtask("detection", schema=self.schema)
        if self.config.doDeblend:
            self.makeSubtask("deblend", schema=self.schema)
        self.makeSubtask("measurement",
                         schema=self.schema,
                         algMetadata=self.algMetadata)
        if self.config.doMeasureApCorr:
            # add field to flag stars useful for measuring aperture correction
            self.makeSubtask("measureApCorr", schema=schema)
示例#19
0
    def execute(self, dataRef):
        """!Characterize a science image

        @param dataRef: butler data reference
        @return a pipeBase Struct containing the results
        """
        self.log.info("Performing Super CharacterizeImage on sensor data ID %s" % (dataRef.dataId,))

        self.log.info("Reading input data using dataRef")
        inputData = self.read_input_data(dataRef)

        self.log.info("Running operations. The run() method should not take anything Butler")
        result = CharacterizeImageTask.characterize(CharacterizeImageTask(config=self.config, log=self.log, schema=SourceTable.makeMinimalSchema()),
                                                    **inputData.getDict())

        self.log.info("Writing output data using dataRef")
        self.write_output_data(dataRef, result)

        return result
    def getClumps(self, sigma=1.0, display=False):
        if self._num <= 0:
            raise RuntimeError("No candidate PSF sources")

        psfImage = self.getImage()
        #
        # Embed psfImage into a larger image so we can smooth when measuring it
        #
        width, height = psfImage.getWidth(), psfImage.getHeight()
        largeImg = psfImage.Factory(afwGeom.ExtentI(2 * width, 2 * height))
        largeImg.set(0)

        bbox = afwGeom.BoxI(afwGeom.PointI(width, height),
                            afwGeom.ExtentI(width, height))
        largeImg.assign(psfImage, bbox, afwImage.LOCAL)
        #
        # Now measure that image, looking for the highest peak.  Start by building an Exposure
        #
        msk = afwImage.MaskU(largeImg.getDimensions())
        msk.set(0)
        var = afwImage.ImageF(largeImg.getDimensions())
        var.set(1)
        mpsfImage = afwImage.MaskedImageF(largeImg, msk, var)
        mpsfImage.setXY0(afwGeom.PointI(-width, -height))
        del msk
        del var
        exposure = afwImage.makeExposure(mpsfImage)

        #
        # Next run an object detector
        #
        maxVal = afwMath.makeStatistics(psfImage, afwMath.MAX).getValue()
        threshold = maxVal - sigma * math.sqrt(maxVal)
        if threshold <= 0.0:
            threshold = maxVal

        threshold = afwDetection.Threshold(threshold)

        ds = afwDetection.FootprintSet(mpsfImage, threshold, "DETECTED")
        #
        # And measure it.  This policy isn't the one we use to measure
        # Sources, it's only used to characterize this PSF histogram
        #
        schema = SourceTable.makeMinimalSchema()
        psfImageConfig = SingleFrameMeasurementConfig()
        psfImageConfig.slots.centroid = "base_SdssCentroid"
        psfImageConfig.plugins["base_SdssCentroid"].doFootprintCheck = False
        psfImageConfig.slots.psfFlux = None  # "base_PsfFlux"
        psfImageConfig.slots.apFlux = "base_CircularApertureFlux_3_0"
        psfImageConfig.slots.modelFlux = None
        psfImageConfig.slots.instFlux = None
        psfImageConfig.slots.calibFlux = None
        psfImageConfig.slots.shape = "base_SdssShape"
        #   Formerly, this code had centroid.sdss, flux.psf, flux.naive,
        #   flags.pixel, and shape.sdss
        psfImageConfig.algorithms.names = [
            "base_SdssCentroid", "base_CircularApertureFlux", "base_SdssShape"
        ]
        psfImageConfig.algorithms["base_CircularApertureFlux"].radii = [3.0]
        psfImageConfig.validate()
        task = SingleFrameMeasurementTask(schema, config=psfImageConfig)

        sourceCat = SourceCatalog(schema)

        gaussianWidth = 1.5  # Gaussian sigma for detection convolution
        exposure.setPsf(algorithmsLib.DoubleGaussianPsf(11, 11, gaussianWidth))

        ds.makeSources(sourceCat)
        #
        # Show us the Histogram
        #
        if display:
            frame = 1
            dispImage = mpsfImage.Factory(
                mpsfImage,
                afwGeom.BoxI(afwGeom.PointI(width, height),
                             afwGeom.ExtentI(width, height)), afwImage.LOCAL)
            ds9.mtv(dispImage, title="PSF Selection Image", frame=frame)

        clumps = list()  # List of clumps, to return
        e = None  # thrown exception
        IzzMin = 1.0  # Minimum value for second moments
        IzzMax = (
            self._xSize /
            8.0)**2  # Max value ... clump radius should be < clumpImgSize/8
        apFluxes = []
        task.run(
            sourceCat,
            exposure)  # notes that this is backwards for the new framework
        for i, source in enumerate(sourceCat):
            if source.getCentroidFlag():
                continue
            x, y = source.getX(), source.getY()

            apFluxes.append(source.getApFlux())

            val = mpsfImage.getImage().get(int(x) + width, int(y) + height)

            psfClumpIxx = source.getIxx()
            psfClumpIxy = source.getIxy()
            psfClumpIyy = source.getIyy()

            if display:
                if i == 0:
                    ds9.pan(x, y, frame=frame)

                ds9.dot("+", x, y, ctype=ds9.YELLOW, frame=frame)
                ds9.dot("@:%g,%g,%g" % (psfClumpIxx, psfClumpIxy, psfClumpIyy),
                        x,
                        y,
                        ctype=ds9.YELLOW,
                        frame=frame)

            if psfClumpIxx < IzzMin or psfClumpIyy < IzzMin:
                psfClumpIxx = max(psfClumpIxx, IzzMin)
                psfClumpIyy = max(psfClumpIyy, IzzMin)
                if display:
                    ds9.dot("@:%g,%g,%g" %
                            (psfClumpIxx, psfClumpIxy, psfClumpIyy),
                            x,
                            y,
                            ctype=ds9.RED,
                            frame=frame)

            det = psfClumpIxx * psfClumpIyy - psfClumpIxy * psfClumpIxy
            try:
                a, b, c = psfClumpIyy / det, -psfClumpIxy / det, psfClumpIxx / det
            except ZeroDivisionError:
                a, b, c = 1e4, 0, 1e4

            clumps.append(
                Clump(peak=val,
                      x=x,
                      y=y,
                      a=a,
                      b=b,
                      c=c,
                      ixx=psfClumpIxx,
                      ixy=psfClumpIxy,
                      iyy=psfClumpIyy))

        if len(clumps) == 0:
            msg = "Failed to determine center of PSF clump"
            if e:
                msg += ": %s" % e
            raise RuntimeError(msg)

        # if it's all we got return it
        if len(clumps) == 1:
            return clumps

        # which clump is the best?
        # if we've undistorted the moments, stars should only have 1 clump
        # use the apFlux from the clump measurement, and take the highest
        # ... this clump has more psf star candidate neighbours than the others.

        # get rid of any that are huge, and thus poorly defined
        goodClumps = []
        for clump in clumps:
            if clump.ixx < IzzMax and clump.iyy < IzzMax:
                goodClumps.append(clump)

        # if culling > IzzMax cost us all clumps, we'll have to take what we have
        if len(goodClumps) == 0:
            goodClumps = clumps

        # use the 'brightest' clump
        iBestClump = numpy.argsort(apFluxes)[0]
        clumps = [clumps[iBestClump]]
        return clumps
示例#21
0
    def run(self, ccdExposure):
        """Mask negative pixels"""
        ccd = ccdExposure.getDetector()
        ccdExposure = self.convertIntToFloat(ccdExposure)

        self.updateVariance(ccdExposure, ccd[0])  # Treating as having only a single amplifier

        image = ccdExposure.getMaskedImage().getImage()
        mask = ccdExposure.getMaskedImage().getMask()
        bad = mask.getPlaneBitMask("BAD")
        if False:
            mask.getArray()[:] = numpy.where(image <= 0, bad, 0)  # XXX this causes bad things to happen

        #from lsst.afw.image.utils import clipImage
        #clipImage(image,0,10)
        #exit()


        """ transfer wcs system to TAN """
        matches = ReferenceMatchVector()
        md  = ccdExposure.getMetadata()
        wcs = ccdExposure.getWcs()

        refSchema = SimpleTable.makeMinimalSchema()
        Point2DKey.addFields(refSchema, "centroid", "centroid position", "pixel")
        refCatalog = SimpleCatalog(refSchema)
        schema = SourceTable.makeMinimalSchema()
        centroidKey = Point2DKey.addFields(schema, "centroid", "centroid position", "pixel")
        imgCatalog = SourceCatalog(schema)
        imgCatalog.defineCentroid("centroid")

#        for i in numpy.linspace(10, md.get("ZNAXIS1")-10, 20):
#            for j in numpy.linspace(10, md.get("ZNAXIS2")-10, 20):
        for i in numpy.linspace(10, 4000, 10):
            for j in numpy.linspace(10, 4000, 10):
                imgcrd = Point2D(i,j)  
                skycrd = wcs.pixelToSky(afwGeom.Point2D(i, j))
                # Create the reference catalog (with coordinates on the sky)
                refSrc = refCatalog.addNew()
                refSrc.setCoord(skycrd)
                # Create the position catalog (with positions on the image)
                imgSrc = imgCatalog.addNew()
                imgSrc.set(centroidKey, imgcrd)
                # matches
                matches.push_back(ReferenceMatch(refSrc, imgSrc, float("NaN")))

        # make initial wcs
        refPix = afwGeom.Point2D(0.5*ccdExposure.getWidth(), 0.5*ccdExposure.getHeight())
        refSky = wcs.pixelToSky(refPix)
        xPixelScale = yPixelScale = (0.2*afwGeom.arcseconds).asDegrees()
        initanWcs = afwImage.makeWcs(refSky, refPix, xPixelScale, 0.0, 0.0, yPixelScale)
        # obtain modified wcs with matched catalogs
        fitter = FitTanSipWcsTask()
        fitRes = fitter.fitWcs(
            matches = matches,
            initWcs = initanWcs,
            refCat = refCatalog,
            sourceCat = imgCatalog,
        )
        ccdExposure.setWcs(fitRes.wcs)


        """ Set zero point, ZP error, exptime """
    	zp = md.get("MAGZPT")
    	ccdExposure.getCalib().setFluxMag0(10.0**(0.4*zp))

        return lsst.pipe.base.Struct(exposure=ccdExposure)
    def getClumps(self, sigma=1.0, display=False):
        if self._num <= 0:
            raise RuntimeError("No candidate PSF sources")

        psfImage = self.getImage()
        #
        # Embed psfImage into a larger image so we can smooth when measuring it
        #
        width, height = psfImage.getWidth(), psfImage.getHeight()
        largeImg = psfImage.Factory(afwGeom.ExtentI(2*width, 2*height))
        largeImg.set(0)

        bbox = afwGeom.BoxI(afwGeom.PointI(width, height), afwGeom.ExtentI(width, height))
        largeImg.assign(psfImage, bbox, afwImage.LOCAL)
        #
        # Now measure that image, looking for the highest peak.  Start by building an Exposure
        #
        msk = afwImage.MaskU(largeImg.getDimensions())
        msk.set(0)
        var = afwImage.ImageF(largeImg.getDimensions())
        var.set(1)
        mpsfImage = afwImage.MaskedImageF(largeImg, msk, var)
        mpsfImage.setXY0(afwGeom.PointI(-width, -height))
        del msk
        del var
        exposure = afwImage.makeExposure(mpsfImage)

        #
        # Next run an object detector
        #
        maxVal = afwMath.makeStatistics(psfImage, afwMath.MAX).getValue()
        threshold = maxVal - sigma*math.sqrt(maxVal)
        if threshold <= 0.0:
            threshold = maxVal

        threshold = afwDetection.Threshold(threshold)

        ds = afwDetection.FootprintSet(mpsfImage, threshold, "DETECTED")
        #
        # And measure it.  This policy isn't the one we use to measure
        # Sources, it's only used to characterize this PSF histogram
        #
        schema = SourceTable.makeMinimalSchema()
        psfImageConfig = SingleFrameMeasurementConfig()
        psfImageConfig.doApplyApCorr = "no"
        psfImageConfig.slots.centroid = "base_SdssCentroid"
        psfImageConfig.slots.psfFlux = None #"base_PsfFlux"
        psfImageConfig.slots.apFlux = "base_CircularApertureFlux_3_0"
        psfImageConfig.slots.modelFlux = None
        psfImageConfig.slots.instFlux = None
        psfImageConfig.slots.calibFlux = None
        psfImageConfig.slots.shape = "base_SdssShape"
        #   Formerly, this code had centroid.sdss, flux.psf, flux.naive,
        #   flags.pixel, and shape.sdss
        psfImageConfig.algorithms.names = ["base_SdssCentroid", "base_CircularApertureFlux", "base_SdssShape"]
        psfImageConfig.algorithms["base_CircularApertureFlux"].radii = [3.0]
        psfImageConfig.validate()
        task = SingleFrameMeasurementTask(schema, config=psfImageConfig)

        sourceCat = SourceCatalog(schema)

        gaussianWidth = 1.5                       # Gaussian sigma for detection convolution
        exposure.setPsf(algorithmsLib.DoubleGaussianPsf(11, 11, gaussianWidth))

        ds.makeSources(sourceCat)
        #
        # Show us the Histogram
        #
        if display:
            frame = 1
            dispImage = mpsfImage.Factory(mpsfImage, afwGeom.BoxI(afwGeom.PointI(width, height),
                                                                  afwGeom.ExtentI(width, height)),
                                                                  afwImage.LOCAL)
            ds9.mtv(dispImage,title="PSF Selection Image", frame=frame)


        clumps = list()                 # List of clumps, to return
        e = None                        # thrown exception
        IzzMin = 1.0                    # Minimum value for second moments
        IzzMax = (self._xSize/8.0)**2   # Max value ... clump r < clumpImgSize/8
                                        # diameter should be < 1/4 clumpImgSize
        apFluxes = []
        task.run(exposure, sourceCat)   # notes that this is backwards for the new framework
        for i, source in enumerate(sourceCat):
            if source.getCentroidFlag():
                continue
            x, y = source.getX(), source.getY()

            apFluxes.append(source.getApFlux())

            val = mpsfImage.getImage().get(int(x) + width, int(y) + height)

            psfClumpIxx = source.getIxx()
            psfClumpIxy = source.getIxy()
            psfClumpIyy = source.getIyy()

            if display:
                if i == 0:
                    ds9.pan(x, y, frame=frame)

                ds9.dot("+", x, y, ctype=ds9.YELLOW, frame=frame)
                ds9.dot("@:%g,%g,%g" % (psfClumpIxx, psfClumpIxy, psfClumpIyy), x, y,
                        ctype=ds9.YELLOW, frame=frame)

            if psfClumpIxx < IzzMin or psfClumpIyy < IzzMin:
                psfClumpIxx = max(psfClumpIxx, IzzMin)
                psfClumpIyy = max(psfClumpIyy, IzzMin)
                if display:
                    ds9.dot("@:%g,%g,%g" % (psfClumpIxx, psfClumpIxy, psfClumpIyy), x, y,
                            ctype=ds9.RED, frame=frame)

            det = psfClumpIxx*psfClumpIyy - psfClumpIxy*psfClumpIxy
            try:
                a, b, c = psfClumpIyy/det, -psfClumpIxy/det, psfClumpIxx/det
            except ZeroDivisionError:
                a, b, c = 1e4, 0, 1e4

            clumps.append(Clump(peak=val, x=x, y=y, a=a, b=b, c=c,
                                ixx=psfClumpIxx, ixy=psfClumpIxy, iyy=psfClumpIyy))

        if len(clumps) == 0:
            msg = "Failed to determine center of PSF clump"
            if e:
                msg += ": %s" % e
            raise RuntimeError(msg)

        # if it's all we got return it
        if len(clumps) == 1:
            return clumps

        # which clump is the best?
        # if we've undistorted the moments, stars should only have 1 clump
        # use the apFlux from the clump measurement, and take the highest
        # ... this clump has more psf star candidate neighbours than the others.

        # get rid of any that are huge, and thus poorly defined
        goodClumps = []
        for clump in clumps:
            if clump.ixx < IzzMax and clump.iyy < IzzMax:
                goodClumps.append(clump)

        # if culling > IzzMax cost us all clumps, we'll have to take what we have
        if len(goodClumps) == 0:
            goodClumps = clumps

        # use the 'brightest' clump
        iBestClump = numpy.argsort(apFluxes)[0]
        clumps = [clumps[iBestClump]]
        return clumps