Skip to content

Commit

Permalink
Update with new afw footprint API
Browse files Browse the repository at this point in the history
  • Loading branch information
fred3m committed May 22, 2023
1 parent 54e891a commit 0525d6a
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 42 deletions.
14 changes: 7 additions & 7 deletions python/lsst/summit/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,8 @@ def fluxesFromFootprints(footprints, parentImage, subtractImageMedian=False):
`lsst.afw.detection.Footprint` or
`iterable` of `lsst.afw.detection.Footprint`
The footprints to measure.
parentImage : `lsst.afw.image.Exposure`
The parent exposure.
parentImage : `lsst.afw.image.Image`
The parent image.
subtractImageMedian : `bool`, optional
Subtract a whole-image median from each pixel in the footprint when
summing as a very crude background subtraction. Does not change the
Expand All @@ -336,7 +336,7 @@ def fluxesFromFootprints(footprints, parentImage, subtractImageMedian=False):
"""
median = 0
if subtractImageMedian:
median = np.nanmedian(parentImage.image.array)
median = np.nanmedian(parentImage.array)

# poor person's single dispatch
badTypeMsg = ("This function works with FootprintSets, single Footprints, and iterables of Footprints. "
Expand All @@ -363,8 +363,8 @@ def fluxFromFootprint(footprint, parentImage, backgroundValue=0):
----------
footprint : `lsst.afw.detection.Footprint`
The footprint to measure.
parentImage : `lsst.afw.image.Exposure`
The parent exposure.
parentImage : `lsst.afw.image.Image`
The parent image.
backgroundValue : `bool`, optional
The value to subtract from each pixel in the footprint when summing
as a very crude background subtraction. Does not change the original
Expand All @@ -376,8 +376,8 @@ def fluxFromFootprint(footprint, parentImage, backgroundValue=0):
The flux in the footprint
"""
if backgroundValue: # only do the subtraction if non-zero for speed
return footprint.getSpans().flatten(parentImage.image.array - backgroundValue).sum()
return footprint.getSpans().flatten(parentImage.image.array).sum()
return footprint.getSpans().flatten(parentImage.array - backgroundValue).sum()
return footprint.extractFluxFromImage(parentImage)


def humanNameForCelestialObject(objName):
Expand Down
70 changes: 35 additions & 35 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@

import astropy.time
import astropy.units as u
import lsst.afw.detection as afwDetect
import lsst.afw.image as afwImage
import lsst.afw.geom as afwGeom
import lsst.geom as geom
import lsst.utils.tests
import numpy as np
Expand All @@ -43,10 +45,7 @@
getFilterSeeingCorrection,
quickSmooth,
fluxesFromFootprints,
detectObjectsInExp,
)
from lsst.summit.utils.bestEffort import BestEffortIsr
from lsst.summit.utils.butlerUtils import makeDefaultLatissButler

from lsst.obs.lsst.translators.latiss import AUXTEL_LOCATION

Expand All @@ -60,7 +59,7 @@ def setUp(self):
self.detector = camera[0]

self.viMaker = MakeRawVisitInfoViaObsInfo()
self.mi = afwImage.maskedImage.MaskedImageF(0, 0)
self.mi = afwImage.MaskedImageF(0, 0)
self.baseHeader = dict(boresight_airmass=1.5,
temperature=15*u.deg_C,
observation_type="science",
Expand Down Expand Up @@ -197,53 +196,54 @@ def test_quickSmooth(self):
class ImageBasedTestCase(lsst.utils.tests.TestCase):
"""A test case for testing sky position offsets for exposures."""

@classmethod
def setUpClass(cls):
try:
cls.butler = makeDefaultLatissButler()
except FileNotFoundError:
raise unittest.SkipTest("Skipping tests that require the LATISS butler repo.")
def test_fluxFromFootprint(self):
image = afwImage.Image(
np.arange(8100, dtype=np.int32).reshape(90, 90),
xy0=lsst.geom.Point2I(10, 12),
dtype="I"
)

cls.dataId = {'day_obs': 20200315, 'seq_num': 120, 'detector': 0}
cls.bestEffort = BestEffortIsr() # should always succeed if makeDefaultLatissButler works
cls.exp = cls.bestEffort.getExposure(cls.dataId)
radius = 3
spans = afwGeom.SpanSet.fromShape(radius, afwGeom.Stencil.CIRCLE, offset=(27, 30))
footprint1 = afwDetect.Footprint(spans)

def test_fluxFromFootprint(self):
footPrintSet = detectObjectsInExp(self.exp)
allFootprints = footPrintSet.getFootprints()
self.assertGreaterEqual(len(allFootprints), 3)
singleFootprint = allFootprints[0]
twoFootprints = allFootprints[0:2]
# The extracted footprint should be the same as the product of the
# spans and the overlapped bow with the image
truth1 = spans.asArray() * image.array[15:22, 14:21]

radius = 3
spans = afwGeom.SpanSet.fromShape(radius, afwGeom.Stencil.CIRCLE, offset=(44, 49))
footprint2 = afwDetect.Footprint(spans)
truth2 = spans.asArray() * image.array[34:41, 31:38]

allFootprints = [footprint1, footprint2]
footprintSet = afwDetect.FootprintSet(image.getBBox())
footprintSet.setFootprints(allFootprints)

# check it can accept a footprintSet, and single and iterables of
# footprints

# check the footPrintSet
fluxes = fluxesFromFootprints(footPrintSet, self.exp)
expectedLength = len(footPrintSet.getFootprints())
self.assertEqual(len(fluxes), expectedLength) # always one flux per footprint
self.assertIsInstance(fluxes, Iterable)
self.assertIsInstance(fluxes[0], np.floating) # always returns floats

# check the singleFootprint
fluxes = fluxesFromFootprints(singleFootprint, self.exp)
expectedLength = 1
fluxes = fluxesFromFootprints(footprintSet, image)
expectedLength = len(footprintSet.getFootprints())
self.assertEqual(len(fluxes), expectedLength) # always one flux per footprint
self.assertIsInstance(fluxes, Iterable)
self.assertIsInstance(fluxes[0], np.floating) # always returns floats
self.assertAlmostEqual(fluxes[0], np.sum(truth1))
self.assertAlmostEqual(fluxes[1], np.sum(truth2))

# check the list of twoFootprints
fluxes = fluxesFromFootprints(twoFootprints, self.exp)
# check the list of footprints
fluxes = fluxesFromFootprints(allFootprints, image)
expectedLength = 2
self.assertEqual(len(fluxes), expectedLength) # always one flux per footprint
self.assertIsInstance(fluxes, Iterable)
self.assertIsInstance(fluxes[0], np.floating) # always returns floats
self.assertAlmostEqual(fluxes[0], np.sum(truth1))
self.assertAlmostEqual(fluxes[1], np.sum(truth2))

# ensure that subtracting the image median from fluxes leave image
# functionally unchanged
oldExpArray = copy.deepcopy(self.exp.image.array)
fluxes = fluxesFromFootprints(footPrintSet, self.exp, subtractImageMedian=True)
self.assertTrue(np.alltrue(np.equal(self.exp.image.array, oldExpArray)))
oldImageArray = copy.deepcopy(image.array)
fluxes = fluxesFromFootprints(footprintSet, image, subtractImageMedian=True)
np.testing.assert_array_equal(image.array, oldImageArray)


class TestMemory(lsst.utils.tests.MemoryTestCase):
Expand Down

0 comments on commit 0525d6a

Please sign in to comment.