lsst.ip.diffim g47cf500ddd+6bfc5ab05d
|
Classes | |
class | DetectAndMeasureConnections |
Variables | |
expId : `int` | |
expBits : `int` | |
idFactory : `lsst.afw.table.IdFactory` | |
science : `lsst.afw.image.ExposureF` | |
matchedTemplate : `lsst.afw.image.ExposureF` | |
difference : `lsst.afw.image.ExposureF` | |
measurementResults : `lsst.pipe.base.Struct` | |
sources : `lsst.afw.table.SourceCatalog` | |
positiveFootprints : `lsst.afw.detection.FootprintSet`, optional | |
negativeFootprints : `lsst.afw.detection.FootprintSet`, optional | |
table : `lsst.afw.table.SourceTable` | |
diaSources : `lsst.afw.table.SourceCatalog` | |
mask : `lsst.afw.image.Mask` | |
seed : `int` | |
wcs : `lsst.afw.geom.SkyWcs` | |
scoreExposure : `lsst.afw.image.ExposureF` | |
lsst.ip.diffim.detectAndMeasure.diaSources : `lsst.afw.table.SourceCatalog` |
if self.config.doMerge: fpSet = positiveFootprints fpSet.merge(negativeFootprints, self.config.growFootprint, self.config.growFootprint, False) diaSources = afwTable.SourceCatalog(table) fpSet.makeSources(diaSources) self.log.info("Merging detections into %d sources", len(diaSources)) else: diaSources = sources if self.config.doSkySources: self.addSkySources(diaSources, difference.mask, difference.info.id) self.measureDiaSources(diaSources, science, difference, matchedTemplate) if self.config.doForcedMeasurement: self.measureForcedSources(diaSources, science, difference.getWcs()) measurementResults = pipeBase.Struct( subtractedMeasuredExposure=difference, diaSources=diaSources, ) return measurementResults def addSkySources(self, diaSources, mask, seed):
skySourceFootprints = self.skySources.run(mask=mask, seed=seed) if skySourceFootprints: for foot in skySourceFootprints: s = diaSources.addNew() s.setFootprint(foot) s.set(self.skySourceKey, True) def measureDiaSources(self, diaSources, science, difference, matchedTemplate):
# Note that this may not be correct if we convolved the science image. # In the future we may wish to persist the matchedScience image. self.measurement.run(diaSources, difference, science, matchedTemplate) if self.config.doApCorr: apCorrMap = difference.getInfo().getApCorrMap() if apCorrMap is None: self.log.warning("Difference image does not have valid aperture correction; skipping.") else: self.applyApCorr.run( catalog=diaSources, apCorrMap=apCorrMap, ) def measureForcedSources(self, diaSources, science, wcs):
Definition at line 381 of file detectAndMeasure.py.
lsst.ip.diffim.detectAndMeasure.difference : `lsst.afw.image.ExposureF` |
Definition at line 290 of file detectAndMeasure.py.
lsst.ip.diffim.detectAndMeasure.expBits : `int` |
Definition at line 246 of file detectAndMeasure.py.
lsst.ip.diffim.detectAndMeasure.expId : `int` |
doMerge = pexConfig.Field( dtype=bool, default=True, doc="Merge positive and negative diaSources with grow radius " "set by growFootprint" ) doForcedMeasurement = pexConfig.Field( dtype=bool, default=True, doc="Force photometer diaSource locations on PVI?") doAddMetrics = pexConfig.Field( dtype=bool, default=False, doc="Add columns to the source table to hold analysis metrics?" ) detection = pexConfig.ConfigurableField( target=SourceDetectionTask, doc="Final source detection for diaSource measurement", ) measurement = pexConfig.ConfigurableField( target=DipoleFitTask, doc="Task to measure sources on the difference image.", ) doApCorr = lsst.pex.config.Field( dtype=bool, default=True, doc="Run subtask to apply aperture corrections" ) applyApCorr = lsst.pex.config.ConfigurableField( target=ApplyApCorrTask, doc="Task to apply aperture corrections" ) forcedMeasurement = pexConfig.ConfigurableField( target=ForcedMeasurementTask, doc="Task to force photometer science image at diaSource locations.", ) growFootprint = pexConfig.Field( dtype=int, default=2, doc="Grow positive and negative footprints by this many pixels before merging" ) diaSourceMatchRadius = pexConfig.Field( dtype=float, default=0.5, doc="Match radius (in arcseconds) for DiaSource to Source association" ) doSkySources = pexConfig.Field( dtype=bool, default=False, doc="Generate sky sources?", ) skySources = pexConfig.ConfigurableField( target=SkyObjectsTask, doc="Generate sky sources", ) idGenerator = DetectorVisitIdGeneratorConfig.make_field() def setDefaults(self): # DiaSource Detection self.detection.thresholdPolarity = "both" self.detection.thresholdValue = 5.0 self.detection.reEstimateBackground = False self.detection.thresholdType = "pixel_stdev" self.detection.excludeMaskPlanes = ["EDGE"] # Add filtered flux measurement, the correct measurement for pre-convolved images. self.measurement.algorithms.names.add('base_PeakLikelihoodFlux') self.measurement.plugins.names |= ['ext_trailedSources_Naive', 'base_LocalPhotoCalib', 'base_LocalWcs', 'ext_shapeHSM_HsmSourceMoments', 'ext_shapeHSM_HsmPsfMoments', ] self.measurement.slots.psfShape = "ext_shapeHSM_HsmPsfMoments" self.measurement.slots.shape = "ext_shapeHSM_HsmSourceMoments" self.measurement.plugins["base_NaiveCentroid"].maxDistToPeak = 5.0 self.measurement.plugins["base_SdssCentroid"].maxDistToPeak = 5.0 self.forcedMeasurement.plugins = ["base_TransformedCentroid", "base_PsfFlux"] self.forcedMeasurement.copyColumns = { "id": "objectId", "parent": "parentObjectId", "coord_ra": "coord_ra", "coord_dec": "coord_dec"} self.forcedMeasurement.slots.centroid = "base_TransformedCentroid" self.forcedMeasurement.slots.shape = None # Keep track of which footprints contain streaks self.measurement.plugins['base_PixelFlags'].masksFpAnywhere = ['STREAK'] self.measurement.plugins['base_PixelFlags'].masksFpCenter = ['STREAK'] class DetectAndMeasureTask(lsst.pipe.base.PipelineTask):
ConfigClass = DetectAndMeasureConfig _DefaultName = "detectAndMeasure" def __init__(self, **kwargs): super().__init__(**kwargs) self.schema = afwTable.SourceTable.makeMinimalSchema() # Add coordinate error fields: afwTable.CoordKey.addErrorFields(self.schema) self.algMetadata = dafBase.PropertyList() self.makeSubtask("detection", schema=self.schema) self.makeSubtask("measurement", schema=self.schema, algMetadata=self.algMetadata) if self.config.doApCorr: self.makeSubtask("applyApCorr", schema=self.measurement.schema) if self.config.doForcedMeasurement: self.schema.addField( "ip_diffim_forced_PsfFlux_instFlux", "D", "Forced PSF flux measured on the direct image.", units="count") self.schema.addField( "ip_diffim_forced_PsfFlux_instFluxErr", "D", "Forced PSF flux error measured on the direct image.", units="count") self.schema.addField( "ip_diffim_forced_PsfFlux_area", "F", "Forced PSF flux effective area of PSF.", units="pixel") self.schema.addField( "ip_diffim_forced_PsfFlux_flag", "Flag", "Forced PSF flux general failure flag.") self.schema.addField( "ip_diffim_forced_PsfFlux_flag_noGoodPixels", "Flag", "Forced PSF flux not enough non-rejected pixels in data to attempt the fit.") self.schema.addField( "ip_diffim_forced_PsfFlux_flag_edge", "Flag", "Forced PSF flux object was too close to the edge of the image to use the full PSF model.") self.makeSubtask("forcedMeasurement", refSchema=self.schema) self.schema.addField("refMatchId", "L", "unique id of reference catalog match") self.schema.addField("srcMatchId", "L", "unique id of source match") if self.config.doSkySources: self.makeSubtask("skySources") self.skySourceKey = self.schema.addField("sky_source", type="Flag", doc="Sky objects.") # initialize InitOutputs self.outputSchema = afwTable.SourceCatalog(self.schema) self.outputSchema.getTable().setMetadata(self.algMetadata) # TODO: remove on DM-38687. @staticmethod @deprecated( reason=( "ID factory construction now depends on configuration; use the " "idGenerator config field. Will be removed after v26." ), version="v26.0", category=FutureWarning, ) def makeIdFactory(expId, expBits):
Definition at line 243 of file detectAndMeasure.py.
lsst.ip.diffim.detectAndMeasure.idFactory : `lsst.afw.table.IdFactory` |
Definition at line 257 of file detectAndMeasure.py.
lsst.ip.diffim.detectAndMeasure.mask : `lsst.afw.image.Mask` |
Definition at line 383 of file detectAndMeasure.py.
lsst.ip.diffim.detectAndMeasure.matchedTemplate : `lsst.afw.image.ExposureF` |
Definition at line 287 of file detectAndMeasure.py.
lsst.ip.diffim.detectAndMeasure.measurementResults : `lsst.pipe.base.Struct` |
Definition at line 297 of file detectAndMeasure.py.
lsst.ip.diffim.detectAndMeasure.negativeFootprints : `lsst.afw.detection.FootprintSet`, optional |
Definition at line 329 of file detectAndMeasure.py.
lsst.ip.diffim.detectAndMeasure.positiveFootprints : `lsst.afw.detection.FootprintSet`, optional |
Definition at line 327 of file detectAndMeasure.py.
lsst.ip.diffim.detectAndMeasure.science : `lsst.afw.image.ExposureF` |
return ExposureIdInfo(expId, expBits).makeSourceIdFactory() def runQuantum(self, butlerQC: pipeBase.ButlerQuantumContext, inputRefs: pipeBase.InputQuantizedConnection, outputRefs: pipeBase.OutputQuantizedConnection): inputs = butlerQC.get(inputRefs) idGenerator = self.config.idGenerator.apply(butlerQC.quantum.dataId) idFactory = idGenerator.make_table_id_factory() outputs = self.run(**inputs, idFactory=idFactory) butlerQC.put(outputs, outputRefs) @timeMethod def run(self, science, matchedTemplate, difference, idFactory=None):
# Run forced psf photometry on the PVI at the diaSource locations. # Copy the measured flux and error into the diaSource. forcedSources = self.forcedMeasurement.generateMeasCat( science, diaSources, wcs) self.forcedMeasurement.run(forcedSources, science, diaSources, wcs) mapper = afwTable.SchemaMapper(forcedSources.schema, diaSources.schema) mapper.addMapping(forcedSources.schema.find("base_PsfFlux_instFlux")[0], "ip_diffim_forced_PsfFlux_instFlux", True) mapper.addMapping(forcedSources.schema.find("base_PsfFlux_instFluxErr")[0], "ip_diffim_forced_PsfFlux_instFluxErr", True) mapper.addMapping(forcedSources.schema.find("base_PsfFlux_area")[0], "ip_diffim_forced_PsfFlux_area", True) mapper.addMapping(forcedSources.schema.find("base_PsfFlux_flag")[0], "ip_diffim_forced_PsfFlux_flag", True) mapper.addMapping(forcedSources.schema.find("base_PsfFlux_flag_noGoodPixels")[0], "ip_diffim_forced_PsfFlux_flag_noGoodPixels", True) mapper.addMapping(forcedSources.schema.find("base_PsfFlux_flag_edge")[0], "ip_diffim_forced_PsfFlux_flag_edge", True) for diaSource, forcedSource in zip(diaSources, forcedSources): diaSource.assign(forcedSource, mapper) class DetectAndMeasureScoreConnections(DetectAndMeasureConnections): scoreExposure = pipeBase.connectionTypes.Input( doc="Maximum likelihood image for detection.", dimensions=("instrument", "visit", "detector"), storageClass="ExposureF", name="{fakesType}{coaddName}Diff_scoreExp", ) class DetectAndMeasureScoreConfig(DetectAndMeasureConfig, pipelineConnections=DetectAndMeasureScoreConnections): pass class DetectAndMeasureScoreTask(DetectAndMeasureTask):
ConfigClass = DetectAndMeasureScoreConfig _DefaultName = "detectAndMeasureScore" @timeMethod def run(self, science, matchedTemplate, difference, scoreExposure, idFactory=None):
Definition at line 285 of file detectAndMeasure.py.
lsst.ip.diffim.detectAndMeasure.scoreExposure : `lsst.afw.image.ExposureF` |
Definition at line 500 of file detectAndMeasure.py.
lsst.ip.diffim.detectAndMeasure.seed : `int` |
Definition at line 385 of file detectAndMeasure.py.
lsst.ip.diffim.detectAndMeasure.sources : `lsst.afw.table.SourceCatalog` |
# Ensure that we start with an empty detection mask. mask = difference.mask mask &= ~(mask.getPlaneBitMask("DETECTED") | mask.getPlaneBitMask("DETECTED_NEGATIVE")) table = afwTable.SourceTable.make(self.schema, idFactory) table.setMetadata(self.algMetadata) results = self.detection.run( table=table, exposure=difference, doSmooth=True, ) return self.processResults(science, matchedTemplate, difference, results.sources, table, positiveFootprints=results.positive, negativeFootprints=results.negative) def processResults(self, science, matchedTemplate, difference, sources, table, positiveFootprints=None, negativeFootprints=None,):
Definition at line 325 of file detectAndMeasure.py.
lsst.ip.diffim.detectAndMeasure.table : `lsst.afw.table.SourceTable` |
Definition at line 331 of file detectAndMeasure.py.
lsst.ip.diffim.detectAndMeasure.wcs : `lsst.afw.geom.SkyWcs` |
Definition at line 432 of file detectAndMeasure.py.