CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
EdmDataAccessor.py
Go to the documentation of this file.
1 import logging
2 import os.path
3 
4 from PyQt4.QtGui import QColor
5 
6 from Vispa.Share.BasicDataAccessor import BasicDataAccessor
7 from Vispa.Share.RelativeDataAccessor import RelativeDataAccessor
8 from Vispa.Share.ParticleDataAccessor import ParticleDataAccessor
9 from Vispa.Plugins.EventBrowser.EventFileAccessor import EventFileAccessor
10 from Vispa.Main.Exceptions import exception_traceback
11 from Vispa.Plugins.EdmBrowser.ParticleDataList import defaultParticleDataList
12 
13 def eq(self,other):
14  return id(self)==id(other)
15 def ne(self,other):
16  return id(self)!=id(other)
17 # PhysicsTools.PythonAnalysis.cmstools
18 def all(container):
19  # loop over ROOT::TTree and similar
20  if hasattr(container,'GetEntries'):
21  try:
22  entries = container.GetEntries()
23  for entry in xrange(entries):
24  yield entry
25  except:
26  raise cmserror("Looping of %s failed" %container)
27  # loop over std::vectors and similar
28  elif hasattr(container, 'size'):
29  # convert std::map to std::vector<std::pair>
30  if hasattr(container, 'ids'):
31  container = container.ids()
32  try:
33  entries = container.size()
34  for entry in xrange(entries):
35  yield container[entry]
36  except:
37  pass
38  # loop over c buffer
39  #elif hasattr(container,'begin') and hasattr(container,'end'):
40  # begin=container.begin()
41  # end=container.end()
42  # while (begin!=end):
43  # yield begin.__deref__()
44  # begin.__preinc__()
45 
47  def __init__(self,branchtuple):
48  self.branchtuple=branchtuple
49 
50 class EdmDataAccessor(BasicDataAccessor, RelativeDataAccessor, ParticleDataAccessor, EventFileAccessor):
51 
52  def __init__(self):
53  logging.debug(__name__ + ": __init__")
54 
55  self._dataObjects = []
56  self._edmLabel={}
57  self._edmParent={}
58  self._edmChildren={}
62 
63  self._eventIndex = 0
64  self._numEvents = 0
65 
66  self._filename=""
67  self._branches=[]
69  self._events=None
70  self._readOnDemand=True
71  self._underscore=False
72  self._filterBranches=True
73  self.maxLevels=2
74  self.maxDaughters=1000
75 
76  def isRead(self,object,levels=1):
77  if not id(object) in self._edmChildrenObjects.keys():
78  return False
79  if levels>1 and id(object) in self._edmChildren.keys():
80  for child in self._edmChildren[id(object)]:
81  if not self.isRead(child, levels-1):
82  return False
83  return True
84 
85  def children(self,object):
86  """ Get children of an object """
87  if id(object) in self._edmChildren.keys() and self.isRead(object):
88  return self._edmChildren[id(object)]
89  else:
90  return ()
91 
92  def isContainer(self,object):
93  """ Get children of an object """
94  if id(object) in self._edmChildren.keys() and self.isRead(object):
95  return len(self._edmChildren[id(object)])>0
96  else:
97  return True
98 
99  def motherRelations(self,object):
100  """ Get motherRelations of an object """
101  if id(object) in self._edmMotherRelations.keys():
102  return self._edmMotherRelations[id(object)]
103  else:
104  return ()
105 
106  def daughterRelations(self,object):
107  """ Get daughterRelations of an object """
108  if id(object) in self._edmDaughterRelations.keys():
109  return self._edmDaughterRelations[id(object)]
110  else:
111  return ()
112 
113  def label(self,object):
114  return self.getShortLabel(object)
115 
116  def getShortLabel(self,object):
117  if id(object) in self._edmLabel.keys():
118  splitlabel=self._edmLabel[id(object)].strip(".").split(".")
119  return splitlabel[len(splitlabel)-1]
120  else:
121  return ""
122 
123  def getShortLabelWithType(self,object):
124  return self.getShortLabel(object)+" <"+self.getShortType(object)+">"
125 
126  def getObjectLabel(self,object):
127  splitlabel=self._edmLabel[id(object)].strip(".").split(".")
128  return ".".join(splitlabel[1:-1])
129 
130  def getType(self,object):
131  typ=str(object.__class__)
132  if "\'" in typ:
133  typ=typ.split("\'")[1]
134  if "." in typ:
135  typ=typ.split(".")[len(typ.split("."))-1]
136  return typ.strip(" ")
137 
138  def getShortType(self,object):
139  typ=self.getType(object).split("<")[0].strip(" ")
140  return typ
141 
142  def getBranch(self,object):
143  entry=object
144  while id(entry) in self._edmParent.keys() and self._edmParent[id(entry)]!=None:
145  entry=self._edmParent[id(entry)]
146  return entry
147 
148  def getDepth(self,object):
149  entry=object
150  i=0
151  while id(entry) in self._edmParent.keys() and self._edmParent[id(entry)]!=None:
152  entry=self._edmParent[id(entry)]
153  i+=1
154  return i
155 
156  def getObjectProperties(self,object):
157  """ get all method properties of an object """
158  objects=[]
159  for attr in dir(object):
160  prop=getattr(object,attr)
161  if not attr.startswith("__") and (self._underscore or attr.strip("_")==attr):
162  objects+=[(attr,prop)]
163  return objects
164 
165  def getObjectRef(self,object):
166  """ get object and resolve references """
167  typshort=self.getShortType(object)
168  ref_types=["edm::Ref","edm::RefProd","edm::RefToBase","edm::RefToBaseProd","edm::Ptr"]
169  value=object
170  ref=False
171  if typshort in ref_types:
172  try:
173  if hasattr(object, "isNull") and object.isNull():
174  value="ERROR: "+self.getType(object)+" object is null"
175  elif hasattr(object, "isAvailable") and not object.isAvailable():
176  value="ERROR: "+self.getType(object)+" object is not available"
177  else:
178  value=object.get()
179  if type(value)==type(None):
180  value="ERROR: Could not get "+self.getType(object)
181  else:
182  ref=True
183  except Exception, message:
184  value="ERROR: "+str(message)
185  return value,ref
186 
187  def getObjectContent(self,object):
188  """ get string value of a method """
189  if not callable(object):
190  return object
191  else:
192  typ=""
193  if not object.__doc__ or str(object.__doc__)=="":
194  return "ERROR: Empty __doc__ string"
195  docs=str(object.__doc__).split("\n")
196  for doc in docs:
197  parameters=[]
198  for p in doc[doc.find("(")+1:doc.find(")")].split(","):
199  if p!="" and not "=" in p:
200  parameters+=[p]
201  if len(parameters)!=0:
202  continue
203  typestring=doc[:doc.find("(")]
204  split_typestring=typestring.split(" ")
205  templates=0
206  end_typestring=0
207  for i in reversed(range(len(split_typestring))):
208  templates+=split_typestring[i].count("<")
209  templates-=split_typestring[i].count(">")
210  if templates==0:
211  end_typestring=i
212  break
213  typ=" ".join(split_typestring[:end_typestring])
214  hidden_types=["iterator","Iterator"]
215  root_types=["ROOT::"]
216  if typ=="" or "void" in typ or True in [t in typ for t in hidden_types]:
217  return None
218  from ROOT import TClass
219  if True in [t in typ for t in root_types] and TClass.GetClass(typ)==None:
220  return "ERROR: Cannot display object of type "+typ
221  try:
222  object=object()
223  value=object
224  except Exception, message:
225  value="ERROR: "+str(message)
226  if "Buffer" in str(type(value)):
227  return "ERROR: Cannot display object of type "+typ
228  else:
229  return value
230 
231  def isVectorObject(self,object):
232  typ=self.getShortType(object)
233  return typ=="list" or typ[-6:].lower()=="vector" or typ[-3:].lower()=="map" or typ[-10:].lower()=="collection" or hasattr(object,"size")
234 
235  def compareObjects(self,a,b):
236  same=False
237  if hasattr(a,"px") and hasattr(a,"py") and hasattr(a,"pz") and hasattr(a,"energy") and \
238  hasattr(b,"px") and hasattr(b,"py") and hasattr(b,"pz") and hasattr(b,"energy"):
239  same=a.px()==b.px() and a.py()==b.py() and a.pz()==b.pz() and a.energy()==b.energy()
240  return same
241 
242  def getDaughterObjects(self,object):
243  """ get list of daughter objects from properties """
244  objects=[]
245  # subobjects
246  objectdict={}
247  hidden_attr=["front","back","IsA","clone","masterClone","masterClonePtr","mother","motherRef","motherPtr","daughter","daughterRef","daughterPtr","is_back_safe"]
248  broken_attr=[]#["jtaRef"]
249  for attr1,property1 in self.getObjectProperties(object):
250  if attr1 in hidden_attr:
251  pass
252  elif attr1 in broken_attr:
253  objectdict[attr1]=("ERROR: Cannot read property",False)
254  else:
255  (value,ref)=self.getObjectRef(self.getObjectContent(property1))
256  if not isinstance(value,type(None)) and (not self.isVectorObject(object) or self._propertyType(value)!=None):
257  objectdict[attr1]=(value,ref)
258  for name in sorted(objectdict.keys()):
259  objects+=[(name,objectdict[name][0],objectdict[name][1],self._propertyType(objectdict[name][0]))]
260  # entries in vector
261  if self.isVectorObject(object):
262  n=0
263  for o in all(object):
264  (value,ref)=self.getObjectRef(o)
265  typ=self._propertyType(value)
266  if typ!=None:
267  name="["+str(n)+"]"
268  elif "GenParticle" in str(value):
269  name=defaultParticleDataList.getNameFromId(value.pdgId())
270  else:
271  name=self.getType(value)+" ["+str(n)+"]"
272  objects+=[(name,value,ref,typ)]
273  n+=1
274  # read candidate relations
275  for name,mother,ref,propertyType in objects:
276  if hasattr(mother,"numberOfDaughters") and hasattr(mother,"daughter"):
277  for n in range(mother.numberOfDaughters()):
278  try:
279  daughter=mother.daughter(n)
280  found=False
281  for na,da,re,st in objects:
282  if self.compareObjects(daughter,da):
283  daughter=da
284  found=True
285  if not id(mother) in self._edmDaughterRelations.keys():
286  self._edmDaughterRelations[id(mother)]=[]
287  self._edmDaughterRelations[id(mother)]+=[daughter]
288  if not id(daughter) in self._edmMotherRelations.keys():
289  self._edmMotherRelations[id(daughter)]=[]
290  self._edmMotherRelations[id(daughter)]+=[mother]
291  except Exception, message:
292  logging.error("Cannot read candidate relations: "+str(message))
293  return objects
294 
295  def _propertyType(self,value):
296  if type(value) in (bool,):
297  return "Boolean"
298  elif type(value) in (int, long):
299  return "Integer"
300  elif type(value) in (float,):
301  return "Double"
302  elif type(value) in (complex,str,unicode):
303  return "String"
304  else:
305  return None
306 
307  def properties(self,object):
308  """ Make list of all properties """
309  logging.debug(__name__ + ": properties: "+self.label(object))
310  properties=[]
311 
312  objectproperties={}
313  objectproperties_sorted=[]
314  if id(object) in self._edmChildrenObjects.keys():
315  for name,value,ref,propertyType in self._edmChildrenObjects[id(object)]:
316  if propertyType!=None:
317  objectproperties[name]=(value,propertyType)
318  objectproperties_sorted+=[name]
319 
320  properties+=[("Category","Object info","")]
321  shortlabel=self.getShortLabel(object)
322  properties+=[("String","label",shortlabel)]
323  properties+=[("String","type",self.getType(object))]
324  objectlabel=self.getObjectLabel(object)
325  if objectlabel!="":
326  properties+=[("String","object",objectlabel)]
327  branchlabel=self.label(self.getBranch(object))
328  if shortlabel.strip(".")!=branchlabel.strip("."):
329  properties+=[("String","branch",branchlabel)]
330  else:
331  properties+=[("Category","Branch info","")]
332  properties+=[("String","Type",branchlabel.split("_")[0])]
333  properties+=[("String","Label",branchlabel.split("_")[1])]
334  properties+=[("String","Product",branchlabel.split("_")[2])]
335  properties+=[("String","Process",branchlabel.split("_")[3])]
336 
337  for property in ["pdgId","charge","status"]:
338  if property in objectproperties.keys():
339  properties+=[(objectproperties[property][1],property,objectproperties[property][0])]
340  del objectproperties[property]
341 
342  if "px" in objectproperties.keys():
343  properties+=[("Category","Vector","")]
344  for property in ["energy","px","py","pz","mass","pt","eta","phi","p","theta","y","rapidity","et","mt","mtSqr","massSqr"]:
345  if property in objectproperties.keys():
346  properties+=[(objectproperties[property][1],property,objectproperties[property][0])]
347  del objectproperties[property]
348 
349  if "x" in objectproperties.keys():
350  properties+=[("Category","Vector","")]
351  for property in ["x","y","z"]:
352  if property in objectproperties.keys():
353  properties+=[(objectproperties[property][1],property,objectproperties[property][0])]
354  del objectproperties[property]
355 
356  if False in [str(value[0]).startswith("ERROR") for value in objectproperties.values()]:
357  properties+=[("Category","Values","")]
358  for property in objectproperties_sorted:
359  if property in objectproperties.keys():
360  if not str(objectproperties[property][0]).startswith("ERROR"):
361  properties+=[(objectproperties[property][1],property,objectproperties[property][0])]
362  del objectproperties[property]
363 
364  if len(objectproperties.keys())>0:
365  properties+=[("Category","Errors","")]
366  for property in objectproperties_sorted:
367  if property in objectproperties.keys():
368  properties+=[(objectproperties[property][1],property,objectproperties[property][0])]
369 
370  return tuple(properties)
371 
372  def readObjectsRecursive(self,mother,label,edmobject,levels=1):
373  """ read edm objects recursive """
374  logging.debug(__name__ + ": readObjectsRecursive (levels="+str(levels)+"): "+label)
375  # save object information
376  if not id(edmobject) in self._edmLabel.keys():
377  if not isinstance(edmobject,(int,float,long,complex,str,unicode,bool)):
378  # override comparison operator of object
379  try:
380  type(edmobject).__eq__=eq
381  type(edmobject).__ne__=ne
382  except:
383  pass
384  self._edmLabel[id(edmobject)]=label
385  self._edmParent[id(edmobject)]=mother
386  self._edmChildren[id(edmobject)]=[]
387  if not id(mother) in self._edmChildren.keys():
388  self._edmChildren[id(mother)]=[]
389  self._edmChildren[id(mother)]+=[edmobject]
390  if levels==0:
391  # do not read more daughters
392  return [edmobject],True
393  else:
394  # read daughters
395  return self.readDaughtersRecursive(edmobject,[edmobject],levels)
396 
397  def readDaughtersRecursive(self,edmobject,objects,levels=1):
398  """ read daughter objects of an edmobject """
399  logging.debug(__name__ + ": readDaughtersRecursive (levels="+str(levels)+"): "+str(edmobject))
400  # read children information
401  if not id(edmobject) in self._edmChildrenObjects.keys():
402  self._edmChildrenObjects[id(edmobject)]=self.getDaughterObjects(edmobject)
403  # analyze children information
404  ok=True
405  daughters=self._edmChildrenObjects[id(edmobject)]
406  i=0
407  for name,daughter,ref,propertyType in daughters:
408  # create children objects
409  if propertyType==None:
410  if ref:
411  label="* "+name
412  else:
413  label=name
414  if id(edmobject) in self._edmLabel.keys() and self._edmLabel[id(edmobject)]!="":
415  label=self._edmLabel[id(edmobject)]+"."+label
416  (res,ok)=self.readObjectsRecursive(edmobject,label,daughter,levels-1)
417  objects+=res
418  i+=1
419  if i>self.maxDaughters:
420  logging.warning("Did not read all daughter objects. Maximum is set to "+str(self.maxDaughters)+".")
421  return objects,False
422  return objects,ok
423 
424  def read(self,object,levels=1):
425  """ reads contents of a branch """
426  logging.debug(__name__ + ": read")
427  if isinstance(object,BranchDummy):
428  if hasattr(object,"product"):
429  return object.product
430  if not self._events:
431  return object
432  try:
433  self._events.getByLabel(object.branchtuple[2],object.branchtuple[3],object.branchtuple[4],object.branchtuple[1])
434  if object.branchtuple[1].isValid():
435  product=object.branchtuple[1].product()
436  if not isinstance(product,(int,float,long,complex,str,unicode,bool)):
437  # override comparison operator of object
438  try:
439  type(product).__eq__=eq
440  type(product).__ne__=ne
441  except:
442  pass
443  self._dataObjects.insert(self._dataObjects.index(object),product)
444  self._dataObjects.remove(object)
445  self._edmLabel[id(product)]=object.branchtuple[0]
446  object.product=product
447  object=product
448  else:
449  self._edmChildrenObjects[id(object)]=[("ERROR","ERROR: Branch is not valid.",False,True)]
450  logging.info("Branch is not valid: "+object.branchtuple[0]+".")
451  object.invalid=True
452  return object
453  except Exception, e:
454  self._edmChildrenObjects[id(object)]=[("ERROR","ERROR: Unable to read branch : "+str(e),False,True)]
455  object.unreadable=True
456  logging.warning("Unable to read branch "+object.branchtuple[0]+" : "+exception_traceback())
457  return object
458  if self.isRead(object,levels):
459  return object
460  if levels>0:
461  self.readDaughtersRecursive(object,[],levels)
462  return object
463 
464  def goto(self, index):
465  """ Goto event number index in file.
466  """
467  self._eventIndex=index-1
468  self._edmLabel={}
469  self._edmChildren={}
470  self._edmMotherRelations={}
471  self._edmDaughterRelations={}
472  self._edmChildrenObjects={}
473  if self._events:
474  self._events.to(self._eventIndex)
475  self._dataObjects=[]
476  i=0
477  for branchtuple in self._filteredBranches:
478  branch=BranchDummy(branchtuple)
479  self._dataObjects+=[branch]
480  self._edmLabel[id(branch)]=branchtuple[0]
481  if not self._readOnDemand:
482  self.read(branch,self.maxLevels)
483  i+=1
484  if self._filterBranches and self._events:
485  self.setFilterBranches(True)
486  return True
487 
488  def eventNumber(self):
489  return self._eventIndex+1
490 
491  def numberOfEvents(self):
492  return self._numEvents
493 
494  def topLevelObjects(self):
495  return self._dataObjects
496 
497  def open(self, filename=None):
498  """ Open edm file and show first event """
499  self._filename=filename
500  self._branches=[]
501  if os.path.splitext(filename)[1].lower()==".txt":
502  file = open(filename)
503  for line in file.readlines():
504  if "\"" in line:
505  linecontent=[l.strip(" \n").rstrip(".") for l in line.split("\"")]
506  self._branches+=[(linecontent[0]+"_"+linecontent[1]+"_"+linecontent[3]+"_"+linecontent[5],None,linecontent[1],linecontent[3],linecontent[5])]
507  else:
508  linecontent=line.strip("\n").split(" ")[0].split("_")
509  if len(linecontent)>3:
510  self._branches+=[(linecontent[0]+"_"+linecontent[1]+"_"+linecontent[2]+"_"+linecontent[3],None,linecontent[1],linecontent[2],linecontent[3])]
511  elif os.path.splitext(filename)[1].lower()==".root":
512  from DataFormats.FWLite import Events, Handle
513  self._events = Events(self._filename)
514  self._numEvents=self._events.size()
515  branches=self._events.object().getBranchDescriptions()
516  for branch in branches:
517  try:
518  branchname=branch.friendlyClassName()+"_"+branch.moduleLabel()+"_"+branch.productInstanceName()+"_"+branch.processName()
519  handle=Handle(branch.fullClassName())
520  self._branches+=[(branchname,handle,branch.moduleLabel(),branch.productInstanceName(),branch.processName())]
521  except Exception, e:
522  logging.warning("Cannot read branch "+branchname+":"+str(e))
523  self._branches.sort(lambda x, y: cmp(x[0], y[0]))
524  self._filteredBranches=self._branches[:]
525  return self.goto(1)
526 
527  def particleId(self, object):
528  charge=self.property(object,"pdgId")
529  if charge==None:
530  charge=0
531  return charge
532 
533  def isQuark(self, object):
534  particleId = self.particleId(object)
535  if not particleId:
536  return False
537  return defaultParticleDataList.isQuarkId(particleId)
538 
539  def isLepton(self, object):
540  particleId = self.particleId(object)
541  if not particleId:
542  return False
543  return defaultParticleDataList.isLeptonId(particleId)
544 
545  def isGluon(self, object):
546  particleId = self.particleId(object)
547  if not particleId:
548  return False
549  return defaultParticleDataList.isGluonId(particleId)
550 
551  def isBoson(self, object):
552  particleId = self.particleId(object)
553  if not particleId:
554  return False
555  return defaultParticleDataList.isBosonId(particleId)
556 
557  def isPhoton(self, object):
558  particleId = self.particleId(object)
559  if not particleId:
560  return False
561  if not hasattr(defaultParticleDataList,"isPhotonId"):
562  return False
563  return defaultParticleDataList.isPhotonId(particleId)
564 
565  def isHiggs(self, object):
566  particleId = self.particleId(object)
567  if not particleId:
568  return False
569  if not hasattr(defaultParticleDataList,"isHiggsId"):
570  return False
571  return defaultParticleDataList.isHiggsId(particleId)
572 
573  def lineStyle(self, object):
574  particleId = self.particleId(object)
575  if hasattr(defaultParticleDataList,"isPhotonId") and defaultParticleDataList.isPhotonId(particleId):
576  return self.LINE_STYLE_WAVE
577  elif defaultParticleDataList.isGluonId(particleId):
578  return self.LINE_STYLE_SPIRAL
579  elif defaultParticleDataList.isBosonId(particleId):
580  return self.LINE_STYLE_DASH
581  return self.LINE_STYLE_SOLID
582 
583  def color(self, object):
584  particleId = self.particleId(object)
585  if defaultParticleDataList.isLeptonId(particleId):
586  return QColor(244, 164, 96)
587  elif defaultParticleDataList.isQuarkId(particleId):
588  return QColor(0, 100, 0)
589  elif hasattr(defaultParticleDataList,"isHiggsId") and defaultParticleDataList.isHiggsId(particleId):
590  return QColor(247, 77, 251)
591  elif defaultParticleDataList.isBosonId(particleId):
592  return QColor(253, 74, 74)
593  return QColor(176, 179, 177)
594 
595  def charge(self, object):
596  charge=self.property(object,"charge")
597  if charge==None:
598  charge=0
599  return charge
600 
601  def linkMother(self, object, mother):
602  pass
603 
604  def linkDaughter(self, object, daughter):
605  pass
606 
608  return self._underscore
609 
610  def setUnderscoreProperties(self,check):
611  self._underscore=check
612 
613  def filterBranches(self):
614  return self._filterBranches
615 
616  def setFilterBranches(self,check):
617  if not self._events:
618  return True
619  self._filterBranches=check
620  if check:
621  for branch in self._dataObjects[:]:
622  result=self.read(branch,0)
623  if isinstance(result,BranchDummy):
624  self._dataObjects.remove(result)
625  if hasattr(result,"invalid"):
626  self._filteredBranches.remove(result.branchtuple)
627  return True
628  else:
629  self._filteredBranches=self._branches[:]
630  self.goto(self.eventNumber())
631  return False
632 
633  def filteredBranches(self):
634  return self._filteredBranches
635 
## Events
Definition: __init__.py:435
void strip(std::string &input, const std::string &blanks=" \n\t")
Definition: stringTools.cc:16
## Handle
Definition: __init__.py:49
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
list object
Definition: dbtoconf.py:77
dbl *** dir
Definition: mlp_gen.cc:35
double split
Definition: MVATrainer.cc:139