24 __all__ = [
"BaseSourceSelectorConfig",
"BaseSourceSelectorTask",
"sourceSelectorRegistry",
25 "ColorLimit",
"MagnitudeLimit",
"SignalToNoiseLimit",
"MagnitudeErrorLimit",
26 "RequireFlags",
"RequireUnresolved",
27 "ScienceSourceSelectorConfig",
"ScienceSourceSelectorTask",
28 "ReferenceSourceSelectorConfig",
"ReferenceSourceSelectorTask",
41 badFlags = pexConfig.ListField(
42 doc=
"List of flags which cause a source to be rejected as bad",
45 "base_PixelFlags_flag_edge",
46 "base_PixelFlags_flag_interpolatedCenter",
47 "base_PixelFlags_flag_saturatedCenter",
48 "base_PixelFlags_flag_crCenter",
49 "base_PixelFlags_flag_bad",
55 """!Base class for source selectors 57 Register all source selectors with the sourceSelectorRegistry using: 58 sourceSelectorRegistry.register(name, class) 61 ConfigClass = BaseSourceSelectorConfig
62 _DefaultName =
"sourceSelector" 65 """!Initialize a source selector.""" 66 pipeBase.Task.__init__(self, **kwargs)
68 def run(self, sourceCat, maskedImage=None, **kwargs):
69 """!Select sources and return them. 71 @param[in] sourceCat catalog of sources that may be sources (an lsst.afw.table.SourceCatalog) 72 @param[in] maskedImage the maskedImage containing the sources, for plotting. 74 @return an lsst.pipe.base.Struct containing: 75 - sourceCat catalog of sources that were selected 77 return self.
selectSources(maskedImage=maskedImage, sourceCat=sourceCat, **kwargs)
81 """!Return a catalog of sources: a subset of sourceCat. 83 @param[in] sourceCat catalog of sources that may be sources (an lsst.afw.table.SourceCatalog) 85 @return a pipeBase.Struct containing: 86 - sourceCat a catalog of sources 90 result = afwTable.SourceCatalog(sourceCat.table)
91 for source
in sourceCat:
92 if not self.
_isBad(source):
94 return pipeBase.Struct(sourceCat=result)
96 def _isBad(self, source):
97 """Return True if any of config.badFlags are set for this source.""" 98 return any(source.get(flag)
for flag
in self.config.badFlags)
101 sourceSelectorRegistry = pexConfig.makeRegistry(
102 doc=
"A registry of source selectors (subclasses of BaseSourceSelectorTask)",
107 """Base class for selecting sources by applying a limit 109 This object can be used as a `lsst.pex.config.Config` for configuring 110 the limit, and then the `apply` method can be used to identify sources 111 in the catalog that match the configured limit. 113 This provides the `maximum` and `minimum` fields in the Config, and 114 a method to apply the limits to an array of values calculated by the 117 minimum = pexConfig.Field(dtype=float, optional=
True, doc=
"Select objects with value greater than this")
118 maximum = pexConfig.Field(dtype=float, optional=
True, doc=
"Select objects with value less than this")
121 """Apply the limits to an array of values 123 Subclasses should calculate the array of values and then 124 return the result of calling this method. 128 values : `numpy.ndarray` 129 Array of values to which to apply limits. 133 selected : `numpy.ndarray` 134 Boolean array indicating for each source whether it is selected 135 (True means selected). 137 selected = np.ones(len(values), dtype=bool)
138 with np.errstate(invalid=
"ignore"):
140 selected &= values > self.
minimum 142 selected &= values < self.
maximum 147 """Select sources using a color limit 149 This object can be used as a `lsst.pex.config.Config` for configuring 150 the limit, and then the `apply` method can be used to identify sources 151 in the catalog that match the configured limit. 153 We refer to 'primary' and 'secondary' flux measurements; these are the 154 two components of the color, which is: 156 instFluxToMag(cat[primary]) - instFluxToMag(cat[secondary]) 158 primary = pexConfig.Field(dtype=str, doc=
"Name of column with primary flux measurement")
159 secondary = pexConfig.Field(dtype=str, doc=
"Name of column with secondary flux measurement")
162 """Apply the color limit to a catalog 166 catalog : `lsst.afw.table.SourceCatalog` 167 Catalog of sources to which the limit will be applied. 171 selected : `numpy.ndarray` 172 Boolean array indicating for each source whether it is selected 173 (True means selected). 177 color = primary - secondary
178 return BaseLimit.apply(self, color)
182 """Select sources using a flux limit 184 This object can be used as a `lsst.pex.config.Config` for configuring 185 the limit, and then the `apply` method can be used to identify sources 186 in the catalog that match the configured limit. 188 fluxField = pexConfig.Field(dtype=str, default=
"slot_CalibFlux_flux",
189 doc=
"Name of the source flux field to use.")
192 """Apply the flux limits to a catalog 196 catalog : `lsst.afw.table.SourceCatalog` 197 Catalog of sources to which the limit will be applied. 201 selected : `numpy.ndarray` 202 Boolean array indicating for each source whether it is selected 203 (True means selected). 206 if flagField
in catalog.schema:
207 selected = np.logical_not(catalog[flagField])
209 selected = np.ones(len(catalog), dtype=bool)
212 selected &= BaseLimit.apply(self, flux)
217 """Select sources using a magnitude limit 219 Note that this assumes that a zero-point has already been applied and 220 the fluxes are in AB fluxes in Jansky. It is therefore principally 221 intended for reference catalogs rather than catalogs extracted from 224 This object can be used as a `lsst.pex.config.Config` for configuring 225 the limit, and then the `apply` method can be used to identify sources 226 in the catalog that match the configured limit. 228 fluxField = pexConfig.Field(dtype=str, default=
"flux",
229 doc=
"Name of the source flux field to use.")
232 """Apply the magnitude limits to a catalog 236 catalog : `lsst.afw.table.SourceCatalog` 237 Catalog of sources to which the limit will be applied. 241 selected : `numpy.ndarray` 242 Boolean array indicating for each source whether it is selected 243 (True means selected). 246 if flagField
in catalog.schema:
247 selected = np.logical_not(catalog[flagField])
249 selected = np.ones(len(catalog), dtype=bool)
252 selected &= BaseLimit.apply(self, magnitude)
257 """Select sources using a flux signal-to-noise limit 259 This object can be used as a `lsst.pex.config.Config` for configuring 260 the limit, and then the `apply` method can be used to identify sources 261 in the catalog that match the configured limit. 263 fluxField = pexConfig.Field(dtype=str, default=
"flux",
264 doc=
"Name of the source flux field to use.")
265 errField = pexConfig.Field(dtype=str, default=
"flux_err",
266 doc=
"Name of the source flux error field to use.")
269 """Apply the signal-to-noise limits to a catalog 273 catalog : `lsst.afw.table.SourceCatalog` 274 Catalog of sources to which the limit will be applied. 278 selected : `numpy.ndarray` 279 Boolean array indicating for each source whether it is selected 280 (True means selected). 283 if flagField
in catalog.schema:
284 selected = np.logical_not(catalog[flagField])
286 selected = np.ones(len(catalog), dtype=bool)
289 selected &= BaseLimit.apply(self, signalToNoise)
294 """Select sources using a magnitude error limit 296 Because the magnitude error is the inverse of the signal-to-noise 297 ratio, this also works to select sources by signal-to-noise when 298 you only have a magnitude. 300 This object can be used as a `lsst.pex.config.Config` for configuring 301 the limit, and then the `apply` method can be used to identify sources 302 in the catalog that match the configured limit. 304 magErrField = pexConfig.Field(dtype=str, default=
"mag_err",
305 doc=
"Name of the source flux error field to use.")
308 """Apply the magnitude error limits to a catalog 312 catalog : `lsst.afw.table.SourceCatalog` 313 Catalog of sources to which the limit will be applied. 317 selected : `numpy.ndarray` 318 Boolean array indicating for each source whether it is selected 319 (True means selected). 321 return BaseLimit.apply(self, catalog[self.
magErrField])
325 """Select sources using flags 327 This object can be used as a `lsst.pex.config.Config` for configuring 328 the limit, and then the `apply` method can be used to identify sources 329 in the catalog that match the configured limit. 331 good = pexConfig.ListField(dtype=str, default=[],
332 doc=
"List of source flag fields that must be set for a source to be used.")
333 bad = pexConfig.ListField(dtype=str, default=[],
334 doc=
"List of source flag fields that must NOT be set for a source to be used.")
337 """Apply the flag requirements to a catalog 339 Returns whether the source is selected. 343 catalog : `lsst.afw.table.SourceCatalog` 344 Catalog of sources to which the requirements will be applied. 348 selected : `numpy.ndarray` 349 Boolean array indicating for each source whether it is selected 350 (True means selected). 352 selected = np.ones(len(catalog), dtype=bool)
353 for flag
in self.
good:
354 selected &= catalog[flag]
355 for flag
in self.
bad:
356 selected &= ~catalog[flag]
361 """Select sources using star/galaxy separation 363 This object can be used as a `lsst.pex.config.Config` for configuring 364 the limit, and then the `apply` method can be used to identify sources 365 in the catalog that match the configured limit. 367 name = pexConfig.Field(dtype=str, default=
"base_ClassificationExtendedness_value",
368 doc=
"Name of column for star/galaxy separation")
371 """Apply the flag requirements to a catalog 373 Returns whether the source is selected. 377 catalog : `lsst.afw.table.SourceCatalog` 378 Catalog of sources to which the requirements will be applied. 382 selected : `numpy.ndarray` 383 Boolean array indicating for each source whether it is selected 384 (True means selected). 386 value = catalog[self.
name]
387 return BaseLimit.apply(self, value)
391 """Select sources based on whether they are isolated 393 This object can be used as a `lsst.pex.config.Config` for configuring 394 the column names to check for "parent" and "nChild" keys. 396 Note that this should only be run on a catalog that has had the 397 deblender already run (or else deblend_nChild does not exist). 399 parentName = pexConfig.Field(dtype=str, default=
"parent",
400 doc=
"Name of column for parent")
401 nChildName = pexConfig.Field(dtype=str, default=
"deblend_nChild",
402 doc=
"Name of column for nChild")
405 """Apply the isolation requirements to a catalog 407 Returns whether the source is selected. 411 catalog : `lsst.afw.table.SourceCatalog` 412 Catalog of sources to which the requirements will be applied. 416 selected : `numpy.ndarray` 417 Boolean array indicating for each source whether it is selected 418 (True means selected). 426 """Configuration for selecting science sources""" 427 doFluxLimit = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply flux limit?")
428 doFlags = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply flag limitation?")
429 doUnresolved = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply unresolved limitation?")
430 doSignalToNoise = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply signal-to-noise limit?")
431 doIsolated = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply isolated limitation?")
432 fluxLimit = pexConfig.ConfigField(dtype=FluxLimit, doc=
"Flux limit to apply")
433 flags = pexConfig.ConfigField(dtype=RequireFlags, doc=
"Flags to require")
434 unresolved = pexConfig.ConfigField(dtype=RequireUnresolved, doc=
"Star/galaxy separation to apply")
435 signalToNoise = pexConfig.ConfigField(dtype=SignalToNoiseLimit, doc=
"Signal-to-noise limit to apply")
436 isolated = pexConfig.ConfigField(dtype=RequireIsolated, doc=
"Isolated criteria to apply")
439 pexConfig.Config.setDefaults(self)
440 self.
flags.bad = [
"base_PixelFlags_flag_edge",
"base_PixelFlags_flag_saturated",
"base_PsfFlux_flags"]
446 """Science source selector 448 By "science" sources, we mean sources that are on images that we 449 are processing, as opposed to sources from reference catalogs. 451 This selects (science) sources by (optionally) applying each of a 452 magnitude limit, flag requirements and star/galaxy separation. 454 ConfigClass = ScienceSourceSelectorConfig
457 """Return a catalog of selected sources 461 catalog : `lsst.afw.table.SourceCatalog` 462 Catalog of sources to select. 463 matches : `lsst.afw.table.ReferenceMatchVector`, optional 464 List of matches; ignored. 468 sourceCat : `lsst.afw.table.SourceCatalog` 469 Catalog of selected sources, non-contiguous. 471 selected = np.ones(len(catalog), dtype=bool)
472 if self.config.doFluxLimit:
473 selected &= self.config.fluxLimit.apply(catalog)
474 if self.config.doFlags:
475 selected &= self.config.flags.apply(catalog)
476 if self.config.doUnresolved:
477 selected &= self.config.unresolved.apply(catalog)
478 if self.config.doSignalToNoise:
479 selected &= self.config.signalToNoise.apply(catalog)
480 if self.config.doIsolated:
481 selected &= self.config.isolated.apply(catalog)
483 self.log.info(
"Selected %d/%d sources", selected.sum(), len(catalog))
485 return pipeBase.Struct(sourceCat=catalog[selected],
490 doMagLimit = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply magnitude limit?")
491 doFlags = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply flag limitation?")
492 doSignalToNoise = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply signal-to-noise limit?")
493 doMagError = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply magnitude error limit?")
494 magLimit = pexConfig.ConfigField(dtype=MagnitudeLimit, doc=
"Magnitude limit to apply")
495 flags = pexConfig.ConfigField(dtype=RequireFlags, doc=
"Flags to require")
496 signalToNoise = pexConfig.ConfigField(dtype=SignalToNoiseLimit, doc=
"Signal-to-noise limit to apply")
497 magError = pexConfig.ConfigField(dtype=MagnitudeErrorLimit, doc=
"Magnitude error limit to apply")
498 colorLimits = pexConfig.ConfigDictField(keytype=str, itemtype=ColorLimit, default={},
499 doc=
"Color limits to apply; key is used as a label only")
503 """Reference source selector 505 This selects reference sources by (optionally) applying each of a 506 magnitude limit, flag requirements and color limits. 508 ConfigClass = ReferenceSourceSelectorConfig
511 """Return a catalog of selected reference sources 515 catalog : `lsst.afw.table.SourceCatalog` 516 Catalog of sources to select. 517 matches : `lsst.afw.table.ReferenceMatchVector`, optional 518 List of matches; ignored. 522 sourceCat : `lsst.afw.table.SourceCatalog` 523 Catalog of selected sources, non-contiguous. 525 selected = np.ones(len(catalog), dtype=bool)
526 if self.config.doMagLimit:
527 selected &= self.config.magLimit.apply(catalog)
528 if self.config.doFlags:
529 selected &= self.config.flags.apply(catalog)
530 if self.config.doSignalToNoise:
531 selected &= self.config.signalToNoise.apply(catalog)
532 if self.config.doMagError:
533 selected &= self.config.magError.apply(catalog)
534 for limit
in self.config.colorLimits.values():
535 selected &= limit.apply(catalog)
537 self.log.info(
"Selected %d/%d references", selected.sum(), len(catalog))
539 result = type(catalog)(catalog.table)
540 for source
in catalog[selected]:
541 result.append(source)
542 return pipeBase.Struct(sourceCat=result, selection=selected)
545 sourceSelectorRegistry.register(
"science", ScienceSourceSelectorTask)
546 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.