CMS 3D CMS Logo

cmstools.py
Go to the documentation of this file.
1 """Python helper tools for CMS FWLite
2 
3 benedikt.hegner@cern.ch
4 
5 """
6 from __future__ import absolute_import
7 import re
8 import ROOT
9 import exceptions
10 import six
11 import sys
12 ### define tab completion
13 try:
14  import readline #cmscompleter
15  readline.parse_and_bind('tab: complete')
16 except:
17  print 'WARNING: Could not load tab completion'
18 
19 
20 # for adding iterators at runtime
21 from . import iterators
22 
23 
24 ### workaround iterator generators for ROOT classes
25 def all(container):
26 
27  # loop over ROOT::TTree and similar
28  if hasattr(container,'GetEntries'):
29  try:
30  entries = container.GetEntries()
31  for entry in xrange(entries):
32  yield entry
33  except:
34  raise cmserror("Looping of %s failed" %container)
35 
36  # loop over std::vectors and similar
37  elif hasattr(container, 'size'):
38  try:
39  entries = container.size()
40  for entry in xrange(entries):
41  yield container[entry]
42  except:
43  pass
44 
45  # loop over containers with begin and end iterators
46 def loop(begin, end):
47  """Convert a pair of C++ iterators into a python generator"""
48  while (begin != end):
49  yield begin.__deref__() #*b
50  begin.__preinc__() #++b
51 
52 ### auto branch types (Chris Jones)
53 def createBranchBuffer(branch):
54  reColons = re.compile(r'::')
55  reCloseTemplate =re.compile(r'>')
56  reOpenTemplate =re.compile(r'<')
57  branchType = ROOT.branchToClass(branch)
58  #buffer = eval ('ROOT.'+reColons.sub(".",reOpenTemplate.sub("(ROOT.",reCloseTemplate.sub(")",branchType.GetName())))+'()')
59  buffer = ROOT.MakeRootClass(branchType.GetName()) ()
60  if( branch.GetName()[-1] != '.') and (branch.GetName()!="EventAuxiliary"):
61  branch.SetAddress(buffer)
62  else:
63  branch.SetAddress(ROOT.AddressOf(buffer))
64  return buffer
65 
66 
68  def __init__(self,obj):
69  sys.stderr.write ("WARNING: This package has been deprecated and will be removed in the near future.\nPlease switch to using FWLite.Python (https://twiki.cern.ch/twiki/bin/viewauth/CMS/WorkBookFWLitePython)\n")
70  treeName = 'Events'
71  if isinstance(obj, ROOT.TTree):
72  self._tree = obj
73  elif isinstance(obj, ROOT.TFile):
74  self._tree = obj.Get(treeName)
75  elif isinstance(obj, str):
76  self._tree = ROOT.TFile.Open(obj).Get(treeName)
77  else:
78  raise cmserror("EventTree accepts only TTrees, TFiles and filenames")
80  self._index = -1
81  self._aliases = self._tree.GetListOfAliases()
82  def branch(self,name):
83  # support for aliases
84  alias = self._tree.GetAlias(name)
85  if alias != '': name = alias
86  # access the branch in ttree
87  if name in self._usedBranches:
88  return self._usedBranches[name]
89  self._usedBranches[name]=EventBranch(self,name)
90  return self._usedBranches[name]
91  def cppCode(self, name):
92  """C++ code for accessing the product inside the full framework"""
93  alias = self._tree.GetAlias(name)
94  if alias != '': name = alias
95  tmpBranch = self._tree.GetBranch(name)
96  typeString = ROOT.branchToClass(tmpBranch).GetName()
97  if "edm::Wrapper" in typeString:
98  typeString = typeString.replace("<edm::Wrapper","")
99  typeString = typeString.rstrip(">")
100  nameParts = name.split("_")
101  if nameParts[2] == "":
102  cppCode = 'edm::Handle<%s > dummy;\nevent.getByLabel("%s", dummy);'\
103  %(typeString, nameParts[1])
104  else:
105  cppCode = 'edm::Handle<%s > dummy;\nevent.getByLabel("%s", "%s", dummy);'\
106  %(typeString, nameParts[1], nameParts[2])
107  return cppCode
108  def getListOfAliases(self):
109  return self._aliases
110  def SetAlias (self, alias, fullName):
111  self.tree().SetAlias(alias, fullName)
112  def index(self):
113  return self._index
114  def tree(self):
115  return self._tree
117  for branch in six.itervalues(self._usedBranches):
118  branch.setIndex(self._index)
119  def __getattr__(self, name):
120  return self.branch(name)
121  def __getitem__(self,key):
122  if key <0 or key > self._tree.GetEntries():
123  raise IndexError
124  self._index = key
125  self.__setBranchIndicies()
126  self._tree.GetEntry(self._index,0)
127  return Event(self)
128  def __iter__(self):
129  # flushing/initializing the root buffers
130  entry = 0
131  self._index = entry
132  self.__setBranchIndicies()
133  self._tree.GetEntry(self._index,0)
134  # the real loop
135  for entry in xrange(self._tree.GetEntries()):
136  self._index = entry
137  self.__setBranchIndicies()
138  self._tree.GetEntry(self._index,0)
139  yield Event(self) # TODO: don't return a new object but update the old one
140 
141 
142 class Event(object):
143  def __init__(self, eventTree):
144  self._eventTree = eventTree
145 
146  def getProduct(self, name):
147  return iterators.addIterator(self._eventTree.branch(name)())
148 
149  def __getattr__(self, name):
150  return iterators.addIterator(self._eventTree.branch(name)())
151 
152 
154  def __init__(self,parent,name):
155  self._branch = parent.tree().GetBranch(name)
156  if self._branch == None:
157  raise cmserror("Unknown branch "+name)
159  self._index = parent.index()
160  self._readData = False
161  def setIndex(self,index):
162  self._index = index
163  self._readData = False
164  def __readData(self):
165  self._branch.GetEntry(self._index)
166  self._readData = True
167 
168  # replace this by __getattr__ to allow branch.attr instead of branch().attr
169  def __call__(self):
170  if not self._readData:
171  self.__readData()
172  return self._buffer
173 
174 
175 class cmserror(exceptions.Exception):
176  def __init__(self, message):
177  length = len(message)+7 #7=len("ERROR: ")
178  print "="*length
179  print "ERROR:", message
180  print "="*length
def getProduct(self, name)
Definition: cmstools.py:146
def loop(begin, end)
Definition: cmstools.py:46
def __setBranchIndicies(self)
Definition: cmstools.py:116
def __getitem__(self, key)
Definition: cmstools.py:121
def getListOfAliases(self)
Definition: cmstools.py:108
def __init__(self, obj)
Definition: cmstools.py:68
def all(container)
workaround iterator generators for ROOT classes
Definition: cmstools.py:25
def __init__(self, eventTree)
Definition: cmstools.py:143
def setIndex(self, index)
Definition: cmstools.py:161
def __getattr__(self, name)
Definition: cmstools.py:149
def createBranchBuffer(branch)
auto branch types (Chris Jones)
Definition: cmstools.py:53
def __init__(self, parent, name)
Definition: cmstools.py:154
def __getattr__(self, name)
Definition: cmstools.py:119
def branch(self, name)
Definition: cmstools.py:82
def __init__(self, message)
Definition: cmstools.py:176
def cppCode(self, name)
Definition: cmstools.py:91
def SetAlias(self, alias, fullName)
Definition: cmstools.py:110