LSST Applications g04a91732dc+146a938ab0,g07dc498a13+80b84b0d75,g0fba68d861+4c4f3dcb5c,g1409bbee79+80b84b0d75,g1a7e361dbc+80b84b0d75,g1fd858c14a+f6e422e056,g20f46db602+333b6c0f32,g35bb328faa+fcb1d3bbc8,g42c1b31a95+a1301e4c20,g4d2262a081+f1facf12e5,g4d39ba7253+9b833be27e,g4e0f332c67+5d362be553,g53246c7159+fcb1d3bbc8,g60b5630c4e+9b833be27e,g78460c75b0+2f9a1b4bcd,g786e29fd12+cf7ec2a62a,g7b71ed6315+fcb1d3bbc8,g8852436030+790117df0f,g89139ef638+80b84b0d75,g8d6b6b353c+9b833be27e,g9125e01d80+fcb1d3bbc8,g989de1cb63+80b84b0d75,g9f33ca652e+9c6b68d7f3,ga9baa6287d+9b833be27e,gaaedd4e678+80b84b0d75,gabe3b4be73+1e0a283bba,gb1101e3267+9f3571abad,gb58c049af0+f03b321e39,gb90eeb9370+691e4ab549,gc741bbaa4f+2bcd3860df,gcf25f946ba+790117df0f,gd315a588df+5b65d88fe4,gd6cbbdb0b4+c8606af20c,gd9a9a58781+fcb1d3bbc8,gde0f65d7ad+ee6a3faa19,ge278dab8ac+932305ba37,ge82c20c137+76d20ab76d,gee8db133a9+2a6ae0040b,w.2025.10
LSST Data Management Base Package
|
Classes | |
class | SubtractBrightStarsConnections |
Variables | |
logger = logging.getLogger(__name__) | |
inputExposure : `~lsst.afw.image.ExposureF` | |
inputBrightStarStamps : | |
inputExtendedPsf : `~lsst.pipe.tasks.extended_psf.ExtendedPsf` | |
dataId : `dict` or `~lsst.daf.butler.DataCoordinate` | |
skyCorr : `~lsst.afw.math.backgroundList.BackgroundList`, optional | |
refObjLoader : `~lsst.meas.algorithms.ReferenceObjectLoader`, optional | |
subtractorExp : `~lsst.afw.image.ExposureF` | |
invImages : `list` [`~lsst.afw.image.MaskedImageF`] | |
invImage : `~lsst.afw.image.MaskedImageF` | |
brightStarStamps : | |
subtractor : `~lsst.afw.image.MaskedImageF` | |
bool | multipleAnnuli , optional |
Retrieve extended PSF model and subtract bright stars at visit level.
lsst.pipe.tasks.subtractBrightStars.brightStarStamps : |
bbox, invImage = self.preparePlaneModelStamp(brightStarStamp) bbox.clip(self.inputExpBBox) if bbox.getArea() > 0: if multipleAnnuli: cond = self.psf_annular_fluxes[:, 0] == brightStarStamp.optimalOuterRadius psf_annular_flux = self.psf_annular_fluxes[cond, 1][0] self.scaleModel( invImage, brightStarStamp, inPlace=True, nb90Rots=self.inv90Rots, psf_annular_flux=psf_annular_flux, ) else: self.scaleModel(invImage, brightStarStamp, inPlace=True, nb90Rots=self.inv90Rots) # Replace NaNs before subtraction (all NaNs have the NO_DATA flag). invImage.image.array[np.isnan(invImage.image.array)] = 0 subtractor[bbox] += invImage[bbox] return subtractor, invImage def buildSubtractor(self, brightStarStamps, subtractor, invImages, multipleAnnuli=False):
Definition at line 810 of file subtractBrightStars.py.
lsst.pipe.tasks.subtractBrightStars.dataId : `dict` or `~lsst.daf.butler.DataCoordinate` |
Definition at line 303 of file subtractBrightStars.py.
lsst.pipe.tasks.subtractBrightStars.inputBrightStarStamps : |
Definition at line 295 of file subtractBrightStars.py.
lsst.pipe.tasks.subtractBrightStars.inputExposure : `~lsst.afw.image.ExposureF` |
doWriteSubtractor = Field[bool]( doc="Should an exposure containing all bright star models be written to disk?", default=True, ) doWriteSubtractedExposure = Field[bool]( doc="Should an exposure with bright stars subtracted be written to disk?", default=True, ) magLimit = Field[float]( doc="Magnitude limit, in Gaia G; all stars brighter than this value will be subtracted", default=18, ) minValidAnnulusFraction = Field[float]( doc="Minimum number of valid pixels that must fall within the annulus for the bright star to be " "saved for subsequent generation of a PSF.", default=0.0, ) numSigmaClip = Field[float]( doc="Sigma for outlier rejection; ignored if annularFluxStatistic != 'MEANCLIP'.", default=4, ) numIter = Field[int]( doc="Number of iterations of outlier rejection; ignored if annularFluxStatistic != 'MEANCLIP'.", default=3, ) warpingKernelName = ChoiceField[str]( doc="Warping kernel", default="lanczos5", allowed={ "bilinear": "bilinear interpolation", "lanczos3": "Lanczos kernel of order 3", "lanczos4": "Lanczos kernel of order 4", "lanczos5": "Lanczos kernel of order 5", "lanczos6": "Lanczos kernel of order 6", "lanczos7": "Lanczos kernel of order 7", }, ) scalingType = ChoiceField[str]( doc="How the model should be scaled to each bright star; implemented options are " "`annularFlux` to reuse the annular flux of each stamp, or `leastSquare` to perform " "least square fitting on each pixel with no bad mask plane set.", default="leastSquare", allowed={ "annularFlux": "reuse BrightStarStamp annular flux measurement", "leastSquare": "find least square scaling factor", }, ) annularFluxStatistic = ChoiceField[str]( doc="Type of statistic to use to compute annular flux.", default="MEANCLIP", allowed={ "MEAN": "mean", "MEDIAN": "median", "MEANCLIP": "clipped mean", }, ) badMaskPlanes = ListField[str]( doc="Mask planes that, if set, lead to associated pixels not being included in the computation of " "the scaling factor (`BAD` should always be included). Ignored if scalingType is `annularFlux`, " "as the stamps are expected to already be normalized.", # Note that `BAD` should always be included, as secondary detected # sources (i.e., detected sources other than the primary source of # interest) also get set to `BAD`. default=("BAD", "CR", "CROSSTALK", "EDGE", "NO_DATA", "SAT", "SUSPECT", "UNMASKEDNAN"), ) subtractionBox = ListField[int]( doc="Size of the stamps to be extracted, in pixels.", default=(250, 250), ) subtractionBoxBuffer = Field[float]( doc=( "'Buffer' (multiplicative) factor to be applied to determine the size of the stamp the " "processed stars will be saved in. This is also the size of the extended PSF model. The buffer " "region is masked and contain no data and subtractionBox determines the region where contains " "the data." ), default=1.1, ) doApplySkyCorr = Field[bool]( doc="Apply full focal plane sky correction before extracting stars?", default=True, ) refObjLoader = ConfigField[LoadReferenceObjectsConfig]( doc="Reference object loader for astrometric calibration.", ) class SubtractBrightStarsTask(PipelineTask):
ConfigClass = SubtractBrightStarsConfig _DefaultName = "subtractBrightStars" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # Placeholders to set up Statistics if scalingType is leastSquare. self.statsControl, self.statsFlag = None, None # Warping control; only contains shiftingALg provided in config. self.warpControl = WarpingControl(self.config.warpingKernelName) def runQuantum(self, butlerQC, inputRefs, outputRefs): # Docstring inherited. inputs = butlerQC.get(inputRefs) if inputs["inputExtendedPsf"].default_extended_psf is None: if not self._detectorInRegions(inputs["inputExposure"], inputs["inputExtendedPsf"]): self.log.warning( "Extended PSF model is not available for detector %i. Skipping withouth processing this " "exposure.", inputs["inputExposure"].detector.getId(), ) return None dataId = butlerQC.quantum.dataId refObjLoader = ReferenceObjectLoader( dataIds=[ref.datasetRef.dataId for ref in inputRefs.refCat], refCats=inputs.pop("refCat"), name=self.config.connections.refCat, config=self.config.refObjLoader, ) subtractor, _, badStamps = self.run(**inputs, dataId=dataId, refObjLoader=refObjLoader) if self.config.doWriteSubtractedExposure: outputExposure = inputs["inputExposure"].clone() outputExposure.image -= subtractor.image if self.config.doApplySkyCorr and (inputs["skyCorr"] is not None): outputExposure.image += inputs["skyCorr"].getImage() else: outputExposure = None outputBackgroundExposure = subtractor if self.config.doWriteSubtractor else None # In its current state, the code produces outputBadStamps which are the # stamps of stars that have not been subtracted from the image for any # reason. If all the stars are subtracted from the calexp, the output # is an empty fits file. output = Struct( outputExposure=outputExposure, outputBackgroundExposure=outputBackgroundExposure, outputBadStamps=badStamps, ) butlerQC.put(output, outputRefs) def run( self, inputExposure, inputBrightStarStamps, inputExtendedPsf, dataId, skyCorr=None, refObjLoader=None ):
Definition at line 293 of file subtractBrightStars.py.
lsst.pipe.tasks.subtractBrightStars.inputExtendedPsf : `~lsst.pipe.tasks.extended_psf.ExtendedPsf` |
Definition at line 300 of file subtractBrightStars.py.
lsst.pipe.tasks.subtractBrightStars.invImage : `~lsst.afw.image.MaskedImageF` |
self.inputExpBBox = inputExposure.getBBox() if self.config.doApplySkyCorr and (skyCorr is not None): self.log.info( "Applying sky correction to exposure %s (exposure will be modified in-place).", dataId ) self.applySkyCorr(inputExposure, skyCorr) # Create an empty image the size of the exposure. # TODO: DM-31085 (set mask planes). subtractorExp = ExposureF(bbox=inputExposure.getBBox()) subtractor = subtractorExp.maskedImage # Make a copy of the input model. self.model = inputExtendedPsf(dataId["detector"]).clone() self.modelStampSize = self.model.getDimensions() # Number of 90 deg. rotations to reverse each stamp's rotation. self.inv90Rots = 4 - inputBrightStarStamps.nb90Rots % 4 self.model = rotateImageBy90(self.model, self.inv90Rots) brightStarList = self.makeBrightStarList(inputBrightStarStamps, inputExposure, refObjLoader) invImages = [] subtractor, invImages = self.buildSubtractor( inputBrightStarStamps, subtractor, invImages, multipleAnnuli=False ) if brightStarList: self.setMissedStarsStatsControl() # This may change when multiple star bins are used for PSF # creation. innerRadius = inputBrightStarStamps._innerRadius outerRadius = inputBrightStarStamps._outerRadius brightStarStamps, badStamps = BrightStarStamps.initAndNormalize( brightStarList, innerRadius=innerRadius, outerRadius=outerRadius, nb90Rots=self.warpOutputs.nb90Rots, imCenter=self.warper.modelCenter, use_archive=True, statsControl=self.missedStatsControl, statsFlag=self.missedStatsFlag, badMaskPlanes=self.warper.config.badMaskPlanes, discardNanFluxObjects=False, forceFindFlux=True, ) self.metadata["subtractedStarCount"] = len(inputBrightStarStamps) + len(brightStarStamps) self.psf_annular_fluxes = self.findPsfAnnularFluxes(brightStarStamps) subtractor, invImages = self.buildSubtractor( brightStarStamps, subtractor, invImages, multipleAnnuli=True ) else: self.metadata["subtractedStarCount"] = len(inputBrightStarStamps) badStamps = [] badStamps = BrightStarStamps(badStamps) return subtractorExp, invImages, badStamps def _detectorInRegions(self, inputExposure, inputExtendedPsf):
Definition at line 780 of file subtractBrightStars.py.
lsst.pipe.tasks.subtractBrightStars.invImages : `list` [`~lsst.afw.image.MaskedImageF`] |
Definition at line 319 of file subtractBrightStars.py.
lsst.pipe.tasks.subtractBrightStars.logger = logging.getLogger(__name__) |
Definition at line 49 of file subtractBrightStars.py.
bool lsst.pipe.tasks.subtractBrightStars.multipleAnnuli , optional |
Definition at line 821 of file subtractBrightStars.py.
lsst.pipe.tasks.subtractBrightStars.refObjLoader : `~lsst.meas.algorithms.ReferenceObjectLoader`, optional |
Definition at line 310 of file subtractBrightStars.py.
lsst.pipe.tasks.subtractBrightStars.skyCorr : `~lsst.afw.math.backgroundList.BackgroundList`, optional |
Definition at line 306 of file subtractBrightStars.py.
lsst.pipe.tasks.subtractBrightStars.subtractor : `~lsst.afw.image.MaskedImageF` |
Definition at line 815 of file subtractBrightStars.py.
lsst.pipe.tasks.subtractBrightStars.subtractorExp : `~lsst.afw.image.ExposureF` |
Definition at line 315 of file subtractBrightStars.py.