22__all__ = [
"PropagateVisitFlagsConfig",
"PropagateVisitFlagsTask"]
29from deprecated.sphinx
import deprecated
33 """Configuration for propagating flags to coadd."""
36 default={
"calib_psf_candidate": 0.2,
"calib_psf_used": 0.2,
"calib_psf_reserved": 0.2,
37 "calib_astrometry_used": 0.2,
"calib_photometry_used": 0.2,
38 "calib_photometry_reserved": 0.2, },
39 doc=(
"Source catalog flags to propagate, with the threshold of relative occurrence "
40 "(valid range: [0-1], default is 0.2). Coadd object will have flag set if the "
41 "fraction of input visits in which it is flagged is greater than the threshold."))
42 matchRadius =
Field(dtype=float, default=0.2, doc=
"Source matching radius (arcsec)")
43 ccdName =
Field(dtype=str, default=
'ccd', doc=
"Name of ccd to give to butler")
46@deprecated(reason=
"This task has been replaced with PropagateSourceFlagsTask",
47 version=
"v24.0", category=FutureWarning)
49 """Task to propagate flags from single-frame measurements to coadd measurements.
54 The input schema for the reference source catalog, used to initialize
57 Additional keyword arguments.
61 We want to be able to set a flag
for sources on the coadds using flags
62 that were determined
from the individual visits. A common example
is sources
63 that were used
for PSF determination, since we do
not do any PSF determination
64 on the coadd but use the individual visits. This requires matching the coadd
65 source catalog to each of the catalogs
from the inputs (see
66 PropagateVisitFlagsConfig.matchRadius),
and thresholding on the number of
67 times a source
is flagged on the input catalog.
69 An important consideration
in this
is that the flagging of sources
in the
70 individual visits can be somewhat stochastic, e.g., the same stars may
not
71 always be used
for PSF determination because the field of view moves slightly
72 between visits,
or the seeing changed. We there threshold on the relative
73 occurrence of the flag
in the visits (see PropagateVisitFlagsConfig.flags).
74 Flagging a source that
is always flagged
in inputs corresponds to a threshold
75 of 1,
while flagging a source that
is flagged
in any of the input corresponds
76 to a threshold of 0. But neither of these extrema are really useful
in
79 Setting the threshold too high means that sources that are
not consistently
80 flagged (e.g., due to chip gaps) will
not have the flag propagated. Setting
81 that threshold too low means that random sources which are falsely flagged
in
82 the inputs will start to dominate. If
in doubt, we suggest making this
83 threshold relatively low, but
not zero (e.g., 0.1 to 0.2
or so). The more
84 confidence
in the quality of the flagging, the lower the threshold can be.
85 The relative occurrence accounts
for the edge of the field-of-view of the
86 camera, but does
not include chip gaps, bad
or saturated pixels, etc.
90 Beyond the usual Task initialization, PropagateVisitFlagsTask also requires
91 a schema
for the catalog that
is being constructed.
93 The
'run' method (described below)
is the entry-point
for operations. The
94 'getCcdInputs' staticmethod
is provided
as a convenience
for retrieving the
95 'ccdInputs' (CCD inputs table)
from an Exposure.
105 config.flags[
"calib_psf_used"] = 0.3
106 config.matchRadius = 0.5
108 ccdInputs = task.getCcdInputs(coaddExposure)
109 task.run(butler, coaddCatalog, ccdInputs, coaddExposure.getWcs())
112 ConfigClass = PropagateVisitFlagsConfig
115 Task.__init__(self, **kwargs)
117 self.
_keys = dict((f, self.
schema.addField(f, type=
"Flag", doc=
"Propagated from visits"))
for
118 f
in self.config.flags)
122 """Convenience method to retrieve the CCD inputs table from a coadd exposure.
127 The exposure we need to retrieve the CCD inputs table from.
132 CCD inputs table
from a coadd exposure.
134 return coaddExposure.getInfo().getCoaddInputs().ccds
136 def run(self, butler, coaddSources, ccdInputs, coaddWcs, visitCatalogs=None, wcsUpdates=None):
137 """Propagate flags from individual visit measurements to coadd.
139 This requires matching the coadd source catalog to each of the catalogs
140 from the inputs,
and thresholding on the number of times a source
is
141 flagged on the input catalog. The threshold
is made on the relative
142 occurrence of the flag
in each source. Flagging a source that
is always
143 flagged
in inputs corresponds to a threshold of 1,
while flagging a
144 source that
is flagged
in any of the input corresponds to a threshold of
145 0. But neither of these extrema are really useful
in practise.
147 Setting the threshold too high means that sources that are
not consistently
148 flagged (e.g., due to chip gaps) will
not have the flag propagated. Setting
149 that threshold too low means that random sources which are falsely flagged
in
150 the inputs will start to dominate. If
in doubt, we suggest making this threshold
151 relatively low, but
not zero (e.g., 0.1 to 0.2
or so). The more confidence
in
152 the quality of the flagging, the lower the threshold can be.
154 The relative occurrence accounts
for the edge of the field-of-view of
155 the camera, but does
not include chip gaps, bad
or saturated pixels, etc.
160 Data butler,
for retrieving the input source catalogs.
161 coaddSources : `lsst.afw.image.SourceCatalog`
162 Source catalog
from the coadd.
164 Table of CCDs that contribute to the coadd.
167 visitCatalogs : `list` of `lsst.afw.image.SourceCatalog`, optional
168 List of loaded source catalogs
for each input ccd
in
169 the coadd. If provided this
is used instead of this
170 method loading
in the catalogs itself.
172 If visitCatalogs
is a list of ccd catalogs, this
173 should be a list of updated wcs to apply.
178 Raised
if any of the following occur:
179 - A list of wcs updates
for each catalog
is not supplied
in the wcsUpdates parameter
180 and ccdInputs
is a list of src catalogs.
181 - The visitCatalogs
and ccdInput parameters are both `
None`.
183 if len(self.config.flags) == 0:
186 flags = self.
_keys.keys()
187 counts = dict((f, numpy.zeros(len(coaddSources), dtype=int))
for f
in flags)
188 indices = numpy.array([s.getId()
for s
in coaddSources])
189 radius = self.config.matchRadius*geom.arcseconds
191 def processCcd(ccdSources, wcsUpdate):
192 for sourceRecord
in ccdSources:
193 sourceRecord.updateCoord(wcsUpdate)
200 mc.findOnlyClosest =
False
203 index = (numpy.where(indices == m.first.getId()))[0][0]
204 counts[flag][index] += 1
206 if visitCatalogs
is not None:
207 if wcsUpdates
is None:
208 raise pexExceptions.ValueError(
"If ccdInputs is a list of src catalogs, a list of wcs"
209 " updates for each catalog must be supplied in the "
210 "wcsUpdates parameter")
211 for i, ccdSource
in enumerate(visitCatalogs):
212 processCcd(ccdSource, wcsUpdates[i])
214 if ccdInputs
is None:
215 raise pexExceptions.ValueError(
"The visitCatalogs and ccdInput parameters can't both be None")
216 visitKey = ccdInputs.schema.find(
"visit").key
217 ccdKey = ccdInputs.schema.find(
"ccd").key
219 self.log.info(
"Propagating flags %s from inputs", flags)
222 for ccdRecord
in ccdInputs:
223 v = ccdRecord.get(visitKey)
224 c = ccdRecord.get(ccdKey)
225 dataId = {
"visit": int(v), self.config.ccdName: int(c)}
226 ccdSources = butler.get(
"src", dataId=dataId, immediate=
True)
227 processCcd(ccdSources, ccdRecord.getWcs())
232 for s, num
in zip(coaddSources, counts[f]):
233 numOverlaps = len(ccdInputs.subsetContaining(s.getCentroid(), coaddWcs,
True))
234 s.setFlag(key, bool(num > numOverlaps*self.config.flags[f]))
235 self.log.info(
"Propagated %d sources with flag %s", sum(s.get(key)
for s
in coaddSources), f)
A 2-dimensional celestial WCS that transform pixels to ICRS RA/Dec, using the LSST standard for pixel...
A class to contain the data, WCS, and other information needed to describe an image of the sky.
Custom catalog class for ExposureRecord/Table.
Pass parameters to algorithms that match list of sources.
Defines the fields and offsets for a table.
def getCcdInputs(coaddExposure)
def __init__(self, schema, **kwargs)
std::vector< Match< typename Cat1::Record, typename Cat2::Record > > matchRaDec(Cat1 const &cat1, Cat2 const &cat2, lsst::geom::Angle radius, MatchControl const &mc=MatchControl())
Compute all tuples (s1,s2,d) where s1 belings to cat1, s2 belongs to cat2 and d, the distance between...