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