ATLAS Offline Software
Loading...
Searching...
No Matches
Control/AthenaPython/python/Bindings.py
Go to the documentation of this file.
1# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
2
3# @file: AthenaPython/python/Bindings.py
4# @author: Sebastien Binet <binet@cern.ch>
5
6
7__author__ = "Sebastien Binet (binet@cern.ch)"
8
9
10from functools import cache, partialmethod
11from AthenaCommon.Logging import logging
12
13@cache
14def _load_dict(lib):
15 """Helper function to remember which libraries have been already loaded
16 """
17 import cppyy
18 if not lib.startswith(lib):
19 lib="lib"+lib
20 return cppyy.load_library(lib)
21
22@cache
24 import ROOT
25 ROOT.gROOT.SetBatch(True)
26 return ROOT
27
28
29
30
32_clid_typename_aliases = {
33
34 'vector<int>' : 'std::vector<int>',
35 'vector<unsigned int>' : 'std::vector<unsigned int>',
36 'vector<float>' : 'std::vector<float>',
37 'vector<double>' : 'std::vector<double>',
38 'string' : 'std::string',
39
41 'INavigable4MomentumCollection' : 'DataVector<INavigable4Momentum>',
42 'DataVector<IParticle>' : 'IParticleContainer',
43 'ParticleBaseContainer' : 'DataVector<ParticleBase>',
44 'TrackCollection' : 'DataVector<Trk::Track>',
45 'Trk::TrackCollection' : 'DataVector<Trk::Track>',
46 'DataVector<Track>' : 'TrackCollection',
47 'AthenaHitsVector<TrackRecord>' : 'TrackRecordCollection',
48 'Trk::SegmentCollection' : 'DataVector<Trk::Segment>',
49 }
50
51
52
54 """Placeholder class to register callbacks for 'pythonizations' of C++
55 classes.
56 FIXME: find a better mechanism ?
57 """
58 msg = logging.getLogger('AthenaBindingsCatalog')
59 instances = {}
60
61 @staticmethod
62 def register(klass, cb=None):
63 """Register a class name `klass` with an initialization method.
64 If no callback method has been given, the default is to call:
65 _py_init_<klass>()
66 """
67 try:
68 if cb is None: eval( 'cb = _py_init_%s'%klass )
69 except Exception as err:
70 _msg = _PyAthenaBindingsCatalog.msg
71 _msg.error("Problem registering callback for [%s]", klass)
72 _msg.error("Exception: %s", err)
73 cb = lambda : None # noqa: E731
74 _PyAthenaBindingsCatalog.instances[klass] = cb
75 return
76
77 @staticmethod
78 @cache
79 def init(name):
80 """Initialize the python binding with the callback previously registered
81 If no callback was registered, swallow the warning...
82 """
83 klass = None
84 try: klass = _PyAthenaBindingsCatalog.instances[name]()
85 except KeyError:
86 ROOT = _import_ROOT() # noqa: F841
87 from AthenaServices.Dso import registry
88 registry.load_type (name)
89 try:
90 import cppyy
91 klass=getattr(cppyy.gbl,name)
92 except AttributeError:
93 raise AttributeError("no reflex-dict for type [%s]"%name)
94 return klass
95
96
97@cache
98def py_svc(svcName, createIf=True, iface=None):
99 """
100 Helper function to retrieve a service by name, using Gaudi python bindings.
101 @param svcName: the name of the service one wants to retrieve (possibly a
102 fully qualified name as in: 'MySvcClass/TheSvcName')
103 @param createIf: If True, the service will be created if it hasn't been yet
104 instantiated.
105 @param iface: type one wants to cast the service to (can be a string or the
106 cppyy type)
107 """
108 fullName = svcName
109 s = svcName.split('/')
110 svcType = s[0]
111 if len(s)==2: svcName=s[1]
112
113 # handle pycomponents...
114 from .Configurables import PyComponents
115 if svcType in _PyAthenaBindingsCatalog.instances:
116 pytype = _PyAthenaBindingsCatalog.init( svcType )
117 # for types which have been pythonized, help the user
118 # find the good interface...
119 if iface is None: iface = pytype
120
121 from GaudiPython.Bindings import gbl,InterfaceCast
122 svcLocator = gbl.Gaudi.svcLocator()
123 svc = gbl.GaudiPython.Helper.service(svcLocator, fullName, createIf)
124 if svc and not(iface is None):
125 svc = InterfaceCast(iface).cast(svc)
126
127 # if the component is actually a py-component,
128 # retrieve the python object from the registry
129 if svcName in PyComponents.instances:
130 svc = PyComponents.instances[svcName]
131
132 if svc:
133 from AthenaPython import PyAthena
134 setattr(PyAthena.services, svcName, svc)
135 return svc
136
137
138@cache
139def py_tool(toolName, createIf=True, iface=None):
140 """
141 Helper function to retrieve a tool (owned by the ToolSvc) by name, using
142 Gaudi python bindings.
143 @param toolName: the name of the tool one wants to retrieve (possibly a
144 fully qualified name as in: 'MyToolClass/TheToolName')
145 @param createIf: If True, the tool will be created if it hasn't been yet
146 instantiated.
147 @param iface: type one wants to cast the tool to (can be a string or the
148 cppyy type)
149
150 Ex:
151 ## retrieve default interface (ie: GaudiKernel/IAlgTool)
152 tool = py_tool('LArOnlDbPrepTool')
153 assert(type(tool) == cppyy.gbl.IAlgTool)
154
155 ## retrieve with specified interface
156 tool = py_tool('LArOnlDbPrepTool', iface='ILArOnlDbPrepTool')
157 assert(type(tool) == cppyy.gbl.ILArOnlDbPrepTool)
158
159 """
160 t = toolName.split('/')
161 toolType = t[0]
162 if len(t)==2: toolName=t[1]
163
164 # handle pycomponents...
165 from .Configurables import PyComponents
166 if toolType in _PyAthenaBindingsCatalog.instances:
167 pytype = _PyAthenaBindingsCatalog.init( toolType )
168 # for types which have been pythonized, help the user
169 # find the good interface...
170 if iface is None: iface = pytype
171
172 from GaudiPython.Bindings import gbl,InterfaceCast
173 _py_tool = gbl.GaudiPython.Helper.tool
174 toolSvc = py_svc('ToolSvc', iface='IToolSvc')
175 tool = _py_tool(toolSvc, toolType, toolName, 0, createIf)
176 if tool and not(iface is None):
177 tool = InterfaceCast(iface).cast(tool)
178
179 # if the component is actually a py-component,
180 # retrieve the python object from the registry
181 if toolName in PyComponents.instances:
182 tool = PyComponents.instances[toolName]
183
184 if tool:
185 from AthenaPython import PyAthena
186 setattr(PyAthena.services.ToolSvc, toolName, tool)
187 return tool
188
189
190def py_alg(algName, iface=None):
191 """
192 Helper function to retrieve an IAlgorithm (managed by the IAlgManager_) by
193 name, using Gaudi python bindings.
194 @param algName: the name of the algorithm's instance one wants to retrieve
195 ex: 'McAodBuilder'
196 @param iface: type one wants to cast the algorithm to (can be a string or the
197 cppyy type)
198
199 Ex:
200 ## retrieve default interface (ie: GaudiKernel/IAlgorithm)
201 alg = py_alg('McAodBuilder')
202 assert(type(alg) == cppyy.gbl.IAlgorithm)
203
204 ## retrieve with specified interface
205 alg = py_alg('McAodBuilder', iface='Algorithm')
206 assert(type(alg) == cppyy.gbl.Algorithm)
207
208 """
209 algmgr = py_svc('ApplicationMgr',iface='IAlgManager')
210 if not algmgr:
211 msg = logging.getLogger('PyAthena.py_alg')
212 error = 'could not retrieve IAlgManager/ApplicationMgr'
213 msg.error (error)
214 raise RuntimeError (error)
215
216 # handle pycomponents...
217 from .Configurables import PyComponents
218 alg = algmgr.algorithm(algName)
219 if not alg:
220 return
221
222 if iface is not None:
223 from GaudiPython.Bindings import InterfaceCast
224 alg = InterfaceCast(iface).cast(alg)
225
226 # if the component is actually a py-component,
227 # retrieve the python object from the registry
228 if algName in PyComponents.instances:
229 alg = PyComponents.instances[algName]
230
231 if alg:
232 from AthenaPython import PyAthena
233 setattr(PyAthena.algs, algName, alg)
234 return alg
235
236
237@cache
239
241 import RootUtils.PyROOTFixes
242
243 try: RootUtils.PyROOTFixes.enable_pickling()
244 except Exception: pass # fwd compatibility
245 from StoreGateBindings.Bindings import StoreGateSvc
246
247 return StoreGateSvc
248
249
250@cache
252 import cppyy
253 # IIncidentSvc bindings from dictionary
254 _load_dict( "libGaudiKernelDict" )
255
256 # retrieve the IIncidentSvc class
257 global IIncidentSvc
258 IIncidentSvc = cppyy.gbl.IIncidentSvc
259
260 IIncidentSvc._cpp_addListener = IIncidentSvc.addListener
261 def addListener (self, *args):
262 listener = args[0]
263 if hasattr (listener, '_cppHandle'):
264 args = (listener._cppHandle,) + args[1:] # noqa: B009 (private property)
265 return self._cpp_addListener (*args)
266 addListener.__doc__ = IIncidentSvc._cpp_addListener.__doc__
267 IIncidentSvc.addListener = addListener
268 del addListener
269
270 IIncidentSvc._cpp_removeListener = IIncidentSvc.removeListener
271 def removeListener (self, *args):
272 listener = args[0]
273 if hasattr (listener, '_cppHandle'):
274 args = (listener._cppHandle,) + args[1:]
275 return self._cpp_removeListener (*args)
276 removeListener.__doc__ = IIncidentSvc._cpp_removeListener.__doc__
277 IIncidentSvc.removeListener = removeListener
278 del removeListener
279 return IIncidentSvc
280
281
282@cache
284 import cppyy
285 # IClassIDSvc bindings from dictionary
286 _load_dict( "libAthenaPythonDict" )
287
288 # retrieve the IClassIDSvc class
289 global IClassIDSvc
290 IClassIDSvc = cppyy.gbl.IClassIDSvc
291
292 _missing_clids = {
293 'DataHistory' : 83814411,
294 83814411 : 'DataHistory',
295 }
296
297 # re-use the python-based clid generator
298 # (faster than calling back into C++ via Reflex bindings)
299 from CLIDComps.clidGenerator import clidGenerator
300 IClassIDSvc._clidgen = clidGenerator(db=None)
301
302 # add pythonized methods
303 @cache
304 def _clid (self, name):
305 # handle special cases where CLID has been registered with a typedef
306 try: name = _clid_typename_aliases[name]
307 except KeyError: pass
308 try:
309 return _missing_clids[name]
310 except KeyError: pass
311 return self._clidgen.getClidFromName(name)
312 IClassIDSvc.clid = _clid
313 del _clid
314
315 @cache
316 def _typename (self, clid):
317 # handle special cases of missing clids
318 try:
319 return _missing_clids[clid]
320 except KeyError:
321 pass
322 return self._clidgen.getNameFromClid(clid)
323 IClassIDSvc.typename = _typename
324 del _typename
325
326 return IClassIDSvc
327
328
329@cache
331 import cppyy
332 # ITHistSvc bindings from dictionary
333 _load_dict( "libGaudiKernelDict" )
334
335
336 # retrieve the ITHistSvc class
337 global ITHistSvc
338 ITHistSvc = cppyy.gbl.ITHistSvc
339
340 ROOT = _import_ROOT()
341 @property
342 def _py_cache(self):
343 try:
344 return self.__py_cache
345 except AttributeError:
346 self.__py_cache = dict()
347 return self.__py_cache
348 ITHistSvc._py_cache = _py_cache
349
350 # save original regXYZ methods: we'll use some modified ones
351 # to improve look-up time from python
352 ITHistSvc._cpp_regHist = ITHistSvc.regHist
353 ITHistSvc._cpp_regGraph = ITHistSvc.regGraph
354 ITHistSvc._cpp_regEfficiency = ITHistSvc.regEfficiency
355 ITHistSvc._cpp_regTree = ITHistSvc.regTree
356
357 _cpp_getHist = ROOT.AthenaInternal.getHist
358 _cpp_getGraph = ROOT.AthenaInternal.getGraph
359 _cpp_getEfficiency = ROOT.AthenaInternal.getEfficiency
360 _cpp_getTree = ROOT.AthenaInternal.getTree
361
362 def book(self, oid, obj=None, *args, **kw):
363 """book a histogram, profile or tree
364 @param oid is the unique object identifier even across streams,
365 ie: 'stream'+'id'
366 @param obj either an already full-fledge constructed ROOT object
367 or None (then `*args` or `**kw` need to be correctly setup)
368 @param *args list of arguments to give to the constructor of the
369 ROOT object one wants to book
370 @param **kw a dictionary containing a key 'args' being the list of
371 arguments to the constructor of the ROOT objects one wants to
372 book
373 examples:
374 >>> th.book('/temp/1d/h1', 'TH1D', args=('h1','h1',100,0.,100.))
375 >>> th.book('/temp/1d/h2', ROOT.TH1D, args=('h2','h2',100,0.,100.))
376 >>> th.book('/temp/1d/h3', ROOT.TH1D, 'h3','h3',100,0.,100.)
377 >>> th.book('/temp/1d/h4', ROOT.TH1D('h4','h4',100,0.,100.))
378 >>> th.book('/temp/1d/h5', obj=ROOT.TH1D('h5','h5',100,0.,100.))
379 >>> th.book('/temp/1d/h6', klass='TH1D', args=('h6','h6',100,0.,100.))
380
381 >>> th.book('/temp/tree/t1', ROOT.TTree('t1','t1'))
382 >>> th.book('/temp/tree/t2', obj=ROOT.TTree('t2','t2'))
383 >>> th.book('/temp/tree/t3', klass='TTree', args=('t3','t3'))
384 """
385 _err = "please provide _either_ an already constructed ROOT object or"\
386 "a class name/class type (with appropriate arguments)"
387 klass = kw.get('klass', None)
388 assert not (obj is None and klass is None), _err
389 assert not (obj is not None and klass is not None), _err
390
391 if isinstance(obj, (str,type)):
392 klass=obj
393 obj=None
394 if obj:
395 if isinstance(obj, ROOT.TH1):
396 # capture all of TH1x,TH2x,TH3x,TProfileXY
397 meth = self._cpp_regHist
398 elif isinstance(obj, (ROOT.TGraph,)):
399 meth = self._cpp_regGraph
400 elif isinstance(obj, (ROOT.TEfficiency,)):
401 meth = self._cpp_regEfficiency
402 elif isinstance(obj, (ROOT.TTree,)):
403 meth = self._cpp_regTree
404 else:
405 raise TypeError("invalid type '%r'"%type(obj))
406 if meth(oid, obj).isSuccess():
407 self._py_cache[oid]=obj
408 return obj
409 raise RuntimeError('could not book object [%r]'%obj)
410
411 if klass:
412 if isinstance(klass, str):
413 klass = getattr(ROOT, klass)
414 if args:
415 return self.book(oid, obj=klass(*args))
416 if kw and 'args' in kw:
417 return self.book(oid, obj=klass(*kw['args']))
418 err = "invalid arguments: either provide a valid `*args` or "\
419 "a `**kw` containing a 'args' key"
420 raise RuntimeError(err)
421 raise RuntimeError("unforseen case: oid='%r' obj='%r' args='%r' "
422 "kw='%r'"%(oid,obj,args,kw))
423
424 ITHistSvc.book = book
425
426 def get(self, oid, klass=None):
427 """retrieve an already booked ROOT object.
428 If the object was booked on the C++ side, try to use the `klass` hint
429 (the usual string or type) to find the object in the correct 'folder'
430 (histograms, graphs or trees).
431 If `klass` is None, then go through all the folders iteratively (slow)
432 """
433 try:
434 return self._py_cache[oid]
435 except KeyError:
436 pass
437 def _get_helper(hsvc, func, oid, update_cache=True):
438 sc, o = func(hsvc, oid)
439 if sc.isSuccess():
440 if update_cache:
441 hsvc._py_cache[oid] = o
442 return o
443 return
444 if klass:
445 if isinstance(klass, str):
446 klass = getattr(ROOT, klass)
447 if issubclass(klass, (ROOT.TH1,)):
448 return _get_helper(self, _cpp_getHist, oid)
449 if issubclass(klass, (ROOT.TGraph,)):
450 return _get_helper(self, _cpp_getGraph, oid)
451 if issubclass(klass, (ROOT.TEfficiency,)):
452 return _get_helper(self, _cpp_getEfficiency, oid)
453 if issubclass(klass, (ROOT.TTree,)):
454 return _get_helper(self, _cpp_getTree, oid)
455 raise RuntimeError('unsupported type [%r]'%klass)
456
457 # as we are sentenced to crawl through all these std::vector<str>
458 # we might as well update our local cache...
459
460 # first update histos
461 oids = [n for n in self.getHists() if n not in self._py_cache.keys()]
462 for name in oids:
463 obj = _get_helper(self, _cpp_getHist, name, update_cache=False)
464 if obj:
465 # now try with real class
466 klass = getattr(ROOT, obj.ClassName())
467 obj = _get_helper(self, _cpp_getHist, name)
468
469 # then graphs
470 oids = [n for n in self.getGraphs() if n not in self._py_cache.keys()]
471 for name in oids:
472 _get_helper(self, _cpp_getGraph, name)
473
474 # then efficiencies
475 oids = [n for n in self.getEfficiencies() if n not in self._py_cache.keys()]
476 for name in oids:
477 _get_helper(self, _cpp_getEfficiency, name)
478
479 # finally try ttrees
480 oids = [n for n in self.getTrees() if n not in self._py_cache.keys()]
481 for name in oids:
482 _get_helper(self, _cpp_getTree, name)
483
484
485 return self._py_cache[oid]
486
487 ITHistSvc.get = get
488 del get
489
490 def getitem(self, oid):
491 return self.get(oid)
492 ITHistSvc.__getitem__ = getitem
493 del getitem
494
495 def delitem(self, oid):
496 if isinstance(oid, str):
497 self.get(oid)
498 del self._py_cache[oid]
499 assert self.deReg(oid).isSuccess(), \
500 "could not remove object [%r]"%oid
501 return
502 ITHistSvc.__delitem__ = delitem
503
504 def setitem(self, k, v):
505 return self.book(k, obj=v)
506 ITHistSvc.__setitem__ = setitem
507 del setitem
508
509 def regObject(self, regFcn, oid, oid_type=None):
510 """Helper method to register object 'oid' using 'regFcn'."""
511 if oid_type is not None:
512 return self.book(oid,obj=oid_type)
513 if regFcn(self,oid).isSuccess():
514 # update py_cache
515 return self.get(oid)
516 err = ''.join(['invalid arguments oid=',repr(oid),' oid_type=',
517 repr(oid_type)])
518 raise ValueError(err)
519
520 ITHistSvc.regHist = partialmethod(regObject, ITHistSvc._cpp_regHist)
521 ITHistSvc.regTree = partialmethod(regObject, ITHistSvc._cpp_regTree)
522 ITHistSvc.regEfficiency = partialmethod(regObject, ITHistSvc._cpp_regEfficiency)
523 ITHistSvc.regGraph = partialmethod(regObject, ITHistSvc._cpp_regGraph)
524 del regObject
525
526 def load(self, oid, oid_type):
527 """Helper method to load a given object `oid' from a stream, knowing
528 its type. `oid_type' is a string whose value is either:
529 - 'hist', to load any THx and TProfiles
530 - 'tree', to load TTrees
531 - 'efficiency', to load TEfficiency
532 - 'graph', to load TGraph and TGraphErrors
533 """
534 if oid_type == 'hist':
535 return self.regHist(oid)
536 elif oid_type == 'tree':
537 return self.regTree(oid)
538 elif oid_type == 'efficiency':
539 return self.regEfficiency(oid)
540 elif oid_type == 'graph':
541 return self.regGraph(oid)
542 else:
543 raise ValueError(f'oid_type (={oid_type}) MUST be one of hist, tree, efficiency, graph')
544
545 ITHistSvc.load = load
546 del load
547
548
549
550 for n in ('__contains__',
551 '__iter__',
552 '__len__',
553 'has_key',
554 'items', 'iteritems',
555 'iterkeys', 'itervalues',
556 'keys', 'values'):
557 code = """\
558def %s(self, *args, **kw):
559 return self._py_cache.%s(*args,**kw)
560ITHistSvc.%s = %s
561del %s""" % (n,n,n,n,n)
562 exec (code, globals(),locals())
563
564
565 def __bool__(self):
566 return self is not None
567 ITHistSvc.__bool__ = __bool__
568 del __bool__
569
570 def pop(self, k):
571 obj = self.get(k)
572 assert self.deReg(obj).isSuccess(), \
573 "could not remove object [%r]"%k
574 return obj
575 ITHistSvc.pop = pop
576 del pop
577
578 def popitem(self):
579 k = self.iterkeys().next()
580 return (k, self.pop(k))
581 ITHistSvc.popitem = popitem
582 del popitem
583
584
585
586
591
592
596
597
599 return ITHistSvc
600
601
602@cache
604 import cppyy
605 # EventStreamInfo bindings from dictionary
606 _load_dict( "libEventInfoDict" )
607
608 # retrieve the EventStreamInfo class
609 ESI = cppyy.gbl.EventStreamInfo
610 # retrieve the PyEventStreamInfo helper class
611 PyESI= cppyy.gbl.PyEventStreamInfo
612 def run_numbers(self):
613 self._run_numbers = PyESI.runNumbers(self)
614 return list(self._run_numbers)
615 def evt_types(self):
616 self._evt_types = PyESI.eventTypes(self)
617 return list(self._evt_types)
618 def item_list(self):
619 self._item_list = PyESI.itemList(self)
620 return list(tuple(i) for i in self._item_list)
621 def lumi_blocks(self):
622 self._lumi_blocks = PyESI.lumiBlockNumbers(self)
623 return list(self._lumi_blocks)
624 def processing_tags(self):
625 self._processing_tags = PyESI.processingTags(self)
626 return list(self._processing_tags)
627 for fct in ('run_numbers', 'evt_types', 'item_list',
628 'lumi_blocks', 'processing_tags'):
629 setattr(ESI, fct, locals()[fct])
630
631 return ESI
632
633
634@cache
636 import cppyy
637 # EventStreamInfo bindings from dictionary
638 _load_dict( "libEventInfoDict" )
639
640 # retrieve the EventType class
641 cls = cppyy.gbl.EventType
642 cls.bit_mask_typecodes = [
643 ('IS_DATA','IS_SIMULATION'), #0
644 ('IS_ATLAS', 'IS_TESTBEAM'), #1
645 ('IS_PHYSICS','IS_CALIBRATION'),#2
646 ]
647 # retrieve the PyEventType class
648 py_cls = cppyy.gbl.PyEventType
649 def raw_bit_mask(self):
650 self._raw_bit_mask = py_cls.bit_mask(self)
651 return self._raw_bit_mask
652 cls.raw_bit_mask = property(raw_bit_mask)
653 def bit_mask(self):
654 def decode_bitmask(idx):
655 if len(self.raw_bit_mask) <= idx:
656 return self.bit_mask_typecodes[idx][0]
657 isa_idx = self.raw_bit_mask[idx]
658 return self.bit_mask_typecodes[idx][isa_idx]
659 bm = map(decode_bitmask,
660 range(len(self.bit_mask_typecodes)))
661 return tuple(bm)
662 cls.bit_mask = property(bit_mask)
663 return cls
664
665
666@cache
668 return _gen_data_link
669
670
671@cache
673 return _gen_element_link
674
675
676@cache
678 return _gen_elv
679
680
681@cache
683 return _gen_navtok
684
685
686@cache
687def _gen_data_link(klass, storage_policy=None):
688 """helper method to easily instantiate a DataLink class.
689 Sensible default for the storage policy is chosen if none given (it usually
690 boils down to DataProxyStorage)
691
692 @example:
693 >>> DLink = PyAthena.DataLink('CompositeParticleContainer')
694 >>> cp = DLink()
695 >>> cp = DLink('MyStoreGateKey')
696 """
697 ROOT = _import_ROOT ()
698 if isinstance(klass, str):
699 klass = getattr(ROOT, klass)
700 if storage_policy is None:
701 storage_policy = ROOT.DataProxyStorage(klass)
702 return ROOT.DataLink(klass, storage_policy)
703
704
705@cache
706def _gen_element_link(klass, storage_policy=None, indexing_policy=None):
707 """helper method to easily instantiate an ElementLink class.
708 Sensible defaults for the storage and indexing policies are chosen if none
709 given (it usually boils down to DataProxyStorage and ForwardIndexingPolicy)
710
711 @example:
712 >>> CPLink = PyAthena.ElementLink('CompositeParticleContainer')
713 >>> cp = CPLink()
714 >>> EleLink = PyAthena.ElementLink(PyAthena.ElectronContainer)
715 >>> ele = EleLink()
716 """
717 ROOT = _import_ROOT ()
718 if isinstance(klass, str):
719 klass = getattr(ROOT, klass)
720 #if storage_policy is None:
721 # storage_policy = ROOT.DataProxyStorage(klass)
722 #if indexing_policy is None:
723 # indexing_policy = ROOT.ForwardIndexingPolicy(klass)
724 #return ROOT.ElementLink(klass, storage_policy, indexing_policy)
725 return ROOT.ElementLink(klass)
726
727
728@cache
729def _gen_elv(klass, storage_policy=None, indexing_policy=None):
730 """helper method to easily instantiate an ElementLinkVector class.
731 Sensible defaults for the storage and indexing policies are chosen if none
732 given (it usually boils down to DataProxyStorage and ForwardIndexingPolicy)
733
734 @example:
735 >>> IELV = PyAthena.ElementLinkVector('INavigable4MomentumCollection')
736 >>> ielv = IELV()
737 """
738 ROOT = _import_ROOT ()
739 if isinstance(klass, str):
740 klass = getattr(ROOT, klass)
741 if storage_policy is None:
742 storage_policy = ROOT.DataProxyStorage(klass)
743 if indexing_policy is None:
744 indexing_policy = ROOT.ForwardIndexingPolicy(klass)
745 return ROOT.ElementLinkVector(klass, storage_policy, indexing_policy)
746
747
748@cache
749def _gen_navtok(klass, weight_cls=None, hash_cls=None):
750 """helper method to easily instantiate a NavigationToken class.
751 Sensible default for the weight and hash parameters are chosen if none are
752 given
753
754 @example:
755 >>> cls = PyAthena.NavigationToken('CaloCell')
756 >>> token = cls()
757 """
758 ROOT = _import_ROOT ()
759 if isinstance(klass, str):
760 klass = getattr(ROOT, klass)
761 if weight_cls is None:
762 weight_cls = getattr(ROOT, 'NavigationDefaults::DefaultWeight')
763 if hash_cls is None:
764 hash_cls = getattr(ROOT, 'SG::hash<const %s *>' % (klass.__name__,))
765 return ROOT.NavigationToken(klass, weight_cls, hash_cls)
766
767
768def _std_map_pythonize(cls, key_type, value_type):
769 def __contains__(self, k):
770 return self.find(k) != self.end()
771 cls.__contains__ = __contains__
772
773 def __setitem__(self, k, v):
774 itr = self.find(k)
775 self.insert(itr, self.__class__.value_type(k,v))
776 return v
777 cls.__setitem__ = __setitem__
778
779 cls.__cxx_getitem__ = cls.__getitem__
780 def __getitem__(self, k):
781 # python's dict semantics
782 if k not in self:
783 raise KeyError(k)
784 return self.__cxx_getitem__(k)
785 cls.__getitem__ = __getitem__
786
787 if not hasattr(cls, '__iter__'):
788 def toiter(beg, end):
789 while beg != end:
790 yield beg.__deref__()
791 beg.__preinc__()
792 return
793
794 def __iter__(self):
795 for i in toiter(self.begin(), self.end()):
796 yield i
797 cls.__iter__ = __iter__
798
799 def keys(self):
800 keys = []
801 for i in self:
802 keys.append(i.first)
803 return keys
804 cls.keys = keys
805
806 def values(self):
807 vals = []
808 for i in self:
809 vals.append(i.first)
810 return vals
811 cls.values = values
812
813 def iterkeys(self):
814 for i in self:
815 yield i.first
816 cls.iterkeys = iterkeys
817
818 def itervalues(self):
819 for i in self:
820 yield i.second
821 cls.itervalues = itervalues
822
823 def iteritems(self):
824 for i in self:
825 yield (i.first, i.second)
826 cls.iteritems = iteritems
827
828 return cls
829
830# -----------------------------------------------------------------------------
831
832def _setup():
833 _register = _PyAthenaBindingsCatalog.register
834 _register('StoreGateSvc', _py_init_StoreGateSvc)
835
836 _register( 'IncidentSvc', _py_init_IIncidentSvc)
837 _register('IIncidentSvc', _py_init_IIncidentSvc)
838
839 _register( 'ClassIDSvc', _py_init_ClassIDSvc)
840 _register('IClassIDSvc', _py_init_ClassIDSvc)
841
842 _register( 'THistSvc', _py_init_THistSvc)
843 _register('ITHistSvc', _py_init_THistSvc)
844
845 _register('EventStreamInfo', _py_init_EventStreamInfo)
846 _register('EventType', _py_init_EventType)
847
848 _register('DataLink', _py_init_DataLink)
849 _register('ElementLink', _py_init_ElementLink)
850 _register('ElementLinkVector', _py_init_ElementLinkVector)
851 pass
852
853
854_setup()
855
856
857del _setup
858
STL class.
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:132
_py_init_EventStreamInfo()
def setattr( self, attr, value ): try: from GaudiPython.Bindings import iProperty except ImportError:...
_gen_navtok(klass, weight_cls=None, hash_cls=None)
helper method to easily instantiate NavigationToken --------------------—
py_svc(svcName, createIf=True, iface=None)
_py_init_ClassIDSvc()
pythonizations for ClassIDSvc
_py_init_StoreGateSvc()
pythonizations for StoreGateSvc
_py_init_NavigationToken()
pythonizations for NavigationToken
py_alg(algName, iface=None)
helper method to easily retrieve algorithms by name --------------------—
_py_init_DataLink()
pythonizations for DataLink
_py_init_ElementLink()
pythonizations for ElementLink
_py_init_EventType()
pythonizations for EventType
_gen_data_link(klass, storage_policy=None)
helper method to easily instantiate DataLink ---------------------------—
py_tool(toolName, createIf=True, iface=None)
helper method to easily retrieve tools from ToolSvc by name ------------—
_py_init_ElementLinkVector()
pythonizations for ElementLinkVector
_std_map_pythonize(cls, key_type, value_type)
helper method to pythonize further std.map
_py_init_THistSvc()
pythonizations for ITHistSvc
_py_init_IIncidentSvc()
pythonizations for IIncidentSvc
_gen_elv(klass, storage_policy=None, indexing_policy=None)
helper method to easily instantiate ElementLinkVector ------------------—
_setup()
initialize the bindings' registration
_gen_element_link(klass, storage_policy=None, indexing_policy=None)
helper method to easily instantiate ElementLink ------------------------—