22"""Select sources that are useful for astrometry.
24Such sources have good signal-to-noise, are well centroided, not blended,
25and not flagged with a handful of "bad" flags.
28__all__ = [
"AstrometrySourceSelectorConfig",
"AstrometrySourceSelectorTask"]
34from .sourceSelector
import BaseSourceSelectorConfig, BaseSourceSelectorTask, sourceSelectorRegistry
36from functools
import reduce
40 badFlags = pexConfig.ListField(
41 doc=
"List of flags which cause a source to be rejected as bad",
44 "base_PixelFlags_flag_edge",
45 "base_PixelFlags_flag_interpolatedCenter",
46 "base_PixelFlags_flag_saturatedCenter",
47 "base_PixelFlags_flag_crCenter",
48 "base_PixelFlags_flag_bad",
51 sourceFluxType = pexConfig.Field(
52 doc=
"Type of source flux; typically one of Ap or Psf",
56 minSnr = pexConfig.Field(
58 doc=
"Minimum allowed signal-to-noise ratio for sources used for matching "
59 "(in the flux specified by sourceFluxType); <= 0 for no limit",
64@pexConfig.registerConfigurable("astrometry", sourceSelectorRegistry)
66 """Select sources that are useful for astrometry.
68 Good astrometry sources have high signal/noise, are non-blended, and
69 did
not have certain
"bad" flags set during source extraction. They need
not
70 be PSF sources, just have reliable centroids.
72 ConfigClass = AstrometrySourceSelectorConfig
75 BaseSourceSelectorTask.__init__(self, *args, **kwargs)
78 """Return a selection of sources that are useful for astrometry.
83 Catalog of sources to select from.
84 This catalog must be contiguous
in memory.
86 Ignored
in this SourceSelector.
88 The exposure the catalog was built
from; used
for debug display.
92 struct : `lsst.pipe.base.Struct`
93 The struct contains the following data:
96 Boolean array of sources that were selected, same length
as
97 sourceCat. (`numpy.ndarray` of `bool`)
101 bad = reduce(lambda x, y: np.logical_or(x, sourceCat[y]), self.config.badFlags,
False)
103 return Struct(selected=good & ~bad)
105 def _getSchemaKeys(self, schema):
106 """Extract and save the necessary keys from schema with asKey.
117 except NotFoundError:
120 self.
edgeKey = schema[
"base_PixelFlags_flag_edge"].asKey()
124 fluxPrefix =
"slot_%sFlux_" % (self.config.sourceFluxType,)
129 def _isMultiple(self, sourceCat):
130 """Return True for each source that is likely multiple sources.
134 for i, cat
in enumerate(sourceCat):
135 footprint = cat.getFootprint()
136 test[i] |= (footprint
is not None)
and (len(footprint.getPeaks()) > 1)
139 def _hasCentroid(self, sourceCat):
140 """Return True for each source that has a valid centroid
142 def checkNonfiniteCentroid():
143 """Return True for sources with non-finite centroids.
147 assert ~checkNonfiniteCentroid().any(), \
148 "Centroids not finite for %d unflagged sources." % (checkNonfiniteCentroid().sum())
153 def _goodSN(self, sourceCat):
154 """Return True for each source that has Signal/Noise > config.minSnr.
156 if self.config.minSnr <= 0:
159 with np.errstate(invalid=
"ignore"):
162 def _isUsable(self, sourceCat):
163 """Return True for each source that is usable for matching, even if it may
164 have a poor centroid.
166 For a source to be usable it must:
167 - have a valid centroid
169 - have a valid flux (of the type specified
in this object
's constructor)
170 - have adequate signal-to-noise
178 def _isPrimary(self, sourceCat):
179 """Return True if this is a primary source.
184 return np.ones(len(sourceCat), dtype=bool)
186 def _isGood(self, sourceCat):
187 """Return True for each source that is usable for matching and likely has a
190 The additional tests for a good centroid, beyond isUsable, are:
191 -
not interpolated
in the center
202 def _isBadFlagged(self, source):
203 """Return True if any of config.badFlags are set for this source.
205 return any(source[flag]
for flag
in self.config.badFlags)
def _hasCentroid(self, sourceCat)
def _isUsable(self, sourceCat)
def __init__(self, *args, **kwargs)
def selectSources(self, sourceCat, matches=None, exposure=None)
def _isMultiple(self, sourceCat)
def _isGood(self, sourceCat)
def _getSchemaKeys(self, schema)
def _isPrimary(self, sourceCat)
def _goodSN(self, sourceCat)