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)
141 with np.errstate(invalid=
"ignore"):
143 selected &= values > self.
minimum 145 selected &= values < self.
maximum 150 """Select sources using a color limit 152 This object can be used as a `lsst.pex.config.Config` for configuring 153 the limit, and then the `apply` method can be used to identify sources 154 in the catalog that match the configured limit. 156 We refer to 'primary' and 'secondary' flux measurements; these are the 157 two components of the color, which is: 159 instFluxToMag(cat[primary]) - instFluxToMag(cat[secondary]) 161 primary = pexConfig.Field(dtype=str, doc=
"Name of column with primary flux measurement")
162 secondary = pexConfig.Field(dtype=str, doc=
"Name of column with secondary flux measurement")
165 """Apply the color limit to a catalog 169 catalog : `lsst.afw.table.SourceCatalog` 170 Catalog of sources to which the limit will be applied. 174 selected : `numpy.ndarray` 175 Boolean array indicating for each source whether it is selected 176 (True means selected). 180 color = primary - secondary
181 return BaseLimit.apply(self, color)
185 """Select sources using a flux limit 187 This object can be used as a `lsst.pex.config.Config` for configuring 188 the limit, and then the `apply` method can be used to identify sources 189 in the catalog that match the configured limit. 191 fluxField = pexConfig.Field(dtype=str, default=
"slot_CalibFlux_flux",
192 doc=
"Name of the source flux field to use.")
195 """Apply the flux limits to a catalog 199 catalog : `lsst.afw.table.SourceCatalog` 200 Catalog of sources to which the limit will be applied. 204 selected : `numpy.ndarray` 205 Boolean array indicating for each source whether it is selected 206 (True means selected). 209 if flagField
in catalog.schema:
210 selected = np.logical_not(catalog[flagField])
212 selected = np.ones(len(catalog), dtype=bool)
215 selected &= BaseLimit.apply(self, flux)
220 """Select sources using a magnitude limit 222 Note that this assumes that a zero-point has already been applied and 223 the fluxes are in AB fluxes in Jansky. It is therefore principally 224 intended for reference catalogs rather than catalogs extracted from 227 This object can be used as a `lsst.pex.config.Config` for configuring 228 the limit, and then the `apply` method can be used to identify sources 229 in the catalog that match the configured limit. 231 fluxField = pexConfig.Field(dtype=str, default=
"flux",
232 doc=
"Name of the source flux field to use.")
235 """Apply the magnitude limits to a catalog 239 catalog : `lsst.afw.table.SourceCatalog` 240 Catalog of sources to which the limit will be applied. 244 selected : `numpy.ndarray` 245 Boolean array indicating for each source whether it is selected 246 (True means selected). 249 if flagField
in catalog.schema:
250 selected = np.logical_not(catalog[flagField])
252 selected = np.ones(len(catalog), dtype=bool)
255 selected &= BaseLimit.apply(self, magnitude)
260 """Select sources using a flux signal-to-noise limit 262 This object can be used as a `lsst.pex.config.Config` for configuring 263 the limit, and then the `apply` method can be used to identify sources 264 in the catalog that match the configured limit. 266 fluxField = pexConfig.Field(dtype=str, default=
"flux",
267 doc=
"Name of the source flux field to use.")
268 errField = pexConfig.Field(dtype=str, default=
"flux_err",
269 doc=
"Name of the source flux error field to use.")
272 """Apply the signal-to-noise limits to a catalog 276 catalog : `lsst.afw.table.SourceCatalog` 277 Catalog of sources to which the limit will be applied. 281 selected : `numpy.ndarray` 282 Boolean array indicating for each source whether it is selected 283 (True means selected). 286 if flagField
in catalog.schema:
287 selected = np.logical_not(catalog[flagField])
289 selected = np.ones(len(catalog), dtype=bool)
292 selected &= BaseLimit.apply(self, signalToNoise)
297 """Select sources using a magnitude error limit 299 Because the magnitude error is the inverse of the signal-to-noise 300 ratio, this also works to select sources by signal-to-noise when 301 you only have a magnitude. 303 This object can be used as a `lsst.pex.config.Config` for configuring 304 the limit, and then the `apply` method can be used to identify sources 305 in the catalog that match the configured limit. 307 magErrField = pexConfig.Field(dtype=str, default=
"mag_err",
308 doc=
"Name of the source flux error field to use.")
311 """Apply the magnitude error limits to a catalog 315 catalog : `lsst.afw.table.SourceCatalog` 316 Catalog of sources to which the limit will be applied. 320 selected : `numpy.ndarray` 321 Boolean array indicating for each source whether it is selected 322 (True means selected). 324 return BaseLimit.apply(self, catalog[self.
magErrField])
328 """Select sources using flags 330 This object can be used as a `lsst.pex.config.Config` for configuring 331 the limit, and then the `apply` method can be used to identify sources 332 in the catalog that match the configured limit. 334 good = pexConfig.ListField(dtype=str, default=[],
335 doc=
"List of source flag fields that must be set for a source to be used.")
336 bad = pexConfig.ListField(dtype=str, default=[],
337 doc=
"List of source flag fields that must NOT be set for a source to be used.")
340 """Apply the flag requirements to a catalog 342 Returns whether the source is selected. 346 catalog : `lsst.afw.table.SourceCatalog` 347 Catalog of sources to which the requirements will be applied. 351 selected : `numpy.ndarray` 352 Boolean array indicating for each source whether it is selected 353 (True means selected). 355 selected = np.ones(len(catalog), dtype=bool)
356 for flag
in self.
good:
357 selected &= catalog[flag]
358 for flag
in self.
bad:
359 selected &= ~catalog[flag]
364 """Select sources using star/galaxy separation 366 This object can be used as a `lsst.pex.config.Config` for configuring 367 the limit, and then the `apply` method can be used to identify sources 368 in the catalog that match the configured limit. 370 name = pexConfig.Field(dtype=str, default=
"base_ClassificationExtendedness_value",
371 doc=
"Name of column for star/galaxy separation")
374 """Apply the flag requirements to a catalog 376 Returns whether the source is selected. 380 catalog : `lsst.afw.table.SourceCatalog` 381 Catalog of sources to which the requirements will be applied. 385 selected : `numpy.ndarray` 386 Boolean array indicating for each source whether it is selected 387 (True means selected). 389 selected = np.ones(len(catalog), dtype=bool)
390 value = catalog[self.
name]
391 return BaseLimit.apply(self, value)
395 """Configuration for selecting science sources""" 396 doFluxLimit = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply flux limit?")
397 doFlags = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply flag limitation?")
398 doUnresolved = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply unresolved limitation?")
399 doSignalToNoise = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply signal-to-noise limit?")
400 fluxLimit = pexConfig.ConfigField(dtype=FluxLimit, doc=
"Flux limit to apply")
401 flags = pexConfig.ConfigField(dtype=RequireFlags, doc=
"Flags to require")
402 unresolved = pexConfig.ConfigField(dtype=RequireUnresolved, doc=
"Star/galaxy separation to apply")
403 signalToNoise = pexConfig.ConfigField(dtype=SignalToNoiseLimit, doc=
"Signal-to-noise limit to apply")
406 pexConfig.Config.setDefaults(self)
407 self.
flags.bad = [
"base_PixelFlags_flag_edge",
"base_PixelFlags_flag_interpolated",
408 "base_PixelFlags_flag_saturated",
"base_PsfFlux_flags"]
414 """Science source selector 416 By "science" sources, we mean sources that are on images that we 417 are processing, as opposed to sources from reference catalogs. 419 This selects (science) sources by (optionally) applying each of a 420 magnitude limit, flag requirements and star/galaxy separation. 422 ConfigClass = ScienceSourceSelectorConfig
425 """Return a catalog of selected sources 429 catalog : `lsst.afw.table.SourceCatalog` 430 Catalog of sources to select. 431 matches : `lsst.afw.table.ReferenceMatchVector`, optional 432 List of matches; ignored. 436 sourceCat : `lsst.afw.table.SourceCatalog` 437 Catalog of selected sources, non-contiguous. 439 selected = np.ones(len(catalog), dtype=bool)
440 if self.config.doFluxLimit:
441 selected &= self.config.fluxLimit.apply(catalog)
442 if self.config.doFlags:
443 selected &= self.config.flags.apply(catalog)
444 if self.config.doUnresolved:
445 selected &= self.config.unresolved.apply(catalog)
446 if self.config.doSignalToNoise:
447 selected &= self.config.signalToNoise.apply(catalog)
449 self.log.info(
"Selected %d/%d sources", selected.sum(), len(catalog))
451 result = type(catalog)(catalog.table)
452 for source
in catalog[selected]:
453 result.append(source)
454 return pipeBase.Struct(sourceCat=result, selection=selected)
458 doMagLimit = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply magnitude limit?")
459 doFlags = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply flag limitation?")
460 doSignalToNoise = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply signal-to-noise limit?")
461 doMagError = pexConfig.Field(dtype=bool, default=
False, doc=
"Apply magnitude error limit?")
462 magLimit = pexConfig.ConfigField(dtype=MagnitudeLimit, doc=
"Magnitude limit to apply")
463 flags = pexConfig.ConfigField(dtype=RequireFlags, doc=
"Flags to require")
464 signalToNoise = pexConfig.ConfigField(dtype=SignalToNoiseLimit, doc=
"Signal-to-noise limit to apply")
465 magError = pexConfig.ConfigField(dtype=MagnitudeErrorLimit, doc=
"Magnitude error limit to apply")
466 colorLimits = pexConfig.ConfigDictField(keytype=str, itemtype=ColorLimit, default={},
467 doc=
"Color limits to apply; key is used as a label only")
471 """Reference source selector 473 This selects reference sources by (optionally) applying each of a 474 magnitude limit, flag requirements and color limits. 476 ConfigClass = ReferenceSourceSelectorConfig
479 """Return a catalog of selected reference sources 483 catalog : `lsst.afw.table.SourceCatalog` 484 Catalog of sources to select. 485 matches : `lsst.afw.table.ReferenceMatchVector`, optional 486 List of matches; ignored. 490 sourceCat : `lsst.afw.table.SourceCatalog` 491 Catalog of selected sources, non-contiguous. 493 selected = np.ones(len(catalog), dtype=bool)
494 if self.config.doMagLimit:
495 selected &= self.config.magLimit.apply(catalog)
496 if self.config.doFlags:
497 selected &= self.config.flags.apply(catalog)
498 if self.config.doSignalToNoise:
499 selected &= self.config.signalToNoise.apply(catalog)
500 if self.config.doMagError:
501 selected &= self.config.magError.apply(catalog)
502 for limit
in self.config.colorLimits.values():
503 selected &= limit.apply(catalog)
505 self.log.info(
"Selected %d/%d references", selected.sum(), len(catalog))
507 result = type(catalog)(catalog.table)
508 for source
in catalog[selected]:
509 result.append(source)
510 return pipeBase.Struct(sourceCat=result, selection=selected)
513 sourceSelectorRegistry.register(
"science", ScienceSourceSelectorTask)
514 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.