7This module defines various components to be used in AnalysisBase releases.
8These components (classes, submodules...) can be used in place of some Athena components
9they are replacing, so athena-style configuration can be used unchanged in AnalysisBase
11This module is thus designed ONLY for AnalysisBase and to run EventLoop jobs.
13IMPORTANT : this module is only designed so the jet configuration works. There's no guarantee it won't mess up
14when used with other part of Athena configuration.
16Internally, the athena-style configurations of algorithms are translated to AnaReentrantAlgorithmConfig or
17AnaAlgorithmConfig. The configuration of AsgTools are translated to call to AnaAlgorithmConfig.addPrivateTool()
18or AnaAlgorithmConfig.setPropertyFromString()
20This module allows to write python config for EventLoop exactly as one would do for Athena :
22alg1 = CompFactory.MyAlg("algname",
23 InputContainer = "SomeJets".
25 AprivateTool = CompFactory.SomeTool("tool", AToolparam =0.21), )
26alg2 = CompFactory.AnOtherAlg( ... )
30job.addManyAlgs([alg1, alg2]) # specific call allowed by this module
32driver = ROOT.EL.DirectDriver()
33driver.submit( job, "out")
38from types
import ModuleType
46logging.setLoggerClass( logging.Logger )
50 """Helper function producing a string property value"""
52 stringValue = str( value )
53 if isinstance( value, bool ):
54 stringValue = str( int( value ) )
61 """A simplistic array of Configured (see below) to replace the ToolHandleArray of Athena """
83 tool = anaAlg.addPrivateToolInArray(conf.fullname(), conf.type)
84 conf._name = tool._prefix.split(
'.')[-1]
85 conf.assignAllProperties(anaAlg)
90 """A replacement for Athena auto-generated Configured python class.
91 Configured has the same interface as its Athena counterpart and can describe both Tools and Algorithms
93 This is a base class. The system replacing CompFactory will generate a derived class for each c++ Tool/Algorithm
94 to hold the configuration of such tool/alg (see generateConfigured())
102 _allowed = [
'_properties',
'_name',
'_parent',
'_anaAlg']
108 for k,v
in props.items():
115 raise AttributeError(
"Configuration of Tool {} / {} . can't set attribute : {}".format(self.
type, self.
_name, k) )
123 if isinstance(v, Configured):
125 raise RuntimeError(
"Configuring {} / {} : Tool for property {} already exists".format(self.
type, self.
_name, k) )
129 elif isinstance(v, (list, tuple) ):
130 if isinstance(v[0], Configured):
145 if self.
_parent is None:
return k
149 if self.
_parent is None :
return [self]
154 return '.'.join([p._name
for p
in parents])
157 return [ (k, getattr(self,k))
for k
in self.
_properties]
164 """Returns this configured alg as an instance of Ana(Reentrant)AlgorithmConfig
166 if issubclass(self.
_cppclass, ROOT.EL.AnaReentrantAlgorithm):
167 alg=ROOT.EL.AnaReentrantAlgorithmConfig()
169 alg=ROOT.EL.AnaAlgorithmConfig()
177 """If self represents a configured AlgTool,
178 this call will configure the AnaAlgorithmConfig 'anaAlg' so
179 its ToolHandle property 'handlename' is configured with self
181 props = {handlename:self, }
182 klass=
type(
'TmpConf', (Configured,), dict(_allowed=self.
_allowed+[handlename], _propTypes={},
183 type=anaAlg.getType(),_cppclass=
'none') )
185 c=klass(anaAlg.name(), **props)
186 c.assignAllProperties(anaAlg)
189 """ Transfer all the configuration in self to anaAlg
190 where anaAlg is an AnaAlgorithmConfig."""
197 if isinstance(v , Configured):
200 alg.addPrivateTool(v.fullname(), v.type)
204 v.assignAllProperties(alg)
205 elif isinstance(v, ConfArray ):
207 v.assignAllProperties(alg)
211 alg.setProperty[cpptype](self.
prefixed(k) , v)
221 if issubclass(cppclass, cppyy.gbl.asg.IAsgTool):
222 dummy = cppclass(
'dummy')
224 dummy = cppclass(
'dummy', 0)
227 pm = dummy.getPropertyMgr()
228 propkeys = [str(k)
for k,p
in pm.getProperties() ]
229 propTypes = dict( (k,
propertyType(pm.getProperty(k)) )
for k
in propkeys)
230 allowedProp = Configured._allowed + [k
for k
in propkeys]
232 klass=
type(classname+
'Conf', (Configured,), dict(_allowed=allowedProp, _propTypes=propTypes,
233 type=prefix+classname,_cppclass=cppclass) )
238 """Guess the type of the TProperty p.
239 p is a C++ instance of a TProperty.
241 This simply interpret the cpp name as set by cppyy...
243 clsname = p.__class__.__cpp_name__
245 typ = clsname[10:-1].
strip()
252 """A namespace able to automatically generate Configured when quering attributes :
253 Used to replace CompFactory so that expressions like :
254 tool = CompFactory.Trk.SomeTrkTool("tname", Prop=2.345)
255 tool = CompFactory.getComp("Trk::SomeTrkTool")("tname", Prop=2.345)
257 In the above 2 examples both CompFactory and Trk are ConfNameSpace
260 self.
prefix=name+
"::" if name !=
"" else ""
266 """generates a new Configured class for the C++ class ROOT.classname .
267 This implies there must be a dictionnary for classname.
271 c = self.__dict__.
get(classname,
None)
276 c=getattr(ROOT, self.
prefix+classname,
None)
279 print(
"JetAnalysisCommon ERROR : ",classname,
" is not a known C++ tool, alg, or namespace ")
282 if hasattr(c,
'getPropertyMgr'):
289 setattr(self, classname, conf)
302CompFactory.addNameSpaces(
'Analysis',
'Trk',
'Jet',
'Sim',)
305ComponentFactory = ModuleType(
"ComponentFactory")
306ComponentFactory.CompFactory = CompFactory
308ComponentFactory.isComponentAccumulatorCfg =
lambda :
True
315CFElements = ModuleType(
"CFElements")
316CFElements.parOR = parOR
322 """Provdide similar interface than AthenaConfiguration.ComponentAccumulator and also very simplistic
323 merging of list of algorithms
330 return iter(self.
algs)
336 setattr(self, alg._name, alg)
338 def merge(self, ca, sequenceName=""):
339 myTNs =
set( alg.typeAndName()
for alg
in self.
algs)
341 tn = alg.typeAndName()
343 self.
algs.append(alg)
344 setattr(self, alg._name, alg)
347ComponentAccumulator = ModuleType(
"ComponentAccumulator")
356 """a little configuration function added from the python module JetAnalysisCommon.py to easily schedule
357 # a list of Configured algs as defined by this module."""
359 job.algsAdd( alg.asAnaAlg() )
361ROOT.EL.Job.addManyAlgs = addManyAlgs
368JetAnalysisCommon = sys.modules[__name__]
371sys.modules[
'AthenaConfiguration.ComponentFactory'] = JetAnalysisCommon.ComponentFactory
372sys.modules[
'AthenaConfiguration.ComponentAccumulator'] = JetAnalysisCommon.ComponentAccumulator
373sys.modules[
'AthenaCommon.CFElements'] = JetAnalysisCommon.CFElements
377 """Allows to ignore JetRecTools in case this package is not checked out on top of AnalysisBase"""
378 sys.modules[
'JetRecTools'] = ModuleType(
'JetRecTools')
379 sys.modules[
'JetRecTools.JetRecToolsConfig'] = ModuleType(
'JetRecToolsConfig')
386import JetRecConfig.JetRecConfig
as JetRecConfig
395JetRecConfig.JetRecCfg_original = JetRecConfig.JetRecCfg
397 """Builds the algs with JetRecConfig.JetRecCfg and then make sure
398 they are in proper order.
399 Re-ordering is done manually, according to various input alg type.
401 res = JetRecConfig.JetRecCfg_original(flags, jetdef , returnFinalJetDef)
403 acc , _ = res
if returnFinalJetDef
else (res,
None)
408 if not hasattr(ROOT,
'EventDensityAthAlg'):
410 evtDensityAlgs = [ (i,alg)
for (i,alg)
in enumerate(algs)
if alg._cppclass == ROOT.EventDensityAthAlg ]
411 pjAlgs = [ (i,alg)
for (i,alg)
in enumerate(algs)
if alg._cppclass == ROOT.PseudoJetAlgorithm ]
413 for i,edalg
in evtDensityAlgs:
414 edInput = edalg.EventDensityTool.InputContainer
415 for j,pjalg
in pjAlgs:
417 if edInput == pjalg.OutputContainer:
418 pairsToswap.append( (i,j) )
419 for (i,j)
in pairsToswap:
420 algs[i], algs[j] = algs[j], algs[i]
428JetRecConfig.JetRecCfg = JetRecCfg_reorder
void print(char *figname, TCanvas *c1)
__init__(self, name="ca")
addSequence(self, seqName)
addEventAlgo(self, alg, primary=False, sequenceName="")
assignAllProperties(self, anaAlg)
__init__(self, key, conflist, parent)
addNameSpaces(self, *nsList)
bool add(const std::string &hname, TKey *tobj)
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
JetRecCfg_reorder(jetdef, flags, returnFinalJetDef=False)
generateConfigured(classname, cppclass, prefix="")