22 from collections
import namedtuple
25 import lsst.pex.config
28 from .pluginsBase
import BasePlugin, BasePluginConfig
29 from .pluginRegistry
import PluginRegistry, PluginMap
30 from .
import FatalAlgorithmError, MeasurementError
34 FATAL_EXCEPTIONS = (MemoryError, FatalAlgorithmError)
36 __all__ = (
"CatalogCalculationPluginConfig",
"CatalogCalculationPlugin",
"CatalogCalculationConfig",
37 "CatalogCalculationTask")
41 """Default configuration class for catalog calcuation plugins.
47 """Base class for catalog calculation plugins.
51 config : `CatalogCalculationPlugin.ConfigClass`
54 The string the plugin was registered with.
55 schema : `lsst.afw.table.Schema`
56 The source schema, New fields should be added here to
57 hold output produced by this plugin.
58 metadata : `lsst.daf.base.PropertySet`
59 Plugin metadata that will be attached to the output catalog
62 ConfigClass = CatalogCalculationPluginConfig
65 """List of available plugins (`lsst.meas.base.PluginRegistry`).
69 """Does the plugin operate on a single source or the whole catalog (`str`)?
71 If the plugin operates on a single source at a time, this should be set to
72 ``"single"``; if it expects the whoe catalog, to ``"multi"``. If the
73 plugin is of type ``"multi"``, the `fail` method must be implemented to
74 accept the whole catalog. If the plugin is of type ``"single"``, `fail`
75 should accept a single source record.
78 def __init__(self, config, name, schema, metadata):
79 BasePlugin.__init__(self, config, name)
83 r"""Used to set the relative order of plugin execution.
85 The values returned by `getExecutionOrder` are compared across all
86 plugins, and smaller numbers run first.
90 `CatalogCalculationPlugin`\s must run with
91 `BasePlugin.DEFAULT_CATALOGCALCULATION` or higher.
93 All plugins must implement this method with an appropriate run level
95 raise NotImplementedError()
98 """Perform the calculation specified by this plugin.
100 This method can either be used to operate on a single catalog record
101 or a whole catalog, populating it with the output defined by this
104 Note that results may be added to catalog records as new columns, or
105 may result in changes to existing values.
109 cat : `lsst.afw.table.SourceCatalog` or `lsst.afw.table.SourceRecord`
110 May either be a `~lsst.afw.table.SourceCatalog` or a single
111 `~lsst.afw.table.SourceRecord`, depending on the plugin type. Will
112 be updated in place to contain the results of plugin execution.
114 Any additional keyword arguments that may be passed to the plugin.
116 raise NotImplementedError()
120 """Handle errors that are thrown by catalog calculation plugins.
122 This is a context manager.
126 plugin : `CatalogCalculationPlugin`
127 The plugin that is to be run.
128 cat : `lsst.afw.table.SourceCatalog` or `lsst.afw.table.SourceRecord`
129 May either be a `~lsst.afw.table.SourceCatalog` or a single
130 `~lsst.afw.table.SourceRecord`, depending on the plugin type.
132 A logger. Generally, this should be the logger of the object in which
133 the context manager is being used.
143 def __exit__(self, exc_type, exc_value, traceback):
146 if exc_type
in FATAL_EXCEPTIONS:
148 elif exc_type
is MeasurementError:
149 self.plugin.fail(self.cat, exc_value)
151 self.log.
warn(
"Error in {}.calculate: {}".
format(self.plugin.name, exc_value))
156 """Config class for the catalog calculation driver task.
158 Specifies which plugins will execute when the `CatalogCalculationTask`
159 associated with this configuration is run.
162 plugins = CatalogCalculationPlugin.registry.makeField(
164 default=[
"base_ClassificationExtendedness",
165 "base_FootprintArea"],
166 doc=
"Plugins to be run and their configuration")
170 """Run plugins which operate on a catalog of sources.
172 This task facilitates running plugins which will operate on a source
173 catalog. These plugins may do things such as classifying an object based
174 on source record entries inserted during a measurement task.
178 plugMetaData : `lsst.daf.base.PropertyList` or `None`
179 Will be modified in-place to contain metadata about the plugins being
180 run. If `None`, an empty `~lsst.daf.base.PropertyList` will be
183 Additional arguments passed to the superclass constructor.
187 Plugins may either take an entire catalog to work on at a time, or work on
190 ConfigClass = CatalogCalculationConfig
191 _DefaultName =
"catalogCalculation"
193 def __init__(self, schema, plugMetadata=None, **kwargs):
194 lsst.pipe.base.Task.__init__(self, **kwargs)
196 if plugMetadata
is None:
204 """Initialize the plugins according to the configuration.
207 pluginType = namedtuple(
'pluginType',
'single multi')
213 for executionOrder, name, config, PluginClass
in sorted(self.
config.plugins.apply()):
215 self.
executionDict[executionOrder] = pluginType(single=[], multi=[])
216 if PluginClass.getExecutionOrder() >= BasePlugin.DEFAULT_CATALOGCALCULATION:
219 if plug.plugType ==
'single':
221 elif plug.plugType ==
'multi':
224 errorTuple = (PluginClass, PluginClass.getExecutionOrder(),
225 BasePlugin.DEFAULT_CATALOGCALCULATION)
226 raise ValueError(
"{} has an execution order less than the minimum for an catalogCalculation "
227 "plugin. Value {} : Minimum {}".
format(*errorTuple))
229 @lsst.pipe.base.timeMethod
231 """The entry point for the catalog calculation task.
235 meascat : `lsst.afw.table.SourceCatalog`
236 Catalog for measurement.
241 """Run each of the plugins on the catalog.
245 catalog : `lsst.afw.table.SourceCatalog`
246 The catalog on which the plugins will operate.
252 plug.calculate(catalog)
254 for measRecord
in catalog:
257 plug.calculate(measRecord)