LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
sourceSelector.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 #
4 # Copyright 2008-2017 AURA/LSST.
5 #
6 # This product includes software developed by the
7 # LSST Project (http://www.lsst.org/).
8 #
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the LSST License Statement and
20 # the GNU General Public License along with this program. If not,
21 # see <https://www.lsstcorp.org/LegalNotices/>.
22 #
23 
24 __all__ = ["BaseSourceSelectorConfig", "BaseSourceSelectorTask", "sourceSelectorRegistry",
25  "ColorLimit", "MagnitudeLimit", "SignalToNoiseLimit", "MagnitudeErrorLimit",
26  "RequireFlags", "RequireUnresolved",
27  "ScienceSourceSelectorConfig", "ScienceSourceSelectorTask",
28  "ReferenceSourceSelectorConfig", "ReferenceSourceSelectorTask",
29  ]
30 
31 import abc
32 import numpy as np
33 import astropy.units as u
34 import pandas
35 import astropy.table
36 
37 import lsst.pex.config as pexConfig
38 import lsst.pipe.base as pipeBase
39 
40 
41 class BaseSourceSelectorConfig(pexConfig.Config):
42  pass
43 
44 
45 class BaseSourceSelectorTask(pipeBase.Task, metaclass=abc.ABCMeta):
46  """Base class for source selectors
47 
48  Source selectors are classes that perform a selection on a catalog
49  object given a set of criteria or cuts. They return the selected catalog
50  and can optionally set a specified Flag field in the input catalog to
51  identify if the source was selected.
52 
53  Register all source selectors with the sourceSelectorRegistry using:
54  sourceSelectorRegistry.register(name, class)
55 
56  Attributes
57  ----------
58  usesMatches : `bool`
59  A boolean variable specify if the inherited source selector uses
60  matches to an external catalog, and thus requires the ``matches``
61  argument to ``run()``.
62  """
63 
64  ConfigClass = BaseSourceSelectorConfig
65  _DefaultName = "sourceSelector"
66  usesMatches = False
67 
68  def __init__(self, **kwargs):
69  pipeBase.Task.__init__(self, **kwargs)
70 
71  def run(self, sourceCat, sourceSelectedField=None, matches=None, exposure=None):
72  """Select sources and return them.
73 
74  The input catalog must be contiguous in memory.
75 
76  Parameters:
77  -----------
78  sourceCat : `lsst.afw.table.SourceCatalog` or `pandas.DataFrame`
79  or `astropy.table.Table`
80  Catalog of sources to select from.
81  sourceSelectedField : `str` or None
82  Name of flag field in sourceCat to set for selected sources.
83  If set, will modify sourceCat in-place.
84  matches : `list` of `lsst.afw.table.ReferenceMatch` or None
85  List of matches to use for source selection.
86  If usesMatches is set in source selector this field is required.
87  If not, it is ignored.
88  exposure : `lsst.afw.image.Exposure` or None
89  The exposure the catalog was built from; used for debug display.
90 
91  Return
92  ------
93  struct : `lsst.pipe.base.Struct`
94  The struct contains the following data:
95 
96  - sourceCat : `lsst.afw.table.SourceCatalog` or `pandas.DataFrame`
97  or `astropy.table.Table`
98  The catalog of sources that were selected.
99  (may not be memory-contiguous)
100  - selected : `numpy.ndarray` of `bool``
101  Boolean array of sources that were selected, same length as
102  sourceCat.
103 
104  Raises
105  ------
106  RuntimeError
107  Raised if ``sourceCat`` is not contiguous.
108  """
109  if hasattr(sourceCat, 'isContiguous'):
110  # Check for continuity on afwTable catalogs
111  if not sourceCat.isContiguous():
112  raise RuntimeError("Input catalogs for source selection must be contiguous.")
113 
114  result = self.selectSourcesselectSources(sourceCat=sourceCat,
115  exposure=exposure,
116  matches=matches)
117 
118  if sourceSelectedField is not None:
119  if isinstance(sourceCat, (pandas.DataFrame, astropy.table.Table)):
120  sourceCat[sourceSelectedField] = result.selected
121  else:
122  source_selected_key = \
123  sourceCat.getSchema()[sourceSelectedField].asKey()
124  # TODO: Remove for loop when DM-6981 is completed.
125  for source, flag in zip(sourceCat, result.selected):
126  source.set(source_selected_key, bool(flag))
127  return pipeBase.Struct(sourceCat=sourceCat[result.selected],
128  selected=result.selected)
129 
130  @abc.abstractmethod
131  def selectSources(self, sourceCat, matches=None, exposure=None):
132  """Return a selection of sources selected by some criteria.
133 
134  Parameters
135  ----------
136  sourceCat : `lsst.afw.table.SourceCatalog` or `pandas.DataFrame`
137  or `astropy.table.Table`
138  Catalog of sources to select from.
139  This catalog must be contiguous in memory.
140  matches : `list` of `lsst.afw.table.ReferenceMatch` or None
141  A list of lsst.afw.table.ReferenceMatch objects
142  exposure : `lsst.afw.image.Exposure` or None
143  The exposure the catalog was built from; used for debug display.
144 
145  Return
146  ------
147  struct : `lsst.pipe.base.Struct`
148  The struct contains the following data:
149 
150  - selected : `numpy.ndarray` of `bool``
151  Boolean array of sources that were selected, same length as
152  sourceCat.
153  """
154  raise NotImplementedError("BaseSourceSelectorTask is abstract")
155 
156 
157 sourceSelectorRegistry = pexConfig.makeRegistry(
158  doc="A registry of source selectors (subclasses of "
159  "BaseSourceSelectorTask)",
160 )
161 
162 
163 class BaseLimit(pexConfig.Config):
164  """Base class for selecting sources by applying a limit
165 
166  This object can be used as a `lsst.pex.config.Config` for configuring
167  the limit, and then the `apply` method can be used to identify sources
168  in the catalog that match the configured limit.
169 
170  This provides the `maximum` and `minimum` fields in the Config, and
171  a method to apply the limits to an array of values calculated by the
172  subclass.
173  """
174  minimum = pexConfig.Field(dtype=float, optional=True, doc="Select objects with value greater than this")
175  maximum = pexConfig.Field(dtype=float, optional=True, doc="Select objects with value less than this")
176 
177  def apply(self, values):
178  """Apply the limits to an array of values
179 
180  Subclasses should calculate the array of values and then
181  return the result of calling this method.
182 
183  Parameters
184  ----------
185  values : `numpy.ndarray`
186  Array of values to which to apply limits.
187 
188  Returns
189  -------
190  selected : `numpy.ndarray`
191  Boolean array indicating for each source whether it is selected
192  (True means selected).
193  """
194  selected = np.ones(len(values), dtype=bool)
195  with np.errstate(invalid="ignore"): # suppress NAN warnings
196  if self.minimumminimum is not None:
197  selected &= values > self.minimumminimum
198  if self.maximummaximum is not None:
199  selected &= values < self.maximummaximum
200  return selected
201 
202 
204  """Select sources using a color limit
205 
206  This object can be used as a `lsst.pex.config.Config` for configuring
207  the limit, and then the `apply` method can be used to identify sources
208  in the catalog that match the configured limit.
209 
210  We refer to 'primary' and 'secondary' flux measurements; these are the
211  two components of the color, which is:
212 
213  instFluxToMag(cat[primary]) - instFluxToMag(cat[secondary])
214  """
215  primary = pexConfig.Field(dtype=str, doc="Name of column with primary flux measurement")
216  secondary = pexConfig.Field(dtype=str, doc="Name of column with secondary flux measurement")
217 
218  def apply(self, catalog):
219  """Apply the color limit to a catalog
220 
221  Parameters
222  ----------
223  catalog : `lsst.afw.table.SourceCatalog` or `pandas.DataFrame`
224  or `astropy.table.Table`
225  Catalog of sources to which the limit will be applied.
226 
227  Returns
228  -------
229  selected : `numpy.ndarray`
230  Boolean array indicating for each source whether it is selected
231  (True means selected).
232  """
233  primary = _getFieldFromCatalog(catalog, self.primaryprimary)
234  secondary = _getFieldFromCatalog(catalog, self.secondarysecondary)
235 
236  primary = (primary*u.nJy).to_value(u.ABmag)
237  secondary = (secondary*u.nJy).to_value(u.ABmag)
238  color = primary - secondary
239  return BaseLimit.apply(self, color)
240 
241 
243  """Select sources using a flux limit
244 
245  This object can be used as a `lsst.pex.config.Config` for configuring
246  the limit, and then the `apply` method can be used to identify sources
247  in the catalog that match the configured limit.
248  """
249  fluxField = pexConfig.Field(dtype=str, default="slot_CalibFlux_instFlux",
250  doc="Name of the source flux field to use.")
251 
252  def apply(self, catalog):
253  """Apply the flux limits to a catalog
254 
255  Parameters
256  ----------
257  catalog : `lsst.afw.table.SourceCatalog`
258  Catalog of sources to which the limit will be applied.
259 
260  Returns
261  -------
262  selected : `numpy.ndarray`
263  Boolean array indicating for each source whether it is selected
264  (True means selected).
265  """
266  flagField = self.fluxFieldfluxField + "_flag"
267  selected = np.logical_not(_getFieldFromCatalog(catalog, flagField, isFlag=True))
268  flux = _getFieldFromCatalog(catalog, self.fluxFieldfluxField)
269 
270  selected &= BaseLimit.apply(self, flux)
271  return selected
272 
273 
275  """Select sources using a magnitude limit
276 
277  Note that this assumes that a zero-point has already been applied and
278  the fluxes are in AB fluxes in Jansky. It is therefore principally
279  intended for reference catalogs rather than catalogs extracted from
280  science images.
281 
282  This object can be used as a `lsst.pex.config.Config` for configuring
283  the limit, and then the `apply` method can be used to identify sources
284  in the catalog that match the configured limit.
285  """
286  fluxField = pexConfig.Field(dtype=str, default="flux",
287  doc="Name of the source flux field to use.")
288 
289  def apply(self, catalog):
290  """Apply the magnitude limits to a catalog
291 
292  Parameters
293  ----------
294  catalog : `lsst.afw.table.SourceCatalog`
295  Catalog of sources to which the limit will be applied.
296 
297  Returns
298  -------
299  selected : `numpy.ndarray`
300  Boolean array indicating for each source whether it is selected
301  (True means selected).
302  """
303  flagField = self.fluxFieldfluxField + "_flag"
304  selected = np.logical_not(_getFieldFromCatalog(catalog, flagField, isFlag=True))
305  flux = _getFieldFromCatalog(catalog, self.fluxFieldfluxField)
306 
307  magnitude = (flux*u.nJy).to_value(u.ABmag)
308  selected &= BaseLimit.apply(self, magnitude)
309  return selected
310 
311 
313  """Select sources using a flux signal-to-noise limit
314 
315  This object can be used as a `lsst.pex.config.Config` for configuring
316  the limit, and then the `apply` method can be used to identify sources
317  in the catalog that match the configured limit.
318  """
319  fluxField = pexConfig.Field(dtype=str, default="flux",
320  doc="Name of the source flux field to use.")
321  errField = pexConfig.Field(dtype=str, default="flux_err",
322  doc="Name of the source flux error field to use.")
323 
324  def apply(self, catalog):
325  """Apply the signal-to-noise limits to a catalog
326 
327  Parameters
328  ----------
329  catalog : `lsst.afw.table.SourceCatalog`
330  Catalog of sources to which the limit will be applied.
331 
332  Returns
333  -------
334  selected : `numpy.ndarray`
335  Boolean array indicating for each source whether it is selected
336  (True means selected).
337  """
338  flagField = self.fluxFieldfluxField + "_flag"
339  selected = np.logical_not(_getFieldFromCatalog(catalog, flagField, isFlag=True))
340  flux = _getFieldFromCatalog(catalog, self.fluxFieldfluxField)
341  err = _getFieldFromCatalog(catalog, self.errFielderrField)
342 
343  signalToNoise = flux/err
344  selected &= BaseLimit.apply(self, signalToNoise)
345  return selected
346 
347 
349  """Select sources using a magnitude error limit
350 
351  Because the magnitude error is the inverse of the signal-to-noise
352  ratio, this also works to select sources by signal-to-noise when
353  you only have a magnitude.
354 
355  This object can be used as a `lsst.pex.config.Config` for configuring
356  the limit, and then the `apply` method can be used to identify sources
357  in the catalog that match the configured limit.
358  """
359  magErrField = pexConfig.Field(dtype=str, default="mag_err",
360  doc="Name of the source flux error field to use.")
361 
362  def apply(self, catalog):
363  """Apply the magnitude error limits to a catalog
364 
365  Parameters
366  ----------
367  catalog : `lsst.afw.table.SourceCatalog`
368  Catalog of sources to which the limit will be applied.
369 
370  Returns
371  -------
372  selected : `numpy.ndarray`
373  Boolean array indicating for each source whether it is selected
374  (True means selected).
375  """
376  return BaseLimit.apply(self, catalog[self.magErrFieldmagErrField])
377 
378 
379 class RequireFlags(pexConfig.Config):
380  """Select sources using flags
381 
382  This object can be used as a `lsst.pex.config.Config` for configuring
383  the limit, and then the `apply` method can be used to identify sources
384  in the catalog that match the configured limit.
385  """
386  good = pexConfig.ListField(dtype=str, default=[],
387  doc="List of source flag fields that must be set for a source to be used.")
388  bad = pexConfig.ListField(dtype=str, default=[],
389  doc="List of source flag fields that must NOT be set for a source to be used.")
390 
391  def apply(self, catalog):
392  """Apply the flag requirements to a catalog
393 
394  Returns whether the source is selected.
395 
396  Parameters
397  ----------
398  catalog : `lsst.afw.table.SourceCatalog`
399  Catalog of sources to which the requirements will be applied.
400 
401  Returns
402  -------
403  selected : `numpy.ndarray`
404  Boolean array indicating for each source whether it is selected
405  (True means selected).
406  """
407  selected = np.ones(len(catalog), dtype=bool)
408  for flag in self.goodgood:
409  selected &= catalog[flag]
410  for flag in self.badbad:
411  selected &= ~catalog[flag]
412  return selected
413 
414 
416  """Select sources using star/galaxy separation
417 
418  This object can be used as a `lsst.pex.config.Config` for configuring
419  the limit, and then the `apply` method can be used to identify sources
420  in the catalog that match the configured limit.
421  """
422  name = pexConfig.Field(dtype=str, default="base_ClassificationExtendedness_value",
423  doc="Name of column for star/galaxy separation")
424 
425  def setDefaults(self):
426  """Set default
427 
428  ``base_ClassificationExtendedness_value < 0.5`` means unresolved.
429  """
430  self.maximummaximummaximum = 0.5
431 
432  def apply(self, catalog):
433  """Apply the flag requirements to a catalog
434 
435  Returns whether the source is selected.
436 
437  Parameters
438  ----------
439  catalog : `lsst.afw.table.SourceCatalog`
440  Catalog of sources to which the requirements will be applied.
441 
442  Returns
443  -------
444  selected : `numpy.ndarray`
445  Boolean array indicating for each source whether it is selected
446  (True means selected).
447  """
448  value = catalog[self.namename]
449  return BaseLimit.apply(self, value)
450 
451 
452 class RequireIsolated(pexConfig.Config):
453  """Select sources based on whether they are isolated
454 
455  This object can be used as a `lsst.pex.config.Config` for configuring
456  the column names to check for "parent" and "nChild" keys.
457 
458  Note that this should only be run on a catalog that has had the
459  deblender already run (or else deblend_nChild does not exist).
460  """
461  parentName = pexConfig.Field(dtype=str, default="parent",
462  doc="Name of column for parent")
463  nChildName = pexConfig.Field(dtype=str, default="deblend_nChild",
464  doc="Name of column for nChild")
465 
466  def apply(self, catalog):
467  """Apply the isolation requirements to a catalog
468 
469  Returns whether the source is selected.
470 
471  Parameters
472  ----------
473  catalog : `lsst.afw.table.SourceCatalog`
474  Catalog of sources to which the requirements will be applied.
475 
476  Returns
477  -------
478  selected : `numpy.ndarray`
479  Boolean array indicating for each source whether it is selected
480  (True means selected).
481  """
482  selected = ((catalog[self.parentNameparentName] == 0)
483  & (catalog[self.nChildNamenChildName] == 0))
484  return selected
485 
486 
487 class ScienceSourceSelectorConfig(pexConfig.Config):
488  """Configuration for selecting science sources"""
489  doFluxLimit = pexConfig.Field(dtype=bool, default=False, doc="Apply flux limit?")
490  doFlags = pexConfig.Field(dtype=bool, default=False, doc="Apply flag limitation?")
491  doUnresolved = pexConfig.Field(dtype=bool, default=False, doc="Apply unresolved limitation?")
492  doSignalToNoise = pexConfig.Field(dtype=bool, default=False, doc="Apply signal-to-noise limit?")
493  doIsolated = pexConfig.Field(dtype=bool, default=False, doc="Apply isolated limitation?")
494  fluxLimit = pexConfig.ConfigField(dtype=FluxLimit, doc="Flux limit to apply")
495  flags = pexConfig.ConfigField(dtype=RequireFlags, doc="Flags to require")
496  unresolved = pexConfig.ConfigField(dtype=RequireUnresolved, doc="Star/galaxy separation to apply")
497  signalToNoise = pexConfig.ConfigField(dtype=SignalToNoiseLimit, doc="Signal-to-noise limit to apply")
498  isolated = pexConfig.ConfigField(dtype=RequireIsolated, doc="Isolated criteria to apply")
499 
500  def setDefaults(self):
501  pexConfig.Config.setDefaults(self)
502  self.flagsflags.bad = ["base_PixelFlags_flag_edge", "base_PixelFlags_flag_saturated", "base_PsfFlux_flags"]
503  self.signalToNoisesignalToNoise.fluxField = "base_PsfFlux_instFlux"
504  self.signalToNoisesignalToNoise.errField = "base_PsfFlux_instFluxErr"
505 
506 
507 @pexConfig.registerConfigurable("science", sourceSelectorRegistry)
509  """Science source selector
510 
511  By "science" sources, we mean sources that are on images that we
512  are processing, as opposed to sources from reference catalogs.
513 
514  This selects (science) sources by (optionally) applying each of a
515  magnitude limit, flag requirements and star/galaxy separation.
516  """
517  ConfigClass = ScienceSourceSelectorConfig
518 
519  def selectSources(self, sourceCat, matches=None, exposure=None):
520  """Return a selection of sources selected by specified criteria.
521 
522  Parameters
523  ----------
524  sourceCat : `lsst.afw.table.SourceCatalog`
525  Catalog of sources to select from.
526  This catalog must be contiguous in memory.
527  matches : `list` of `lsst.afw.table.ReferenceMatch` or None
528  Ignored in this SourceSelector.
529  exposure : `lsst.afw.image.Exposure` or None
530  The exposure the catalog was built from; used for debug display.
531 
532  Return
533  ------
534  struct : `lsst.pipe.base.Struct`
535  The struct contains the following data:
536 
537  - selected : `array` of `bool``
538  Boolean array of sources that were selected, same length as
539  sourceCat.
540  """
541  selected = np.ones(len(sourceCat), dtype=bool)
542  if self.config.doFluxLimit:
543  selected &= self.config.fluxLimit.apply(sourceCat)
544  if self.config.doFlags:
545  selected &= self.config.flags.apply(sourceCat)
546  if self.config.doUnresolved:
547  selected &= self.config.unresolved.apply(sourceCat)
548  if self.config.doSignalToNoise:
549  selected &= self.config.signalToNoise.apply(sourceCat)
550  if self.config.doIsolated:
551  selected &= self.config.isolated.apply(sourceCat)
552 
553  self.log.info("Selected %d/%d sources", selected.sum(), len(sourceCat))
554 
555  return pipeBase.Struct(selected=selected)
556 
557 
558 class ReferenceSourceSelectorConfig(pexConfig.Config):
559  doMagLimit = pexConfig.Field(dtype=bool, default=False, doc="Apply magnitude limit?")
560  doFlags = pexConfig.Field(dtype=bool, default=False, doc="Apply flag limitation?")
561  doUnresolved = pexConfig.Field(dtype=bool, default=False, doc="Apply unresolved limitation?")
562  doSignalToNoise = pexConfig.Field(dtype=bool, default=False, doc="Apply signal-to-noise limit?")
563  doMagError = pexConfig.Field(dtype=bool, default=False, doc="Apply magnitude error limit?")
564  magLimit = pexConfig.ConfigField(dtype=MagnitudeLimit, doc="Magnitude limit to apply")
565  flags = pexConfig.ConfigField(dtype=RequireFlags, doc="Flags to require")
566  unresolved = pexConfig.ConfigField(dtype=RequireUnresolved, doc="Star/galaxy separation to apply")
567  signalToNoise = pexConfig.ConfigField(dtype=SignalToNoiseLimit, doc="Signal-to-noise limit to apply")
568  magError = pexConfig.ConfigField(dtype=MagnitudeErrorLimit, doc="Magnitude error limit to apply")
569  colorLimits = pexConfig.ConfigDictField(keytype=str, itemtype=ColorLimit, default={},
570  doc="Color limits to apply; key is used as a label only")
571 
572 
573 @pexConfig.registerConfigurable("references", sourceSelectorRegistry)
575  """Reference source selector
576 
577  This selects reference sources by (optionally) applying each of a
578  magnitude limit, flag requirements and color limits.
579  """
580  ConfigClass = ReferenceSourceSelectorConfig
581 
582  def selectSources(self, sourceCat, matches=None, exposure=None):
583  """Return a selection of reference sources selected by some criteria.
584 
585  Parameters
586  ----------
587  sourceCat : `lsst.afw.table.SourceCatalog`
588  Catalog of sources to select from.
589  This catalog must be contiguous in memory.
590  matches : `list` of `lsst.afw.table.ReferenceMatch` or None
591  Ignored in this SourceSelector.
592  exposure : `lsst.afw.image.Exposure` or None
593  The exposure the catalog was built from; used for debug display.
594 
595  Return
596  ------
597  struct : `lsst.pipe.base.Struct`
598  The struct contains the following data:
599 
600  - selected : `array` of `bool``
601  Boolean array of sources that were selected, same length as
602  sourceCat.
603  """
604  selected = np.ones(len(sourceCat), dtype=bool)
605  if self.config.doMagLimit:
606  selected &= self.config.magLimit.apply(sourceCat)
607  if self.config.doFlags:
608  selected &= self.config.flags.apply(sourceCat)
609  if self.config.doUnresolved:
610  selected &= self.config.unresolved.apply(sourceCat)
611  if self.config.doSignalToNoise:
612  selected &= self.config.signalToNoise.apply(sourceCat)
613  if self.config.doMagError:
614  selected &= self.config.magError.apply(sourceCat)
615  for limit in self.config.colorLimits.values():
616  selected &= limit.apply(sourceCat)
617 
618  self.log.info("Selected %d/%d references", selected.sum(), len(sourceCat))
619 
620  return pipeBase.Struct(selected=selected)
621 
622 
623 def _getFieldFromCatalog(catalog, field, isFlag=False):
624  """
625  Get a field from a catalog, for `lsst.afw.table` catalogs or
626  `pandas.DataFrame` or `astropy.table.Table` catalogs.
627 
628  Parameters
629  ----------
630  catalog : `lsst.afw.table.SourceCatalog` or `pandas.DataFrame`
631  or `astropy.table.Table`
632  Catalog of sources to extract field array
633  field : `str`
634  Name of field
635  isFlag : `bool`, optional
636  Is this a flag column? If it does not exist, return array
637  of False.
638 
639  Returns
640  -------
641  array : `np.ndarray`
642  Array of field values from the catalog.
643  """
644  found = False
645  if isinstance(catalog, (pandas.DataFrame, astropy.table.Table)):
646  if field in catalog.columns:
647  found = True
648  # Sequences must be converted to numpy arrays
649  arr = np.array(catalog[field])
650  else:
651  if field in catalog.schema:
652  found = True
653  arr = catalog[field]
654 
655  if isFlag and not found:
656  arr = np.zeros(len(catalog), dtype=bool)
657  elif not found:
658  raise KeyError(f"Could not find field {field} in catalog.")
659 
660  return arr
def selectSources(self, sourceCat, matches=None, exposure=None)
def run(self, sourceCat, sourceSelectedField=None, matches=None, exposure=None)
def selectSources(self, sourceCat, matches=None, exposure=None)
def selectSources(self, sourceCat, matches=None, exposure=None)