32 """!Configuration for propagating flags to coadd""" 34 default={
"calib_psf_candidate": 0.2,
"calib_psf_used": 0.2,
"calib_psf_reserved": 0.2,
35 "calib_astrometry_used": 0.2,
"calib_photometry_used": 0.2,
36 "calib_photometry_reserved": 0.2, },
37 doc=(
"Source catalog flags to propagate, with the threshold of relative occurrence " 38 "(valid range: [0-1], default is 0.2). Coadd object will have flag set if the " 39 "fraction of input visits in which it is flagged is greater than the threshold."))
40 matchRadius =
Field(dtype=float, default=0.2, doc=
"Source matching radius (arcsec)")
41 ccdName =
Field(dtype=str, default=
'ccd', doc=
"Name of ccd to give to butler")
52 r"""!Task to propagate flags from single-frame measurements to coadd measurements 54 \anchor PropagateVisitFlagsTask_ 56 \brief Propagate flags from individual visit measurements to coadd measurements 58 \section pipe_tasks_propagateVisitFlagsTask_Contents Contents 60 - \ref pipe_tasks_propagateVisitFlagsTask_Description 61 - \ref pipe_tasks_propagateVisitFlagsTask_Initialization 62 - \ref pipe_tasks_propagateVisitFlagsTask_Config 63 - \ref pipe_tasks_propagateVisitFlagsTask_Use 64 - \ref pipe_tasks_propagateVisitFlagsTask_Example 66 \section pipe_tasks_propagateVisitFlagsTask_Description Description 68 \copybrief PropagateVisitFlagsTask 70 We want to be able to set a flag for sources on the coadds using flags 71 that were determined from the individual visits. A common example is sources 72 that were used for PSF determination, since we do not do any PSF determination 73 on the coadd but use the individual visits. This requires matching the coadd 74 source catalog to each of the catalogs from the inputs (see 75 PropagateVisitFlagsConfig.matchRadius), and thresholding on the number of 76 times a source is flagged on the input catalog. 78 An important consideration in this is that the flagging of sources in the 79 individual visits can be somewhat stochastic, e.g., the same stars may not 80 always be used for PSF determination because the field of view moves slightly 81 between visits, or the seeing changed. We there threshold on the relative 82 occurrence of the flag in the visits (see PropagateVisitFlagsConfig.flags). 83 Flagging a source that is always flagged in inputs corresponds to a threshold 84 of 1, while flagging a source that is flagged in any of the input corresponds 85 to a threshold of 0. But neither of these extrema are really useful in 88 Setting the threshold too high means that sources that are not consistently 89 flagged (e.g., due to chip gaps) will not have the flag propagated. Setting 90 that threshold too low means that random sources which are falsely flagged in 91 the inputs will start to dominate. If in doubt, we suggest making this 92 threshold relatively low, but not zero (e.g., 0.1 to 0.2 or so). The more 93 confidence in the quality of the flagging, the lower the threshold can be. 95 The relative occurrence accounts for the edge of the field-of-view of the 96 camera, but does not include chip gaps, bad or saturated pixels, etc. 98 \section pipe_tasks_propagateVisitFlagsTask_Initialization Initialization 100 Beyond the usual Task initialization, PropagateVisitFlagsTask also requires 101 a schema for the catalog that is being constructed. 103 \section pipe_tasks_propagateVisitFlagsTask_Config Configuration parameters 105 See \ref PropagateVisitFlagsConfig 107 \section pipe_tasks_propagateVisitFlagsTask_Use Use 109 The 'run' method (described below) is the entry-point for operations. The 110 'getCcdInputs' staticmethod is provided as a convenience for retrieving the 111 'ccdInputs' (CCD inputs table) from an Exposure. 115 \section pipe_tasks_propagateVisitFlagsTask_Example Example 119 # * butler: data butler, for retrieving the CCD catalogs 120 # * coaddCatalog: catalog of source measurements on the coadd (lsst.afw.table.SourceCatalog) 121 # * coaddExposure: coadd (lsst.afw.image.Exposure) 122 from lsst.pipe.tasks.propagateVisitFlags import PropagateVisitFlagsTask, PropagateVisitFlagsConfig 123 config = PropagateVisitFlagsConfig() 124 config.flags["calib_psf_used"] = 0.3 # Relative threshold for this flag 125 config.matchRadius = 0.5 # Matching radius in arcsec 126 task = PropagateVisitFlagsTask(coaddCatalog.schema, config=config) 127 ccdInputs = task.getCcdInputs(coaddExposure) 128 task.run(butler, coaddCatalog, ccdInputs, coaddExposure.getWcs()) 131 ConfigClass = PropagateVisitFlagsConfig
134 Task.__init__(self, **kwargs)
136 self.
_keys = dict((f, self.
schema.addField(f, type=
"Flag", doc=
"Propagated from visits"))
for 141 """!Convenience method to retrieve the CCD inputs table from a coadd exposure""" 142 return coaddExposure.getInfo().getCoaddInputs().ccds
144 def run(self, butler, coaddSources, ccdInputs, coaddWcs, visitCatalogs=None, wcsUpdates=None):
145 """!Propagate flags from individual visit measurements to coadd 147 This requires matching the coadd source catalog to each of the catalogs 148 from the inputs, and thresholding on the number of times a source is 149 flagged on the input catalog. The threshold is made on the relative 150 occurrence of the flag in each source. Flagging a source that is always 151 flagged in inputs corresponds to a threshold of 1, while flagging a 152 source that is flagged in any of the input corresponds to a threshold of 153 0. But neither of these extrema are really useful in practise. 155 Setting the threshold too high means that sources that are not consistently 156 flagged (e.g., due to chip gaps) will not have the flag propagated. Setting 157 that threshold too low means that random sources which are falsely flagged in 158 the inputs will start to dominate. If in doubt, we suggest making this threshold 159 relatively low, but not zero (e.g., 0.1 to 0.2 or so). The more confidence in 160 the quality of the flagging, the lower the threshold can be. 162 The relative occurrence accounts for the edge of the field-of-view of 163 the camera, but does not include chip gaps, bad or saturated pixels, etc. 165 @param[in] butler Data butler, for retrieving the input source catalogs 166 @param[in,out] coaddSources Source catalog from the coadd 167 @param[in] ccdInputs Table of CCDs that contribute to the coadd 168 @param[in] coaddWcs Wcs for coadd 169 @param[in] visitCatalogs List of loaded source catalogs for each input ccd in 170 the coadd. If provided this is used instead of this 171 method loading in the catalogs itself 172 @param[in] wcsUpdates optional, If visitCatalogs is a list of ccd catalogs, this 173 should be a list of updated wcs to apply 175 if len(self.
config.flags) == 0:
179 counts = dict((f, numpy.zeros(len(coaddSources), dtype=int))
for f
in flags)
180 indices = numpy.array([s.getId()
for s
in coaddSources])
181 radius = self.
config.matchRadius*afwGeom.arcseconds
183 def processCcd(ccdSources, wcsUpdate):
184 for sourceRecord
in ccdSources:
185 sourceRecord.updateCoord(wcsUpdate)
192 mc.findOnlyClosest =
False 195 index = (numpy.where(indices == m.first.getId()))[0][0]
196 counts[flag][index] += 1
198 if visitCatalogs
is not None:
199 if wcsUpdates
is None:
200 raise pexExceptions.ValueError(
"If ccdInputs is a list of src catalogs, a list of wcs" 201 " updates for each catalog must be supplied in the " 202 "wcsUpdates parameter")
203 for i, ccdSource
in enumerate(visitCatalogs):
204 processCcd(ccdSource, wcsUpdates[i])
206 if ccdInputs
is None:
207 raise pexExceptions.ValueError(
"The visitCatalogs and ccdInput parameters can't both be None")
208 visitKey = ccdInputs.schema.find(
"visit").key
209 ccdKey = ccdInputs.schema.find(
"ccd").key
211 self.
log.
info(
"Propagating flags %s from inputs" % (flags,))
214 for ccdRecord
in ccdInputs:
215 v = ccdRecord.get(visitKey)
216 c = ccdRecord.get(ccdKey)
218 ccdSources = butler.get(
"src", dataId=dataId, immediate=
True)
219 processCcd(ccdSources, ccdRecord.getWcs())
224 for s, num
in zip(coaddSources, counts[f]):
225 numOverlaps = len(ccdInputs.subsetContaining(s.getCentroid(), coaddWcs,
True))
226 s.setFlag(key, bool(num > numOverlaps*self.
config.flags[f]))
227 self.
log.
info(
"Propagated %d sources with flag %s" % (sum(s.get(key)
for s
in coaddSources), f))
Task to propagate flags from single-frame measurements to coadd measurements.
template SourceMatchVector matchRaDec(SourceCatalog const &, lsst::geom::Angle, MatchControl const &)
Pass parameters to algorithms that match list of sources.
def __init__(self, schema, kwargs)
def run(self, butler, coaddSources, ccdInputs, coaddWcs, visitCatalogs=None, wcsUpdates=None)
Propagate flags from individual visit measurements to coadd.
def getCcdInputs(coaddExposure)
Convenience method to retrieve the CCD inputs table from a coadd exposure.
Configuration for propagating flags to coadd.