LSST Applications g06d8191974+b5247657d3,g180d380827+b23588344e,g2079a07aa2+86d27d4dc4,g2305ad1205+0130fb9023,g29320951ab+7714a6b20a,g2bbee38e9b+0e5473021a,g337abbeb29+0e5473021a,g33d1c0ed96+0e5473021a,g3a166c0a6a+0e5473021a,g3ddfee87b4+8783ab7716,g48712c4677+72a8b1060b,g487adcacf7+bbaada240a,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+ecccb6240b,g5a732f18d5+53520f316c,g5ea96fc03c+33ab2bc355,g64a986408d+b5247657d3,g858d7b2824+b5247657d3,g8a8a8dda67+585e252eca,g99cad8db69+1453026da9,g9ddcbc5298+9a081db1e4,ga1e77700b3+15fc3df1f7,gb0e22166c9+60f28cb32d,gba4ed39666+c2a2e4ac27,gbb8dafda3b+3751ca9c65,gc120e1dc64+c91d1388df,gc28159a63d+0e5473021a,gc3e9b769f7+241adb7c58,gcf0d15dbbd+8783ab7716,gdaeeff99f8+f9a426f77a,ge6526c86ff+acdbe9a537,ge79ae78c31+0e5473021a,gee10cc3b42+585e252eca,gff1a9f87cc+b5247657d3,w.2024.17
LSST Data Management Base Package
Loading...
Searching...
No Matches
pluginRegistry.py
Go to the documentation of this file.
1# This file is part of meas_base.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
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 GNU General Public License
20# along with this program. If not, see <https://www.gnu.org/licenses/>.
21
22"""Registry for measurement plugins and utilities for plugin management.
23"""
24
25import collections
26
27import lsst.pipe.base
28import lsst.pex.config
29from .apCorrRegistry import addApCorrName
30
31__all__ = ("generateAlgorithmName", "PluginRegistry", "register", "PluginMap")
32
33
35 """Generate a name for an algorithm.
36
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
39 code.
40
41 Parameters
42 ----------
43 AlgClass : subclass of `BaseAlgorithm`
44 The class to generate a name for.
45
46 Returns
47 -------
48 name : `str`
49 A short name for the algorithm.
50
51 Notes
52 -----
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``.
57 """
58 name = AlgClass.__name__
59 pkg = AlgClass.__module__
60 name = name.replace("Algorithm", "")
61 terms = pkg.split(".")
62 # Hide private module name only if it's part of a public package
63 if len(terms) > 1 and terms[-1].startswith("_"):
64 terms = terms[:-1]
65 if len(terms) > 1 and terms[-1].endswith("Lib"):
66 terms = terms[:-1]
67 if terms[0] == "lsst":
68 terms = terms[1:]
69 if terms[0] == "meas":
70 terms = terms[1:]
71 if name.lower().startswith(terms[-1].lower()):
72 terms = terms[:-1]
73 return "%s_%s" % ("_".join(terms), name)
74
75
77 """Base class for plugin registries.
78
79 Notes
80 -----
81 The class of plugins allowed in the registry is defined in the constructor
82 of the registry.
83
84 Single-frame and forced plugins have different registries.
85 """
86
88 """Class used as the element in the plugin registry.
89
90 Parameters
91 ----------
92 name : `str`
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.
96
97 Notes
98 -----
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.
103 """
104
105 __slots__ = "PluginClass", "name"
106
107 def __init__(self, name, PluginClass):
108 self.name = name
109 self.PluginClass = PluginClass
110
111 @property
112 def ConfigClass(self):
113 return self.PluginClass.ConfigClass
114
115 def __call__(self, config):
116 return (self.PluginClass.getExecutionOrder(), self.name, config, self.PluginClass)
117
118 def register(self, name, PluginClass, shouldApCorr=False, apCorrList=()):
119 """Register a plugin class with the given name.
120
121 Parameters
122 ----------
123 name : `str`
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.
146
147 Notes
148 -----
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.
152 """
153 lsst.pex.config.Registry.register(self, name, self.Configurable(name, PluginClass))
154 if shouldApCorr and not apCorrList:
155 apCorrList = [name]
156 for prefix in apCorrList:
157 addApCorrName(prefix)
158
159 def makeField(self, doc, default=None, optional=False, multi=False):
160 return lsst.pex.config.RegistryField(doc, self, default, optional, multi)
161
162
163def register(name, shouldApCorr=False, apCorrList=()):
164 """A decorator to register a plugin class in its base class's registry.
165
166 Parameters
167 ----------
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.
181
182 """
183
184 def decorate(PluginClass):
185 PluginClass.registry.register(name, PluginClass, shouldApCorr=shouldApCorr, apCorrList=apCorrList)
186 return PluginClass
187 return decorate
188
189
190class PluginMap(collections.OrderedDict):
191 """Map of plugins to be run for a given task.
192
193 Notes
194 -----
195 Plugins are classes derived from `BasePlugin`.
196
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`).
201 """
202
203 def iter(self):
204 """Return an iterator over plugins for use in single-object mode.
205
206 Notes
207 -----
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.
211 """
212 for plugin in self.values():
213 if plugin.config.doMeasure:
214 yield plugin
215
216 def iterN(self):
217 """Return an iterator over plugins for use in multi-object mode.
218
219 Notes
220 -----
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.
224 """
225 for plugin in self.values():
226 if plugin.config.doMeasureN:
227 yield plugin
register(self, name, PluginClass, shouldApCorr=False, apCorrList=())
makeField(self, doc, default=None, optional=False, multi=False)
register(name, shouldApCorr=False, apCorrList=())