test
CMS 3D CMS Logo

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