Skip to content

Commit

Permalink
Merge branch 'tickets/DM-28961'
Browse files Browse the repository at this point in the history
  • Loading branch information
morriscb committed Apr 6, 2021
2 parents 5212702 + e05e6aa commit 4828449
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 33 deletions.
81 changes: 59 additions & 22 deletions python/lsst/ap/association/packageAlerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import lsst.afw.geom as afwGeom
import lsst.geom as geom
import lsst.pex.config as pexConfig
from lsst.pex.exceptions import InvalidParameterError
import lsst.pipe.base as pipeBase


Expand Down Expand Up @@ -128,17 +129,20 @@ def run(self,
sphPoint = geom.SpherePoint(diaSource["ra"],
diaSource["decl"],
geom.degrees)
cutoutBBox = self.createDiaSourceBBox(diaSource["bboxSize"])

cutoutExtent = self.createDiaSourceExtent(diaSource["bboxSize"])
diffImCutout = self.createCcdDataCutout(
diffIm.getCutout(sphPoint, cutoutBBox),
diffIm,
sphPoint,
diffImPhotoCalib)

templateBBox = self.createDiaSourceBBox(diaSource["bboxSize"])
cutoutExtent,
diffImPhotoCalib,
diaSource["diaSourceId"])
templateCutout = self.createCcdDataCutout(
template.getCutout(sphPoint, templateBBox),
template,
sphPoint,
templatePhotoCalib)
cutoutExtent,
templatePhotoCalib,
diaSource["diaSourceId"])

# TODO: Create alertIds DM-24858
alertId = diaSource["diaSourceId"]
Expand All @@ -165,9 +169,9 @@ def _patchDiaSources(self, diaSources):
"""
diaSources["programId"] = 0

def createDiaSourceBBox(self, bboxSize):
"""Create a bounding box for the cutouts given the size of the square
BBox that covers the source footprint.
def createDiaSourceExtent(self, bboxSize):
"""Create a extent for a box for the cutouts given the size of the
square BBox that covers the source footprint.
Parameters
----------
Expand All @@ -176,34 +180,60 @@ def createDiaSourceBBox(self, bboxSize):
Returns
-------
bbox : `lsst.geom.Extent2I`
extent : `lsst.geom.Extent2I`
Geom object representing the size of the bounding box.
"""
if bboxSize < self.config.minCutoutSize:
bbox = geom.Extent2I(self.config.minCutoutSize,
self.config.minCutoutSize)
extent = geom.Extent2I(self.config.minCutoutSize,
self.config.minCutoutSize)
else:
bbox = geom.Extent2I(bboxSize, bboxSize)
return bbox
extent = geom.Extent2I(bboxSize, bboxSize)
return extent

def createCcdDataCutout(self, cutout, skyCenter, photoCalib):
"""Convert a cutout into a calibrate CCDData image.
def createCcdDataCutout(self, image, skyCenter, extent, photoCalib, srcId):
"""Grab an image as a cutout and return a calibrated CCDData image.
Parameters
----------
cutout : `lsst.afw.image.ExposureF`
Cutout to convert.
image : `lsst.afw.image.ExposureF`
Image to pull cutout from.
skyCenter : `lsst.geom.SpherePoint`
Center point of DiaSource on the sky.
extent : `lsst.geom.Extent2I`
Bounding box to cutout from the image.
photoCalib : `lsst.afw.image.PhotoCalib`
Calibrate object of the image the cutout is cut from.
srcId : `int`
Unique id of DiaSource. Used for when an error occurs extracting
a cutout.
Returns
-------
ccdData : `astropy.nddata.CCDData`
ccdData : `astropy.nddata.CCDData` or `None`
CCDData object storing the calibrate information from the input
difference or template image.
"""
# Catch errors in retrieving the cutout.
try:
cutout = image.getCutout(skyCenter, extent)
except InvalidParameterError:
point = image.getWcs().skyToPixel(skyCenter)
imBBox = image.getBBox()
if not geom.Box2D(image.getBBox()).contains(point):
self.log.warn(
"DiaSource id=%i centroid lies at pixel (%.2f, %.2f) "
"which is outside the Exposure with bounding box "
"((%i, %i), (%i, %i)). Returning None for cutout..." %
(srcId, point.x, point.y,
imBBox.minX, imBBox.maxX, imBBox.minY, imBBox.maxY))
else:
raise InvalidParameterError(
"Failed to retrieve cutout from image for DiaSource with "
"id=%i. InvalidParameterError thrown during cutout "
"creation. Exiting."
% srcId)
return None

# Find the value of the bottom corner of our cutout's BBox and
# subtract 1 so that the CCDData cutout position value will be
# [1, 1].
Expand Down Expand Up @@ -310,8 +340,15 @@ def makeAlertDict(self,

alert['ssObject'] = None

alert['cutoutDifference'] = self.streamCcdDataToBytes(diffImCutout)
alert["cutoutTemplate"] = self.streamCcdDataToBytes(templateCutout)
if diffImCutout is None:
alert['cutoutDifference'] = None
else:
alert['cutoutDifference'] = self.streamCcdDataToBytes(diffImCutout)

if templateCutout is None:
alert["cutoutTemplate"] = None
else:
alert["cutoutTemplate"] = self.streamCcdDataToBytes(templateCutout)

return alert

Expand Down
42 changes: 31 additions & 11 deletions tests/test_packageAlerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,31 +333,35 @@ def setUp(self):
self.cutoutWcs.wcs.cd = self.exposure.getWcs().getCdMatrix()
self.cutoutWcs.wcs.ctype = ["RA---TAN", "DEC--TAN"]

def testCreateBBox(self):
"""Test the bbox creation
def testCreateExtent(self):
"""Test the extent creation for the cutout bbox.
"""
packConfig = PackageAlertsConfig()
# Just create a minimum less than the default cutout.
packConfig.minCutoutSize = self.cutoutSize - 5
packageAlerts = PackageAlertsTask(config=packConfig)
bbox = packageAlerts.createDiaSourceBBox(packConfig.minCutoutSize - 5)
self.assertTrue(bbox == geom.Extent2I(packConfig.minCutoutSize,
packConfig.minCutoutSize))
extent = packageAlerts.createDiaSourceExtent(
packConfig.minCutoutSize - 5)
self.assertTrue(extent == geom.Extent2I(packConfig.minCutoutSize,
packConfig.minCutoutSize))
# Test that the cutout size is correct.
bbox = packageAlerts.createDiaSourceBBox(self.cutoutSize)
self.assertTrue(bbox == geom.Extent2I(self.cutoutSize,
self.cutoutSize))
extent = packageAlerts.createDiaSourceExtent(self.cutoutSize)
self.assertTrue(extent == geom.Extent2I(self.cutoutSize,
self.cutoutSize))

def testCreateCcdDataCutout(self):
"""Test that the data is being extracted into the CCDData cutout
correctly.
"""
packageAlerts = PackageAlertsTask()

diaSrcId = 1234
ccdData = packageAlerts.createCcdDataCutout(
self.exposure,
self.exposure.getWcs().getSkyOrigin(),
self.exposure.getPhotoCalib())
self.exposure.getBBox().getDimensions(),
self.exposure.getPhotoCalib(),
diaSrcId)
calibExposure = self.exposure.getPhotoCalib().calibrateImage(
self.exposure.getMaskedImage())

Expand All @@ -366,6 +370,14 @@ def testCreateCcdDataCutout(self):
self.assertFloatsAlmostEqual(ccdData.data,
calibExposure.getImage().array)

ccdData = packageAlerts.createCcdDataCutout(
self.exposure,
geom.SpherePoint(0, 0, geom.degrees),
self.exposure.getBBox().getDimensions(),
self.exposure.getPhotoCalib(),
diaSrcId)
self.assertTrue(ccdData is None)

def testMakeLocalTransformMatrix(self):
"""Test that the local WCS approximation is correct.
"""
Expand Down Expand Up @@ -417,7 +429,11 @@ def testMakeAlertDict(self):
geom.Extent2I(self.cutoutSize,
self.cutoutSize))
ccdCutout = packageAlerts.createCcdDataCutout(
cutout, sphPoint, cutout.getPhotoCalib())
cutout,
sphPoint,
geom.Extent2I(self.cutoutSize, self.cutoutSize),
cutout.getPhotoCalib(),
1234)
cutoutBytes = packageAlerts.streamCcdDataToBytes(
ccdCutout)
objSources = self.diaSourceHistory.loc[srcIdx[0]]
Expand Down Expand Up @@ -479,7 +495,11 @@ def testRun(self):
geom.Extent2I(self.cutoutSize,
self.cutoutSize))
ccdCutout = packageAlerts.createCcdDataCutout(
cutout, sphPoint, cutout.getPhotoCalib())
cutout,
sphPoint,
geom.Extent2I(self.cutoutSize, self.cutoutSize),
cutout.getPhotoCalib(),
1234)
self.assertEqual(alert["cutoutDifference"],
packageAlerts.streamCcdDataToBytes(ccdCutout))

Expand Down

0 comments on commit 4828449

Please sign in to comment.