6060from lsst .pipe .base import PipelineTask , PipelineTaskConfig , PipelineTaskConnections , Struct
6161from lsst .pipe .base .connectionTypes import Input , Output , PrerequisiteInput
6262from lsst .utils .timer import timeMethod
63+ from copy import deepcopy
6364
6465NEIGHBOR_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
0 commit comments