示例#1
0
def run():
    if len(sys.argv) < 2:
        srcExposure = afwImage.ExposureF(InputExposurePath)
        if WarpSubregion:
            bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0),
                                 afwGeom.Extent2I(2000, 2000))
            srcExposure = afwImage.ExposureF(srcExposure, bbox, afwImage.LOCAL,
                                             False)
    else:
        srcExposure = afwImage.ExposureF(sys.argv[1])
    srcMaskedImage = srcExposure.getMaskedImage()
    srcMetadata = afwImage.DecoratedImageF(InputExposurePath).getMetadata()
    srcWcs = afwGeom.SkyWcs(srcMetadata)
    srcDim = srcExposure.getDimensions()
    srcCtrPos = afwGeom.Box2D(srcMaskedImage.getBBox()).getCenter()
    srcCtrSky = srcWcs.applyForward(srcCtrPos)
    srcScale = srcWcs.getPixelScale()

    # make the destination exposure small enough that even after rotation and offset
    # (by reasonable amounts) there are no edge pixels
    destDim = afwGeom.Extent2I(*[int(sd * 0.5) for sd in srcDim])
    destMaskedImage = afwImage.MaskedImageF(destDim)
    destCrPix = afwGeom.Box2D(destMaskedImage.getBBox()).getCenter()

    maskKernelName = ""
    cacheSize = 0

    print("Warping", InputExposurePath)
    print("Source (sub)image size:", srcDim)
    print("Destination image size:", destDim)
    print()

    print(
        "test# interp  scaleFac    destSkyOff    rotAng   kernel   goodPix time/iter"
    )
    print(
        '       (pix)              (bear°, len")    (deg)                      (sec)'
    )
    testNum = 1
    for interpLength in (0, 1, 5, 10):
        for scaleFac in (1.2, ):
            destScale = srcScale / scaleFac
            for offsetOrientDegLenArcsec in ((
                    0.0, 0.0), ):  # ((0.0, 0.0), (-35.0, 10.5)):
                # offset (bearing, length) from sky at center of source to sky at center of dest
                offset = (offsetOrientDegLenArcsec[0] * afwGeom.degrees,
                          offsetOrientDegLenArcsec[1] * afwGeom.arcseconds)
                destCtrSky = srcCtrSky.offset(*offset)
                for rotAngDeg, kernelName in (
                    (0.0, "bilinear"),
                    (0.0, "lanczos2"),
                    (0.0, "lanczos3"),
                    (45.0, "lanczos3"),
                ):
                    warpingControl = afwMath.WarpingControl(
                        kernelName,
                        maskKernelName,
                        cacheSize,
                        interpLength,
                    )
                    destWcs = afwGeom.SkyWcs(
                        crpix=destCrPix,
                        crval=destCtrSky,
                        cdMatrix=afwGeom.makeCdMatrix(scale=destScale,
                                                      orientation=rotAngDeg *
                                                      afwGeom.degrees,
                                                      flipX=False))
                    destToSrc = destWcs.then(srcWcs.getInverse())
                    dTime, nIter, goodPix = timeWarp(destMaskedImage,
                                                     srcMaskedImage, destToSrc,
                                                     warpingControl)
                    print(
                        "%4d  %5d  %8.1f  %6.1f, %6.1f  %7.1f %10s %8d %6.2f" %
                        (testNum, interpLength, scaleFac,
                         offsetOrientDegLenArcsec[0],
                         offsetOrientDegLenArcsec[1], rotAngDeg, kernelName,
                         goodPix, dTime / float(nIter)))

                    if SaveImages:
                        destMaskedImage.writeFits(
                            "warpedMaskedImage%03d.fits" % (testNum, ))
                    testNum += 1
示例#2
0
 def testMtv(self):
     """Test basic image display"""
     exp = afwImage.ExposureF(self.fileName)
     self.display0.mtv(exp, title="parent")
    def setUp(self):
        self.configAL = ipDiffim.ImagePsfMatchTask.ConfigClass()
        self.configAL.kernel.name = "AL"
        self.subconfigAL = self.configAL.kernel.active

        self.configDF = ipDiffim.ImagePsfMatchTask.ConfigClass()
        self.configDF.kernel.name = "DF"
        self.subconfigDF = self.configDF.kernel.active

        self.configDFr = ipDiffim.ImagePsfMatchTask.ConfigClass()
        self.configDFr.kernel.name = "DF"
        self.subconfigDFr = self.configDFr.kernel.active

        self.subconfigDF.useRegularization = False
        self.subconfigDFr.useRegularization = True
        self.subconfigDFr.lambdaValue = 1000.0

        self.subconfigAL.fitForBackground = fitForBackground
        self.subconfigDF.fitForBackground = fitForBackground
        self.subconfigDFr.fitForBackground = fitForBackground

        self.subconfigAL.constantVarianceWeighting = constantVarianceWeighting
        self.subconfigDF.constantVarianceWeighting = constantVarianceWeighting
        self.subconfigDFr.constantVarianceWeighting = constantVarianceWeighting

        self.kListAL = ipDiffim.makeKernelBasisList(self.subconfigAL)
        self.kListDF = ipDiffim.makeKernelBasisList(self.subconfigDF)
        self.kListDFr = ipDiffim.makeKernelBasisList(self.subconfigDFr)
        self.hMatDFr = ipDiffim.makeRegularizationMatrix(
            pexConfig.makePolicy(self.subconfigDFr))

        self.bskvAL = ipDiffim.BuildSingleKernelVisitorF(
            self.kListAL, pexConfig.makePolicy(self.subconfigAL))
        self.bskvDF = ipDiffim.BuildSingleKernelVisitorF(
            self.kListDF, pexConfig.makePolicy(self.subconfigDF))
        self.bskvDFr = ipDiffim.BuildSingleKernelVisitorF(
            self.kListDFr, pexConfig.makePolicy(self.subconfigDF),
            self.hMatDFr)

        defSciencePath = globals()['defSciencePath']
        defTemplatePath = globals()['defTemplatePath']
        if defSciencePath and defTemplatePath:
            self.scienceExposure = afwImage.ExposureF(defSciencePath)
            self.templateExposure = afwImage.ExposureF(defTemplatePath)
        else:
            defDataDir = lsst.utils.getPackageDir('afwdata')
            defSciencePath = os.path.join(defDataDir, "DC3a-Sim", "sci",
                                          "v26-e0", "v26-e0-c011-a00.sci.fits")
            defTemplatePath = os.path.join(defDataDir, "DC3a-Sim", "sci",
                                           "v5-e0", "v5-e0-c011-a00.sci.fits")

            self.scienceExposure = afwImage.ExposureF(defSciencePath)
            self.templateExposure = afwImage.ExposureF(defTemplatePath)
            warper = afwMath.Warper.fromConfig(self.subconfigAL.warpingConfig)
            self.templateExposure = warper.warpExposure(
                self.scienceExposure.getWcs(),
                self.templateExposure,
                destBBox=self.scienceExposure.getBBox())

        #
        tmi = self.templateExposure.getMaskedImage()
        smi = self.scienceExposure.getMaskedImage()

        # Object detection
        detConfig = self.subconfigAL.detectionConfig
        detPolicy = pexConfig.makePolicy(detConfig)
        detPolicy.set("detThreshold", 50.)
        detPolicy.set("detThresholdType", "stdev")
        detPolicy.set("detOnTemplate", False)
        kcDetect = ipDiffim.KernelCandidateDetectionF(detPolicy)
        kcDetect.apply(tmi, smi)
        self.footprints = kcDetect.getFootprints()
示例#4
0
    def testPeakLikelihoodFlux(self):
        """Test measurement with PeakLikelihoodFlux."""
        # make and measure a series of exposures containing just one star, approximately centered
        bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(100, 101))
        kernelWidth = 35
        var = 100
        fwhm = 3.0
        sigma = fwhm / FwhmPerSigma
        convolutionControl = afwMath.ConvolutionControl()
        psf = afwDetection.GaussianPsf(kernelWidth, kernelWidth, sigma)
        psfKernel = psf.getLocalKernel()
        psfImage = psf.computeKernelImage()
        sumPsfSq = np.sum(psfImage.getArray()**2)
        psfSqArr = psfImage.getArray()**2

        for flux in (1000, 10000):
            ctrInd = afwGeom.Point2I(50, 51)
            ctrPos = afwGeom.Point2D(ctrInd)

            kernelBBox = psfImage.getBBox()
            kernelBBox.shift(afwGeom.Extent2I(ctrInd))

            # compute predicted flux error
            unshMImage = makeFakeImage(bbox, [ctrPos], [flux], fwhm, var)

            # filter image by PSF
            unshFiltMImage = afwImage.MaskedImageF(unshMImage.getBBox())
            afwMath.convolve(unshFiltMImage, unshMImage, psfKernel,
                             convolutionControl)

            # compute predicted flux = value of image at peak / sum(PSF^2)
            # this is a sanity check of the algorithm, as much as anything
            predFlux = unshFiltMImage.getImage().get(ctrInd[0],
                                                     ctrInd[1]) / sumPsfSq
            self.assertLess(abs(flux - predFlux), flux * 0.01)

            # compute predicted flux error based on filtered pixels
            # = sqrt(value of filtered variance at peak / sum(PSF^2)^2)
            predFluxErr = math.sqrt(unshFiltMImage.getVariance().get(
                ctrInd[0], ctrInd[1])) / sumPsfSq

            # compute predicted flux error based on unfiltered pixels
            # = sqrt(sum(unfiltered variance * PSF^2)) / sum(PSF^2)
            # and compare to that derived from filtered pixels;
            # again, this is a test of the algorithm
            varView = afwImage.ImageF(unshMImage.getVariance(), kernelBBox)
            varArr = varView.getArray()
            unfiltPredFluxErr = math.sqrt(np.sum(varArr * psfSqArr)) / sumPsfSq
            self.assertLess(abs(unfiltPredFluxErr - predFluxErr),
                            predFluxErr * 0.01)

            for fracOffset in (afwGeom.Extent2D(0, 0),
                               afwGeom.Extent2D(0.2, -0.3)):
                adjCenter = ctrPos + fracOffset
                if fracOffset == afwGeom.Extent2D(0, 0):
                    maskedImage = unshMImage
                    filteredImage = unshFiltMImage
                else:
                    maskedImage = makeFakeImage(bbox, [adjCenter], [flux],
                                                fwhm, var)
                    # filter image by PSF
                    filteredImage = afwImage.MaskedImageF(
                        maskedImage.getBBox())
                    afwMath.convolve(filteredImage, maskedImage, psfKernel,
                                     convolutionControl)

                exp = afwImage.makeExposure(filteredImage)
                exp.setPsf(psf)
                control = measBase.PeakLikelihoodFluxControl()
                plugin, cat = makePluginAndCat(
                    measBase.PeakLikelihoodFluxAlgorithm,
                    "test",
                    control,
                    centroid="centroid")
                source = cat.makeRecord()
                source.set("centroid_x", adjCenter.getX())
                source.set("centroid_y", adjCenter.getY())
                plugin.measure(source, exp)
                measFlux = source.get("test_flux")
                measFluxErr = source.get("test_fluxSigma")
                self.assertLess(abs(measFlux - flux), flux * 0.003)

                self.assertLess(abs(measFluxErr - predFluxErr),
                                predFluxErr * 0.2)

                # try nearby points and verify that the flux is smaller;
                # this checks that the sub-pixel shift is performed in the correct direction
                for dx in (-0.2, 0, 0.2):
                    for dy in (-0.2, 0, 0.2):
                        if dx == dy == 0:
                            continue
                        offsetCtr = afwGeom.Point2D(adjCenter[0] + dx,
                                                    adjCenter[1] + dy)
                        source = cat.makeRecord()
                        source.set("centroid_x", offsetCtr.getX())
                        source.set("centroid_y", offsetCtr.getY())
                        plugin.measure(source, exp)
                        self.assertLess(source.get("test_flux"), measFlux)

        # source so near edge of image that PSF does not overlap exposure should result in failure
        for edgePos in (
            (1, 50),
            (50, 1),
            (50, bbox.getHeight() - 1),
            (bbox.getWidth() - 1, 50),
        ):
            source = cat.makeRecord()
            source.set("centroid_x", edgePos[0])
            source.set("centroid_y", edgePos[1])
            with self.assertRaises(lsst.pex.exceptions.RangeError):
                plugin.measure(source, exp)

        # no PSF should result in failure: flags set
        noPsfExposure = afwImage.ExposureF(filteredImage)
        source = cat.makeRecord()
        source.set("centroid_x", edgePos[0])
        source.set("centroid_y", edgePos[1])
        with self.assertRaises(lsst.pex.exceptions.InvalidParameterError):
            plugin.measure(source, noPsfExposure)
示例#5
0
    def assembleCcd(self, assembleInput):
        """!Assemble a set of amps into a single CCD size image
        @param[in] assembleInput -- Either a dictionary of amp lsst.afw.image.Exposures or a single
                                    lsst.afw.image.Exposure containing all raw
                                    amps.  If a dictionary of amp exposures,
                                    the key should be the amp name.
        @return assembledCcd -- An lsst.afw.image.Exposure of the assembled amp sections.

        @throws TypeError with the following string:

        <DL>
          <DT> Expected either a dictionary of amp exposures or a single raw exposure
          <DD> The input exposures to be assembled do not adhere to the required format.
        </DL>

        @throws RuntimeError with the following string:

        <DL>
          <DT> No ccd detector found
          <DD> The detector set on the input exposure is not set.
        </DL>
        """
        ccd = None
        if isinstance(assembleInput, dict):
            # assembleInput is a dictionary of amp name: amp exposure

            # Assume all amps have the same detector, so get the detector from an arbitrary amp
            ccd = next(iter(assembleInput.values())).getDetector()

            def getNextExposure(amp):
                return assembleInput[amp.getName()]
        elif hasattr(assembleInput, "getMaskedImage"):
            # assembleInput is a single exposure
            ccd = assembleInput.getDetector()

            def getNextExposure(amp):
                return assembleInput
        else:
            raise TypeError(
                "Expected either a dictionary of amp exposures or a single raw exposure"
            )

        if ccd is None:
            raise RuntimeError("No ccd detector found")

        if not self.config.doTrim:
            outBox = cameraGeomUtils.calcRawCcdBBox(ccd)
        else:
            outBox = ccd.getBBox()
        outExposure = afwImage.ExposureF(outBox)
        outMI = outExposure.getMaskedImage()

        if self.config.doTrim:
            assemble = cameraGeom.assembleAmplifierImage
        else:
            assemble = cameraGeom.assembleAmplifierRawImage

        for amp in ccd:
            inMI = getNextExposure(amp).getMaskedImage()
            assemble(outMI, inMI, amp)
        #
        # If we are returning an "untrimmed" image (with overscans and extended register) we
        # need to update the ampInfo table in the Detector as we've moved the amp images into
        # place in a single Detector image
        #
        if not self.config.doTrim:
            ccd = cameraGeom.makeUpdatedDetector(ccd)

        outExposure.setDetector(ccd)
        self.postprocessExposure(outExposure=outExposure,
                                 inExposure=getNextExposure(ccd[0]))

        return outExposure
示例#6
0
def getSkyMap(center_coord, width, height, filter, units, source, map_type):
    """Merge multiple patches from a SkyMap into a single image.
    This function takes advantage of the fact that all tracts in a SkyMap share
    the same WCS and should have identical pixels where they overlap.
    @center_coord: base coordinate of the box RA and Dec (minimum values, lower left corner)
    @width: in Pixel
    @height: in Pixels
    @filter: valid filter for the data set such as 'i', 'r', 'g'
    @units: 'pixel' or 'arcsecond' (defaults to 'pixel')
    @source: source for Butler, such as "/lsst7/releaseW13EP"
    @map_type: type of SkyMap, such as "deepCoadd_skyMap"
    """
    # Get the basic SkyMap information
    butler = lsst.daf.persistence.Butler(source)
    sky_map = butler.get(map_type)
    dest_tract_info = sky_map.findTract(center_coord)
    dest_wcs = dest_tract_info.getWcs()
    # Determine target area.
    if units != 'arcsecond' and units != 'pixel':
        units = 'pixel'
    dest_bbox = _bbox_for_coords(dest_wcs, center_coord, width, height, units)
    dest_corner_coords = [
        dest_wcs.pixelToSky(pixPos)
        for pixPos in afw_geom.Box2D(dest_bbox).getCorners()
    ]
    # Collect patches of the SkyMap that are in the target region.
    # Create source exposures from the patches within each tract
    # as all patches from a tract share a WCS.
    exposure_list = []
    tract_patch_list = sky_map.findTractPatchList(dest_corner_coords)
    for j, tract_patch in enumerate(tract_patch_list):
        tract_info = tract_patch[0]
        patch_list = tract_patch[1]
        log.info("tract_info[{}]={}".format(j, tract_info))
        log.info("patch_list[{}]={}".format(j, patch_list))
        src_wcs = tract_info.getWcs()
        src_bbox = afw_geom.Box2I()
        for patch_info in patch_list:
            src_bbox.include(patch_info.getOuterBBox())
        src_exposure = afw_image.ExposureF(src_bbox, src_wcs)  # blank, so far
        exposure_list.append(src_exposure)

        # load srcExposures with patches
        tract_id = tract_info.getId()
        for patch_info in patch_list:
            patch_index = patch_info.getIndex()
            patch_index_str = ','.join(str(i) for i in patch_index)
            log.info("butler.get dataId=filter:{}, tract:{}, "
                     "patch:{}".format(filter, tract_id, patch_index_str))
            patch_exposure = butler.get("deepCoadd",
                                        dataId={
                                            "filter": filter,
                                            "tract": tract_id,
                                            "patch": patch_index_str
                                        })
            src_view = afw_image.ExposureF(src_exposure,
                                           patch_exposure.getBBox())
            src_view_img = src_view.getMaskedImage()
            patch_img = patch_exposure.getMaskedImage()
            src_view_img[:] = patch_img

    # Copy the pixels from the source exposures to the destination exposures.
    dest_exposure_list = []
    for j, src_exposure in enumerate(exposure_list):
        src_image = src_exposure.getMaskedImage()
        src_wcs = src_exposure.getWcs()
        if j == 0:
            expo_bbox = dest_bbox  # dest_bbox only correct for first image
        else:
            # Determine the correct BBox (in pixels) for the current src_wcs
            ll_corner = afw_geom.Point2I(
                src_wcs.skyToPixel(dest_corner_coords[0]))
            ur_corner = afw_geom.Point2I(
                src_wcs.skyToPixel(dest_corner_coords[2]))
            # Handle negative values for in expo_bbox.
            if ll_corner.getX() < 0:
                ll_corner.setX(0)
            if ll_corner.getY() < 0:
                ll_corner.setY(0)
            if ur_corner.getX() < 0:
                ur_corner.setX(0)
                log.warn("getSkyMap negative X for ur_corner")
            if ur_corner.getY() < 0:
                ur_corner.setY(0)
                log.warn("getSkyMap negative Y for ur_corner")
            expo_bbox = afw_geom.Box2I(ll_corner, ur_corner)
        log.info("j={} expo_bbox={} sBBox={}".format(j, expo_bbox,
                                                     src_exposure.getBBox()))
        dest_exposure = afw_image.ExposureF(expo_bbox, src_wcs)
        dest_img = dest_exposure.getMaskedImage()
        begin_x = expo_bbox.getBeginX() - src_image.getX0()
        end_x = expo_bbox.getEndX() - src_image.getX0()
        begin_y = expo_bbox.getBeginY() - src_image.getY0()
        end_y = expo_bbox.getEndY() - src_image.getY0()

        new_width = src_exposure.getBBox().getEndX() - expo_bbox.getBeginX()
        new_height = src_exposure.getBBox().getEndY() - expo_bbox.getBeginY()

        # Do a final check to make sure that the we're not going past the end of src_image.
        src_img_len_x = src_image.getWidth()
        if end_x > src_img_len_x:
            new_width = src_img_len_x - begin_x
            end_x = src_img_len_x
        s_img_len_y = src_image.getHeight()
        if end_y > s_img_len_y:
            new_width = s_img_len_y - begin_y
            end_y = s_img_len_y

        log.debug("begin_x={} end_x={}".format(begin_x, end_x))
        log.debug("new_width{} = sBBox.EndX{} - sBBox.BeginX{}".format(
            new_width,
            src_exposure.getBBox().getEndX(), expo_bbox.getBeginX()))
        log.debug("begin_y={} end_y={}".format(begin_y, end_y))
        log.debug("new_height{} = sBBox.EndY{} - sBBox.BeginY{}".format(
            new_height,
            src_exposure.getBBox().getEndY(), expo_bbox.getBeginY()))
        dest_img[0:new_width, 0:new_height] = src_image[begin_x:end_x,
                                                        begin_y:end_y]
        dest_exposure_list.append(dest_exposure)

    # If there's only one exposure in the list (and there usually is) just return it.
    if len(dest_exposure_list) == 1:
        return dest_exposure_list[0]

    # Need to stitch together the multiple destination exposures.
    log.debug("getSkyMap stitching together multiple destExposures")
    warper_config = afw_math.WarperConfig()
    warper = afw_math.Warper.fromConfig(warper_config)
    stitched_exposure = stitch_exposures_good_pixel_copy(
        dest_wcs, dest_bbox, dest_exposure_list, warper)
    return stitched_exposure
示例#7
0
    def runModelType(self, fitForBackground):
        self.subconfig.fitForBackground = fitForBackground

        templateSubImage = afwImage.ExposureF(self.templateImage, self.bbox)
        scienceSubImage = afwImage.ExposureF(self.scienceImage, self.bbox)

        self.subconfig.spatialModelType = 'chebyshev1'
        psfmatch1 = ipDiffim.ImagePsfMatchTask(config=self.config)
        results1 = psfmatch1.subtractExposures(templateSubImage,
                                               scienceSubImage,
                                               doWarping=True)
        spatialKernel1 = results1.psfMatchingKernel
        backgroundModel1 = results1.backgroundModel

        self.subconfig.spatialModelType = 'polynomial'
        psfmatch2 = ipDiffim.ImagePsfMatchTask(config=self.config)
        results2 = psfmatch2.subtractExposures(templateSubImage,
                                               scienceSubImage,
                                               doWarping=True)
        spatialKernel2 = results2.psfMatchingKernel
        backgroundModel2 = results2.backgroundModel

        # Got the types right?
        self.assertTrue(spatialKernel1.getSpatialFunctionList()
                        [0].toString().startswith('Chebyshev1Function2'))
        self.assertTrue(spatialKernel2.getSpatialFunctionList()
                        [0].toString().startswith('PolynomialFunction2'))

        # First order term has zero spatial variation and sum = kernel sum
        kp1par0 = spatialKernel1.getSpatialFunctionList()[0].getParameters()
        kp2par0 = spatialKernel2.getSpatialFunctionList()[0].getParameters()
        self.assertAlmostEqual(kp1par0[0], kp2par0[0], delta=1e-5)
        for i in range(1, len(kp1par0)):
            self.assertAlmostEqual(kp1par0[i], 0.0, delta=1e-5)
            self.assertAlmostEqual(kp1par0[i], kp2par0[i], delta=1e-5)

        if fitForBackground:
            # Nterms (zeroth order model)
            self.assertEqual(backgroundModel1.getNParameters(), 1)
            self.assertEqual(backgroundModel2.getNParameters(), 1)

            # Same value of function coefficients (different to 0.001 level)
            self.assertAlmostEqual(backgroundModel1.getParameters()[0],
                                   backgroundModel2.getParameters()[0],
                                   delta=1e-3)

            # Functions evaluate to same value at origin (0.001 difference)
            self.assertAlmostEqual(backgroundModel1(0, 0),
                                   backgroundModel2(0, 0),
                                   delta=1e-3)

            # At at different location within image
            self.assertAlmostEqual(backgroundModel1(10, 10),
                                   backgroundModel2(10, 10),
                                   delta=1e-3)

        else:
            # More improtant is the kernel needs to be then same when realized at a coordinate
            kim1 = afwImage.ImageD(spatialKernel1.getDimensions())
            kim2 = afwImage.ImageD(spatialKernel2.getDimensions())
            ksum1 = spatialKernel1.computeImage(kim1, False, 0.0, 0.0)
            ksum2 = spatialKernel2.computeImage(kim2, False, 0.0, 0.0)
            self.assertAlmostEqual(ksum1, ksum2, delta=1e-5)
            for y in range(kim1.getHeight()):
                for x in range(kim1.getHeight()):
                    self.assertAlmostEqual(kim1[x, y, afwImage.LOCAL],
                                           kim2[x, y, afwImage.LOCAL],
                                           delta=1e-1)

            # Nterms (zeroth order)
            self.assertEqual(backgroundModel1.getNParameters(), 1)
            self.assertEqual(backgroundModel2.getNParameters(), 1)

            # Zero value in function
            self.assertAlmostEqual(backgroundModel1.getParameters()[0],
                                   0.0,
                                   delta=1e-7)
            self.assertAlmostEqual(backgroundModel2.getParameters()[0],
                                   0.0,
                                   delta=1e-7)

            # Function evaluates to zero
            self.assertAlmostEqual(backgroundModel1(0, 0), 0.0, delta=1e-7)
            self.assertAlmostEqual(backgroundModel2(0, 0), 0.0, delta=1e-7)

            # Spatially...
            self.assertAlmostEqual(backgroundModel1(10, 10), 0.0, delta=1e-7)
            self.assertAlmostEqual(backgroundModel2(10, 10), 0.0, delta=1e-7)
示例#8
0
 def testArchiveImports(self):
     # This file was saved with a Psf defined in testTableArchivesLib, so we'll only be able
     # to load it if the module-importer mechanism works.
     filename = os.path.join(testPath, "data", "archiveImportTest.fits")
     exposure = afwImage.ExposureF(filename)
     self.assertIsNotNone(exposure.getPsf())
def warpAndCoadd(coaddPath, exposureListPath, config):
    """Create a coadd by warping and psf-matching

    Inputs:
    - coaddPath: path to desired coadd; ovewritten if it exists
    - exposureListPath: a file containing a list of paths to input exposures;
        blank lines and lines that start with # are ignored
    - config: an instance of WarpAndCoaddConfig

    The first exposure in exposureListPath is used as the reference: all other exposures
    are warped to match to it.
    """
    weightPath = os.path.splitext(coaddPath)[0] + "_weight.fits"

    bbox = afwGeom.Box2I(
        afwGeom.Point2I(config.bboxMin[0], config.bboxMin[1]),
        afwGeom.Extent2I(config.bboxSize[0], config.bboxSize[1]),
    )
    print("SaveDebugImages =", config.saveDebugImages)
    print("bbox =", bbox)

    # process exposures
    accumGoodTime = 0
    coadd = None
    expNum = 0
    numExposuresInCoadd = 0
    numExposuresFailed = 0
    with file(exposureListPath, "rU") as infile:
        for exposurePath in infile:
            exposurePath = exposurePath.strip()
            if not exposurePath or exposurePath.startswith("#"):
                continue
            expNum += 1

            try:
                print("Processing exposure: %s" % (exposurePath,), file=sys.stderr)
                startTime = time.time()
                exposure = afwImage.ExposureF(exposurePath, 0, bbox, afwImage.LOCAL)
                if config.saveDebugImages:
                    exposure.writeFits("exposure%s.fits" % (expNum,))

                if not coadd:
                    print("Create warper and coadd with size and WCS matching the first/reference exposure",
                          file=sys.stderr)
                    warper = afwMath.Warper.fromConfig(config.warp)
                    coadd = coaddChiSq.Coadd.fromConfig(
                        bbox=exposure.getBBox(),
                        wcs=exposure.getWcs(),
                        config=config.coadd)
                    print("badPixelMask=", coadd.getBadPixelMask())

                    print("Add reference exposure to coadd (without warping)", file=sys.stderr)
                    coadd.addExposure(exposure)
                else:
                    print("Warp exposure", file=sys.stderr)
                    warpedExposure = warper.warpExposure(
                        destWcs=coadd.getWcs(),
                        srcExposure=exposure,
                        maxBBox=coadd.getBBox(),
                    )
                    if config.saveDebugImages:
                        warpedExposure.writeFits("warped%s.fits" % (expNum,))

                    print("Add warped exposure to coadd", file=sys.stderr)
                    coadd.addExposure(warpedExposure)

                    # ignore time for first exposure since nothing happens to it
                    deltaTime = time.time() - startTime
                    print("Elapsed time for processing exposure: %0.1f sec" % (deltaTime,), file=sys.stderr)
                    accumGoodTime += deltaTime
                numExposuresInCoadd += 1
            except Exception as e:
                print("Exposure %s failed: %s" % (exposurePath, e), file=sys.stderr)
                traceback.print_exc(file=sys.stderr)
                numExposuresFailed += 1
                continue

    coaddExposure = coadd.getCoadd()
    coaddExposure.writeFits(coaddPath)
    print("Wrote coadd: %s" % (coaddPath,), file=sys.stderr)
    weightMap = coadd.getWeightMap()
    weightMap.writeFits(weightPath)
    print("Wrote weightMap: %s" % (weightPath,), file=sys.stderr)

    print("Coadded %d exposures and failed %d" % (numExposuresInCoadd, numExposuresFailed), file=sys.stderr)
    if numExposuresInCoadd > 1:
        timePerGoodExposure = accumGoodTime / float(numExposuresInCoadd - 1)
        print("Processing speed: %.1f seconds/exposure (ignoring first and failed)" % (timePerGoodExposure,),
              file=sys.stderr)
示例#10
0
 def setUp(self):
     self.calexpOrig = afwImage.ExposureF(
         os.path.join(DATA_DIR, "ticket1738.fits"))
     self.calexp = afwImage.ExposureF(
         os.path.join(DATA_DIR, "ticket1738.fits"))
示例#11
0
    def run(self, exposure, referencePsfModel, kernelSum=1.0):
        """!Psf-match an exposure to a model Psf

        @param exposure: Exposure to Psf-match to the reference Psf model;
            it must return a valid PSF model via exposure.getPsf()
        @param referencePsfModel: The Psf model to match to (an lsst.afw.detection.Psf)
        @param kernelSum: A multipicative factor to apply to the kernel sum (default=1.0)

        @return
        - psfMatchedExposure: the Psf-matched Exposure.  This has the same parent bbox, Wcs, Calib and 
            Filter as the input Exposure but no Psf.  In theory the Psf should equal referencePsfModel but 
            the match is likely not exact.
        - psfMatchingKernel: the spatially varying Psf-matching kernel
        - kernelCellSet: SpatialCellSet used to solve for the Psf-matching kernel

        Raise a RuntimeError if the Exposure does not contain a Psf model
        """
        if not exposure.hasPsf():
            raise RuntimeError("exposure does not contain a Psf model")

        maskedImage = exposure.getMaskedImage()

        self.log.log(pexLog.Log.INFO, "compute Psf-matching kernel")
        kernelCellSet = self._buildCellSet(exposure, referencePsfModel)
        width, height = referencePsfModel.getLocalKernel().getDimensions()
        psfAttr1 = measAlg.PsfAttributes(exposure.getPsf(), width // 2,
                                         height // 2)
        psfAttr2 = measAlg.PsfAttributes(referencePsfModel, width // 2,
                                         height // 2)
        s1 = psfAttr1.computeGaussianWidth(
            psfAttr1.ADAPTIVE_MOMENT)  # gaussian sigma in pixels
        s2 = psfAttr2.computeGaussianWidth(
            psfAttr2.ADAPTIVE_MOMENT)  # gaussian sigma in pixels
        fwhm1 = s1 * sigma2fwhm  # science Psf
        fwhm2 = s2 * sigma2fwhm  # template Psf

        basisList = makeKernelBasisList(self.kConfig,
                                        fwhm1,
                                        fwhm2,
                                        metadata=self.metadata)
        spatialSolution, psfMatchingKernel, backgroundModel = self._solve(
            kernelCellSet, basisList)

        if psfMatchingKernel.isSpatiallyVarying():
            sParameters = num.array(psfMatchingKernel.getSpatialParameters())
            sParameters[0][0] = kernelSum
            psfMatchingKernel.setSpatialParameters(sParameters)
        else:
            kParameters = num.array(psfMatchingKernel.getKernelParameters())
            kParameters[0] = kernelSum
            psfMatchingKernel.setKernelParameters(kParameters)

        self.log.log(pexLog.Log.INFO,
                     "Psf-match science exposure to reference")
        psfMatchedExposure = afwImage.ExposureF(exposure.getBBox(),
                                                exposure.getWcs())
        psfMatchedExposure.setFilter(exposure.getFilter())
        psfMatchedExposure.setCalib(exposure.getCalib())
        psfMatchedMaskedImage = psfMatchedExposure.getMaskedImage()

        # Normalize the psf-matching kernel while convolving since its magnitude is meaningless
        # when PSF-matching one model to another.
        doNormalize = True
        afwMath.convolve(psfMatchedMaskedImage, maskedImage, psfMatchingKernel,
                         doNormalize)

        self.log.log(pexLog.Log.INFO, "done")
        return pipeBase.Struct(psfMatchedExposure=psfMatchedExposure,
                               psfMatchingKernel=psfMatchingKernel,
                               kernelCellSet=kernelCellSet,
                               metadata=self.metadata)
示例#12
0
    def run(self, snap0, snap1, defects=None):
        """Combine two snaps
        
        @param[in] snap0: snapshot exposure 0
        @param[in] snap1: snapshot exposure 1
        @defects[in] defect list (for repair task)
        @return a pipe_base Struct with fields:
        - exposure: snap-combined exposure
        - sources: detected sources, or None if detection not performed
        """
        # initialize optional outputs
        sources = None

        if self.config.doRepair:
            self.log.info("snapCombine repair")
            psf = self.makeInitialPsf(snap0, fwhmPix=self.config.repairPsfFwhm)
            snap0.setPsf(psf)
            snap1.setPsf(psf)
            self.repair.run(snap0, defects=defects, keepCRs=False)
            self.repair.run(snap1, defects=defects, keepCRs=False)

            repair0frame = getDebugFrame(self._display, "repair0")
            if repair0frame:
                getDisplay(repair0frame).mtv(snap0)
            repair1frame = getDebugFrame(self._display, "repair1")
            if repair1frame:
                getDisplay(repair1frame).mtv(snap1)

        if self.config.doDiffIm:
            if self.config.doPsfMatch:
                self.log.info("snapCombine psfMatch")
                diffRet = self.diffim.run(snap0, snap1, "subtractExposures")
                diffExp = diffRet.subtractedImage

                # Measure centroid and width of kernel; dependent on ticket #1980
                # Useful diagnostic for the degree of astrometric shift between snaps.
                diffKern = diffRet.psfMatchingKernel
                width, height = diffKern.getDimensions()
                # TBD...
                #psfAttr = measAlg.PsfAttributes(diffKern, width//2, height//2)

            else:
                diffExp = afwImage.ExposureF(snap0, True)
                diffMi = diffExp.getMaskedImage()
                diffMi -= snap1.getMaskedImage()

            psf = self.makeInitialPsf(snap0)
            diffExp.setPsf(psf)
            table = afwTable.SourceTable.make(self.schema)
            table.setMetadata(self.algMetadata)
            detRet = self.detection.makeSourceCatalog(table, diffExp)
            sources = detRet.sources
            fpSets = detRet.fpSets
            if self.config.doMeasurement:
                self.measurement.measure(diffExp, sources)

            mask0 = snap0.getMaskedImage().getMask()
            mask1 = snap1.getMaskedImage().getMask()
            fpSets.positive.setMask(mask0, "DETECTED")
            fpSets.negative.setMask(mask1, "DETECTED")

            maskD = diffExp.getMaskedImage().getMask()
            fpSets.positive.setMask(maskD, "DETECTED")
            fpSets.negative.setMask(maskD, "DETECTED_NEGATIVE")

        combinedExp = self.addSnaps(snap0, snap1)

        return pipeBase.Struct(
            exposure=combinedExp,
            sources=sources,
        )
示例#13
0
def plotPixelResiduals(exposure, warpedTemplateExposure, diffExposure, kernelCellSet,
                       kernel, background, testSources, config,
                       origVariance = False, nptsFull = 1e6, keepPlots = True, titleFs=14):
    """Plot diffim residuals for LOCAL and SPATIAL models"""
    candidateResids = []
    spatialResids   = []
    nonfitResids    = []

    for cell in kernelCellSet.getCellList():
        for cand in cell.begin(True): # only look at good ones
            # Be sure
            if not (cand.getStatus() == afwMath.SpatialCellCandidate.GOOD):
                continue

            cand    = diffimLib.cast_KernelCandidateF(cand)
            diffim  = cand.getDifferenceImage(diffimLib.KernelCandidateF.ORIG)
            orig    = cand.getScienceMaskedImage()

            ski     = afwImage.ImageD(kernel.getDimensions())
            kernel.computeImage(ski, False, int(cand.getXCenter()), int(cand.getYCenter()))
            sk      = afwMath.FixedKernel(ski)
            sbg     = background(int(cand.getXCenter()), int(cand.getYCenter()))
            sdiffim = cand.getDifferenceImage(sk, sbg)

            # trim edgs due to convolution
            bbox    = kernel.shrinkBBox(diffim.getBBox())
            tdiffim  = diffim.Factory(diffim, bbox)
            torig    = orig.Factory(orig, bbox)
            tsdiffim = sdiffim.Factory(sdiffim, bbox)

            if origVariance:
                candidateResids.append(np.ravel(tdiffim.getImage().getArray() /
                                                np.sqrt(torig.getVariance().getArray())))
                spatialResids.append(np.ravel(tsdiffim.getImage().getArray() /
                                              np.sqrt(torig.getVariance().getArray())))
            else:
                candidateResids.append(np.ravel(tdiffim.getImage().getArray() /
                                                np.sqrt(tdiffim.getVariance().getArray())))
                spatialResids.append(np.ravel(tsdiffim.getImage().getArray() /
                                              np.sqrt(tsdiffim.getVariance().getArray())))

    fullIm   = diffExposure.getMaskedImage().getImage().getArray()
    fullMask = diffExposure.getMaskedImage().getMask().getArray()
    if origVariance:
        fullVar  = exposure.getMaskedImage().getVariance().getArray()
    else:
        fullVar  = diffExposure.getMaskedImage().getVariance().getArray()

    bitmaskBad  = 0
    bitmaskBad |= afwImage.MaskU.getPlaneBitMask('NO_DATA')
    bitmaskBad |= afwImage.MaskU.getPlaneBitMask('SAT')
    idx = np.where((fullMask & bitmaskBad) == 0)
    stride = int(len(idx[0]) // nptsFull)
    sidx = idx[0][::stride], idx[1][::stride]
    allResids = fullIm[sidx] / np.sqrt(fullVar[sidx])

    testFootprints = diffimTools.sourceToFootprintList(testSources, warpedTemplateExposure, 
                                                       exposure, config, pexLog.getDefaultLog())
    for fp in testFootprints:
        subexp = diffExposure.Factory(diffExposure, fp["footprint"].getBBox())
        subim  = subexp.getMaskedImage().getImage()
        if origVariance:
            subvar = afwImage.ExposureF(exposure, fp["footprint"].getBBox()).getMaskedImage().getVariance()
        else:
            subvar = subexp.getMaskedImage().getVariance()
        nonfitResids.append(np.ravel(subim.getArray() / np.sqrt(subvar.getArray())))

    candidateResids = np.ravel(np.array(candidateResids))
    spatialResids   = np.ravel(np.array(spatialResids))
    nonfitResids    = np.ravel(np.array(nonfitResids))

    try:
        import pylab
        from matplotlib.font_manager import FontProperties
    except ImportError, e:
        print "Unable to import pylab: %s" % e
        return
示例#14
0
    def run(self, exposure, referencePsfModel, kernelSum=1.0):
        """Psf-match an exposure to a model Psf

        Parameters
        ----------
        exposure : `lsst.afw.image.Exposure`
            Exposure to Psf-match to the reference Psf model;
            it must return a valid PSF model via exposure.getPsf()
        referencePsfModel : `lsst.afw.detection.Psf`
            The Psf model to match to
        kernelSum : `float`, optional
            A multipicative factor to apply to the kernel sum (default=1.0)

        Returns
        -------
        result : `struct`
            - ``psfMatchedExposure`` : the Psf-matched Exposure.
                This has the same parent bbox, Wcs, PhotoCalib and
                Filter as the input Exposure but no Psf.
                In theory the Psf should equal referencePsfModel but
                the match is likely not exact.
            - ``psfMatchingKernel`` : the spatially varying Psf-matching kernel
            - ``kernelCellSet`` : SpatialCellSet used to solve for the Psf-matching kernel
            - ``referencePsfModel`` : Validated and/or modified reference model used

        Raises
        ------
        RuntimeError
            if the Exposure does not contain a Psf model
        """
        if not exposure.hasPsf():
            raise RuntimeError("exposure does not contain a Psf model")

        maskedImage = exposure.getMaskedImage()

        self.log.info("compute Psf-matching kernel")
        result = self._buildCellSet(exposure, referencePsfModel)
        kernelCellSet = result.kernelCellSet
        referencePsfModel = result.referencePsfModel
        fwhmScience = exposure.getPsf().computeShape().getDeterminantRadius()*sigma2fwhm
        fwhmModel = referencePsfModel.computeShape().getDeterminantRadius()*sigma2fwhm

        basisList = makeKernelBasisList(self.kConfig, fwhmScience, fwhmModel, metadata=self.metadata)
        spatialSolution, psfMatchingKernel, backgroundModel = self._solve(kernelCellSet, basisList)

        if psfMatchingKernel.isSpatiallyVarying():
            sParameters = np.array(psfMatchingKernel.getSpatialParameters())
            sParameters[0][0] = kernelSum
            psfMatchingKernel.setSpatialParameters(sParameters)
        else:
            kParameters = np.array(psfMatchingKernel.getKernelParameters())
            kParameters[0] = kernelSum
            psfMatchingKernel.setKernelParameters(kParameters)

        self.log.info("Psf-match science exposure to reference")
        psfMatchedExposure = afwImage.ExposureF(exposure.getBBox(), exposure.getWcs())
        psfMatchedExposure.setFilter(exposure.getFilter())
        psfMatchedExposure.setPhotoCalib(exposure.getPhotoCalib())
        psfMatchedExposure.getInfo().setVisitInfo(exposure.getInfo().getVisitInfo())
        psfMatchedExposure.setPsf(referencePsfModel)
        psfMatchedMaskedImage = psfMatchedExposure.getMaskedImage()

        # Normalize the psf-matching kernel while convolving since its magnitude is meaningless
        # when PSF-matching one model to another.
        convolutionControl = afwMath.ConvolutionControl()
        convolutionControl.setDoNormalize(True)
        afwMath.convolve(psfMatchedMaskedImage, maskedImage, psfMatchingKernel, convolutionControl)

        self.log.info("done")
        return pipeBase.Struct(psfMatchedExposure=psfMatchedExposure,
                               psfMatchingKernel=psfMatchingKernel,
                               kernelCellSet=kernelCellSet,
                               metadata=self.metadata,
                               )
table = afwTable.SourceTable.make(schema)

lsst_images = {}
for filter_ in filter_names:
    lsst_images[filter_] = afwImage.ImageF('%s/image_%s.fits' %
                                           (output_dir, filter_))

# Run only detection on each filter
detections = {}
exposures = {}
for filter_ in filter_names:
    print 'detecting in ', filter_
    lsst_image = lsst_images[filter_]

    exposure = afwImage.ExposureF(lsst_image.getBBox(afwImage.PARENT))
    exposure.getMaskedImage().getImage().getArray(
    )[:, :] = lsst_image.getArray()

    exposure.getMaskedImage().getVariance().set(noise_sigma**2)
    exposure.setPsf(kernelPsf)
    exposure.setWcs(wcs)
    exposure.setCalib(calib)
    exposures[filter_] = exposure
    result = detectTask.makeSourceCatalog(table, exposure)
    detections[filter_] = result.sources
    result.sources.writeFits('%s/det_%s.fits' % (args.output_dir, filter_))

# merge detection lists together
merged = afwDet.FootprintMergeList(schema,
                                   [filter_ for filter_ in filter_names])
示例#16
0
variance   = %0.1f
""" % (coaddPath, numImages, config.imageShape, config.imageSigma,
       config.variance))

    np.random.seed(0)

    coadd = None
    for imInd in range(numImages):
        print("Create exposure %d" % (imInd, ), file=sys.stderr)
        maskedImage = afwTestUtils.makeGaussianNoiseMaskedImage(
            dimensions=config.imageShape,
            sigma=config.imageSigma,
            variance=config.variance)
        # the WCS doesn't matter; the default will do
        wcs = afwImage.Wcs()
        exposure = afwImage.ExposureF(maskedImage, wcs)

        if not coadd:
            print("Create coadd", file=sys.stderr)
            coadd = coaddChiSq.Coadd.fromConfig(bbox=exposure.getBBox(),
                                                wcs=exposure.getWcs(),
                                                config=config.coadd)
            print("badPixelMask=", coadd.getBadPixelMask(), file=sys.stderr)

        coadd.addExposure(exposure)

    print("Save weight map as %s" % (weightPath, ), file=sys.stderr)
    weightMap = coadd.getWeightMap()
    weightMap.writeFits(weightPath)
    coaddExposure = coadd.getCoadd()
    print("Save coadd as %s" % (coaddPath, ), file=sys.stderr)
示例#17
0
 def readImage(self, image):
     exp = afwImage.ExposureF(image)
     self.log.info("Read %dx%d image" % (exp.getWidth(), exp.getHeight()))
     return exp
示例#18
0
    def subtractExposures(self, templateExposure, scienceExposure,
                          templateFwhmPix=None, scienceFwhmPix=None,
                          candidateList=None, doWarping=True, convolveTemplate=True):
        """Register, Psf-match and subtract two Exposures.

        Do the following, in order:

        - Warp templateExposure to match scienceExposure, if their WCSs do not already match
        - Determine a PSF matching kernel and differential background model
            that matches templateExposure to scienceExposure
        - PSF-match templateExposure to scienceExposure
        - Compute subtracted exposure (see return values for equation).

        Parameters
        ----------
        templateExposure : `lsst.afw.image.Exposure`
            Exposure to PSF-match to scienceExposure
        scienceExposure : `lsst.afw.image.Exposure`
            Reference Exposure
        templateFwhmPix : `float`
            FWHM (in pixels) of the Psf in the template image (image to convolve)
        scienceFwhmPix : `float`
            FWHM (in pixels) of the Psf in the science image
        candidateList : `list`, optional
            A list of footprints/maskedImages for kernel candidates;
            if `None` then source detection is run.

            - Currently supported: list of Footprints or measAlg.PsfCandidateF

        doWarping : `bool`
            What to do if ``templateExposure``` and ``scienceExposure`` WCSs do
            not match:

            - if `True` then warp ``templateExposure`` to match ``scienceExposure``
            - if `False` then raise an Exception

        convolveTemplate : `bool`
            Convolve the template image or the science image

            - if `True`, ``templateExposure`` is warped if doWarping,
              ``templateExposure`` is convolved
            - if `False`, ``templateExposure`` is warped if doWarping,
              ``scienceExposure is`` convolved

        Returns
        -------
        result : `lsst.pipe.base.Struct`
            An `lsst.pipe.base.Struct` containing these fields:

            - ``subtractedExposure`` : subtracted Exposure
                scienceExposure - (matchedImage + backgroundModel)
            - ``matchedImage`` : ``templateExposure`` after warping to match
                                 ``templateExposure`` (if doWarping true),
                                 and convolving with psfMatchingKernel
            - ``psfMatchingKernel`` : PSF matching kernel
            - ``backgroundModel`` : differential background model
            - ``kernelCellSet`` : SpatialCellSet used to determine PSF matching kernel
        """
        results = self.matchExposures(
            templateExposure=templateExposure,
            scienceExposure=scienceExposure,
            templateFwhmPix=templateFwhmPix,
            scienceFwhmPix=scienceFwhmPix,
            candidateList=candidateList,
            doWarping=doWarping,
            convolveTemplate=convolveTemplate
        )

        subtractedExposure = afwImage.ExposureF(scienceExposure, True)
        if convolveTemplate:
            subtractedMaskedImage = subtractedExposure.getMaskedImage()
            subtractedMaskedImage -= results.matchedExposure.getMaskedImage()
            subtractedMaskedImage -= results.backgroundModel
        else:
            subtractedExposure.setMaskedImage(results.warpedExposure.getMaskedImage())
            subtractedMaskedImage = subtractedExposure.getMaskedImage()
            subtractedMaskedImage -= results.matchedExposure.getMaskedImage()
            subtractedMaskedImage -= results.backgroundModel

            # Preserve polarity of differences
            subtractedMaskedImage *= -1

            # Place back on native photometric scale
            subtractedMaskedImage /= results.psfMatchingKernel.computeImage(
                afwImage.ImageD(results.psfMatchingKernel.getDimensions()), False)

        import lsstDebug
        display = lsstDebug.Info(__name__).display
        displayDiffIm = lsstDebug.Info(__name__).displayDiffIm
        maskTransparency = lsstDebug.Info(__name__).maskTransparency
        if not maskTransparency:
            maskTransparency = 0
        if display:
            afwDisplay.setDefaultMaskTransparency(maskTransparency)
        if display and displayDiffIm:
            disp = afwDisplay.Display(frame=lsstDebug.frame)
            disp.mtv(templateExposure, title="Template")
            lsstDebug.frame += 1
            disp = afwDisplay.Display(frame=lsstDebug.frame)
            disp.mtv(results.matchedExposure, title="Matched template")
            lsstDebug.frame += 1
            disp = afwDisplay.Display(frame=lsstDebug.frame)
            disp.mtv(scienceExposure, title="Science Image")
            lsstDebug.frame += 1
            disp = afwDisplay.Display(frame=lsstDebug.frame)
            disp.mtv(subtractedExposure, title="Difference Image")
            lsstDebug.frame += 1

        results.subtractedExposure = subtractedExposure
        return results
示例#19
0
    def runXY0(self, poly, fitForBackground=False):
        self.subconfig.spatialModelType = poly
        self.subconfig.fitForBackground = fitForBackground

        templateSubImage = afwImage.ExposureF(self.templateImage.clone(),
                                              self.bbox)
        scienceSubImage = afwImage.ExposureF(self.scienceImage.clone(),
                                             self.bbox)

        # Have an XY0
        psfmatch = ipDiffim.ImagePsfMatchTask(config=self.config)
        fwhm = psfmatch.getFwhmPix(self.psf)
        results1 = psfmatch.subtractExposures(templateSubImage,
                                              scienceSubImage,
                                              doWarping=True,
                                              templateFwhmPix=fwhm,
                                              scienceFwhmPix=fwhm)
        spatialKernel1 = results1.psfMatchingKernel
        backgroundModel1 = results1.backgroundModel
        kernelCellSet1 = results1.kernelCellSet

        # And then take away XY0
        templateSubImage = afwImage.ExposureF(self.templateImage.clone(),
                                              self.bbox)
        scienceSubImage = afwImage.ExposureF(self.scienceImage.clone(),
                                             self.bbox)
        templateSubImage.setXY0(geom.Point2I(0, 0))
        scienceSubImage.setXY0(geom.Point2I(0, 0))

        results2 = psfmatch.subtractExposures(templateSubImage,
                                              scienceSubImage,
                                              doWarping=True,
                                              templateFwhmPix=fwhm,
                                              scienceFwhmPix=fwhm)
        spatialKernel2 = results2.psfMatchingKernel
        backgroundModel2 = results2.backgroundModel
        kernelCellSet2 = results2.kernelCellSet

        # need to count up the candidates first, since its a running tally
        count = 0
        for cell in kernelCellSet1.getCellList():
            for cand1 in cell.begin(False):
                count += 1

        for cell in kernelCellSet1.getCellList():
            for cand1 in cell.begin(False):
                if cand1.getStatus() == afwMath.SpatialCellCandidate.UNKNOWN:
                    continue
                if cand1.getStatus() == afwMath.SpatialCellCandidate.BAD:
                    continue

                cand2 = kernelCellSet2.getCandidateById(cand1.getId() + count)

                # positions are nearly the same (different at the 0.01 pixel level)
                self.assertAlmostEqual(cand1.getXCenter(),
                                       cand2.getXCenter(),
                                       delta=1e-1)
                self.assertAlmostEqual(cand1.getYCenter(),
                                       cand2.getYCenter() + self.offset,
                                       delta=1e-1)

                # kernels are the same
                im1 = cand1.getKernelImage(ipDiffim.KernelCandidateF.RECENT)
                im2 = cand2.getKernelImage(ipDiffim.KernelCandidateF.RECENT)
                for y in range(im1.getHeight()):
                    for x in range(im1.getWidth()):
                        self.assertAlmostEqual(im1[x, y, afwImage.LOCAL],
                                               im2[x, y, afwImage.LOCAL],
                                               delta=1e-7)

        # Spatial fits are the same
        skp1 = spatialKernel1.getSpatialParameters()
        skp2 = spatialKernel2.getSpatialParameters()
        bgp1 = backgroundModel1.getParameters()
        bgp2 = backgroundModel2.getParameters()

        # first term = kernel sum, 0, 0
        self.assertAlmostEqual(skp1[0][0], skp2[0][0], delta=1e-6)

        # On other terms, the spatial terms are the same, the zpt terms are different
        for nk in range(1, len(skp1)):

            # Zeropoint
            if poly == 'polynomial':
                self.assertNotEqual(skp1[nk][0], skp2[nk][0])
            elif poly == 'chebyshev1':
                # Cheby remaps coords, so model should be the same!
                self.assertAlmostEqual(skp1[nk][0], skp2[nk][0], delta=1e-4)
            else:
                self.fail()

            # Spatial terms
            for np in range(1, len(skp1[nk])):
                self.assertAlmostEqual(skp1[nk][np], skp2[nk][np], delta=1e-4)

        for np in range(len(bgp1)):
            self.assertAlmostEqual(bgp1[np], bgp2[np], delta=1e-4)
示例#20
0
    # We need to fit for a TAN-SIP
    x = np.arange(0, 1489 + stepSize, stepSize)
    y = np.arange(0, 2048 + stepSize, stepSize)
    coords = np.meshgrid(x, y)
    xs = np.ravel(coords[0]).astype(np.float)
    ys = np.ravel(coords[1]).astype(np.float)
    mapper = CoordinateMapper(node_rad, incl_rad, dRow0, dRow1, dRow2, dRow3,
                              dCol0, dCol1, dCol2, dCol3, a, b, c, d, e, f)
    wcs = createWcs(xs, ys, mapper)

    if doValidate:
        validate(xs, ys, mapper, wcs)

    return wcs


if __name__ == '__main__':
    infile = sys.argv[1]
    filt = sys.argv[2]
    camcol = int(sys.argv[3])
    field = int(sys.argv[4])

    wcs = convertasTrans(infile, filt, camcol, field, doValidate=True)

    if len(sys.argv) > 5:
        fpC = sys.argv[5]
        image = afwImage.ImageF(fpC)
        mi = afwImage.MaskedImageF(image)
        exp = afwImage.ExposureF(mi, wcs)
        exp.writeFits("/tmp/exp.fits")
示例#21
0
    def testSetPolygonIntersect(self):
        # Create a detector
        detector = DetectorWrapper().detector
        numPolygonPoints = 50
        # Create an exposure with bounding box defined by detector
        exposure = afwImage.ExposureF(detector.getBBox())
        exposure.setDetector(detector)

        pixelSizeMm = exposure.getDetector().getPixelSize()[0]

        pixX0 = exposure.getX0()
        pixY0 = exposure.getY0()
        pixX1 = pixX0 + exposure.getWidth() - 1
        pixY1 = pixY0 + exposure.getHeight() - 1

        fpCenter = exposure.getDetector().getCenter(FOCAL_PLANE)
        fpCenterX = fpCenter[0]
        fpCenterY = fpCenter[1]
        pixCenter = exposure.getDetector().getCenter(PIXELS)

        # Make a polygon that encompases entire ccd (radius of 2*max of
        # width/height)
        fpRadius = 2.0 * max(exposure.getWidth() * pixelSizeMm,
                             exposure.getHeight() * pixelSizeMm)
        fpPolygon = makeCircularPolygon(fpCenterX, fpCenterY, fpRadius,
                                        numPolygonPoints)
        # Set the polygon that is the intersection of fpPolygon and ccd
        setValidPolygonCcdIntersect(exposure, fpPolygon)
        # Since the ccd is fully contained in the fpPolygon, the intersection
        # should be the ccdPolygon itself
        ccdPolygonPix = afwGeom.Polygon(
            exposure.getDetector().getCorners(PIXELS))
        self.assertEqual(exposure.getInfo().getValidPolygon(), ccdPolygonPix)

        # Make a polygon that is entirely within, but smaller than, the ccd
        # (radius of 0.2*min of width/height)
        fpRadius = 0.2 * min(exposure.getWidth() * pixelSizeMm,
                             exposure.getHeight() * pixelSizeMm)
        fpPolygon = makeCircularPolygon(fpCenterX, fpCenterY, fpRadius,
                                        numPolygonPoints)
        # Set the polygon that is the intersection of fpPolygon and ccd
        setValidPolygonCcdIntersect(exposure, fpPolygon)
        # all vertices of polygon should be contained within the ccd
        for x in exposure.getInfo().getValidPolygon():
            self.assertTrue(ccdPolygonPix.contains(lsst.geom.Point2D(x)))
        # intersection is smaller than the ccd
        self.assertNotEqual(exposure.getInfo().getValidPolygon(),
                            ccdPolygonPix)

        # make a simple square polygon that partly intersects the ccd, centered
        # at ccd center
        fpPolygonSize = max(exposure.getWidth() * pixelSizeMm,
                            exposure.getHeight() * pixelSizeMm)
        fpPolygon = makeSquarePolygon(fpCenterX, fpCenterY, fpPolygonSize)
        setValidPolygonCcdIntersect(exposure, fpPolygon)
        # Check that the polygon contains the central pixel (offset by one to
        # actually be "contained")
        pixCenterPlusOne = lsst.geom.Point2D(pixCenter[0] + 1,
                                             pixCenter[1] + 1)
        self.assertTrue(exposure.getInfo().getValidPolygon().contains(
            lsst.geom.Point2D(pixCenterPlusOne)))
        # Check that the polygon contains the upper right ccd edge
        self.assertTrue(exposure.getInfo().getValidPolygon().contains(
            lsst.geom.Point2D(pixX1, pixY1)))
    def runDataRef(self, sensorRefList, calibType):
        """Process a calibration frame.

        @param sensorRef: sensor-level butler data reference
        @return pipe_base Struct containing these fields:
        - masterExpList: amp exposures of master calibration products
        """
        referenceAmps = sensorRefList[0].subItems(level="channel")
        masterExpList = []
        dataIdList = []
        expmeta = None
        for amp in referenceAmps:
            if amp.dataId['snap'] == 1:
                continue
            self.log.info("Amp: Processing %s", amp.dataId)
            print("dataid %s" % (amp.dataId))
            butler = amp.butlerSubset.butler
            ampMIList = []
            for sRef in sensorRefList:
                self.log.info("Sensor: Processing %s", sRef.dataId)
                ampSnapMIList = []
                dataId = eval(amp.dataId.__repr__())
                dataId['visit'] = sRef.dataId['visit']
                for snap in (0, 1):
                    dataId['snap'] = snap
                    ampExposure = sRef.butlerSubset.butler.get('raw', dataId)
                    if expmeta is None:
                        expmeta = ampExposure.getMetadata()
                        expfilter = ampExposure.getFilter()
                        expPhotoCalib = ampExposure.getPhotoCalib()
                    ampDetector = ampExposure.getDetector()

                    ampExposure = self.convertIntToFloat(ampExposure)
                    ampExpDataView = ampExposure.Factory(ampExposure, ampDetector.getDiskDataSec())

                    self.saturationDetection(ampExposure, ampDetector)

                    self.overscanCorrection(ampExposure, ampDetector)
                    if calibType in ('flat', 'dark'):
                        self.biasCorrection(ampExpDataView, amp)

                    if False:
                        self.darkCorrection(ampExpDataView, amp)

                    self.updateVariance(ampExpDataView, ampDetector)
                    ampSnapMIList.append(ampExpDataView.getMaskedImage())
                ampMIList.append(self.combineMIList(ampSnapMIList))
            masterFrame = self.combineMIList(ampMIList)
            # Fix saturation too???
            self.fixDefectsAndSat(masterFrame, ampDetector)
            exp = afwImage.ExposureF(masterFrame)
            self.copyMetadata(exp, expmeta, calibType)
            exp.setDetector(ampDetector)
            exp.setWcs(None)
            exp.setPhotoCalib(expPhotoCalib)
            if calibType == 'flat':
                exp.setFilter(expfilter)
            if self.config.doWrite and calibType != 'flat':
                print("writing file %s" % dataId)
                butler.put(exp, calibType, dataId=amp.dataId)
            masterExpList.append(exp)
            dataIdList.append(amp.dataId)
        if self.config.doWrite and calibType == 'flat':
            self.normChipAmps(masterExpList)
            for exp, dataId in zip(masterExpList, dataIdList):
                print("writing flat file %s" % dataId)
                butler.put(exp, calibType, dataId)
        return pipeBase.Struct(
            masterFrameList=masterExpList,
        )
 def testExposure(self):
     inExposure = afwImage.ExposureF(self.maskedImage)
     outExposure = exposureFromImage(inExposure)
     self.assertIs(inExposure, outExposure)
示例#24
0
 def getExposure():
     afwImage.ExposureF(inFilePathSmallImage)
示例#25
0
    def subtractExposures(self,
                          templateExposure,
                          scienceExposure,
                          templateFwhmPix=None,
                          scienceFwhmPix=None,
                          candidateList=None,
                          doWarping=True,
                          convolveTemplate=True):
        """!Register, Psf-match and subtract two Exposures

        Do the following, in order:
        - Warp templateExposure to match scienceExposure, if their WCSs do not already match
        - Determine a PSF matching kernel and differential background model
            that matches templateExposure to scienceExposure
        - PSF-match templateExposure to scienceExposure
        - Compute subtracted exposure (see return values for equation).

        @param templateExposure: exposure to PSF-match to scienceExposure
        @param scienceExposure: reference Exposure
        @param templateFwhmPix: FWHM (in pixels) of the Psf in the template image (image to convolve)
        @param scienceFwhmPix: FWHM (in pixels) of the Psf in the science image
        @param candidateList: a list of footprints/maskedImages for kernel candidates;
                              if None then source detection is run.
            - Currently supported: list of Footprints or measAlg.PsfCandidateF
        @param doWarping: what to do if templateExposure's and scienceExposure's WCSs do not match:
            - if True then warp templateExposure to match scienceExposure
            - if False then raise an Exception
        @param convolveTemplate: convolve the template image or the science image
            - if True, templateExposure is warped if doWarping, templateExposure is convolved
            - if False, templateExposure is warped if doWarping, scienceExposure is convolved

        @return a pipeBase.Struct containing these fields:
        - subtractedExposure: subtracted Exposure = scienceExposure - (matchedImage + backgroundModel)
        - matchedImage: templateExposure after warping to match templateExposure (if doWarping true),
            and convolving with psfMatchingKernel
        - psfMatchingKernel: PSF matching kernel
        - backgroundModel: differential background model
        - kernelCellSet: SpatialCellSet used to determine PSF matching kernel
        """
        results = self.matchExposures(templateExposure=templateExposure,
                                      scienceExposure=scienceExposure,
                                      templateFwhmPix=templateFwhmPix,
                                      scienceFwhmPix=scienceFwhmPix,
                                      candidateList=candidateList,
                                      doWarping=doWarping,
                                      convolveTemplate=convolveTemplate)

        subtractedExposure = afwImage.ExposureF(scienceExposure, True)
        if convolveTemplate:
            subtractedMaskedImage = subtractedExposure.getMaskedImage()
            subtractedMaskedImage -= results.matchedExposure.getMaskedImage()
            subtractedMaskedImage -= results.backgroundModel
        else:
            subtractedExposure.setMaskedImage(
                results.warpedExposure.getMaskedImage())
            subtractedMaskedImage = subtractedExposure.getMaskedImage()
            subtractedMaskedImage -= results.matchedExposure.getMaskedImage()
            subtractedMaskedImage -= results.backgroundModel

            # Preserve polarity of differences
            subtractedMaskedImage *= -1

            # Place back on native photometric scale
            subtractedMaskedImage /= results.psfMatchingKernel.computeImage(
                afwImage.ImageD(results.psfMatchingKernel.getDimensions()),
                False)

        import lsstDebug
        display = lsstDebug.Info(__name__).display
        displayDiffIm = lsstDebug.Info(__name__).displayDiffIm
        maskTransparency = lsstDebug.Info(__name__).maskTransparency
        if not maskTransparency:
            maskTransparency = 0
        if display:
            ds9.setMaskTransparency(maskTransparency)
        if display and displayDiffIm:
            ds9.mtv(templateExposure, frame=lsstDebug.frame, title="Template")
            lsstDebug.frame += 1
            ds9.mtv(results.matchedExposure,
                    frame=lsstDebug.frame,
                    title="Matched template")
            lsstDebug.frame += 1
            ds9.mtv(scienceExposure,
                    frame=lsstDebug.frame,
                    title="Science Image")
            lsstDebug.frame += 1
            ds9.mtv(subtractedExposure,
                    frame=lsstDebug.frame,
                    title="Difference Image")
            lsstDebug.frame += 1

        results.subtractedExposure = subtractedExposure
        return results
示例#26
0
    def __call__(self, source, exposure):
        fp = source.getFootprint()
        peaks = fp.getPeaks()
        peaksF = [pk.getF() for pk in peaks]
        fbb = fp.getBBox()
        fmask = afwImage.Mask(fbb)
        fmask.setXY0(fbb.getMinX(), fbb.getMinY())
        fp.spans.setMask(fmask, 1)

        psf = exposure.getPsf()
        psfSigPix = psf.computeShape().getDeterminantRadius()
        psfFwhmPix = psfSigPix * self.sigma2fwhm
        subimage = afwImage.ExposureF(exposure, bbox=fbb, deep=True)
        cpsf = deblendBaseline.CachingPsf(psf)

        # if fewer than 2 peaks, just return a copy of the source
        if len(peaks) < 2:
            return source.getTable().copyRecord(source)

        # make sure you only deblend 2 peaks; take the brighest and faintest
        speaks = [(p.getPeakValue(), p) for p in peaks]
        speaks.sort()
        dpeaks = [speaks[0][1], speaks[-1][1]]

        # and only set these peaks in the footprint (peaks is mutable)
        peaks.clear()
        for peak in dpeaks:
            peaks.append(peak)

        if True:
            # Call top-level deblend task
            fpres = deblendBaseline.deblend(fp, exposure.getMaskedImage(), psf, psfFwhmPix,
                                            log=self.log,
                                            psfChisqCut1=self.psfChisqCut1,
                                            psfChisqCut2=self.psfChisqCut2,
                                            psfChisqCut2b=self.psfChisqCut2b)
        else:
            # Call lower-level _fit_psf task

            # Prepare results structure
            fpres = deblendBaseline.DeblenderResult(fp, exposure.getMaskedImage(), psf, psfFwhmPix, self.log)

            for pki, (pk, pkres, pkF) in enumerate(zip(dpeaks, fpres.deblendedParents[0].peaks, peaksF)):
                self.log.debug('Peak %i', pki)
                deblendBaseline._fitPsf(fp, fmask, pk, pkF, pkres, fbb, dpeaks, peaksF, self.log,
                                        cpsf, psfFwhmPix,
                                        subimage.getMaskedImage().getImage(),
                                        subimage.getMaskedImage().getVariance(),
                                        self.psfChisqCut1, self.psfChisqCut2, self.psfChisqCut2b)

        deblendedSource = source.getTable().copyRecord(source)
        deblendedSource.setParent(source.getId())
        peakList = deblendedSource.getFootprint().getPeaks()
        peakList.clear()

        for i, peak in enumerate(fpres.deblendedParents[0].peaks):
            if peak.psfFitFlux > 0:
                suffix = "pos"
            else:
                suffix = "neg"
            c = peak.psfFitCenter
            self.log.info("deblended.centroid.dipole.psf.%s %f %f",
                          suffix, c[0], c[1])
            self.log.info("deblended.chi2dof.dipole.%s %f",
                          suffix, peak.psfFitChisq / peak.psfFitDof)
            self.log.info("deblended.flux.dipole.psf.%s %f",
                          suffix, peak.psfFitFlux * np.sum(peak.templateImage.getArray()))
            peakList.append(peak.peak)
        return deblendedSource
示例#27
0
def cutoutImage(butler, skymap, specObjID, ra, dec, bands, width=60.):
    # width is in arcsec

    #coord = afwCoord.Coord(afwGeom.Point2D(ra, dec))
    coord = lsstGeom.SpherePoint(ra, dec, lsstGeom.degrees)
    tract, patch, wcs = findTractPatch(skymap, coord)
    print(tract, patch)
    ipx, ipy = map(int, patch.split(','))

    #x, y = wcs.skyToPixel(coord.toIcrs())
    x, y = wcs.skyToPixel(coord)
    ix = int(math.floor(x + 0.5))
    iy = int(math.floor(y + 0.5))
    width_in_pixel = int(
        width / wcs.getPixelScale().asArcseconds() / 2) * 2 + 1

    pxmin, pymin, pxmax, pymax = getCorners(skymap, tract, ipx, ipy)

    bbox = lsstGeom.Box2I(
        lsstGeom.Point2I(ix - width_in_pixel // 2, iy - width_in_pixel // 2),
        lsstGeom.Point2I(ix + width_in_pixel // 2, iy + width_in_pixel // 2))
    xmin, ymin = bbox.getBegin()
    xmax, ymax = bbox.getEnd()
    xmax -= 1
    ymax -= 1

    patches = list()
    bboxes = list()

    patches.append((ipx, ipy))
    bboxes.append(getBBox(xmin, ymin, xmax, ymax, pxmin, pymin, pxmax, pymax))

    if ix - width_in_pixel // 2 < pxmin:
        patches.append((ipx - 1, ipy))
        _pxmin, _pymin, _pxmax, _pymax = getCorners(skymap, tract, ipx - 1,
                                                    ipy)
        bboxes.append(
            getBBox(xmin, ymin, xmax, ymax, _pxmin, _pymin, _pxmax, _pymax))
        if iy - width_in_pixel // 2 < pymin:
            patches.append((ipx, ipy - 1))
            _pxmin, _pymin, _pxmax, _pymax = getCorners(
                skymap, tract, ipx, ipy - 1)
            bboxes.append(
                getBBox(xmin, ymin, xmax, ymax, _pxmin, _pymin, _pxmax,
                        _pymax))

            patches.append((ipx - 1, ipy - 1))
            _pxmin, _pymin, _pxmax, _pymax = getCorners(
                skymap, tract, ipx - 1, ipy - 1)
            bboxes.append(
                getBBox(xmin, ymin, xmax, ymax, _pxmin, _pymin, _pxmax,
                        _pymax))
        elif iy + width_in_pixel // 2 > pymax:
            patches.append((ipx, ipy + 1))
            _pxmin, _pymin, _pxmax, _pymax = getCorners(
                skymap, tract, ipx, ipy + 1)
            bboxes.append(
                getBBox(xmin, ymin, xmax, ymax, _pxmin, _pymin, _pxmax,
                        _pymax))

            patches.append((ipx - 1, ipy + 1))
            _pxmin, _pymin, _pxmax, _pymax = getCorners(
                skymap, tract, ipx - 1, ipy + 1)
            bboxes.append(
                getBBox(xmin, ymin, xmax, ymax, _pxmin, _pymin, _pxmax,
                        _pymax))
        else:
            pass
    elif ix + width_in_pixel // 2 > pxmax:
        patches.append((ipx + 1, ipy))
        _pxmin, _pymin, _pxmax, _pymax = getCorners(skymap, tract, ipx + 1,
                                                    ipy)
        bboxes.append(
            getBBox(xmin, ymin, xmax, ymax, _pxmin, _pymin, _pxmax, _pymax))
        if iy - width_in_pixel // 2 < pymin:
            patches.append((ipx, ipy - 1))
            _pxmin, _pymin, _pxmax, _pymax = getCorners(
                skymap, tract, ipx, ipy - 1)
            bboxes.append(
                getBBox(xmin, ymin, xmax, ymax, _pxmin, _pymin, _pxmax,
                        _pymax))

            patches.append((ipx + 1, ipy - 1))
            _pxmin, _pymin, _pxmax, _pymax = getCorners(
                skymap, tract, ipx + 1, ipy - 1)
            bboxes.append(
                getBBox(xmin, ymin, xmax, ymax, _pxmin, _pymin, _pxmax,
                        _pymax))
        elif iy + width_in_pixel // 2 > pymax:
            patches.append((ipx, ipy + 1))
            _pxmin, _pymin, _pxmax, _pymax = getCorners(
                skymap, tract, ipx, ipy + 1)
            bboxes.append(
                getBBox(xmin, ymin, xmax, ymax, _pxmin, _pymin, _pxmax,
                        _pymax))

            patches.append((ipx + 1, ipy + 1))
            _pxmin, _pymin, _pxmax, _pymax = getCorners(
                skymap, tract, ipx + 1, ipy + 1)
            bboxes.append(
                getBBox(xmin, ymin, xmax, ymax, _pxmin, _pymin, _pxmax,
                        _pymax))
        else:
            pass
    else:
        if iy - width_in_pixel // 2 < pymin:
            patches.append((ipx, ipy - 1))
            _pxmin, _pymin, _pxmax, _pymax = getCorners(
                skymap, tract, ipx, ipy - 1)
            bboxes.append(
                getBBox(xmin, ymin, xmax, ymax, _pxmin, _pymin, _pxmax,
                        _pymax))
        elif iy + width_in_pixel // 2 > pymax:
            patches.append((ipx, ipy + 1))
            _pxmin, _pymin, _pxmax, _pymax = getCorners(
                skymap, tract, ipx, ipy + 1)
            bboxes.append(
                getBBox(xmin, ymin, xmax, ymax, _pxmin, _pymin, _pxmax,
                        _pymax))
        else:
            pass

    for band in bands:

        try:
            fname = butler.get('deepCoadd_calexp_filename', {
                'tract': tract,
                'patch': patch,
                'filter': band
            })[0]
            exposure = afwImage.ExposureF(fname, origin=afwImage.PARENT)
            psfExp = exposure.getPsf().computeImage(lsstGeom.Point2D(ix, iy))
            psf_fname = '%s_%s_psf.fits' % (specObjID, band)
            psfExp.writeFits(psf_fname)

            x0, y0 = exposure.getXY0()

            newExp = afwImage.ExposureF(width_in_pixel, width_in_pixel)
            wcs = exposure.getWcs()

            for _patch, _bbox in zip(patches, bboxes):
                fname = butler.get('deepCoadd_calexp_filename', {
                    'tract': tract,
                    'patch': '%d,%d' % (_patch),
                    'filter': band
                })[0]
                exposure = afwImage.ExposureF(fname,
                                              bbox=_bbox,
                                              origin=afwImage.PARENT)
                sub = afwImage.MaskedImageF(
                    newExp.getMaskedImage(),
                    lsstGeom.Box2I(
                        lsstGeom.Point2I(_bbox.getMinX() - xmin,
                                         _bbox.getMinY() - ymin),
                        _bbox.getDimensions()), afwImage.PARENT)
                #sub <<= exposure.getMaskedImage()
                sub.assign(exposure.getMaskedImage())

            image_fname = '%s_%s.fits' % (specObjID, band)
            newExp.setXY0(lsstGeom.Point2I(xmin, ymin))
            newExp.setWcs(wcs)
            newExp.writeFits(image_fname)

        except Exception as e:
            print(e.args)
示例#28
0
from astropy.io import fits
import lsst.afw.image.basicUtils as bu
import lsst.skymap as skymap
import lsst.daf.persistence as dafPersist
import numpy as np
import os
import sys

import lsst.log
logger = lsst.log.Log.getDefaultLogger()
logger.setLevel(lsst.log.FATAL)

HOME_PATH = os.path.expanduser("~")

fn = HOME_PATH + "/lsst_data/raw/crblasted0289697/instcal0289697.12.fits"
image = afwImage.ExposureF(fn)
charImage = CharacterizeImageTask()
charRes = charImage.characterize(image, exposureIdInfo=None, background=None)

# try out one exposure
visit = 289697
ccdnum = 1
filterName = 'g'
"""
folder data should have the following structure - for every visit there should be folder <visitnumber> and <crblastedvisitnumber>
<visitnumber> should have three files: dqmask0288935.fits.fz    instcal0288935.fits.fz  wtmap0288935.fits.fz, where visit number is 0288935
<crblasted> should have one file per ccd called instcal0288935.1.fits where visit number is 0288935 and ccd number is 1

All fo this data is available at:https://lsst-web.ncsa.illinois.edu/~yusra/hits_calexp_dir/
root folder in this case data, should also have a file _mapper with the following line.
    def setUp(self, CFHT=True):
        lambdaValue = 1.0

        self.config1 = ipDiffim.ImagePsfMatchTask.ConfigClass()
        self.config1.kernel.name = "DF"
        self.subconfig1 = self.config1.kernel.active

        self.config2 = ipDiffim.ImagePsfMatchTask.ConfigClass()
        self.config2.kernel.name = "DF"
        self.subconfig2 = self.config2.kernel.active

        self.config3 = ipDiffim.ImagePsfMatchTask.ConfigClass()
        self.config3.kernel.name = "DF"
        self.subconfig3 = self.config3.kernel.active

        self.config4 = ipDiffim.ImagePsfMatchTask.ConfigClass()
        self.config4.kernel.name = "DF"
        self.subconfig4 = self.config4.kernel.active

        self.subconfig1.useRegularization = False

        self.subconfig2.useRegularization = True
        self.subconfig2.lambdaType = "absolute"
        self.subconfig2.lambdaValue = lambdaValue
        self.subconfig2.regularizationType = "centralDifference"
        self.subconfig2.centralRegularizationStencil = 5

        self.subconfig3.useRegularization = True
        self.subconfig3.lambdaType = "absolute"
        self.subconfig3.lambdaValue = lambdaValue
        self.subconfig3.regularizationType = "centralDifference"
        self.subconfig3.centralRegularizationStencil = 9

        self.subconfig4.useRegularization = True
        self.subconfig4.lambdaType = "absolute"
        self.subconfig4.lambdaValue = lambdaValue
        self.subconfig4.regularizationType = "forwardDifference"
        self.subconfig4.forwardRegularizationOrders = [1, 2]

        self.kList1 = ipDiffim.makeKernelBasisList(self.subconfig1)
        self.bskv1 = ipDiffim.BuildSingleKernelVisitorF(
            self.kList1, pexConfig.makePolicy(self.subconfig1))

        self.kList2 = ipDiffim.makeKernelBasisList(self.subconfig2)
        self.hMat2 = ipDiffim.makeRegularizationMatrix(
            pexConfig.makePolicy(self.subconfig2))
        self.bskv2 = ipDiffim.BuildSingleKernelVisitorF(
            self.kList2, pexConfig.makePolicy(self.subconfig2), self.hMat2)

        self.kList3 = ipDiffim.makeKernelBasisList(self.subconfig3)
        self.hMat3 = ipDiffim.makeRegularizationMatrix(
            pexConfig.makePolicy(self.subconfig3))
        self.bskv3 = ipDiffim.BuildSingleKernelVisitorF(
            self.kList3, pexConfig.makePolicy(self.subconfig3), self.hMat3)

        self.kList4 = ipDiffim.makeKernelBasisList(self.subconfig4)
        self.hMat4 = ipDiffim.makeRegularizationMatrix(
            pexConfig.makePolicy(self.subconfig4))
        self.bskv4 = ipDiffim.BuildSingleKernelVisitorF(
            self.kList4, pexConfig.makePolicy(self.subconfig4), self.hMat4)

        # known input images
        defDataDir = lsst.utils.getPackageDir('afwdata')
        if CFHT:
            defSciencePath = os.path.join(defDataDir, 'CFHT', 'D4', CFHTTORUN)
            defTemplatePath = os.path.join(defDataDir, 'CFHT', 'D4',
                                           CFHTTORUN + '_tmpl')

            # no need to remap
            self.scienceExposure = afwImage.ExposureF(defSciencePath)
            self.templateExposure = afwImage.ExposureF(defTemplatePath)
        else:
            defSciencePath = os.path.join(defDataDir, "DC3a-Sim", "sci",
                                          "v26-e0", "v26-e0-c011-a00.sci")
            defTemplatePath = os.path.join(defDataDir, "DC3a-Sim", "sci",
                                           "v5-e0", "v5-e0-c011-a00.sci")

            self.scienceExposure = afwImage.ExposureF(defSciencePath)
            self.templateExposure = afwImage.ExposureF(defTemplatePath)
            warper = afwMath.Warper.fromConfig(self.subconfig1.warpingConfig)
            self.templateExposure = warper.warpExposure(
                self.scienceExposure.getWcs(),
                self.templateExposure,
                destBBox=self.scienceExposure.getBBox())

        diffimTools.backgroundSubtract(self.subconfig1.afwBackgroundConfig, [
            self.scienceExposure.getMaskedImage(),
            self.templateExposure.getMaskedImage()
        ])

        # image statistics
        self.dStats = ipDiffim.ImageStatisticsF()

        #
        tmi = self.templateExposure.getMaskedImage()
        smi = self.scienceExposure.getMaskedImage()

        detConfig = self.subconfig1.detectionConfig
        detPolicy = pexConfig.makePolicy(detConfig)
        detPolicy.set("detThreshold", 50.)
        detPolicy.set("detOnTemplate", False)
        kcDetect = ipDiffim.KernelCandidateDetectionF(detPolicy)
        kcDetect.apply(tmi, smi)
        self.footprints = kcDetect.getFootprints()
    def testComputeExposureSummary(self):
        """Make a fake exposure and background and compute summary.
        """
        np.random.seed(12345)

        # Make an exposure with a noise image
        exposure = afwImage.ExposureF(100, 100)
        skySigma = 10.0
        exposure.getImage().getArray()[:, :] = np.random.normal(0.0, skySigma, size=(100, 100))
        exposure.getVariance().getArray()[:, :] = skySigma**2.

        # Set the visitInfo
        date = DateTime(date=59234.7083333334, system=DateTime.DateSystem.MJD)
        observatory = Observatory(-70.7366*lsst.geom.degrees, -30.2407*lsst.geom.degrees,
                                  2650.)
        visitInfo = afwImage.VisitInfo(exposureTime=10.0,
                                       date=date,
                                       observatory=observatory)
        exposure.getInfo().setVisitInfo(visitInfo)

        # Install a Gaussian PSF
        psfSize = 2.0
        psf = GaussianPsf(5, 5, psfSize)
        exposure.setPsf(psf)

        # Install a simple WCS
        scale = 0.2*lsst.geom.arcseconds
        raCenter = 300.0*lsst.geom.degrees
        decCenter = 0.0*lsst.geom.degrees
        cdMatrix = makeCdMatrix(scale=scale)
        skyWcs = makeSkyWcs(crpix=exposure.getBBox().getCenter(),
                            crval=lsst.geom.SpherePoint(raCenter, decCenter),
                            cdMatrix=cdMatrix)
        exposure.setWcs(skyWcs)

        # Install a simple photoCalib
        photoCalib = afwImage.PhotoCalib(calibrationMean=0.3)
        zp = 2.5*np.log10(photoCalib.getInstFluxAtZeroMagnitude())
        exposure.setPhotoCalib(photoCalib)

        # Compute the background image
        bgGridSize = 10
        bctrl = afwMath.BackgroundControl(afwMath.Interpolate.NATURAL_SPLINE)
        bctrl.setNxSample(int(exposure.getMaskedImage().getWidth()/bgGridSize) + 1)
        bctrl.setNySample(int(exposure.getMaskedImage().getHeight()/bgGridSize) + 1)
        backobj = afwMath.makeBackground(exposure.getMaskedImage().getImage(), bctrl)
        background = afwMath.BackgroundList()
        background.append(backobj)

        # Run the task
        expSummaryTask = ComputeExposureSummaryStatsTask()
        summary = expSummaryTask.run(exposure, None, background)

        # Test the outputs
        self.assertFloatsAlmostEqual(summary.psfSigma, psfSize)
        self.assertFloatsAlmostEqual(summary.psfIxx, psfSize**2.)
        self.assertFloatsAlmostEqual(summary.psfIyy, psfSize**2.)
        self.assertFloatsAlmostEqual(summary.psfIxy, 0.0)
        self.assertFloatsAlmostEqual(summary.psfArea, 23.088975164455444)

        delta = (scale*50).asDegrees()
        for a, b in zip(summary.raCorners,
                        [raCenter.asDegrees() + delta, raCenter.asDegrees() - delta,
                         raCenter.asDegrees() - delta, raCenter.asDegrees() + delta]):
            self.assertFloatsAlmostEqual(a, b, atol=1e-10)
        for a, b in zip(summary.decCorners,
                        [decCenter.asDegrees() - delta, decCenter.asDegrees() - delta,
                         decCenter.asDegrees() + delta, decCenter.asDegrees() + delta]):
            self.assertFloatsAlmostEqual(a, b, atol=1e-10)

        self.assertFloatsAlmostEqual(summary.ra, raCenter.asDegrees(), atol=1e-10)
        self.assertFloatsAlmostEqual(summary.decl, decCenter.asDegrees(), atol=1e-10)

        self.assertFloatsAlmostEqual(summary.zeroPoint, zp)

        # Need to compare background level and noise
        # These are only approximately 0+/-10 because of the small image
        self.assertFloatsAlmostEqual(summary.skyBg, -0.079, atol=1e-3)
        self.assertFloatsAlmostEqual(summary.skyNoise, 9.816, atol=1e-3)

        self.assertFloatsAlmostEqual(summary.meanVar, skySigma**2.)

        self.assertFloatsAlmostEqual(summary.zenithDistance, 59.42888, atol=1e-5)