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