00001 """Python helper tools for CMS FWLite
00002
00003 benedikt.hegner@cern.ch
00004
00005 """
00006 import re
00007 import ROOT
00008 import exceptions
00009
00010 try:
00011 import readline
00012 readline.parse_and_bind('tab: complete')
00013 except:
00014 print 'WARNING: Could not load tab completion'
00015
00016
00017
00018 import iterators
00019
00020
00021
00022 def all(container):
00023
00024
00025 if hasattr(container,'GetEntries'):
00026 try:
00027 entries = container.GetEntries()
00028 for entry in xrange(entries):
00029 yield entry
00030 except:
00031 raise cmserror("Looping of %s failed" %container)
00032
00033
00034 elif hasattr(container, 'size'):
00035 try:
00036 entries = container.size()
00037 for entry in xrange(entries):
00038 yield container[entry]
00039 except:
00040 pass
00041
00042
00043 def loop(begin, end):
00044 """Convert a pair of C++ iterators into a python generator"""
00045 while (begin != end):
00046 yield begin.__deref__()
00047 begin.__preinc__()
00048
00049
00050 def createBranchBuffer(branch):
00051 reColons = re.compile(r'::')
00052 reCloseTemplate =re.compile(r'>')
00053 reOpenTemplate =re.compile(r'<')
00054 branchType = ROOT.branchToClass(branch)
00055
00056 buffer = ROOT.MakeRootClass(branchType.GetName()) ()
00057 if( branch.GetName()[-1] != '.') and (branch.GetName()!="EventAuxiliary"):
00058 branch.SetAddress(buffer)
00059 else:
00060 branch.SetAddress(ROOT.AddressOf(buffer))
00061 return buffer
00062
00063
00064 class EventTree(object):
00065 def __init__(self,obj):
00066 if isinstance(obj, ROOT.TTree):
00067 self._tree = obj
00068 elif isinstance(obj, ROOT.TFile):
00069 self._tree = obj.Get("Events")
00070 elif isinstance(obj, str):
00071 self._tree = ROOT.TFile.Open(obj).Get("Events")
00072 else:
00073 raise cmserror("EventTree accepts only TTrees, TFiles and filenames")
00074 self._usedBranches = dict()
00075 self._index = -1
00076 self._aliases = self._tree.GetListOfAliases()
00077 def branch(self,name):
00078
00079 alias = self._tree.GetAlias(name)
00080 if alias != '': name = alias
00081
00082 if name in self._usedBranches:
00083 return self._usedBranches[name]
00084 self._usedBranches[name]=EventBranch(self,name)
00085 return self._usedBranches[name]
00086 def cppCode(self, name):
00087 """C++ code for accessing the product inside the full framework"""
00088 alias = self._tree.GetAlias(name)
00089 if alias != '': name = alias
00090 tmpBranch = self._tree.GetBranch(name)
00091 typeString = ROOT.branchToClass(tmpBranch).GetName()
00092 if "edm::Wrapper" in typeString:
00093 typeString = typeString.replace("<edm::Wrapper","")
00094 typeString = typeString.rstrip(">")
00095 nameParts = name.split("_")
00096 if nameParts[2] == "":
00097 cppCode = 'edm::Handle<%s > dummy;\nevent.getByLabel("%s", dummy);'\
00098 %(typeString, nameParts[1])
00099 else:
00100 cppCode = 'edm::Handle<%s > dummy;\nevent.getByLabel("%s", "%s", dummy);'\
00101 %(typeString, nameParts[1], nameParts[2])
00102 return cppCode
00103 def getListOfAliases(self):
00104 return self._aliases
00105 def SetAlias (self, alias, fullName):
00106 self.tree().SetAlias(alias, fullName)
00107 def index(self):
00108 return self._index
00109 def tree(self):
00110 return self._tree
00111 def __setBranchIndicies(self):
00112 for branch in self._usedBranches.itervalues():
00113 branch.setIndex(self._index)
00114 def __getattr__(self, name):
00115 return self.branch(name)
00116 def __getitem__(self,key):
00117 if key <0 or key > self._tree.GetEntries():
00118 raise IndexError
00119 self._index = key
00120 self.__setBranchIndicies()
00121 self._tree.GetEntry(self._index,0)
00122 return Event(self)
00123 def __iter__(self):
00124
00125 entry = 0
00126 self._index = entry
00127 self.__setBranchIndicies()
00128 self._tree.GetEntry(self._index,0)
00129
00130 for entry in xrange(self._tree.GetEntries()):
00131 self._index = entry
00132 self.__setBranchIndicies()
00133 self._tree.GetEntry(self._index,0)
00134 yield Event(self)
00135
00136
00137 class Event(object):
00138 def __init__(self, eventTree):
00139 self._eventTree = eventTree
00140
00141 def getProduct(self, name):
00142 return iterators.addIterator(self._eventTree.branch(name)())
00143
00144 def __getattr__(self, name):
00145 return iterators.addIterator(self._eventTree.branch(name)())
00146
00147
00148 class EventBranch(object):
00149 def __init__(self,parent,name):
00150 self._branch = parent.tree().GetBranch(name)
00151 if self._branch == None:
00152 raise cmserror("Unknown branch "+name)
00153 self._buffer = createBranchBuffer(self._branch)
00154 self._index = parent.index()
00155 self._readData = False
00156 def setIndex(self,index):
00157 self._index = index
00158 self._readData = False
00159 def __readData(self):
00160 self._branch.GetEntry(self._index)
00161 self._readData = True
00162
00163
00164 def __call__(self):
00165 if not self._readData:
00166 self.__readData()
00167 return self._buffer
00168
00169
00170 class cmserror(exceptions.StandardError):
00171 def __init__(self, message):
00172 length = len(message)+7
00173 print "="*length
00174 print "ERROR:", message
00175 print "="*length