23 from __future__
import absolute_import, division, print_function
25 __all__ = [
"BaseSourceSelectorConfig",
"BaseSourceSelectorTask",
"sourceSelectorRegistry",
26 "ColorLimit",
"MagnitudeLimit",
"SignalToNoiseLimit",
"MagnitudeErrorLimit",
27 "RequireFlags",
"RequireUnresolved",
28 "ScienceSourceSelectorConfig",
"ScienceSourceSelectorTask",
29 "ReferenceSourceSelectorConfig",
"ReferenceSourceSelectorTask",
39 from future.utils
import with_metaclass
43 badFlags = pexConfig.ListField(
44 doc=
"List of flags which cause a source to be rejected as bad",
47 "base_PixelFlags_flag_edge",
48 "base_PixelFlags_flag_interpolatedCenter",
49 "base_PixelFlags_flag_saturatedCenter",
50 "base_PixelFlags_flag_crCenter",
51 "base_PixelFlags_flag_bad",
52 "base_PixelFlags_flag_interpolated",
58 """!Base class for source selectors 60 Register all source selectors with the sourceSelectorRegistry using: 61 sourceSelectorRegistry.register(name, class) 64 ConfigClass = BaseSourceSelectorConfig
65 _DefaultName =
"sourceSelector" 68 """!Initialize a source selector.""" 69 pipeBase.Task.__init__(self, **kwargs)
71 def run(self, sourceCat, maskedImage=None, **kwargs):
72 """!Select sources and return them. 74 @param[in] sourceCat catalog of sources that may be sources (an lsst.afw.table.SourceCatalog) 75 @param[in] maskedImage the maskedImage containing the sources, for plotting. 77 @return an lsst.pipe.base.Struct containing: 78 - sourceCat catalog of sources that were selected 80 return self.
selectSources(maskedImage=maskedImage, sourceCat=sourceCat, **kwargs)
84 """!Return a catalog of sources: a subset of sourceCat. 86 @param[in] sourceCat catalog of sources that may be sources (an lsst.afw.table.SourceCatalog) 88 @return a pipeBase.Struct containing: 89 - sourceCat a catalog of sources 93 result = afwTable.SourceCatalog(sourceCat.table)
94 for source
in sourceCat:
95 if not self.
_isBad(source):
97 return pipeBase.Struct(sourceCat=result)
99 def _isBad(self, source):
100 """Return True if any of config.badFlags are set for this source.""" 101 return any(source.get(flag)
for flag
in self.config.badFlags)
104 sourceSelectorRegistry = pexConfig.makeRegistry(
105 doc=
"A registry of source selectors (subclasses of BaseSourceSelectorTask)",
110 """Base class for selecting sources by applying a limit 112 This object can be used as a `lsst.pex.config.Config` for configuring 113 the limit, and then the `apply` method can be used to identify sources 114 in the catalog that match the configured limit. 116 This provides the `maximum` and `minimum` fields in the Config, and 117 a method to apply the limits to an array of values calculated by the 120 minimum = pexConfig.Field(dtype=float, optional=
True, doc=
"Select objects with value greater than this")
121 maximum = pexConfig.Field(dtype=float, optional=
True, doc=
"Select objects with value less than this")
124 """Apply the limits to an array of values 126 Subclasses should calculate the array of values and then 127 return the result of calling this method. 131 values : `numpy.ndarray` 132 Array of values to which to apply limits. 136 selected : `numpy.ndarray` 137 Boolean array indicating for each source whether it is selected 138 (True means selected). 140 selected = np.ones(len(values), dtype=bool)
142 selected &= values > self.
minimum 144 selected &= values < self.
maximum 149 """Select sources using a color limit 151 This object can be used as a `lsst.pex.config.Config` for configuring 152 the limit, and then the `apply` method can be used to identify sources 153 in the catalog that match the configured limit. 155 We refer to 'primary' and 'secondary' flux measurements; these are the 156 two components of the color, which is: 158 instFluxToMag(cat[primary]) - instFluxToMag(cat[secondary]) 160 primary = pexConfig.Field(dtype=str, doc=
"Name of column with primary flux measurement")
161 secondary = pexConfig.Field(dtype=str, doc=
"Name of column with secondary flux measurement")
164 """Apply the color limit to a catalog 168 catalog : `lsst.afw.table.SourceCatalog` 169 Catalog of sources to which the limit will be applied. 173 selected : `numpy.ndarray` 174 Boolean array indicating for each source whether it is selected 175 (True means selected). 179 color = primary - secondary
180 return BaseLimit.apply(self, color)
184 """Select sources using a flux limit 186 This object can be used as a `lsst.pex.config.Config` for configuring 187 the limit, and then the `apply` method can be used to identify sources 188 in the catalog that match the configured limit. 190 fluxField = pexConfig.Field(dtype=str, default=
"slot_CalibFlux_flux",
191 doc=
"Name of the source flux field to use.")
194 """Apply the flux limits to a catalog 198 catalog : `lsst.afw.table.SourceCatalog` 199 Catalog of sources to which the limit will be applied. 203 selected : `numpy.ndarray` 204 Boolean array indicating for each source whether it is selected 205 (True means selected). 208 if flagField
in catalog.schema:
209 selected = np.logical_not(catalog[flagField])
211 selected = np.ones(len(catalog), dtype=bool)
214 selected &= BaseLimit.apply(self, flux)
219 """Select sources using a magnitude limit 221 Note that this assumes that a zero-point has already been applied and 222 the fluxes are in AB fluxes in Jansky. It is therefore principally 223 intended for reference catalogs rather than catalogs extracted from 226 This object can be used as a `lsst.pex.config.Config` for configuring 227 the limit, and then the `apply` method can be used to identify sources 228 in the catalog that match the configured limit. 230 fluxField = pexConfig.Field(dtype=str, default=
"flux",
231 doc=
"Name of the source flux field to use.")
234 """Apply the magnitude limits to a catalog 238 catalog : `lsst.afw.table.SourceCatalog` 239 Catalog of sources to which the limit will be applied. 243 selected : `numpy.ndarray` 244 Boolean array indicating for each source whether it is selected 245 (True means selected). 248 if flagField
in catalog.schema:
249 selected = np.logical_not(catalog[flagField])
251 selected = np.ones(len(catalog), dtype=bool)
254 selected &= BaseLimit.apply(self, magnitude)
259 """Select sources using a flux signal-to-noise limit 261 This object can be used as a `lsst.pex.config.Config` for configuring 262 the limit, and then the `apply` method can be used to identify sources 263 in the catalog that match the configured limit. 265 fluxField = pexConfig.Field(dtype=str, default=
"flux",
266 doc=
"Name of the source flux field to use.")
267 errField = pexConfig.Field(dtype=str, default=
"flux_err",
268 doc=
"Name of the source flux error field to use.")
271 """Apply the signal-to-noise limits to a catalog 275 catalog : `lsst.afw.table.SourceCatalog` 276 Catalog of sources to which the limit will be applied. 280 selected : `numpy.ndarray` 281 Boolean array indicating for each source whether it is selected 282 (True means selected). 285 if flagField
in catalog.schema:
286 selected = np.logical_not(catalog[flagField])
288 selected = np.ones(len(catalog), dtype=bool)
291 selected &= BaseLimit.apply(self, signalToNoise)
296 """Select sources using a magnitude error limit 298 Because the magnitude error is the inverse of the signal-to-noise 299 ratio, this also works to select sources by signal-to-noise when 300 you only have a magnitude. 302 This object can be used as a `lsst.pex.config.Config` for configuring 303 the limit, and then the `apply` method can be used to identify sources 304 in the catalog that match the configured limit. 306 magErrField = pexConfig.Field(dtype=str, default=
"mag_err",
307 doc=
"Name of the source flux error field to use.")
310 """Apply the magnitude error limits to a catalog 314 catalog : `lsst.afw.table.SourceCatalog` 315 Catalog of sources to which the limit will be applied. 319 selected : `numpy.ndarray` 320 Boolean array indicating for each source whether it is selected 321 (True means selected). 323 return BaseLimit.apply(self, catalog[self.
magErrField])
327 """Select sources using flags 329 This object can be used as a `lsst.pex.config.Config` for configuring 330 the limit, and then the `apply` method can be used to identify sources 331 in the catalog that match the configured limit. 333 good = pexConfig.ListField(dtype=str, default=[],
334 doc=
"List of source flag fields that must be set for a source to be used.")
335 bad = pexConfig.ListField(dtype=str, default=[],
336 doc=
"List of source flag fields that must NOT be set for a source to be used.")
339 """Apply the flag requirements to a catalog 341 Returns whether the source is selected. 345 catalog : `lsst.afw.table.SourceCatalog` 346 Catalog of sources to which the requirements will be applied. 350 selected : `numpy.ndarray` 351 Boolean array indicating for each source whether it is selected 352 (True means selected). 354 selected = np.ones(len(catalog), dtype=bool)
355 for flag
in self.
good:
356 selected &= catalog[flag]
357 for flag
in self.
bad:
358 selected &= ~catalog[flag]
363 """Select sources using star/galaxy separation 365 This object can be used as a `lsst.pex.config.Config` for configuring 366 the limit, and then the `apply` method can be used to identify sources 367 in the catalog that match the configured limit. 369 name = pexConfig.Field(dtype=str, default=
"base_ClassificationExtendedness_value",
370 doc=
"Name of column for star/galaxy separation")
373 """Apply the flag requirements to a catalog 375 Returns whether the source is selected. 379 catalog : `lsst.afw.table.SourceCatalog` 380 Catalog of sources to which the requirements will be applied. 384 selected : `numpy.ndarray` 385 Boolean array indicating for each source whether it is selected 386 (True means selected). 388 selected = np.ones(len(catalog), dtype=bool)
389 value = catalog[self.
name]
390 return BaseLimit.apply(self, value)
394 """Configuration for selecting science sources""" 395 doFluxLimit = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply flux limit?")
396 doFlags = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply flag limitation?")
397 doUnresolved = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply unresolved limitation?")
398 doSignalToNoise = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply signal-to-noise limit?")
399 fluxLimit = pexConfig.ConfigField(dtype=FluxLimit, doc=
"Flux limit to apply")
400 flags = pexConfig.ConfigField(dtype=RequireFlags, doc=
"Flags to require")
401 unresolved = pexConfig.ConfigField(dtype=RequireUnresolved, doc=
"Star/galaxy separation to apply")
402 signalToNoise = pexConfig.ConfigField(dtype=SignalToNoiseLimit, doc=
"Signal-to-noise limit to apply")
405 pexConfig.Config.setDefaults(self)
406 self.
flags.bad = [
"base_PixelFlags_flag_edge",
"base_PixelFlags_flag_interpolated",
407 "base_PixelFlags_flag_saturated",
"base_PsfFlux_flags"]
413 """Science source selector 415 By "science" sources, we mean sources that are on images that we 416 are processing, as opposed to sources from reference catalogs. 418 This selects (science) sources by (optionally) applying each of a 419 magnitude limit, flag requirements and star/galaxy separation. 421 ConfigClass = ScienceSourceSelectorConfig
424 """Return a catalog of selected sources 428 catalog : `lsst.afw.table.SourceCatalog` 429 Catalog of sources to select. 430 matches : `lsst.afw.table.ReferenceMatchVector`, optional 431 List of matches; ignored. 435 sourceCat : `lsst.afw.table.SourceCatalog` 436 Catalog of selected sources, non-contiguous. 438 selected = np.ones(len(catalog), dtype=bool)
439 if self.config.doFluxLimit:
440 selected &= self.config.fluxLimit.apply(catalog)
441 if self.config.doFlags:
442 selected &= self.config.flags.apply(catalog)
443 if self.config.doUnresolved:
444 selected &= self.config.unresolved.apply(catalog)
445 if self.config.doSignalToNoise:
446 selected &= self.config.signalToNoise.apply(catalog)
448 self.log.info(
"Selected %d/%d sources", selected.sum(), len(catalog))
450 result = type(catalog)(catalog.table)
451 for source
in catalog[selected]:
452 result.append(source)
453 return pipeBase.Struct(sourceCat=result, selection=selected)
457 doMagLimit = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply magnitude limit?")
458 doFlags = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply flag limitation?")
459 doSignalToNoise = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply signal-to-noise limit?")
460 doMagError = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply magnitude error limit?")
461 magLimit = pexConfig.ConfigField(dtype=MagnitudeLimit, doc=
"Magnitude limit to apply")
462 flags = pexConfig.ConfigField(dtype=RequireFlags, doc=
"Flags to require")
463 signalToNoise = pexConfig.ConfigField(dtype=SignalToNoiseLimit, doc=
"Signal-to-noise limit to apply")
464 magError = pexConfig.ConfigField(dtype=MagnitudeErrorLimit, doc=
"Magnitude error limit to apply")
465 colorLimits = pexConfig.ConfigDictField(keytype=str, itemtype=ColorLimit, default={},
466 doc=
"Color limits to apply; key is used as a label only")
470 """Reference source selector 472 This selects reference sources by (optionally) applying each of a 473 magnitude limit, flag requirements and color limits. 475 ConfigClass = ReferenceSourceSelectorConfig
478 """Return a catalog of selected reference sources 482 catalog : `lsst.afw.table.SourceCatalog` 483 Catalog of sources to select. 484 matches : `lsst.afw.table.ReferenceMatchVector`, optional 485 List of matches; ignored. 489 sourceCat : `lsst.afw.table.SourceCatalog` 490 Catalog of selected sources, non-contiguous. 492 selected = np.ones(len(catalog), dtype=bool)
493 if self.config.doMagLimit:
494 selected &= self.config.magLimit.apply(catalog)
495 if self.config.doFlags:
496 selected &= self.config.flags.apply(catalog)
497 if self.config.doSignalToNoise:
498 selected &= self.config.signalToNoise.apply(catalog)
499 if self.config.doMagError:
500 selected &= self.config.magError.apply(catalog)
501 for limit
in self.config.colorLimits.values():
502 selected &= limit.apply(catalog)
504 self.log.info(
"Selected %d/%d references", selected.sum(), len(catalog))
506 result = type(catalog)(catalog.table)
507 for source
in catalog[selected]:
508 result.append(source)
509 return pipeBase.Struct(sourceCat=result, selection=selected)
512 sourceSelectorRegistry.register(
"science", ScienceSourceSelectorTask)
513 sourceSelectorRegistry.register(
"references", ReferenceSourceSelectorTask)
def selectSources(self, sourceCat, matches=None)
Return a catalog of sources: a subset of sourceCat.
def selectSources(self, catalog, matches=None)
template ndarray::Array< double, 1 > abMagFromFlux(ndarray::Array< double const, 1 > const &flux)
def __init__(self, kwargs)
Initialize a source selector.
def run(self, sourceCat, maskedImage=None, kwargs)
Select sources and return them.
def selectSources(self, catalog, matches=None)
Base class for source selectors.