def subtractSkyFrame(self, image, skyBackground, scale, bgList=None): """Subtract sky frame from science image Parameters ---------- image : `lsst.afw.image.Exposure` or `lsst.afw.image.MaskedImage` Science image. skyBackground : `lsst.afw.math.BackgroundList` Sky background model. scale : `float` Scale to apply to background model. bgList : `lsst.afw.math.BackgroundList` List of backgrounds applied to image """ if isinstance(image, afwImage.Exposure): image = image.getMaskedImage() if isinstance(image, afwImage.MaskedImage): image = image.getImage() image.scaledMinus(scale, skyBackground.getImage()) if bgList is not None: # Append the sky frame to the list of applied background models bgData = list(skyBackground[0]) bg = bgData[0] statsImage = bg.getStatsImage().clone() statsImage *= scale newBg = afwMath.BackgroundMI(bg.getImageBBox(), statsImage) newBgData = [newBg] + bgData[1:] bgList.append(newBgData)
def exposureToBackground(bgExp): """Convert an exposure to background model Calibs need to be persisted as an Exposure, so we need to convert the persisted Exposure to a background model. Parameters ---------- bgExp : `lsst.afw.image.Exposure` Background model in Exposure format. Returns ------- bg : `lsst.afw.math.BackgroundList` Background model """ header = bgExp.getMetadata() xMin = header.getScalar("BOX.MINX") yMin = header.getScalar("BOX.MINY") xMax = header.getScalar("BOX.MAXX") yMax = header.getScalar("BOX.MAXY") algorithm = header.getScalar("ALGORITHM") bbox = afwGeom.Box2I(afwGeom.Point2I(xMin, yMin), afwGeom.Point2I(xMax, yMax)) return afwMath.BackgroundList( (afwMath.BackgroundMI(bbox, bgExp.getMaskedImage()), afwMath.stringToInterpStyle(algorithm), afwMath.stringToUndersampleStyle("REDUCE_INTERP_ORDER"), afwMath.ApproximateControl.UNKNOWN, 0, 0, False))
def toCcdBackground(self, detector, bbox): """Produce a background model for a CCD The superpixel background model is warped back to the CCD frame, for application to the individual CCD. Parameters ---------- detector : `lsst.afw.cameraGeom.Detector` CCD for which to produce background model. bbox : `lsst.geom.Box2I` Bounding box of CCD exposure. Returns ------- bg : `lsst.afw.math.BackgroundList` Background model for CCD. """ transform = detector.getTransformMap().getTransform( detector.makeCameraSys(afwCameraGeom.PIXELS), detector.makeCameraSys(afwCameraGeom.FOCAL_PLANE)) binTransform = ( geom.AffineTransform.makeScaling(self.config.binning) * geom.AffineTransform.makeTranslation(geom.Extent2D(0.5, 0.5))) # Binned image on CCD --> unbinned image on CCD --> focal plane --> binned focal plane toSample = afwGeom.makeTransform(binTransform).then(transform).then( self.transform) focalPlane = self.getStatsImage() fpNorm = afwImage.ImageF(focalPlane.getBBox()) fpNorm.set(1.0) image = afwImage.ImageF(bbox.getDimensions() // self.config.binning) norm = afwImage.ImageF(image.getBBox()) ctrl = afwMath.WarpingControl("bilinear") afwMath.warpImage(image, focalPlane, toSample.inverted(), ctrl) afwMath.warpImage(norm, fpNorm, toSample.inverted(), ctrl) image /= norm mask = afwImage.Mask(image.getBBox()) isBad = numpy.isnan(image.getArray()) mask.getArray()[isBad] = mask.getPlaneBitMask("BAD") image.getArray()[isBad] = image.getArray()[~isBad].mean() return afwMath.BackgroundList( (afwMath.BackgroundMI(bbox, afwImage.makeMaskedImage(image, mask)), afwMath.stringToInterpStyle(self.config.interpolation), afwMath.stringToUndersampleStyle("REDUCE_INTERP_ORDER"), afwMath.ApproximateControl.UNKNOWN, 0, 0, False))
def run(self, exposure, exposureIdInfo=None, background=None, icSourceCat=None): """Produce calibration outputs with no processing. Parameters ---------- exposure : `lsst.afw.image.Exposure` Exposure to calibrate. exposureIdInfo : `lsst.obs.base.ExposureIdInfo` ID info for exposure. background : `lsst.afw.math.BackgroundList` Background model already subtracted from exposure. icSourceCat : `lsst.afw.table.SourceCatalog` A SourceCatalog from CharacterizeImageTask from which we can copy some fields. Returns ------- result : `lsst.pipe.base.Struct` Struct containing these fields: ``outputExposure`` Calibrated science exposure with refined WCS and PhotoCalib (`lsst.afw.image.Exposure`). ``outputBackground`` Model of background subtracted from exposure (`lsst.afw.math.BackgroundList`). ``outputCat`` Catalog of measured sources (`lsst.afw.table.SourceCatalog`). ``astromMatches`` List of source/refObj matches from the astrometry solver (`list` [`lsst.afw.table.ReferenceMatch`]). """ # Can't persist empty BackgroundList; DM-33714 bg = afwMath.BackgroundMI( geom.Box2I(geom.Point2I(0, 0), geom.Point2I(16, 16)), afwImage.MaskedImageF(16, 16)) return Struct( outputExposure=exposure, outputBackground=afwMath.BackgroundList(bg), outputCat=afwTable.SourceCatalog(), astromMatches=[], )
def testBackgroundFromStatsImage(self): """Check that we can rebuild a Background from a BackgroundMI.getStatsImage()""" bgCtrl = afwMath.BackgroundControl(10, 10) bkgd = afwMath.makeBackground(self.image, bgCtrl) interpStyle = afwMath.Interpolate.AKIMA_SPLINE undersampleStyle = afwMath.REDUCE_INTERP_ORDER bkgdImage = bkgd.getImageF(interpStyle, undersampleStyle) self.assertEqual(np.mean(bkgdImage.getArray()), self.val) self.assertEqual(interpStyle, bkgd.getAsUsedInterpStyle()) self.assertEqual(undersampleStyle, bkgd.getAsUsedUndersampleStyle()) # OK, we have our background. Make a copy bkgd2 = afwMath.BackgroundMI(self.image.getBBox(), bkgd.getStatsImage()) del bkgd # we should be handling the memory correctly, but let's check bkgdImage2 = bkgd2.getImageF(interpStyle) self.assertEqual(np.mean(bkgdImage2.getArray()), self.val)
def run(self, exposure, exposureIdInfo=None, background=None): """Produce characterization outputs with no processing. Parameters ---------- exposure : `lsst.afw.image.Exposure` Exposure to characterize. exposureIdInfo : `lsst.obs.base.ExposureIdInfo` ID info for exposure. background : `lsst.afw.math.BackgroundList` Initial model of background already subtracted from exposure. Returns ------- result : `lsst.pipe.base.Struct` Struct containing these fields: ``characterized`` Characterized exposure (`lsst.afw.image.Exposure`). ``sourceCat`` Detected sources (`lsst.afw.table.SourceCatalog`). ``backgroundModel`` Model of background subtracted from exposure (`lsst.afw.math.BackgroundList`) ``psfCellSet`` Spatial cells of PSF candidates (`lsst.afw.math.SpatialCellSet`) """ # Can't persist empty BackgroundList; DM-33714 bg = afwMath.BackgroundMI( geom.Box2I(geom.Point2I(0, 0), geom.Point2I(16, 16)), afwImage.MaskedImageF(16, 16)) return Struct( characterized=exposure, sourceCat=afwTable.SourceCatalog(), backgroundModel=afwMath.BackgroundList(bg), psfCellSet=afwMath.SpatialCellSet(exposure.getBBox(), 10), )