2 from .pluginRegistry
import generateAlgorithmName
3 from .apCorrRegistry
import addApCorrName
4 from .sfm
import SingleFramePlugin
5 from .forcedMeasurement
import ForcedPlugin
7 __all__ = (
"wrapSingleFrameAlgorithm",
"wrapForcedAlgorithm",
"wrapSimpleAlgorithm",
"wrapTransform")
12 def __init__(self, config, name, schema, metadata, logName=None):
13 SingleFramePlugin.__init__(self, config, name, schema, metadata, logName=logName)
14 if hasattr(self,
"hasLogName")
and self.hasLogName
and logName
is not None:
15 self.
cpp = self.factory(config, name, schema, metadata, logName=logName)
17 self.
cpp = self.factory(config, name, schema, metadata)
20 self.cpp.measure(measRecord, exposure)
23 self.cpp.measureN(measCat, exposure)
25 def fail(self, measRecord, error=None):
26 self.cpp.fail(measRecord, error.cpp
if error
is not None else None)
31 def __init__(self, config, name, schemaMapper, metadata, logName=None):
32 ForcedPlugin.__init__(self, config, name, schemaMapper, metadata, logName=logName)
33 if hasattr(self,
"hasLogName")
and self.hasLogName
and logName
is not None:
34 self.
cpp = self.factory(config, name, schemaMapper, metadata, logName=logName)
36 self.
cpp = self.factory(config, name, schemaMapper, metadata)
38 def measure(self, measRecord, exposure, refRecord, refWcs):
39 self.cpp.measureForced(measRecord, exposure, refRecord, refWcs)
41 def measureN(self, measCat, exposure, refCat, refWcs):
42 self.cpp.measureNForced(measCat, exposure, refCat, refWcs)
44 def fail(self, measRecord, error=None):
45 self.cpp.fail(measRecord, error.cpp
if error
is not None else None)
50 Wrap a C++ algorithm's control class into a Python Config class.
52 @param[in] Base Base class for the returned ConfigClass; one of SingleFramePluginConfig or
54 @param[in] Control Control class to be wrapped (a Swigged C++ class)
55 @param[in] module Either a module object, a string specifying the name of the module, or an
56 integer specifying how far back in the stack to look for the module to use:
57 0 is pex.config.wrap, 1 is lsst.meas.base.wrappers, 2 is the immediate
58 caller, etc. This will be used to set __module__ for the new config class,
59 and the class will also be added to the module. The default is to use the
61 @param[in] hasMeasureN Whether the plugin supports fitting multiple objects at once (if so, a
62 config option to enable/disable this will be added).
64 @return a new subclass of lsst.pex.config.Config
66 This function is generally only called by wrapAlgorithm; it is unlikely users will have to call it
75 Control.__name__.replace(
"Control",
"Config"),
77 {
"doMeasureN": lsst.pex.config.Field(dtype=bool, default=
True,
78 doc=
"whether to run this plugin in multi-object mode")}
80 ConfigClass = lsst.pex.config.makeConfigClass(Control, module=module, cls=cls)
84 ConfigClass = lsst.pex.config.makeConfigClass(Control, module=module, base=Base)
88 def wrapAlgorithm(Base, AlgClass, factory, executionOrder, name=None, Control=None,
89 ConfigClass=
None, TransformClass=
None, doRegister=
True, shouldApCorr=
False,
90 apCorrList=(), hasLogName=
False, **kwds):
92 Wrap a C++ Algorithm class into a Python Plugin class.
94 @param[in] Base Base class for the returned Plugin; one of SingleFramePlugin or
96 @param[in] AlgClass Swigged C++ Algorithm class to convert; must be a subclass of
97 SingleFrameAlgorithm or ForcedAlgorithm (matching the Base argument), or
98 an unrelated class with the same measure() and measureN() signatures as
100 @param[in] factory A callable that is used to construct an instance of AlgClass. It must take
101 four arguments, either (config, name, schema, metadata) or
102 (config, name, schemaMapper, metadata), depending on whether the algorithm is
103 single-frame or forced.
104 @param[in] executionOrder The order this plugin should be run, relative to others
105 (see BasePlugin.getExecutionOrder()).
106 @param[in] name String to use when registering the algorithm. Ignored if doRegistry=False,
107 set to generateAlgorithmName(AlgClass) if None.
108 @param[in] Control Swigged C++ Control class for the algorithm; AlgClass.Control is used if None.
109 Ignored if ConfigClass is not None.
110 @param[in] ConfigClass Python Config class that wraps the C++ Algorithm's swigged Control class. If
111 None, wrapAlgorithmControl is called to generate a Config class using the
113 @param[in] TransformClass Transformation which may be used to post-process the results of measurement.
114 If None, the default (defined by BasePlugin) is used.
115 @param[in] doRegister If True (the default), register the plugin with Base's registry, allowing it
116 to be used by measurement Tasks.
117 @param[in] shouldApCorr Does this algorithm measure a flux that can be aperture corrected? This is
118 shorthand for apCorrList=[name] and is ignored if apCorrList is specified.
119 @param[in] apCorrList List of field name prefixes for flux fields that should be aperture corrected.
120 If an algorithm produces a single flux that should be
121 aperture corrected then it is simpler to set shouldApCorr=True. But if an
122 algorithm produces multiple such fields then it must specify apCorrList,
123 instead. For example modelfit_CModel produces 3 such fields: apCorrList=
124 ("modelfit_CModel_exp", "modelfit_CModel_exp", "modelfit_CModel_def")
125 If apCorrList is non-empty then shouldApCorr is ignored.
126 If non-empty and doRegister is True then the names are added to the set
127 retrieved by getApCorrNameSet
128 @param[in] hasLogName Plugin supports a logName as a constructor argument
131 @param[in] **kwds Additional keyword arguments passed to generateAlgorithmControl, including:
132 - hasMeasureN: Whether the plugin supports fitting multiple objects at once
133 (if so, a config option to enable/disable this will be added).
134 - executionOrder: If not None, an override for the default executionOrder for
135 this plugin (the default is 2.0, which is usually appropriate for fluxes).
137 @return the new Plugin class, a subclass of Base
139 This function is generally only called by the public wrapSingleFrameAlgorithm, wrapForcedAlgorithm, and
140 wrapSimpleAlgorithm functions; it is unlikely users will have to call it directly.
142 if ConfigClass
is None:
144 Control = AlgClass.Control
147 def getExecutionOrder():
148 return executionOrder
149 typeDict = dict(AlgClass=AlgClass, ConfigClass=ConfigClass, factory=staticmethod(factory),
150 getExecutionOrder=staticmethod(getExecutionOrder))
152 typeDict[
'getTransformClass'] = staticmethod(
lambda: TransformClass)
153 PluginClass = type(AlgClass.__name__ + Base.__name__, (Base,), typeDict)
157 Base.registry.register(name, PluginClass)
160 PluginClass.hasLogName = hasLogName
165 hasLogName=
False, **kwds):
167 Wrap a C++ SingleFrameAlgorithm class into a Python SingleFramePlugin class.
169 @param[in] AlgClass Swigged C++ Algorithm class to convert; must be a subclass of
170 SingleFrameAlgorithm, or an unrelated class with the same measure(),
171 measureN(), and fail() signatures.
172 @param[in] executionOrder The order this plugin should be run, relative to others
173 (see BasePlugin.getExecutionOrder()).
174 @param[in] name String to use when registering the algorithm. Ignored if doRegistry=False,
175 set to generateAlgorithmName(AlgClass) if None.
176 @param[in] needsMetadata Sets whether the AlgClass's constructor should be passed a PropertySet
178 @param[in] hasMeasureN Whether the algorithm supports simultaneous measurement of multiple sources.
179 If True, a bool doMeasureN field will be added to the generated Config class,
180 and its value will be passed as the last argument when calling the AlgClass
182 @param[in] hasLogName Plugin supports a logName as a constructor argument
183 @param[in] **kwds Additional keyword arguments passed to the lower-level wrapAlgorithm and
184 wrapAlgorithmControl classes. These include:
185 - Control: Swigged C++ Control class for the algorithm; AlgClass.Control
186 is used if None. Ignored if ConfigClass is not None.
187 - ConfigClass: Python Config class that wraps the C++ Algorithm's swigged
188 Control class. If None, wrapAlgorithmControl is called to generate a
189 Config class using the Control argument.
190 - doRegister: If True (the default), register the plugin with
191 SingleFramePlugin.registry, allowing it to be used by
192 SingleFrameMeasurementTask.
193 - shouldApCorr: does this algorithm measure a flux that can be aperture
194 corrected? This is shorthand for apCorrList=[name] and is ignored if
195 apCorrList is specified.
196 - apCorrList: list of field name prefixes for flux fields that should be
197 aperture corrected. If an algorithm produces a single flux that should be
198 aperture corrected then it is simpler to set shouldApCorr=True. But if an
199 algorithm produces multiple such fields then it must specify apCorrList,
200 instead. For example modelfit_CModel produces 3 such fields: apCorrList=
201 ("modelfit_CModel_exp", "modelfit_CModel_exp", "modelfit_CModel_def")
202 If apCorrList is non-empty then shouldApCorr is ignored.
203 If non-empty and doRegister is True then the names are added to the set
204 retrieved by getApCorrNameSet
205 - executionOrder: If not None, an override for the default executionOrder for
206 this plugin (the default is 2.0, which is usually appropriate for fluxes).
208 @return the new SingleFramePlugin subclass
210 The needsMetadata and hasMeasureN arguments combine to determine the expected constructor signature;
211 we always expect the first three arguments to be:
213 Control const & ctrl, std::string const & name, Schema & schema
215 If needsMetadata, we also append:
217 PropertySet & metadata
219 If hasMeasureN, we also append:
223 If hasLogName, we also append:
227 If more than one is True, the metadata PropertySet precedes the doMeasureN bool
228 and the logName comes last of the three
232 def factory(config, name, schema, metadata, **kwargs):
233 return AlgClass(config.makeControl(), name, schema, metadata, config.doMeasureN, **kwargs)
235 def factory(config, name, schema, metadata, **kwargs):
236 return AlgClass(config.makeControl(), name, schema, config.doMeasureN, **kwargs)
239 def factory(config, name, schema, metadata, **kwargs):
240 return AlgClass(config.makeControl(), name, schema, metadata, **kwargs)
242 def factory(config, name, schema, metadata, **kwargs):
243 return AlgClass(config.makeControl(), name, schema, **kwargs)
245 return wrapAlgorithm(WrappedSingleFramePlugin, AlgClass, executionOrder=executionOrder, name=name,
246 factory=factory, hasMeasureN=hasMeasureN, hasLogName=hasLogName, **kwds)
250 hasMeasureN=
False, needsSchemaOnly=
False, hasLogName=
False, **kwds):
252 Wrap a C++ ForcedAlgorithm class into a Python ForcedPlugin class.
254 @param[in] AlgClass Swigged C++ Algorithm class to convert; must be a subclass of
255 ForcedAlgorithm, or an unrelated class with the same measure(), measureN(),
256 and fail() signatures.
257 @param[in] executionOrder The order this plugin should be run, relative to others
258 (see BasePlugin.getExecutionOrder()).
259 @param[in] name String to use when registering the algorithm. Ignored if doRegistry=False,
260 set to generateAlgorithmName(AlgClass) if None.
261 @param[in] needsMetadata Sets whether the AlgClass's constructor should be passed a PropertySet
263 @param[in] hasMeasureN Whether the algorithm supports simultaneous measurement of multiple sources.
264 If True, a bool doMeasureN field will be added to the generated Config class,
265 and its value will be passed as the last argument when calling the AlgClass
267 @param[in] hasLogName Plugin supports a logName as a constructor argument
268 @param[in] needsSchemaOnly Whether the algorithm constructor expects a Schema argument (representing the
269 output Schema) rather than the full SchemaMapper (which provides access to
270 both the reference Schema and the output Schema).
271 @param[in] **kwds Additional keyword arguments passed to the lower-level wrapAlgorithm and
272 wrapAlgorithmControl classes. These include:
273 - Control: Swigged C++ Control class for the algorithm; AlgClass.Control
274 is used if None. Ignored if ConfigClass is not None.
275 - ConfigClass: Python Config class that wraps the C++ Algorithm's swigged
276 Control class. If None, wrapAlgorithmControl is called to generate a
277 Config class using the Control argument.
278 - doRegister: If True (the default), register the plugin with
279 ForcedPlugin.registry, allowing it to be used by ForcedMeasurementTask.
280 - shouldApCorr: does this algorithm measure a flux that can be aperture
281 corrected? This is shorthand for apCorrList=[name] and is ignored if
282 apCorrList is specified.
283 - apCorrList: list of field name prefixes for flux fields that should be
284 aperture corrected. If an algorithm produces a single flux that should be
285 aperture corrected then it is simpler to set shouldApCorr=True. But if an
286 algorithm produces multiple such fields then it must specify apCorrList,
287 instead. For example modelfit_CModel produces 3 such fields: apCorrList=
288 ("modelfit_CModel_exp", "modelfit_CModel_exp", "modelfit_CModel_def")
289 If apCorrList is non-empty then shouldApCorr is ignored.
290 If non-empty and doRegister is True then the names are added to the set
291 retrieved by getApCorrNameSet
292 - executionOrder: If not None, an override for the default executionOrder for
293 this plugin (the default is 2.0, which is usually appropriate for fluxes).
295 @return the new ForcedPlugin subclass
297 The needsMetadata, hasMeasureN, and needsSchemaOnly arguments combine to determine the expected
298 constructor signature; we always expect the first two arguments to be:
300 Control const & ctrl, std::string const & name
302 If needsSchemaOnly is True, then the third argument will be
306 otherwise, it will be:
308 SchemaMapper & schemaMapper
310 If needsMetadata, we also append:
312 PropertySet & metadata
314 If hasMeasureN, we also append:
318 If hasLogName, we also append:
322 If more than one is True, the metadata PropertySet precedes the doMeasureN bool
323 and the logName comes last of the three
326 def extractSchemaArg(m):
327 return m.editOutputSchema()
329 def extractSchemaArg(m):
333 def factory(config, name, schemaMapper, metadata, **kwargs):
334 return AlgClass(config.makeControl(), name, extractSchemaArg(schemaMapper),
335 metadata, config.doMeasureN, **kwargs)
337 def factory(config, name, schemaMapper, metadata, **kwargs):
338 return AlgClass(config.makeControl(), name, extractSchemaArg(schemaMapper),
339 config.doMeasureN, **kwargs)
342 def factory(config, name, schemaMapper, metadata, **kwargs):
343 return AlgClass(config.makeControl(), name, extractSchemaArg(schemaMapper),
346 def factory(config, name, schemaMapper, metadata, **kwargs):
347 return AlgClass(config.makeControl(), name, extractSchemaArg(schemaMapper), **kwargs)
349 return wrapAlgorithm(WrappedForcedPlugin, AlgClass, executionOrder=executionOrder, name=name,
350 factory=factory, hasLogName=hasLogName, **kwds)
353 def wrapSimpleAlgorithm(AlgClass, executionOrder, name=None, needsMetadata=False, hasMeasureN=False,
354 hasLogName=
False, **kwds):
356 Wrap a C++ SimpleAlgorithm class into both a Python SingleFramePlugin and ForcedPlugin classes
358 @param[in] AlgClass Swigged C++ Algorithm class to convert; must be a subclass of
359 simpleAlgorithm, or an unrelated class with the same measure(), measureN(),
360 and fail() signatures.
361 @param[in] executionOrder The order this plugin should be run, relative to others
362 (see BasePlugin.getExecutionOrder()).
363 @param[in] name String to use when registering the algorithm. Ignored if doRegistry=False,
364 set to generateAlgorithmName(AlgClass) if None.
365 @param[in] needsMetadata Sets whether the AlgClass's constructor should be passed a PropertySet
367 @param[in] hasMeasureN Whether the algorithm supports simultaneous measurement of multiple sources.
368 If True, a bool doMeasureN field will be added to the generated Config class,
369 and its value will be passed as the last argument when calling the AlgClass
371 @param[in] hasLogName Plugin supports a logName as a constructor argument
372 @param[in] **kwds Additional keyword arguments passed to the lower-level wrapAlgorithm and
373 wrapAlgorithmControl classes. These include:
374 - Control: Swigged C++ Control class for the algorithm; AlgClass.Control
375 is used if None. Ignored if ConfigClass is not None.
376 - ConfigClass: Python Config class that wraps the C++ Algorithm's swigged
377 Control class. If None, wrapAlgorithmControl is called to generate a
378 Config class using the Control argument.
379 - doRegister: If True (the default), register the plugins with Base's
380 registry, allowing it to be used by measurement Tasks.
381 - shouldApCorr: does this algorithm measure a flux that can be aperture
382 corrected? This is shorthand for apCorrList=[name] and is ignored if
383 apCorrList is specified.
384 - apCorrList: list of field name prefixes for flux fields that should be
385 aperture corrected. If an algorithm produces a single flux that should be
386 aperture corrected then it is simpler to set shouldApCorr=True. But if an
387 algorithm produces multiple such fields then it must specify apCorrList,
388 instead. For example modelfit_CModel produces 3 such fields: apCorrList=
389 ("modelfit_CModel_exp", "modelfit_CModel_exp", "modelfit_CModel_def")
390 If apCorrList is non-empty then shouldApCorr is ignored.
391 If non-empty and doRegister is True then the names are added to the set
392 retrieved by getApCorrNameSet
393 - executionOrder: If not None, an override for the default executionOrder for
394 this plugin (the default is 2.0, which is usually appropriate for fluxes).
396 @return a two-element tuple, containing the new SingleFramePlugin and ForcedPlugin subclasses
398 The needsMetadata and hasMeasureN arguments combine to determine the expected constructor signature;
399 we always expect the first three arguments to be:
401 Control const & ctrl, std::string const & name, Schema & schema
403 If needsMetadata, we also append:
405 PropertySet & metadata
407 If hasMeasureN, we also append:
411 If hasLogName, we also append:
415 If more than one is True, the metadata PropertySet precedes the doMeasureN bool
416 and the logName comes last of the three
419 needsMetadata=needsMetadata, hasLogName=hasLogName, **kwds),
421 needsMetadata=needsMetadata, hasLogName=hasLogName,
422 needsSchemaOnly=
True, **kwds))
426 """Modify a C++ Transform class so that it can be configured with either a Config or a Control.
430 transformClass: class
431 A Transform class. Its constructor must take a Control, a string, and
432 a SchemaMapper, in that order.
434 oldInit = transformClass.__init__
436 def _init(self, ctrl, name, mapper, logName=None):
437 if hasattr(ctrl,
"makeControl"):
438 ctrl = ctrl.makeControl()
440 oldInit(self, ctrl, name, mapper)
442 transformClass.__init__ = _init
def wrapSingleFrameAlgorithm
Wrap a C++ SingleFrameAlgorithm class into a Python SingleFramePlugin class.
def wrapAlgorithm
Wrap a C++ Algorithm class into a Python Plugin class.
def wrapAlgorithmControl
Wrap a C++ algorithm's control class into a Python Config class.
def generateAlgorithmName
def wrapForcedAlgorithm
Wrap a C++ ForcedAlgorithm class into a Python ForcedPlugin class.
def wrapSimpleAlgorithm
Wrap a C++ SimpleAlgorithm class into both a Python SingleFramePlugin and ForcedPlugin classes...
def addApCorrName
Add to the set of field name prefixes for fluxes that should be aperture corrected.