Skip to content

Commit 7943900

Browse files
bazkiaeiAmir Ebadati Bazkiaei
authored andcommitted
tickets/DM-48377 draft
1 parent 8fa37a3 commit 7943900

File tree

3 files changed

+840
-6
lines changed

3 files changed

+840
-6
lines changed

python/lsst/pipe/tasks/brightStarSubtraction/brightStarCutout.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
from lsst.pipe.base import PipelineTask, PipelineTaskConfig, PipelineTaskConnections, Struct
6161
from lsst.pipe.base.connectionTypes import Input, Output, PrerequisiteInput
6262
from lsst.utils.timer import timeMethod
63+
from copy import deepcopy
6364

6465
NEIGHBOR_MASK_PLANE = "NEIGHBOR"
6566

@@ -293,6 +294,8 @@ def run(
293294
# Restore original subtracted background
294295
inputMI = inputExposure.getMaskedImage()
295296
inputMI += inputBackground.getImage()
297+
# Amir: the above addition to inputMI, also adds to the inputExposure.
298+
# Amir: but the calibration, three lines later, only is applied to the inputMI.
296299

297300
# Set up NEIGHBOR mask plane; associate footprints with stars
298301
inputExposure.mask.addMaskPlane(NEIGHBOR_MASK_PLANE)
@@ -317,9 +320,11 @@ def run(
317320
# Set NEIGHBOR footprints in the mask plane
318321
if footprintIndex:
319322
neighborFootprints = [fp for i, fp in enumerate(allFootprints) if i != footprintIndex]
320-
self._setFootprints(inputExposure, neighborFootprints, NEIGHBOR_MASK_PLANE)
323+
# self._setFootprints(inputExposure, neighborFootprints, NEIGHBOR_MASK_PLANE)
324+
self._setFootprints(inputMI, neighborFootprints, NEIGHBOR_MASK_PLANE)
321325
else:
322-
self._setFootprints(inputExposure, allFootprints, NEIGHBOR_MASK_PLANE)
326+
# self._setFootprints(inputExposure, allFootprints, NEIGHBOR_MASK_PLANE)
327+
self._setFootprints(inputMI, allFootprints, NEIGHBOR_MASK_PLANE)
323328

324329
# Define linear shifting to recenter stamps
325330
coordFocalPlaneTan = pixToFocalPlaneTan.applyForward(pixCoord) # center of warped star
@@ -329,7 +334,8 @@ def run(
329334
pixToPolar = pixToFocalPlaneTan.then(shift).then(rotation)
330335

331336
# Apply the warp to the star stamp (in-place)
332-
warpImage(stampMI, inputExposure.maskedImage, pixToPolar, warpingControl)
337+
# warpImage(stampMI, inputExposure.maskedImage, pixToPolar, warpingControl)
338+
warpImage(stampMI, inputMI, pixToPolar, warpingControl)
333339

334340
# Trim to the base stamp size, check mask coverage, update metadata
335341
stampMI = stampMI[self.stampBBox]
@@ -579,6 +585,7 @@ def _fitPsf(self, stampMI: MaskedImageF, psfImage: ImageD | ImageF) -> dict[str,
579585
psfMaskedPixels = ImageF(psfImage.getBBox())
580586
psfMaskedPixels.array[:, :] = (stampMI.mask[psfImage.getBBox()].array & badMaskBitMask).astype(bool)
581587
# TODO: This is np.float64, else FITS metadata serialization fails
588+
# Amir: the following tries to find the fraction of the psf flux in the masked area of the psf image.
582589
psfMaskedFluxFrac = np.dot(psfImage.array.flat, psfMaskedPixels.array.flat).astype(np.float64)
583590
if psfMaskedFluxFrac > self.config.psfMaskedFluxFracThreshold:
584591
return {} # Handle cases where the PSF image is mostly masked
@@ -587,8 +594,10 @@ def _fitPsf(self, stampMI: MaskedImageF, psfImage: ImageD | ImageF) -> dict[str,
587594
paddedPsfImage = ImageF(stampMI.getBBox())
588595
paddedPsfImage[psfImage.getBBox()] = psfImage.convertF()
589596

597+
mask = self.add_psf_mask(paddedPsfImage, stampMI)
590598
# Create consistently masked data
591-
badSpans = SpanSet.fromMask(stampMI.mask, badMaskBitMask)
599+
# badSpans = SpanSet.fromMask(stampMI.mask, badMaskBitMask)
600+
badSpans = SpanSet.fromMask(mask, badMaskBitMask)
592601
goodSpans = SpanSet(stampMI.getBBox()).intersectNot(badSpans)
593602
varianceData = goodSpans.flatten(stampMI.variance.array, stampMI.getXY0())
594603
if self.config.useMedianVariance:
@@ -598,7 +607,6 @@ def _fitPsf(self, stampMI: MaskedImageF, psfImage: ImageD | ImageF) -> dict[str,
598607
imageData /= sigmaData
599608
psfData = goodSpans.flatten(paddedPsfImage.array, paddedPsfImage.getXY0())
600609
psfData /= sigmaData
601-
602610
# Fit the PSF scale factor and global pedestal
603611
nData = len(imageData)
604612
coefficientMatrix = np.ones((nData, 4), dtype=float) # A
@@ -659,3 +667,10 @@ def _fitPsf(self, stampMI: MaskedImageF, psfImage: ImageD | ImageF) -> dict[str,
659667
psfDegreesOfFreedom=psfBBoxDegreesOfFreedom,
660668
psfMaskedFluxFrac=psfMaskedFluxFrac,
661669
)
670+
671+
def add_psf_mask(self, psfImage, stampMI):
672+
cond = np.isnan(psfImage.array)
673+
cond |= psfImage.array < 0
674+
mask = deepcopy(stampMI.mask)
675+
mask.array[cond] = np.bitwise_or(mask.array[cond], 1)
676+
return mask

python/lsst/pipe/tasks/brightStarSubtraction/brightStarStack.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
__all__ = ["BrightStarStackConnections", "BrightStarStackConfig", "BrightStarStackTask"]
2525

2626
import numpy as np
27-
from lsst.afw.image import ImageF
27+
from lsst.afw.image import ImageF, MaskedImageF
2828
from lsst.afw.math import StatisticsControl, statisticsStack, stringToStatisticsProperty
2929
from lsst.geom import Box2I, Extent2I, Point2I
3030
from lsst.meas.algorithms import BrightStarStamps
@@ -187,19 +187,24 @@ def run(
187187
badMaskBitMask = stampMI.mask.getPlaneBitMask(self.config.badMaskPlanes)
188188
statisticsControl.setAndMask(badMaskBitMask)
189189

190+
# Amir: In case the total number of stamps is less than 20, the following will result in an
191+
# empty subsetStampMIs list.
190192
if len(tempStampMIs) == self.config.subsetStampNumber:
191193
subsetStampMIs.append(statisticsStack(tempStampMIs, stackTypeProperty, statisticsControl))
192194
# TODO: what to do with remaining temp stamps?
193195
tempStampMIs = []
194196

195197
# TODO: which stamp mask plane to use here?
198+
# TODO: Amir: there might be cases where subsetStampMIs is an empty list. What do we want to do then?
199+
# Currently, we get an "IndexError: list index out of range"
196200
badMaskBitMask = subsetStampMIs[0].mask.getPlaneBitMask(self.config.badMaskPlanes)
197201
statisticsControl.setAndMask(badMaskBitMask)
198202
extendedPsfMI = statisticsStack(subsetStampMIs, stackTypeProperty, statisticsControl)
199203

200204
extendedPsfExtent = extendedPsfMI.getBBox().getDimensions()
201205
extendedPsfOrigin = Point2I(-1 * (extendedPsfExtent.x // 2), -1 * (extendedPsfExtent.y // 2))
202206
extendedPsfMI.setXY0(extendedPsfOrigin)
207+
# return Struct(extendedPsf=[extendedPsfMI])
203208

204209
return Struct(extendedPsf=extendedPsfMI.getImage())
205210

0 commit comments

Comments
 (0)