23 """Base measurement task, which subclassed by the single frame and forced measurement tasks. 28 from .pluginRegistry
import PluginMap
29 from .exceptions
import FatalAlgorithmError, MeasurementError
30 from .pluginsBase
import BasePluginConfig, BasePlugin
31 from .noiseReplacer
import NoiseReplacerConfig
33 __all__ = (
"BaseMeasurementPluginConfig",
"BaseMeasurementPlugin",
34 "BaseMeasurementConfig",
"BaseMeasurementTask")
37 FATAL_EXCEPTIONS = (MemoryError, FatalAlgorithmError)
42 Base config class for all measurement plugins 44 Most derived classes will want to override setDefaults() in order to customize 45 the default exceutionOrder. 47 A derived class whose corresponding Plugin class implements measureN() should 48 additionally add a bool doMeasureN field to replace the bool class attribute 52 doMeasure = lsst.pex.config.Field(dtype=bool, default=
True,
53 doc=
"whether to run this plugin in single-object mode")
60 Base class for all measurement plugins 62 This is class is a placeholder for future behavior which will be shared only between 63 measurement plugins and is implemented for symmetry with the measurement base plugin 71 Slot configuration which assigns a particular named plugin to each of a set of 72 slots. Each slot allows a type of measurement to be fetched from the SourceTable 73 without knowing which algorithm was used to produced the data. 75 NOTE: the default algorithm for each slot must be registered, even if the default is not used. 78 centroid = lsst.pex.config.Field(dtype=str, default=
"base_SdssCentroid", optional=
True,
79 doc=
"the name of the centroiding algorithm used to set source x,y")
80 shape = lsst.pex.config.Field(dtype=str, default=
"base_SdssShape", optional=
True,
81 doc=
"the name of the algorithm used to set source moments parameters")
82 psfShape = lsst.pex.config.Field(dtype=str, default=
"base_SdssShape_psf", optional=
True,
83 doc=
"the name of the algorithm used to set PSF moments parameters")
84 apFlux = lsst.pex.config.Field(dtype=str, default=
"base_CircularApertureFlux_12_0", optional=
True,
85 doc=
"the name of the algorithm used to set the source aperture flux slot")
86 modelFlux = lsst.pex.config.Field(dtype=str, default=
"base_GaussianFlux", optional=
True,
87 doc=
"the name of the algorithm used to set the source model flux slot")
88 psfFlux = lsst.pex.config.Field(dtype=str, default=
"base_PsfFlux", optional=
True,
89 doc=
"the name of the algorithm used to set the source psf flux slot")
90 instFlux = lsst.pex.config.Field(dtype=str, default=
"base_GaussianFlux", optional=
True,
91 doc=
"the name of the algorithm used to set the source inst flux slot")
92 calibFlux = lsst.pex.config.Field(dtype=str, default=
"base_CircularApertureFlux_12_0", optional=
True,
93 doc=
"the name of the flux measurement algorithm used for calibration")
96 """Convenience method to setup a Schema's slots according to the config definition. 98 This is defined in the Config class to support use in unit tests without needing 99 to construct a Task object. 101 aliases = schema.getAliasMap()
103 aliases.set(
"slot_Centroid", self.
centroid)
104 if self.
shape is not None:
105 aliases.set(
"slot_Shape", self.
shape)
107 aliases.set(
"slot_PsfShape", self.
psfShape)
108 if self.
apFlux is not None:
109 aliases.set(
"slot_ApFlux", self.
apFlux)
111 aliases.set(
"slot_ModelFlux", self.
modelFlux)
113 aliases.set(
"slot_PsfFlux", self.
psfFlux)
115 aliases.set(
"slot_InstFlux", self.
instFlux)
117 aliases.set(
"slot_CalibFlux", self.
calibFlux)
122 Base config class for all measurement driver tasks. 124 Subclasses should define the 'plugins' and 'undeblended' registries, e.g.: 126 plugins = PluginBaseClass.registry.makeField( 129 doc="Plugins to be run and their configuration" 131 undeblended = PluginBaseClass.registry.makeField( 134 doc="Plugins to run on undeblended image" 137 where PluginBaseClass is the appropriate base class of the plugin 138 (e.g., SingleFramePlugin or ForcedPlugin). 141 slots = lsst.pex.config.ConfigField(
142 dtype=SourceSlotConfig,
143 doc=
"Mapping from algorithms to special aliases in Source." 146 doReplaceWithNoise = lsst.pex.config.Field(
147 dtype=bool, default=
True, optional=
False,
148 doc=
'When measuring, replace other detected footprints with noise?')
150 noiseReplacer = lsst.pex.config.ConfigField(
151 dtype=NoiseReplacerConfig,
152 doc=
"configuration that sets how to replace neighboring sources with noise" 154 undeblendedPrefix = lsst.pex.config.Field(
155 dtype=str, default=
"undeblended_",
156 doc=
"Prefix to give undeblended plugins" 160 lsst.pex.config.Config.validate(self)
161 if self.
slots.centroid
is not None and self.
slots.centroid
not in self.plugins.names:
162 raise ValueError(
"source centroid slot algorithm is not being run.")
163 if self.
slots.shape
is not None and self.
slots.shape
not in self.plugins.names:
164 raise ValueError(
"source shape slot algorithm '%s' is not being run." % self.
slots.shape)
165 for slot
in (self.
slots.psfFlux, self.
slots.apFlux, self.
slots.modelFlux,
168 for name
in self.plugins.names:
169 if len(name) <= len(slot)
and name == slot[:len(name)]:
172 raise ValueError(
"source flux slot algorithm '%s' is not being run." % slot)
183 Ultimate base class for all measurement tasks. 185 This base class for SingleFrameMeasurementTask and ForcedMeasurementTask mostly exists to share 186 code between the two, and generally should not be used directly. 189 ConfigClass = BaseMeasurementConfig
190 _DefaultName =
"measurement" 194 Constructor; only called by derived classes. 196 @param[in] algMetadata An lsst.daf.base.PropertyList that will be filled with metadata 197 about the plugins being run. If None, an empty PropertyList will 199 @param[in] **kwds Additional arguments passed to lsst.pipe.base.Task.__init__. 201 This attaches two public attributes to the class for use by derived classes and parent tasks: 202 - plugins: an empty PluginMap, which will eventually contain all active plugins that will by 203 invoked by the run() method (to be filled by subclasses). This should be considered read-only. 204 - algMetadata: a lsst.daf.base.PropertyList that will contain additional information about the 205 active plugins to be saved with the output catalog (to be filled by subclasses). 207 super(BaseMeasurementTask, self).
__init__(**kwds)
210 if algMetadata
is None:
215 return self.log.getName() +
'.' + pluginName
218 """Initialize the plugins (and slots) according to the configuration. 220 Derived class constructors should call this method to fill the self.plugins 221 attribute and add correspond output fields and slot aliases to the output schema. 223 In addition to the attributes added by BaseMeasurementTask.__init__, a self.schema 224 attribute holding the output schema must also be present before this method is called, . 226 Keyword arguments are forwarded directly to plugin constructors, allowing derived 227 classes to use plugins with different signatures. 232 if self.config.slots.centroid
is not None:
233 self.
plugins[self.config.slots.centroid] =
None 235 for executionOrder, name, config, PluginClass
in sorted(self.config.plugins.apply()):
238 if hasattr(PluginClass,
"hasLogName")
and PluginClass.hasLogName:
247 if self.config.slots.centroid
is not None and self.
plugins[self.config.slots.centroid]
is None:
248 del self.
plugins[self.config.slots.centroid]
250 for executionOrder, name, config, PluginClass
in sorted(self.config.undeblended.apply()):
251 undeblendedName = self.config.undeblendedPrefix + name
257 Call the measure() method on all plugins, handling exceptions in a consistent way. 259 @param[in,out] measRecord lsst.afw.table.SourceRecord that corresponds to the object being 260 measured, and where outputs should be written. 261 @param[in] *args Positional arguments forwarded to Plugin.measure() 262 @param[in] **kwds Keyword arguments. Two are handled locally: 263 - beginOrder: beginning execution order (inclusive): measurements with 264 executionOrder < beginOrder are not executed. None for no limit. 265 - endOrder: ending execution order (exclusive): measurements with 266 executionOrder >= endOrder are not executed. None for no limit. 267 the rest are forwarded to Plugin.measure() 269 This method can be used with plugins that have different signatures; the only requirement is that 270 'measRecord' be the first argument. Subsequent positional arguments and keyword arguments are 271 forwarded directly to the plugin. 273 This method should be considered "protected"; it is intended for use by derived classes, not users. 275 beginOrder = kwds.pop(
"beginOrder",
None)
276 endOrder = kwds.pop(
"endOrder",
None)
278 if beginOrder
is not None and plugin.getExecutionOrder() < beginOrder:
280 if endOrder
is not None and plugin.getExecutionOrder() >= endOrder:
286 Call the measure() method on the nominated plugin, handling exceptions in a consistent way. 288 @param[in] plugin Plugin that will measure 289 @param[in,out] measRecord lsst.afw.table.SourceRecord that corresponds to the object being 290 measured, and where outputs should be written. 291 @param[in] *args Positional arguments forwarded to plugin.measure() 292 @param[in] **kwds Keyword arguments forwarded to plugin.measure() 294 This method can be used with plugins that have different signatures; the only requirement is that 295 the 'plugin' and 'measRecord' be the first two arguments. Subsequent positional arguments and 296 keyword arguments are forwarded directly to the plugin. 298 This method should be considered "protected"; it is intended for use by derived classes, not users. 301 plugin.measure(measRecord, *args, **kwds)
302 except FATAL_EXCEPTIONS:
304 except MeasurementError
as error:
306 "MeasurementError in %s.measure on record %s: %s" 307 % (plugin.name, measRecord.getId(), error))
308 plugin.fail(measRecord, error)
309 except Exception
as error:
311 "Exception in %s.measure on record %s: %s" 312 % (plugin.name, measRecord.getId(), error))
313 plugin.fail(measRecord)
317 Call the measureN() method on all plugins, handling exceptions in a consistent way. 319 @param[in,out] measCat lsst.afw.table.SourceCatalog containing records for just 320 the source family to be measured, and where outputs should 322 @param[in] beginOrder beginning execution order (inclusive): measurements with 323 executionOrder < beginOrder are not executed. None for no limit. 324 @param[in] endOrder ending execution order (exclusive): measurements with 325 executionOrder >= endOrder are not executed. None for no limit. 326 @param[in] *args Positional arguments forwarded to Plugin.measure() 327 @param[in] **kwds Keyword arguments. Two are handled locally: 328 - beginOrder: beginning execution order (inclusive): measurements with 329 executionOrder < beginOrder are not executed. None for no limit. 330 - endOrder: ending execution order (exclusive): measurements with 331 executionOrder >= endOrder are not executed. None for no limit. 332 the rest are forwarded to Plugin.measure() 334 This method can be used with plugins that have different signatures; the only requirement is that 335 'measRecord' be the first argument. Subsequent positional arguments and keyword arguments are 336 forwarded directly to the plugin. 338 This method should be considered "protected"; it is intended for use by derived classes, not users. 340 beginOrder = kwds.pop(
"beginOrder",
None)
341 endOrder = kwds.pop(
"endOrder",
None)
342 for plugin
in self.
plugins.iterN():
343 if beginOrder
is not None and plugin.getExecutionOrder() < beginOrder:
345 if endOrder
is not None and plugin.getExecutionOrder() >= endOrder:
351 Call the measureN() method on the nominated plugin, handling exceptions in a consistent way. 353 @param[in] plugin Plugin that will measure 354 @param[in,out] measCat lsst.afw.table.SourceCatalog containing records for just 355 the source family to be measured, and where outputs should 357 @param[in] *args Positional arguments forwarded to plugin.measureN() 358 @param[in] **kwds Keyword arguments forwarded to plugin.measureN() 360 This method can be used with plugins that have different signatures; the only requirement is that 361 the 'plugin' and 'measCat' be the first two arguments. Subsequent positional arguments and 362 keyword arguments are forwarded directly to the plugin. 364 This method should be considered "protected"; it is intended for use by derived classes, not users. 367 plugin.measureN(measCat, *args, **kwds)
368 except FATAL_EXCEPTIONS:
371 except MeasurementError
as error:
372 for measRecord
in measCat:
374 "MeasurementError in %s.measureN on records %s-%s: %s" 375 % (plugin.name, measCat[0].getId(), measCat[-1].getId(), error))
376 plugin.fail(measRecord, error)
377 except Exception
as error:
378 for measRecord
in measCat:
379 plugin.fail(measRecord)
381 "Exception in %s.measureN on records %s-%s: %s" 382 % (plugin.name, measCat[0].getId(), measCat[-1].getId(), error))
Base config class for all measurement plugins.
def callMeasure(self, measRecord, args, kwds)
Call the measure() method on all plugins, handling exceptions in a consistent way.
def getPluginLogName(self, pluginName)
def setupSchema(self, schema)
def __init__(self, algMetadata=None, kwds)
Constructor; only called by derived classes.
def callMeasureN(self, measCat, args, kwds)
Call the measureN() method on all plugins, handling exceptions in a consistent way.
Base class for measurement plugins.
Base class measurement Plugin config classes.
def doMeasurementN(self, plugin, measCat, args, kwds)
Call the measureN() method on the nominated plugin, handling exceptions in a consistent way...
Map of plugins (instances of subclasses of BasePlugin) to be run for a task.
Slot configuration which assigns a particular named plugin to each of a set of slots.
static Log getLogger(std::string const &loggername)
Ultimate base class for all measurement tasks.
Base config class for all measurement driver tasks.
def initializePlugins(self, kwds)
def doMeasurement(self, plugin, measRecord, args, kwds)
Call the measure() method on the nominated plugin, handling exceptions in a consistent way...