335 ITHistSvc = cppyy.gbl.ITHistSvc
341 return self.__py_cache
342 except AttributeError:
343 self.__py_cache = dict()
344 return self.__py_cache
345 ITHistSvc._py_cache = _py_cache
349 ITHistSvc._cpp_regHist = ITHistSvc.regHist
350 ITHistSvc._cpp_regGraph = ITHistSvc.regGraph
351 ITHistSvc._cpp_regEfficiency = ITHistSvc.regEfficiency
352 ITHistSvc._cpp_regTree = ITHistSvc.regTree
354 def book(self, oid, obj=None, *args, **kw):
355 """book a histogram, profile or tree
356 @param oid is the unique object identifier even across streams,
358 @param obj either an already full-fledge constructed ROOT object
359 or None (then `*args` or `**kw` need to be correctly setup)
360 @param *args list of arguments to give to the constructor of the
361 ROOT object one wants to book
362 @param **kw a dictionary containing a key 'args' being the list of
363 arguments to the constructor of the ROOT objects one wants to
366 >>> th.book('/temp/1d/h1', 'TH1D', args=('h1','h1',100,0.,100.))
367 >>> th.book('/temp/1d/h2', ROOT.TH1D, args=('h2','h2',100,0.,100.))
368 >>> th.book('/temp/1d/h3', ROOT.TH1D, 'h3','h3',100,0.,100.)
369 >>> th.book('/temp/1d/h4', ROOT.TH1D('h4','h4',100,0.,100.))
370 >>> th.book('/temp/1d/h5', obj=ROOT.TH1D('h5','h5',100,0.,100.))
371 >>> th.book('/temp/1d/h6', klass='TH1D', args=('h6','h6',100,0.,100.))
373 >>> th.book('/temp/tree/t1', ROOT.TTree('t1','t1'))
374 >>> th.book('/temp/tree/t2', obj=ROOT.TTree('t2','t2'))
375 >>> th.book('/temp/tree/t3', klass='TTree', args=('t3','t3'))
377 _err =
"please provide _either_ an already constructed ROOT object or"\
378 "a class name/class type (with appropriate arguments)"
379 klass = kw.get(
'klass',
None)
380 assert not (obj
is None and klass
is None), _err
381 assert not (obj
is not None and klass
is not None), _err
383 if isinstance(obj, (str,type)):
387 if isinstance(obj, ROOT.TH1):
389 meth = self._cpp_regHist
390 elif isinstance(obj, (ROOT.TGraph,)):
391 meth = self._cpp_regGraph
392 elif isinstance(obj, (ROOT.TEfficiency,)):
393 meth = self._cpp_regEfficiency
394 elif isinstance(obj, (ROOT.TTree,)):
395 meth = self._cpp_regTree
397 raise TypeError(
"invalid type '%r'"%
type(obj))
398 if meth(oid, obj).isSuccess():
399 self._py_cache[oid]=obj
401 raise RuntimeError(
'could not book object [%r]'%obj)
404 if isinstance(klass, str):
405 klass = getattr(ROOT, klass)
407 return self.book(oid, obj=
klass(*args))
408 if kw
and 'args' in kw:
409 return self.book(oid, obj=
klass(*kw[
'args']))
410 err =
"invalid arguments: either provide a valid `*args` or "\
411 "a `**kw` containing a 'args' key"
412 raise RuntimeError(err)
413 raise RuntimeError(
"unforseen case: oid='%r' obj='%r' args='%r' "
414 "kw='%r'"%(oid,obj,args,kw))
416 ITHistSvc.book = book
418 def get(self, oid, klass=None):
419 """retrieve an already booked ROOT object.
420 If the object was booked on the C++ side, try to use the `klass` hint
421 (the usual string or type) to find the object in the correct 'folder'
422 (histograms, graphs or trees).
423 If `klass` is None, then go through all the folders iteratively (slow)
426 return self._py_cache[oid]
429 def _get_helper(klass, hsvc, meth, oid, update_cache=True):
430 makeNullPtr = ROOT.MakeNullPointer
431 o = makeNullPtr(klass)
432 if meth(oid, o).isSuccess():
434 hsvc._py_cache[oid] = o
438 if isinstance(klass, str):
439 klass = getattr(ROOT, klass)
440 if issubclass(klass, (ROOT.TH1,)):
441 return _get_helper(klass, self, self.getHist, oid)
442 if issubclass(klass, (ROOT.TGraph,)):
443 return _get_helper(klass, self, self.getGraph, oid)
444 if issubclass(klass, (ROOT.TEfficiency,)):
445 return _get_helper(klass, self, self.getEfficiency, oid)
446 if issubclass(klass, (ROOT.TTree,)):
447 return _get_helper(klass, self, self.getTree, oid)
448 raise RuntimeError(
'unsupported type [%r]'%klass)
454 oids = [n
for n
in self.getHists()
if n
not in self._py_cache.
keys()]
456 obj = _get_helper(ROOT.TH1, self, self.getHist, name,
460 klass = getattr(ROOT, obj.ClassName())
461 obj = _get_helper(klass, self, self.getHist, name)
464 oids = [n
for n
in self.getGraphs()
if n
not in self._py_cache.
keys()]
466 _get_helper(ROOT.TGraph, self, self.getGraph, name)
469 oids = [n
for n
in self.getEfficiencies()
if n
not in self._py_cache.
keys()]
471 _get_helper(ROOT.TEfficiency, self, self.getEfficiency, name)
474 oids = [n
for n
in self.getTrees()
if n
not in self._py_cache.
keys()]
476 _get_helper(ROOT.TTree, self, self.getTree, name)
479 return self._py_cache[oid]
484 def getitem(self, oid):
486 ITHistSvc.__getitem__ = getitem
489 def delitem(self, oid):
490 if isinstance(oid, str):
492 del self._py_cache[oid]
493 assert self.deReg(oid).isSuccess(), \
494 "could not remove object [%r]"%oid
496 ITHistSvc.__delitem__ = delitem
498 def setitem(self, k, v):
499 return self.book(k, obj=v)
500 ITHistSvc.__setitem__ = setitem
503 def regObject(self, regFcn, oid, oid_type=None):
504 """Helper method to register object 'oid' using 'regFcn'."""
505 if oid_type
is not None:
506 return self.book(oid,obj=oid_type)
507 if regFcn(self,oid).isSuccess():
510 err =
''.
join([
'invalid arguments oid=',
repr(oid),
' oid_type=',
512 raise ValueError(err)
514 ITHistSvc.regHist = partialmethod(regObject, ITHistSvc._cpp_regHist)
515 ITHistSvc.regTree = partialmethod(regObject, ITHistSvc._cpp_regTree)
516 ITHistSvc.regEfficiency = partialmethod(regObject, ITHistSvc._cpp_regEfficiency)
517 ITHistSvc.regGraph = partialmethod(regObject, ITHistSvc._cpp_regGraph)
520 def load(self, oid, oid_type):
521 """Helper method to load a given object `oid' from a stream, knowing
522 its type. `oid_type' is a string whose value is either:
523 - 'hist', to load any THx and TProfiles
524 - 'tree', to load TTrees
525 - 'efficiency', to load TEfficiency
526 - 'graph', to load TGraph and TGraphErrors
528 if oid_type ==
'hist':
529 return self.regHist(oid)
530 elif oid_type ==
'tree':
531 return self.regTree(oid)
532 elif oid_type ==
'efficiency':
533 return self.regEfficiency(oid)
534 elif oid_type ==
'graph':
535 return self.regGraph(oid)
537 raise ValueError(f
'oid_type (={oid_type}) MUST be one of hist, tree, efficiency, graph')
539 ITHistSvc.load = load
544 for n
in (
'__contains__',
548 'items',
'iteritems',
549 'iterkeys',
'itervalues',
552 def %s(self, *args, **kw):
553 return self._py_cache.%s(*args,**kw)
555 del %s""" % (n,n,n,n,n)
556 exec (code, globals(),locals())
560 return self
is not None
561 ITHistSvc.__bool__ = __bool__
566 assert self.deReg(obj).isSuccess(), \
567 "could not remove object [%r]"%k
573 k = self.iterkeys().
next()
574 return (k, self.pop(k))
575 ITHistSvc.popitem = popitem