23 from __future__
import absolute_import, division, print_function
28 import lsst.pex.config
as pexConfig
29 from .sourceSelector
import BaseSourceSelectorConfig, BaseSourceSelectorTask, sourceSelectorRegistry
30 from lsst.pipe.base
import Struct
31 from functools
import reduce
35 sourceFluxType = pexConfig.Field(
36 doc=
"Type of source flux; typically one of Ap or Psf",
40 minSnr = pexConfig.Field(
42 doc=
"Minimum allowed signal-to-noise ratio for sources used for matching " 43 "(in the flux specified by sourceFluxType); <= 0 for no limit",
50 !Select sources that are useful for astrometry. 52 Good astrometry sources have high signal/noise, are non-blended, and 53 did not have certain "bad" flags set during source extraction. They need not 54 be PSF sources, just have reliable centroids. 56 ConfigClass = AstrometrySourceSelectorConfig
59 BaseSourceSelectorTask.__init__(self, *args, **kwargs)
63 !Return a catalog of sources: a subset of sourceCat. 65 If sourceCat is cotiguous in memory, will use vectorized tests for ~100x 66 execution speed advantage over non-contiguous catalogs. This would be 67 even faster if we didn't have to check footprints for multiple peaks. 69 @param[in] sourceCat catalog of sources that may be sources 70 (an lsst.afw.table.SourceCatalog) 72 @return a pipeBase.Struct containing: 73 - sourceCat a catalog of sources 77 if sourceCat.isContiguous():
78 bad = reduce(
lambda x, y: np.logical_or(x, sourceCat.get(y)), self.config.badFlags,
False)
80 result = sourceCat[good & ~bad]
82 result = table.SourceCatalog(sourceCat.table)
83 for i, source
in enumerate(sourceCat):
86 return Struct(sourceCat=result)
88 def _getSchemaKeys(self, schema):
89 """Extract and save the necessary keys from schema with asKey.""" 96 self.
edgeKey = schema[
"base_PixelFlags_flag_edge"].asKey()
98 self.
saturatedKey = schema[
"base_PixelFlags_flag_saturated"].asKey()
100 fluxPrefix =
"slot_%sFlux_" % (self.config.sourceFluxType,)
101 self.
fluxKey = schema[fluxPrefix +
"flux"].asKey()
105 def _isMultiple_vector(self, sourceCat):
106 """Return True for each source that is likely multiple sources.""" 109 for i, cat
in enumerate(sourceCat):
110 footprint = cat.getFootprint()
111 test[i] |= (footprint
is not None)
and (len(footprint.getPeaks()) > 1)
114 def _isMultiple(self, source):
115 """Return True if source is likely multiple sources.""" 118 footprint = source.getFootprint()
119 return footprint
is not None and len(footprint.getPeaks()) > 1
121 def _hasCentroid_vector(self, sourceCat):
122 """Return True for each source that has a valid centroid""" 127 def _hasCentroid(self, source):
128 """Return True if the source has a valid centroid""" 129 centroid = source.getCentroid()
130 return np.all(np.isfinite(centroid))
and not source.getCentroidFlag()
132 def _goodSN_vector(self, sourceCat):
133 """Return True for each source that has Signal/Noise > config.minSnr.""" 134 if self.config.minSnr <= 0:
139 def _goodSN(self, source):
140 """Return True if source has Signal/Noise > config.minSnr.""" 141 return (self.config.minSnr <= 0
or 144 def _isUsable_vector(self, sourceCat):
146 Return True for each source that is usable for matching, even if it may 147 have a poor centroid. 149 For a source to be usable it must: 150 - have a valid centroid 152 - have a valid flux (of the type specified in this object's constructor) 153 - have adequate signal-to-noise 161 def _isUsable(self, source):
163 Return True if the source is usable for matching, even if it may have a 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 177 def _isGood_vector(self, sourceCat):
179 Return True for each source that is usable for matching and likely has a 182 The additional tests for a good centroid, beyond isUsable, are: 183 - not interpolated in the center 193 def _isGood(self, source):
195 Return True if source is usable for matching and likely has a good centroid. 197 The additional tests for a good centroid, beyond isUsable, are: 198 - not interpolated in the center 205 and not source.get(self.
edgeKey)
208 sourceSelectorRegistry.register(
"astrometry", AstrometrySourceSelectorTask)
def _isGood_vector(self, sourceCat)
def __init__(self, args, kwargs)
def selectSources(self, sourceCat, matches=None)
def _hasCentroid_vector(self, sourceCat)
def _isUsable(self, source)
def _isMultiple(self, source)
def _isGood(self, source)
def _goodSN_vector(self, sourceCat)
def _isMultiple_vector(self, sourceCat)
def _getSchemaKeys(self, schema)
def _goodSN(self, source)
def _hasCentroid(self, source)
def _isUsable_vector(self, sourceCat)
Base class for source selectors.