Exemple #1
0
def main(expName, config, display=False):
    exp = afwImage.ExposureF(expName)

    # Assume exposure is bias-subtracted, CCD-assembled, has variance and mask plane.
    # If not, put code here to fix what's lacking.

    bg, bgSubExp = estimateBackground(exp, config.background, subtract=True)

    detection = SourceDetectionTask(config=config.detection)
    detResults = detection.detectFootprints(bgSubExp, sigma=config.psfSigma)

    fpSet = detResults.positive

    print "Found %d positive footprints" % len(fpSet.getFootprints())

    if display:
        print "Displaying results..."
        import lsst.afw.display.ds9 as ds9
        frame = 1
        ds9.mtv(bgSubExp, frame=frame, title="Background-subtracted exposure")
        with ds9.Buffering():
            for fp in fpSet.getFootprints():
                peakList = fp.getPeaks()
                for p in peakList:
                    ds9.dot("x", p.getFx(), p.getFy(), frame=frame)

    # XXX Work with footprints here

    psf = measAlg.SingleGaussianPsf(config.psfSize, config.psfSize, config.psfSigma)
    exp.setPsf(psf)

    cosmicray(exp, config.cosmicray, display=display)
Exemple #2
0
    def maskAndInterpDefect(self, ccdExposure, defectBaseList):
        """Mask defects and edges, interpolate over defects in place

        Mask defect pixels using mask plane BAD and interpolate over them.
        Mask the potentially problematic glowing edges as SUSPECT.

        Parameters
        ----------
        ccdExposure : `lsst.afw.image.Exposure`
            exposure to process
        defectBaseList : `list`
            a list of defects to mask and interpolate

        Returns
        -------
        ccdExposure : `lsst.afw.image.Exposure`
            exposure corrected in place
        """
        IsrTask.maskAndInterpDefect(self, ccdExposure, defectBaseList)
        maskedImage = ccdExposure.getMaskedImage()
        goodBBox = maskedImage.getBBox()
        # This makes a bbox numEdgeSuspect pixels smaller than the image on each side
        goodBBox.grow(-self.config.numEdgeSuspect)
        # Mask pixels outside goodBBox as SUSPECT
        SourceDetectionTask.setEdgeBits(
            maskedImage, goodBBox,
            maskedImage.getMask().getPlaneBitMask("SUSPECT"))
Exemple #3
0
def run(display=False):
    exposure = loadData()
    schema = afwTable.SourceTable.makeMinimalSchema()
    #
    # Create the detection and measurement Tasks
    #
    config = SourceDetectionTask.ConfigClass()
    config.reEstimateBackground = False
    detectionTask = SourceDetectionTask(config=config, schema=schema)

    config = SingleFrameMeasurementTask.ConfigClass()
    # Use the minimum set of plugins required.
    config.plugins.names.clear()
    for plugin in [
            "base_SdssCentroid", "base_SdssShape", "base_CircularApertureFlux",
            "base_PixelFlags"
    ]:
        config.plugins.names.add(plugin)
    config.plugins["base_CircularApertureFlux"].radii = [7.0]
    # Use of the PSF flux is hardcoded in secondMomentStarSelector
    config.slots.psfFlux = "base_CircularApertureFlux_7_0"
    measureTask = SingleFrameMeasurementTask(schema, config=config)
    #
    # Create the measurePsf task
    #
    config = MeasurePsfTask.ConfigClass()

    psfDeterminer = config.psfDeterminer.apply()
    psfDeterminer.config.sizeCellX = 128
    psfDeterminer.config.sizeCellY = 128
    psfDeterminer.config.spatialOrder = 1
    psfDeterminer.config.nEigenComponents = 3

    measurePsfTask = MeasurePsfTask(config=config, schema=schema)
    #
    # Create the output table
    #
    tab = afwTable.SourceTable.make(schema)
    #
    # Process the data
    #
    sources = detectionTask.run(tab, exposure, sigma=2).sources
    measureTask.measure(exposure, sources)

    result = measurePsfTask.run(exposure, sources)
    psf = result.psf
    cellSet = result.cellSet

    if display:  # display on ds9 (see also --debug argparse option)
        frame = 1
        ds9.mtv(exposure, frame=frame)

        with ds9.Buffering():
            for s in sources:
                xy = s.getCentroid()
                ds9.dot('+', *xy, frame=frame)
                if s.get("calib.psf.candidate"):
                    ds9.dot('x', *xy, ctype=ds9.YELLOW, frame=frame)
                if s.get("calib.psf.used"):
                    ds9.dot('o', *xy, size=4, ctype=ds9.RED, frame=frame)
Exemple #4
0
    def flatCorrection(self, exposure, flatExposure):
        """Apply flat correction in place

        DECam flat products have been trimmed and are smaller than
        the raw exposure.  The size of edge trim is computed based
        on the dimensions of the input data.  Only process the inner
        part of the raw exposure, and mask the outer pixels as EDGE.

        @param[in,out] exposure: exposure to process
        @param[in] flatExposure: flatfield exposure
        """
        nEdge = _computeEdgeSize(exposure, flatExposure)
        if nEdge > 0:
            rawMaskedImage = exposure.getMaskedImage()[nEdge:-nEdge, nEdge:-nEdge]
        else:
            rawMaskedImage = exposure.getMaskedImage()
        flatCorrection(
            rawMaskedImage, flatExposure.getMaskedImage(), self.config.flatScalingType, self.config.flatUserScale
        )
        # Mask the unprocessed edge pixels as EDGE
        SourceDetectionTask.setEdgeBits(
            exposure.getMaskedImage(),
            rawMaskedImage.getBBox(),
            exposure.getMaskedImage().getMask().getPlaneBitMask("EDGE"),
        )
def run(display=False):
    exposure = loadData()
    schema = afwTable.SourceTable.makeMinimalSchema()
    #
    # Create the detection and measurement Tasks
    #
    config = SourceDetectionTask.ConfigClass()
    config.reEstimateBackground = False
    detectionTask = SourceDetectionTask(config=config, schema=schema)

    config = SingleFrameMeasurementTask.ConfigClass()
    # Use the minimum set of plugins required.
    config.plugins.names.clear()
    for plugin in ["base_SdssCentroid", "base_SdssShape", "base_CircularApertureFlux", "base_PixelFlags"]:
        config.plugins.names.add(plugin)
    config.plugins["base_CircularApertureFlux"].radii = [7.0]
    config.slots.psfFlux = "base_CircularApertureFlux_7_0" # Use of the PSF flux is hardcoded in secondMomentStarSelector
    measureTask = SingleFrameMeasurementTask(schema, config=config)
    #
    # Create the measurePsf task
    #
    config = MeasurePsfTask.ConfigClass()

    psfDeterminer = config.psfDeterminer.apply()
    psfDeterminer.config.sizeCellX = 128
    psfDeterminer.config.sizeCellY = 128
    psfDeterminer.config.spatialOrder = 1
    psfDeterminer.config.nEigenComponents = 3

    measurePsfTask = MeasurePsfTask(config=config, schema=schema)
    #
    # Create the output table
    #
    tab = afwTable.SourceTable.make(schema)
    #
    # Process the data
    #
    sources = detectionTask.run(tab, exposure, sigma=2).sources
    measureTask.measure(exposure, sources)

    result = measurePsfTask.run(exposure, sources)
    psf = result.psf
    cellSet = result.cellSet

    if display:                         # display on ds9 (see also --debug argparse option)
        frame = 1
        ds9.mtv(exposure, frame=frame)

        with ds9.Buffering():
            for s in sources:
                xy = s.getCentroid()
                ds9.dot('+', *xy, frame=frame)
                if s.get("calib.psf.candidate"):
                    ds9.dot('x', *xy, ctype=ds9.YELLOW, frame=frame)
                if s.get("calib.psf.used"):
                    ds9.dot('o', *xy, size=4, ctype=ds9.RED, frame=frame)
def run(display=False):
    exposure = loadData()
    schema = afwTable.SourceTable.makeMinimalSchema()
    #
    # Create the detection task
    #
    config = SourceDetectionTask.ConfigClass()
    config.thresholdPolarity = "both"
    config.background.isNanSafe = True
    config.thresholdValue = 3
    detectionTask = SourceDetectionTask(config=config, schema=schema)
    #
    # And the measurement Task
    #
    config = SingleFrameMeasurementTask.ConfigClass()

    config.algorithms.names = ["base_SdssCentroid", "base_SdssShape", "base_CircularApertureFlux"]
    config.algorithms["base_CircularApertureFlux"].radii = [1, 2, 4, 8, 12, 16]  # pixels

    config.slots.gaussianFlux = None
    config.slots.modelFlux = None
    config.slots.psfFlux = None

    algMetadata = dafBase.PropertyList()
    measureTask = SingleFrameMeasurementTask(schema, algMetadata=algMetadata, config=config)
    radii = algMetadata.getArray("base_CircularApertureFlux_radii")
    #
    # Create the output table
    #
    tab = afwTable.SourceTable.make(schema)
    #
    # Process the data
    #
    result = detectionTask.run(tab, exposure)

    sources = result.sources

    print("Found %d sources (%d +ve, %d -ve)" % (len(sources), result.fpSets.numPos, result.fpSets.numNeg))

    measureTask.run(sources, exposure)
    if display:                         # display image (see also --debug argparse option)
        afwDisplay.setDefaultMaskTransparency(75)
        frame = 1
        disp = afwDisplay.Display(frame=frame)
        disp.mtv(exposure)

        with disp.Buffering():
            for s in sources:
                xy = s.getCentroid()
                disp.dot('+', *xy, ctype=afwDisplay.CYAN if s.get("flags_negative") else afwDisplay.GREEN)
                disp.dot(s.getShape(), *xy, ctype=afwDisplay.RED)

                for radius in radii:
                    disp.dot('o', *xy, size=radius, ctype=afwDisplay.YELLOW)
Exemple #7
0
def run(display=False):
    exposure = loadData()
    schema = afwTable.SourceTable.makeMinimalSchema()
    #
    # Create the detection task
    #
    config = SourceDetectionTask.ConfigClass()
    config.thresholdPolarity = "both"
    config.background.isNanSafe = True
    config.thresholdValue = 3
    detectionTask = SourceDetectionTask(config=config, schema=schema)
    #
    # And the measurement Task
    #
    config = SingleFrameMeasurementTask.ConfigClass()
    config.plugins.names.clear()
    for plugin in ["base_SdssCentroid", "base_SdssShape", "base_CircularApertureFlux", "base_GaussianFlux"]:
        config.plugins.names.add(plugin)
    config.slots.psfFlux = None
    config.slots.apFlux = "base_CircularApertureFlux_3_0"

    measureTask = SingleFrameMeasurementTask(schema, config=config)

    #
    # Print the schema the configuration produced
    #
    print(schema)

    #
    # Create the output table
    #
    tab = afwTable.SourceTable.make(schema)
    #
    # Process the data
    #
    result = detectionTask.run(tab, exposure)

    sources = result.sources

    print("Found %d sources (%d +ve, %d -ve)" % (len(sources), result.fpSets.numPos, result.fpSets.numNeg))

    measureTask.run(sources, exposure)
    if display:                         # display image (see also --debug argparse option)
        frame = 1
        disp = afwDisplay.Display(frame=frame)
        disp.mtv(exposure)

        with disp.Buffering():
            for s in sources:
                xy = s.getCentroid()
                disp.dot('+', *xy, ctype=afwDisplay.CYAN if s.get("flags_negative") else afwDisplay.GREEN)
                disp.dot(s.getShape(), *xy, ctype=afwDisplay.RED)
                disp.dot('o', *xy, size=config.plugins["base_CircularApertureFlux"].radii[0],
                         ctype=afwDisplay.YELLOW)
def run(display=False):
    exposure = loadData()
    schema = afwTable.SourceTable.makeMinimalSchema()
    #
    # Create the detection task
    #
    config = SourceDetectionTask.ConfigClass()
    config.thresholdPolarity = "both"
    config.background.isNanSafe = True
    config.thresholdValue = 3
    detectionTask = SourceDetectionTask(config=config, schema=schema)
    #
    # And the measurement Task
    #
    config = SingleFrameMeasurementTask.ConfigClass()

    config.algorithms.names = ["base_SdssCentroid", "base_SdssShape", "base_CircularApertureFlux"]
    config.algorithms["base_CircularApertureFlux"].radii = [1, 2, 4, 8, 16] # pixels

    config.slots.instFlux = None
    config.slots.modelFlux = None
    config.slots.psfFlux = None

    algMetadata = dafBase.PropertyList()
    measureTask = SingleFrameMeasurementTask(schema, algMetadata=algMetadata, config=config)
    radii = algMetadata.get("base_CircularApertureFlux_radii")
    #
    # Create the output table
    #
    tab = afwTable.SourceTable.make(schema)
    #
    # Process the data
    #
    result = detectionTask.run(tab, exposure)

    sources = result.sources

    print("Found %d sources (%d +ve, %d -ve)" % (len(sources), result.fpSets.numPos, result.fpSets.numNeg))

    measureTask.run(sources, exposure)
    if display:                         # display on ds9 (see also --debug argparse option)
        frame = 1
        ds9.mtv(exposure, frame=frame)

        with ds9.Buffering():
            for s in sources:
                xy = s.getCentroid()
                ds9.dot('+', *xy, ctype=ds9.CYAN if s.get("flags.negative") else ds9.GREEN, frame=frame)
                ds9.dot(s.getShape(), *xy, ctype=ds9.RED, frame=frame)

                for i in range(s.get("flux.aperture.nProfile")):
                    ds9.dot('o', *xy, size=radii[i], ctype=ds9.YELLOW, frame=frame)
Exemple #9
0
    def maskAndInterpDefect(self, ccdExposure, defectBaseList):
        """Mask defects and edges, interpolate over defects in place

        Mask defect pixels using mask plane BAD and interpolate over them.
        Mask the potentially problematic glowing edges as SUSPECT.

        @param[in,out] ccdExposure: exposure to process
        @param[in] defectBaseList: a list of defects to mask and interpolate
        """
        IsrTask.maskAndInterpDefect(self, ccdExposure, defectBaseList)
        maskedImage = ccdExposure.getMaskedImage()
        goodBBox = maskedImage.getBBox()
        # This makes a bbox numEdgeSuspect pixels smaller than the image on each side
        goodBBox.grow(-self.config.numEdgeSuspect)
        # Mask pixels outside goodBBox as SUSPECT
        SourceDetectionTask.setEdgeBits(maskedImage, goodBBox, maskedImage.getMask().getPlaneBitMask("SUSPECT"))
Exemple #10
0
def trimToMatchCalibBBox(rawMaskedImage, calibMaskedImage):
    """Compute number of edge trim pixels to match the calibration data.

    Use the dimension difference between the raw exposure and the
    calibration exposure to compute the edge trim pixels.  This trim
    is applied symmetrically, with the same number of pixels masked on
    each side.

    Parameters
    ----------
    rawMaskedImage : `lsst.afw.image.MaskedImage`
        Image to trim.
    calibMaskedImage : `lsst.afw.image.MaskedImage`
        Calibration image to draw new bounding box from.

    Returns
    -------
    replacementMaskedImage : `lsst.afw.image.MaskedImage`
        ``rawMaskedImage`` trimmed to the appropriate size
    Raises
    ------
    RuntimeError
       Rasied if ``rawMaskedImage`` cannot be symmetrically trimmed to
       match ``calibMaskedImage``.
    """
    nx, ny = rawMaskedImage.getBBox().getDimensions(
    ) - calibMaskedImage.getBBox().getDimensions()
    if nx != ny:
        raise RuntimeError(
            "Raw and calib maskedImages are trimmed differently in X and Y.")
    if nx % 2 != 0:
        raise RuntimeError("Calibration maskedImage is trimmed unevenly in X.")
    if nx < 0:
        raise RuntimeError("Calibration maskedImage is larger than raw data.")

    nEdge = nx // 2
    if nEdge > 0:
        replacementMaskedImage = rawMaskedImage[nEdge:-nEdge, nEdge:-nEdge,
                                                afwImage.LOCAL]
        SourceDetectionTask.setEdgeBits(
            rawMaskedImage, replacementMaskedImage.getBBox(),
            rawMaskedImage.getMask().getPlaneBitMask("EDGE"))
    else:
        replacementMaskedImage = rawMaskedImage

    return replacementMaskedImage
def run(args):
    exposure = loadData(args.image)
    if args.debug:
        ds9.mtv(exposure, frame=1)

    schema = afwTable.SourceTable.makeMinimalSchema()

    # Create the detection task
    config = SourceDetectionTask.ConfigClass()
    config.thresholdPolarity = "both"
    config.background.isNanSafe = True
    config.thresholdValue = 3
    detectionTask = SourceDetectionTask(config=config, schema=schema)

    # And the measurement Task
    config = DipoleMeasurementTask.ConfigClass()
    config.plugins.names.remove('base_SkyCoord')

    algMetadata = dafBase.PropertyList()
    measureTask = DipoleMeasurementTask(schema, algMetadata, config=config)

    # Create the output table
    tab = afwTable.SourceTable.make(schema)

    # Process the data
    results = detectionTask.run(tab, exposure)

    # Merge the positve and negative sources
    fpSet = results.fpSets.positive
    growFootprint = 2
    fpSet.merge(results.fpSets.negative, growFootprint, growFootprint, False)
    diaSources = afwTable.SourceCatalog(tab)
    fpSet.makeSources(diaSources)

    print("Merged %s Sources into %d diaSources (from %d +ve, %d -ve)" % (len(results.sources),
                                                                          len(diaSources), 
                                                                          results.fpSets.numPos, 
                                                                          results.fpSets.numNeg))

    measureTask.run(diaSources, exposure)

    # Display dipoles if debug enabled
    if args.debug:
        dpa = DipoleAnalysis()
        dpa.displayDipoles(exposure, diaSources)
Exemple #12
0
def trimToMatchCalibBBox(rawMaskedImage, calibMaskedImage):
    """Compute number of edge trim pixels to match the calibration data.

    Use the dimension difference between the raw exposure and the
    calibration exposure to compute the edge trim pixels.  This trim
    is applied symmetrically, with the same number of pixels masked on
    each side.

    Parameters
    ----------
    rawMaskedImage : `lsst.afw.image.MaskedImage`
        Image to trim.
    calibMaskedImage : `lsst.afw.image.MaskedImage`
        Calibration image to draw new bounding box from.

    Returns
    -------
    replacementMaskedImage : `lsst.afw.image.MaskedImage`
        ``rawMaskedImage`` trimmed to the appropriate size
    Raises
    ------
    RuntimeError
       Rasied if ``rawMaskedImage`` cannot be symmetrically trimmed to
       match ``calibMaskedImage``.
    """
    nx, ny = rawMaskedImage.getBBox().getDimensions() - calibMaskedImage.getBBox().getDimensions()
    if nx != ny:
        raise RuntimeError("Raw and calib maskedImages are trimmed differently in X and Y.")
    if nx % 2 != 0:
        raise RuntimeError("Calibration maskedImage is trimmed unevenly in X.")
    if nx < 0:
        raise RuntimeError("Calibration maskedImage is larger than raw data.")

    nEdge = nx//2
    if nEdge > 0:
        replacementMaskedImage = rawMaskedImage[nEdge:-nEdge, nEdge:-nEdge, afwImage.LOCAL]
        SourceDetectionTask.setEdgeBits(
            rawMaskedImage,
            replacementMaskedImage.getBBox(),
            rawMaskedImage.getMask().getPlaneBitMask("EDGE")
        )
    else:
        replacementMaskedImage = rawMaskedImage

    return replacementMaskedImage
Exemple #13
0
    def testMismatchedSchema(self):
        schema = afwTable.SourceTable.makeMinimalSchema()

        # Create the detection task and process the data
        detectionTask = SourceDetectionTask(schema=schema)
        table = afwTable.SourceTable.make(schema)
        result = detectionTask.run(table, self.calexp)
        self.assertEqual(schema, result.sources.getSchema())

        # SourceDeblendTask modifies the schema in-place at construction
        # and add extra keys to it
        deblendTask = SourceDeblendTask(schema)
        self.assertNotEqual(schema, result.sources.getSchema())

        # As the deblendTask has a different schema than the original schema
        # of the detectionTask, the assert should fail and stop running
        with self.assertRaises(AssertionError):
            deblendTask.run(self.calexp, result.sources)
Exemple #14
0
    def testInclude(self):
        schema = afwTable.SourceTable.makeMinimalSchema()

        # Create the detection task
        config = SourceDetectionTask.ConfigClass()
        config.reEstimateBackground = False  # Turn off so that background does not change from orig
        detectionTask = SourceDetectionTask(config=config, schema=schema)

        # Create the deblender Task
        debConfig = measDeb.SourceDeblendConfig()
        debTask = measDeb.SourceDeblendTask(schema, config=debConfig)

        # Create the measurement Task
        config = SingleFrameMeasurementTask.ConfigClass()
        measureTask = SingleFrameMeasurementTask(schema, config=config)

        # Create the output table
        tab = afwTable.SourceTable.make(schema)

        # Process the data
        result = detectionTask.run(tab, self.calexp)
        sources = result.sources

        # Run the deblender
        debTask.run(self.calexp, sources)

        # Run the measurement task: this where the replace-with-noise occurs
        measureTask.run(sources, self.calexp)

        plotOnFailure = False
        if display:
            plotOnFailure = True

        # The relative differences ranged from 0.02 to ~2.  This rtol is somewhat
        # random, but will certainly catch the pathology if it occurs.
        self.assertFloatsAlmostEqual(
            self.calexpOrig.getMaskedImage().getImage().getArray(),
            self.calexp.getMaskedImage().getImage().getArray(),
            rtol=1E-3,
            printFailures=False,
            plotOnFailure=plotOnFailure)
Exemple #15
0
    def biasCorrection(self, exposure, biasExposure):
        """Apply bias correction in place

        DECam bias products have been trimmed and are smaller than
        the raw exposure.  The size of edge trim is computed based
        on the dimensions of the input data.  Only process the inner
        part of the raw exposure, and mask the outer pixels as EDGE.

        @param[in,out] exposure: exposure to process
        @param[in] biasExposure: bias exposure
        """
        nEdge = _computeEdgeSize(exposure, biasExposure)
        if nEdge > 0:
            rawMaskedImage = exposure.getMaskedImage()[nEdge:-nEdge,
                                                       nEdge:-nEdge]
        else:
            rawMaskedImage = exposure.getMaskedImage()
        biasCorrection(rawMaskedImage, biasExposure.getMaskedImage())
        # Mask the unprocessed edge pixels as EDGE
        SourceDetectionTask.setEdgeBits(
            exposure.getMaskedImage(), rawMaskedImage.getBBox(),
            exposure.getMaskedImage().getMask().getPlaneBitMask("EDGE"))
    def testInclude(self):
        schema = afwTable.SourceTable.makeMinimalSchema()

        # Create the detection task
        config = SourceDetectionTask.ConfigClass()
        config.reEstimateBackground = False  # Turn off so that background does not change from orig
        detectionTask = SourceDetectionTask(config=config, schema=schema)

        # Create the deblender Task
        debConfig = measDeb.SourceDeblendConfig()
        debTask = measDeb.SourceDeblendTask(schema, config=debConfig)

        # Create the measurement Task
        config = SingleFrameMeasurementTask.ConfigClass()
        measureTask = SingleFrameMeasurementTask(schema, config=config)

        # Create the output table
        tab = afwTable.SourceTable.make(schema)

        # Process the data
        result = detectionTask.run(tab, self.calexp)
        sources = result.sources

        # Run the deblender
        debTask.run(self.calexp, sources)

        # Run the measurement task: this where the replace-with-noise occurs
        measureTask.run(sources, self.calexp)

        plotOnFailure = False
        if display:
            plotOnFailure = True

        # The relative differences ranged from 0.02 to ~2.  This rtol is somewhat
        # random, but will certainly catch the pathology if it occurs.
        self.assertFloatsAlmostEqual(self.calexpOrig.getMaskedImage().getImage().getArray(),
                                     self.calexp.getMaskedImage().getImage().getArray(),
                                     rtol=1E-3, printFailures=False, plotOnFailure=plotOnFailure)
Exemple #17
0
    def flatCorrection(self, exposure, flatExposure):
        """Apply flat correction in place

        DECam flat products have been trimmed and are smaller than
        the raw exposure.  The size of edge trim is computed based
        on the dimensions of the input data.  Only process the inner
        part of the raw exposure, and mask the outer pixels as EDGE.

        @param[in,out] exposure: exposure to process
        @param[in] flatExposure: flatfield exposure
        """
        nEdge = _computeEdgeSize(exposure, flatExposure)
        if nEdge > 0:
            rawMaskedImage = exposure.getMaskedImage()[nEdge:-nEdge,
                                                       nEdge:-nEdge]
        else:
            rawMaskedImage = exposure.getMaskedImage()
        flatCorrection(rawMaskedImage, flatExposure.getMaskedImage(),
                       self.config.flatScalingType, self.config.flatUserScale)
        # Mask the unprocessed edge pixels as EDGE
        SourceDetectionTask.setEdgeBits(
            exposure.getMaskedImage(), rawMaskedImage.getBBox(),
            exposure.getMaskedImage().getMask().getPlaneBitMask("EDGE"))
Exemple #18
0
    def biasCorrection(self, exposure, biasExposure):
        """Apply bias correction in place

        DECam bias products have been trimmed and are smaller than
        the raw exposure.  The size of edge trim is computed based
        on the dimensions of the input data.  Only process the inner
        part of the raw exposure, and mask the outer pixels as EDGE.

        @param[in,out] exposure: exposure to process
        @param[in] biasExposure: bias exposure
        """
        nEdge = _computeEdgeSize(exposure, biasExposure)
        if nEdge > 0:
            rawMaskedImage = exposure.getMaskedImage()[nEdge:-nEdge, nEdge:-nEdge]
        else:
            rawMaskedImage = exposure.getMaskedImage()
        biasCorrection(rawMaskedImage, biasExposure.getMaskedImage())
        # Mask the unprocessed edge pixels as EDGE
        SourceDetectionTask.setEdgeBits(
            exposure.getMaskedImage(),
            rawMaskedImage.getBBox(),
            exposure.getMaskedImage().getMask().getPlaneBitMask("EDGE"),
        )
def detectAndMeasureWithDM(display):

    ### what file are you going to look at? This should be in fits format.
    ### The test image included in this example contains stars and galaxies in the center only. 
    imagefile = "test_image_stars.fits"
    
    ### open the file in the stack format
    exposure = afwImage.ExposureF(imagefile)
    im = exposure.getMaskedImage().getImage()

    if display:
        ### display the original image
        frame = 1
        ds9.mtv(exposure, frame=frame, title="Original Image"); frame+=1


    ### Set up the schema
    schema = afwTable.SourceTable.makeMinimalSchema()
    schema.setVersion(0)

    
    ### Create the detection task
    config = SourceDetectionTask.ConfigClass()
    config.reEstimateBackground = False
    detectionTask = SourceDetectionTask(config=config, schema=schema)

    ### create the measurement task
    config = SourceMeasurementTask.ConfigClass()
    
    ### algMetadata is used to return info on the active algorithms
    algMetadata = dafBase.PropertyList()

    ### Set up which algorithms you want to run
    config.algorithms.names.clear()
    for alg in ["shape.sdss", "flux.sinc", "flux.aperture", "flux.gaussian", "flux.psf"]:
        config.algorithms.names.add(alg)

    config.algorithms["flux.aperture"].radii = [1, 2, 4, 8, 16] # pixels
    
    ### Need to un-set some of the slots if we're not using them.
    ### If you include them in the alg list above, then you don't
    ###need to unset these quantities. 
    #config.slots.instFlux = None # flux.gaussian
    #config.slots.modelFlux = None # flux.gaussian
    #config.slots.psfFlux = None # flux.psf

    measureTask = SourceMeasurementTask(schema, algMetadata, config=config)
    

    ### Create the output table
    tab = afwTable.SourceTable.make(schema)

    ### uncomments this to see what algorithms have gone into the schema
    #print schema
    
    ### Process the data
    print "*** running detection task..."
    sources = detectionTask.run(tab, exposure, sigma=5).sources
    print "*** running measure task..."
    measureTask.measure(exposure, sources)

    if display:
        ### Plot the results
        ds9.mtv(exposure, frame=frame, title="Measured Sources")
        with ds9.Buffering():
            for s in sources:
                xy = s.getCentroid()
                ds9.dot('+', *xy, ctype=ds9.CYAN if s.get("flags.negative") else ds9.GREEN, frame=frame)
                ds9.dot(s.getShape(), *xy, ctype=ds9.RED, frame=frame)



    print sources[0]
    
    
    ### Look at some of the information measured.
    ### TODO: add more useful quantities to this. 
    centroids = []
    for i in range(len(sources)):
        record = sources[i]
        centroid = record.getCentroid() #Returns a Point object containing the measured x and y.
        centroidErr = record.getCentroid()#Returns the 2x2 symmetric covariance matrix, with rows and columns ordered (x, y)

        
        ### quantities from the SdssShape class, calculated because we specified shape.sdss
        ixx = record.getIxx()
        iyy = record.getIyy() 
        ixy = record.getIxy() 

        centroids.append(centroid)
        
    print "first centroid:", centroids[0]
def detectAndMeasureWithDM():

    ### what file are you going to look at? This should be in fits format.
    ### The test image included in this example contains stars and galaxies in the center only. 
    imagefile = "test_image_stars.fits"
    
    ### open the file in the stack format
    exposure = afwImage.ExposureF(imagefile)
    im = exposure.getMaskedImage().getImage()

    ### display the original image
    frame = 0
    ds9.mtv(exposure, frame=frame, title="Original Image"); frame+=1



    ### Subtract background. 
    ### To do this, we'll set up a grid of 64x64 pixel areas across th eimage
    ### Fit the second moment of the pixels in each (which should be bg-dominated) and a fit a smooth function
    ### Subtract this function. 
    print "** subtracting background"
    #back_size = 256 ## dunno what this is
    #back_ctrl = afwMath.BackgroundControl(im.getWidth()//back_size+1, im.getHeight()//back_size +1)
    #back_obj = afwMath.makeBackground(im, back_ctrl)
    #im -=back_obj.getImageF("LINEAR")
    
    im -= float(np.median(im.getArray()))
    ds9.mtv(exposure, frame=frame, title="Background removed"); frame+=1

    ### Set up the schema
    schema = afwTable.SourceTable.makeMinimalSchema()
    schema.setVersion(0)

    
    ### Create the detection task
    config = SourceDetectionTask.ConfigClass()
    config.reEstimateBackground = False
    detectionTask = SourceDetectionTask(config=config, schema=schema)

    ### create the measurement task
    config = SourceMeasurementTask.ConfigClass()
    config.slots.psfFlux = "flux.sinc"  # use of the psf flux is hardcoded in secondMomentStarSelector
    measureTask = SourceMeasurementTask(schema, config=config)
    
    ### Create the measurePsf task
    config = MeasurePsfTask.ConfigClass()
    starSelector = config.starSelector.apply()
    starSelector.name = "objectSize"
    #starSelector.config.badFlags = ["flags.pixel.edge",  "flags.pixel.cr.center",
    #                                "flags.pixel.interpolated.center", "flags.pixel.saturated.center"]
    psfDeterminer = config.psfDeterminer.apply()
    psfDeterminer.config.sizeCellX = 128
    psfDeterminer.config.sizeCellY = 128
    psfDeterminer.config.nStarPerCell = 1
    psfDeterminer.config.spatialOrder = 1
    psfDeterminer.config.nEigenComponents = 3
    measurePsfTask = MeasurePsfTask(config=config, schema=schema)

    ### Create the output table
    tab = afwTable.SourceTable.make(schema)


    lsstDebug.getInfo(MeasurePsfTask).display=True
    
    ### Process the data
    print "*** running detection task..."
    sources = detectionTask.run(tab, exposure, sigma=2).sources
    print "*** running measure task..."
    measureTask.measure(exposure, sources)
    print "*** running measurePsf task..."
    result = measurePsfTask.run(exposure, sources)
    
    psf = result.psf
    cellSet = result.cellSet

    ### Look at the psf
    psfIm = psf.computeImage()
    ds9.mtv(psfIm, frame=frame, title = "Psf Image"); frame+=1

    ### render it on a grid
    import lsst.meas.algorithms.utils as measUtils
    cellSet = result.cellSet
    measUtils.showPsfMosaic(exposure, psf=psf, frame=frame); frame += 1
    
    with ds9.Buffering():
        for s in sources:
            xy = s.getCentroid()
            ds9.dot('+', *xy, ctype=ds9.GREEN, frame=frame)
            if s.get("calib.psf.candidate"):
                ds9.dot('x', *xy, ctype=ds9.YELLOW, frame=frame)
            if s.get("calib.psf.used"):
                ds9.dot('o', *xy, size=4, ctype=ds9.RED, frame=frame)
               

    """
Exemple #21
0
def run(display=False):
    exposure = loadData()
    schema = afwTable.SourceTable.makeMinimalSchema()
    #
    # Create the detection task
    #
    config = SourceDetectionTask.ConfigClass()
    config.thresholdPolarity = "both"
    config.background.isNanSafe = True
    config.thresholdValue = 3
    detectionTask = SourceDetectionTask(config=config, schema=schema)
    #
    # And the measurement Task
    #
    config = SingleFrameMeasurementTask.ConfigClass()

    config.algorithms.names = [
        "base_SdssCentroid", "base_SdssShape", "base_CircularApertureFlux"
    ]
    config.algorithms["base_CircularApertureFlux"].radii = [
        1, 2, 4, 8, 12, 16
    ]  # pixels

    config.slots.gaussianFlux = None
    config.slots.modelFlux = None
    config.slots.psfFlux = None

    algMetadata = dafBase.PropertyList()
    measureTask = SingleFrameMeasurementTask(schema,
                                             algMetadata=algMetadata,
                                             config=config)
    radii = algMetadata.getArray("BASE_CIRCULARAPERTUREFLUX_RADII")
    #
    # Create the output table
    #
    tab = afwTable.SourceTable.make(schema)
    #
    # Process the data
    #
    result = detectionTask.run(tab, exposure)

    sources = result.sources

    print("Found %d sources (%d +ve, %d -ve)" %
          (len(sources), result.fpSets.numPos, result.fpSets.numNeg))

    measureTask.run(sources, exposure)
    if display:  # display image (see also --debug argparse option)
        afwDisplay.setDefaultMaskTransparency(75)
        frame = 1
        disp = afwDisplay.Display(frame=frame)
        disp.mtv(exposure)

        with disp.Buffering():
            for s in sources:
                xy = s.getCentroid()
                disp.dot('+',
                         *xy,
                         ctype=afwDisplay.CYAN
                         if s.get("flags_negative") else afwDisplay.GREEN)
                disp.dot(s.getShape(), *xy, ctype=afwDisplay.RED)

                for radius in radii:
                    disp.dot('o', *xy, size=radius, ctype=afwDisplay.YELLOW)
Exemple #22
0
def run(config, inputFiles, weightFiles=None, varianceFiles=None,
        returnCalibSources=False, display=False, verbose=False):
    #
    # Create the tasks
    #
    schema = afwTable.SourceTable.makeMinimalSchema()
    algMetadata = dafBase.PropertyList()
    
    calibrateTask =         CalibrateTask(config=config.calibrate)

    sourceDetectionTask =   SourceDetectionTask(config=config.detection, schema=schema)
    if config.doDeblend:
        if SourceDeblendTask:
            sourceDeblendTask = SourceDeblendTask(config=config.deblend, schema=schema)
        else:
            print >> sys.stderr, "Failed to import lsst.meas.deblender;  setting doDeblend = False"
            config.doDeblend = False

    sourceMeasurementTask = SingleFrameMeasurementTask(config=config.measurement,
                                                       schema=schema, algMetadata=algMetadata)

    exposureDict = {}; calibSourcesDict = {}; sourcesDict = {}
    
    for inputFile, weightFile, varianceFile in zip(inputFiles, weightFiles, varianceFiles):
        #
        # Create the output table
        #
        tab = afwTable.SourceTable.make(schema)
        #
        # read the data
        #
        if verbose:
            print "Reading %s" % inputFile
            
        exposure = makeExposure(inputFile, weightFile, varianceFile,
                                config.badPixelValue, config.variance, verbose)

        #
        # process the data
        #
        calibSources = None                 # sources used to calibrate the frame (photom, astrom, psf)
        if config.doCalibrate:
            result = calibrateTask.run(exposure)
            exposure, sources = result.exposure, result.sources

            if returnCalibSources:
                calibSources = sources
        else:
            if not exposure.getPsf():
                calibrateTask.installInitialPsf(exposure)

        if config.edgeRolloff.applyModel:
            if verbose:
                print "Adding edge rolloff distortion to the exposure WCS"
            addEdgeRolloffDistortion(exposure, config.edgeRolloff)

        exposureDict[inputFile] = exposure
        calibSourcesDict[inputFile] = calibSources

        result = sourceDetectionTask.run(tab, exposure)
        sources = result.sources
        sourcesDict[inputFile] = sources

        if config.doDeblend:
            sourceDeblendTask.run(exposure, sources, exposure.getPsf())

        sourceMeasurementTask.measure(exposure, sources)

        if verbose:
            print "Detected %d objects" % len(sources)

        if display:                         # display on ds9 (see also --debug argparse option)
            if algMetadata.exists("base_CircularApertureFlux_radii"):
                radii = algMetadata.get("base_CircularApertureFlux_radii")
            else:
                radii = None

            frame = 1
            ds9.mtv(exposure, title=os.path.split(inputFile)[1], frame=frame)

            with ds9.Buffering():
                for s in sources:
                    xy = s.getCentroid()
                    ds9.dot('+', *xy, ctype=ds9.CYAN if s.get("flags_negative") else ds9.GREEN, frame=frame)
                    ds9.dot(s.getShape(), *xy, ctype=ds9.RED, frame=frame)

                    if radii:
                        for radius in radii:
                            ds9.dot('o', *xy, size=radius, ctype=ds9.YELLOW, frame=frame)

    return exposureDict, calibSourcesDict, sourcesDict
def run(config, inputFiles, weightFiles=None, varianceFiles=None,
        returnCalibSources=False, displayResults=[], verbose=False):
    #
    # Create the tasks
    #
    schema = afwTable.SourceTable.makeMinimalSchema()
    algMetadata = dafBase.PropertyList()

    isrTask = IsrTask(config=config.isr)
    calibrateTask =         CalibrateTask(config=config.calibrate)
    sourceDetectionTask =   SourceDetectionTask(config=config.detection, schema=schema)
    if config.doDeblend:
        if SourceDeblendTask:
            sourceDeblendTask = SourceDeblendTask(config=config.deblend, schema=schema)
        else:
            print >> sys.stderr, "Failed to import lsst.meas.deblender;  setting doDeblend = False"
            config.doDeblend = False

    sourceMeasurementTask = SingleFrameMeasurementTask(config=config.measurement,
                                                       schema=schema, algMetadata=algMetadata)
    sourceMeasurementTask.config.doApplyApCorr = 'yes'
    #
    # Add fields needed to identify stars while calibrating
    #
    keysToCopy = [(schema.addField(afwTable.Field["Flag"]("calib_detected",
                                                          "Source was detected by calibrate")), None)]
    for key in calibrateTask.getCalibKeys():
        keysToCopy.append((schema.addField(calibrateTask.schema.find(key).field), key))

    exposureDict = {}; calibSourcesDict = {}; sourcesDict = {}

    for inputFile, weightFile, varianceFile in zip(inputFiles, weightFiles, varianceFiles):
        #
        # Create the output table
        #
        tab = afwTable.SourceTable.make(schema)
        #
        # read the data
        #
        if verbose:
            print "Reading %s" % inputFile

        exposure = makeExposure(inputFile, weightFile, varianceFile,
                                config.badPixelValue, config.variance)
        #
        if config.interpPlanes:
            import lsst.ip.isr as ipIsr
            defects = ipIsr.getDefectListFromMask(exposure.getMaskedImage(), config.interpPlanes,
                                                  growFootprints=0)

            isrTask.run(exposure, defects=defects)
        #
        # process the data
        #
        if config.doCalibrate:
            result = calibrateTask.run(exposure)
            exposure, calibSources = result.exposure, result.sources
        else:
            calibSources = None
            if not exposure.getPsf():
                calibrateTask.installInitialPsf(exposure)

        exposureDict[inputFile] = exposure
        calibSourcesDict[inputFile] = calibSources if returnCalibSources else None

        result = sourceDetectionTask.run(tab, exposure)
        sources = result.sources
        sourcesDict[inputFile] = sources

        if config.doDeblend:
            sourceDeblendTask.run(exposure, sources, exposure.getPsf())

        sourceMeasurementTask.measure(exposure, sources)

        if verbose:
            print "Detected %d objects" % len(sources)

        propagateCalibFlags(keysToCopy, calibSources, sources)

        if displayResults:              # display results of processing (see also --debug argparse option)
            showApertures = "showApertures".upper() in displayResults
            showShapes = "showShapes".upper() in displayResults

            display = afwDisplay.getDisplay(frame=1)

            if algMetadata.exists("base_CircularApertureFlux_radii"):
                radii = algMetadata.get("base_CircularApertureFlux_radii")
            else:
                radii = []

            display.mtv(exposure, title=os.path.split(inputFile)[1])

            with display.Buffering():
                for s in sources:
                    xy = s.getCentroid()
                    display.dot('+', *xy,
                                ctype=afwDisplay.CYAN if s.get("flags_negative") else afwDisplay.GREEN)

                    if showShapes:
                        display.dot(s.getShape(), *xy, ctype=afwDisplay.RED)

                    if showApertures:
                        for radius in radii:
                            display.dot('o', *xy, size=radius, ctype=afwDisplay.YELLOW)

    return exposureDict, calibSourcesDict, sourcesDict
Exemple #24
0
def run(config,
        inputFiles,
        weightFiles=None,
        varianceFiles=None,
        returnCalibSources=False,
        displayResults=[],
        verbose=False):
    #
    # Create the tasks
    #
    schema = afwTable.SourceTable.makeMinimalSchema()
    algMetadata = dafBase.PropertyList()

    isrTask = IsrTask(config=config.isr)
    charImageTask = CharacterizeImageTask(None, config=config.charImage)
    sourceDetectionTask = SourceDetectionTask(config=config.detection,
                                              schema=schema)
    if config.doDeblend:
        if SourceDeblendTask:
            sourceDeblendTask = SourceDeblendTask(config=config.deblend,
                                                  schema=schema)
        else:
            print >> sys.stderr, "Failed to import lsst.meas.deblender;  setting doDeblend = False"
            config.doDeblend = False
    sourceMeasurementTask = SingleFrameMeasurementTask(
        schema=schema, config=config.measurement, algMetadata=algMetadata)

    keysToCopy = []
    for key in [
            charImageTask.measurePsf.reservedKey,
            charImageTask.measurePsf.usedKey,
    ]:
        keysToCopy.append(
            (schema.addField(charImageTask.schema.find(key).field), key))

    exposureDict = {}
    calibSourcesDict = {}
    sourcesDict = {}

    for inputFile, weightFile, varianceFile in zip(inputFiles, weightFiles,
                                                   varianceFiles):
        #
        # Create the output table
        #
        tab = afwTable.SourceTable.make(schema)
        #
        # read the data
        #
        if verbose:
            print "Reading %s" % inputFile

        exposure = makeExposure(inputFile, weightFile, varianceFile,
                                config.badPixelValue, config.variance)
        #
        if config.interpPlanes:
            import lsst.ip.isr as ipIsr
            defects = ipIsr.getDefectListFromMask(exposure.getMaskedImage(),
                                                  config.interpPlanes,
                                                  growFootprints=0)

            isrTask.run(exposure, defects=defects)
        #
        # process the data
        #
        if config.doCalibrate:
            result = charImageTask.characterize(exposure)
            exposure, calibSources = result.exposure, result.sourceCat
        else:
            calibSources = None
            if not exposure.getPsf():
                charImageTask.installSimplePsf.run(exposure)

        exposureDict[inputFile] = exposure
        calibSourcesDict[
            inputFile] = calibSources if returnCalibSources else None

        result = sourceDetectionTask.run(tab, exposure)
        sources = result.sources
        sourcesDict[inputFile] = sources

        if config.doDeblend:
            sourceDeblendTask.run(exposure, sources)

        sourceMeasurementTask.measure(exposure, sources)

        if verbose:
            print "Detected %d objects" % len(sources)

        propagatePsfFlags(keysToCopy, calibSources, sources)

        if displayResults:  # display results of processing (see also --debug argparse option)
            showApertures = "showApertures".upper() in displayResults
            showPSFs = "showPSFs".upper() in displayResults
            showShapes = "showShapes".upper() in displayResults

            display = afwDisplay.getDisplay(frame=1)

            if algMetadata.exists("base_CircularApertureFlux_radii"):
                radii = algMetadata.get("base_CircularApertureFlux_radii")
            else:
                radii = []

            display.mtv(exposure, title=os.path.split(inputFile)[1])

            with display.Buffering():
                for s in sources:
                    xy = s.getCentroid()
                    display.dot('+',
                                *xy,
                                ctype=afwDisplay.CYAN if
                                s.get("flags_negative") else afwDisplay.GREEN)

                    if showPSFs and (s.get("calib_psfUsed")
                                     or s.get("calib_psfReserved")):
                        display.dot(
                            'o',
                            *xy,
                            size=10,
                            ctype=afwDisplay.GREEN
                            if s.get("calib_psfUsed") else afwDisplay.YELLOW)

                    if showShapes:
                        display.dot(s.getShape(), *xy, ctype=afwDisplay.RED)

                    if showApertures:
                        for radius in radii:
                            display.dot('o',
                                        *xy,
                                        size=radius,
                                        ctype=afwDisplay.YELLOW)

    return exposureDict, calibSourcesDict, sourcesDict
Exemple #25
0
def run(display=False):
    exposure = loadData()
    schema = afwTable.SourceTable.makeMinimalSchema()
    #
    # Create the detection task
    #
    config = SourceDetectionTask.ConfigClass()
    config.thresholdPolarity = "both"
    config.background.isNanSafe = True
    config.thresholdValue = 3
    detectionTask = SourceDetectionTask(config=config, schema=schema)
    #
    # And the measurement Task
    #
    config = SingleFrameMeasurementTask.ConfigClass()
    config.plugins.names.clear()
    for plugin in [
            "base_SdssCentroid", "base_SdssShape", "base_CircularApertureFlux",
            "base_GaussianFlux"
    ]:
        config.plugins.names.add(plugin)
    config.slots.psfFlux = None
    config.slots.apFlux = "base_CircularApertureFlux_3_0"

    measureTask = SingleFrameMeasurementTask(schema, config=config)

    #
    # Print the schema the configuration produced
    #
    print schema

    #
    # Create the output table
    #
    tab = afwTable.SourceTable.make(schema)
    #
    # Process the data
    #
    result = detectionTask.run(tab, exposure)

    sources = result.sources

    print "Found %d sources (%d +ve, %d -ve)" % (
        len(sources), result.fpSets.numPos, result.fpSets.numNeg)

    measureTask.run(sources, exposure)
    if display:  # display on ds9 (see also --debug argparse option)
        frame = 1
        ds9.mtv(exposure, frame=frame)

        with ds9.Buffering():
            for s in sources:
                xy = s.getCentroid()
                ds9.dot(
                    '+',
                    *xy,
                    ctype=ds9.CYAN if s.get("flags_negative") else ds9.GREEN,
                    frame=frame)
                ds9.dot(s.getShape(), *xy, ctype=ds9.RED, frame=frame)
                ds9.dot(
                    'o',
                    *xy,
                    size=config.plugins["base_CircularApertureFlux"].radii[0],
                    ctype=ds9.YELLOW,
                    frame=frame)