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