22 """Registry for measurement plugins and utilities for plugin management. 
   28 import lsst.pex.config
 
   29 from .apCorrRegistry 
import addApCorrName
 
   31 __all__ = (
"generateAlgorithmName", 
"PluginRegistry", 
"register", 
"PluginMap")
 
   35     """Generate a name for an algorithm. 
   37     This generates a short name for an algorithmic class that strips away 
   38     terms that are generally redundant while remaining easy to trace to the 
   43     AlgClass : subclass of `BaseAlgorithm` 
   44         The class to generate a name for. 
   49         A short name for the algorithm. 
   53     The returned name will cobmine the package name, with any ``lsst`` and/or 
   54     ``meas`` prefix removed, with the class name, with any ``Algorithm`` 
   55     suffix removed.  For instance, ``lsst.meas.base.SdssShapeAlgorithm`` 
   56     becomes ``base_SdssShape``. 
   58     name = AlgClass.__name__
 
   59     pkg = AlgClass.__module__
 
   60     name = name.replace(
"Algorithm", 
"")
 
   61     terms = pkg.split(
".")
 
   63     if len(terms) > 1 
and terms[-1].startswith(
"_"):
 
   65     if len(terms) > 1 
and terms[-1].endswith(
"Lib"):
 
   67     if terms[0] == 
"lsst":
 
   69     if terms[0] == 
"meas":
 
   71     if name.lower().startswith(terms[-1].lower()):
 
   73     return "%s_%s" % (
"_".join(terms), name)
 
   77     """Base class for plugin registries. 
   81     The class of plugins allowed in the registry is defined in the constructor 
   84     Single-frame and forced plugins have different registries. 
   88         """Class used as the element in the plugin registry. 
   93             Name under which the plugin is registerd. 
   94         PluginClass : subclass of `BasePlugin` 
   95             The class of plugin which can be stored in the registry. 
   99         Rather than constructing a Plugin instance, its __call__ method 
  100         (invoked by RegistryField.apply) returns a tuple 
  101         of ``(executionOrder, name, config, PluginClass)``, which can then 
  102         be sorted before the plugins are instantiated. 
  105         __slots__ = 
"PluginClass", 
"name" 
  118     def register(self, name, PluginClass, shouldApCorr=False, apCorrList=()):
 
  119         """Register a plugin class with the given name. 
  124             The name of the plugin. This is used as a prefix for all fields 
  125             produced by the plugin, and it should generally contain the name 
  126             of the plugin or algorithm class itself as well as enough of the 
  127             namespace to make it clear where to find the code.  For example 
  128             ``base_GaussianFlux`` indicates an algorithm in `lsst.meas.base` 
  129             that measures Gaussian Flux and produces fields such as 
  130             ``base_GaussianFlux_instFlux``, ``base_GaussianFlux_instFluxErr`` 
  131             and ``base_GaussianFlux_flag``. 
  132         shouldApCorr : `bool` 
  133             If `True`, then this algorithm measures an instFlux that should 
  134             be aperture corrected. This is shorthand for ``apCorrList=[name]`` 
  135             and is ignored if ``apCorrList`` is specified. 
  136         apCorrList : `list` of `str` 
  137             List of field name prefixes for instFlux fields to be aperture 
  138             corrected.  If an algorithm produces a single instFlux that should 
  139             be aperture corrected then it is simpler to set 
  140             ``shouldApCorr=True``. But if an algorithm produces multiple such 
  141             fields then it must specify ``apCorrList`` instead. For example, 
  142             ``modelfit_CModel`` produces three such fields: 
  143             ``apCorrList=("modelfit_CModel_exp", "modelfit_CModel_exp", 
  144             "modelfit_CModel_def")``. If ``apCorrList`` is not empty then 
  145             shouldApCorr is ignored. 
  149         The same plugin may be registered multiple times with different names; 
  150         this can be useful if we often want to run it multiple times with 
  151         different configuration. 
  153         lsst.pex.config.Registry.register(self, name, self.
Configurable(name, PluginClass))
 
  154         if shouldApCorr 
and not apCorrList:
 
  156         for prefix 
in apCorrList:
 
  159     def makeField(self, doc, default=None, optional=False, multi=False):
 
  160         return lsst.pex.config.RegistryField(doc, self, default, optional, multi)
 
  163 def register(name, shouldApCorr=False, apCorrList=()):
 
  164     """A decorator to register a plugin class in its base class's registry. 
  168     shouldApCorr : `bool` 
  169         If `True`, then this algorithm measures an instFlux that should be 
  170         aperture corrected. This is shorthand for ``apCorrList=[name]`` and is 
  171         ignored if ``apCorrList`` is specified. 
  172     apCorrList : `list` of `str` 
  173         List of field name prefixes for instFlux fields to be aperture 
  174         corrected.  If an algorithm produces a single instFlux that should be 
  175         aperture corrected then it is simpler to set ``shouldApCorr=True``. 
  176         But if an algorithm produces multiple such fields then it must specify 
  177         ``apCorrList`` instead. For example, ``modelfit_CModel`` produces 
  178         three such fields: ``apCorrList=("modelfit_CModel_exp", 
  179         "modelfit_CModel_exp", "modelfit_CModel_def")``. If ``apCorrList`` is 
  180         not empty then shouldApCorr is ignored. 
  184     def decorate(PluginClass):
 
  185         PluginClass.registry.register(name, PluginClass, shouldApCorr=shouldApCorr, apCorrList=apCorrList)
 
  191     """Map of plugins to be run for a given task. 
  195     Plugins are classes derived from `BasePlugin`. 
  197     We assume plugins are added to the plugin map according to their 
  198     "Execution Order", so this class doesn't actually do any of the sorting 
  199     (though it does have to maintain that order, which it does by inheriting 
  200     from `collections.OrderedDict`). 
  204         """Return an iterator over plugins for use in single-object mode. 
  208         Plugins which should be used in single-object mode are identified by 
  209         having the `doMeasure` config attribute evaluate to `True`. This is 
  210         usually a simple boolean class attribute. 
  212         for plugin 
in self.values():
 
  213             if plugin.config.doMeasure:
 
  217         """Return an iterator over plugins for use in multi-object mode. 
  221         Plugins which should be used in multi-object mode are identified by 
  222         having the `doMeasureN` config attribute evaluate to `True`. 
  223         This is usually a simple boolean class attribute. 
  225         for plugin 
in self.values():
 
  226             if plugin.config.doMeasureN: