CMS 3D CMS Logo

useReflexToDescribeForGenObject.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 import ROOT
4 import re
5 import pprint
6 import sys
7 import inspect
8 import optparse
9 
10 defsDict = {
11  'int' : '%-40s : form=%%%%8d type=int',
12  'float' : '%-40s : form=%%%%7.2f prec=',
13  'str' : '%-40s : form=%%%%20s type=string',
14  'long' : '%-40s : form=%%%%10d type=long',
15  }
16 
17 root2GOtypeDict = {
18  'int' : 'int',
19  'float' : 'float',
20  'double' : 'float',
21  'long' : 'long',
22  'long int' : 'long',
23  'unsigned int' : 'int',
24  'bool' : 'int',
25  'string' : 'str',
26  'std::basic_string<char>' : 'str',
27  }
28 
29 startString = """
30 # -*- sh -*- For Font lock mode
31 
32 ###########################
33 ## GenObject Definitions ##
34 ###########################
35 
36 # GenObject 'event' definition
37 [runevent singleton]
38 run: type=int
39 event: type=int
40 """
41 
42 defTemplate = """
43 #####################
44 ## %(OBJS)s Definition ##
45 #####################
46 
47 # Nickname and Tree
48 [%(objs)s:FWLite]
49 
50 # 'reco'-tupe 'runevent' 'tofill' information
51 [runevent:%(objs)s:EventAuxiliary shortcut=eventAuxiliary()]
52 run: run()
53 event: event()
54 
55 """
56 
57 colonRE = re.compile (r':')
58 dotRE = re.compile (r'\.')
59 nonAlphaRE = re.compile (r'\W')
60 alphaRE = re.compile (r'(\w+)')
61 vetoedTypes = set()
62 
63 def getObjectList (objectName, base, verbose = False, memberData = False):
64  """Get a list of interesting things from this object"""
65  # The autoloader needs an object before it loads its dictionary.
66  # So let's give it one.
67  try:
68  rootObjConstructor = getattr (ROOT, objectName)
69  except AttributeError as missingAttr:
70  if str(missingAttr) in ['double', 'int']:
71  print "Do not need to describe doubles or ints"
72  sys.exit(0)
73  else:
74  raise
75 
76  obj = rootObjConstructor()
77  alreadySeenFunction = set()
78  vetoedFunction = set()
79  etaFound, phiFound = False, False
80  global vetoedTypes
81  retval = []
82  # Put the current class on the queue and start the while loop
83  classList = [ ROOT.TClass.GetClass(objectName) ]
84  if verbose: print classList
85  # Uses while because reflixList is really a stack
86  while classList:
87  alreadySeenFunction.update(vetoedFunction) # skip functions hidden by derived class
88  vetoedFunction.clear()
89  oneclass = classList.pop (0) # get first element
90  print "Looking at %s" % oneclass.GetName ()
91  bases = oneclass.GetListOfBases()
92  funcs = oneclass.GetListOfMethods()
93  if verbose:
94  print "baseSize", bases.GetSize()
95  print "FunctionMemberSize", funcs.GetSize()
96  for baseIndex in range( bases.GetSize() ) :
97  classList.append( bases.At(baseIndex).GetClassPointer() )
98  for index in range( funcs.GetSize() ):
99  funcMember = funcs.At (index)
100  # if we've already seen this, don't bother again
101  name = funcMember.GetName()
102  if verbose:
103  print "name", name
104  if name == 'eta':
105  etaFound = True
106  elif name == 'phi':
107  phiFound = True
108  if name in alreadySeenFunction:
109  continue
110  # make sure this is an allowed return type
111  returnType = funcMember.GetReturnTypeName()
112  goType = root2GOtypeDict.get (returnType, None)
113  if verbose:
114  print " type", returnType, goType
115  if not goType:
116  vetoedTypes.add (returnType)
117  if verbose:
118  print " skipped"
119  continue
120  elif verbose:
121  print " good"
122  # only bother printout out lines where it is a const function
123  # and has no input parameters.
124  if funcMember.Property() & ROOT.kIsConstMethod and not funcMember.GetNargs():
125  retval.append( ("%s.%s()" % (base, name), goType))
126  alreadySeenFunction.add( name )
127  if verbose:
128  print " added"
129  else :
130  vetoedFunction.add( name )
131  if verbose:
132  print " failed IsConst() and GetNargs()"
133  if not memberData:
134  continue
135  dataList = oneclass.GetListOfDataMembers()
136  for index in range( dataList.GetSize() ):
137  data = dataList.At( index );
138  name = data.GetName()
139  dataType = data.GetTypeName()
140  goType = root2GOtypeDict.get (dataType, None)
141  if not goType:
142  continue
143  if verbose:
144  print "name", name, "dataType", dataType, "goType", goType
145  retval.append ( ("%s.%s" % (base, name), goType) )
146  retval.sort()
147  return retval, etaFound and phiFound
148 
149 
150 def genObjNameDef (line):
151  """Returns GenObject name and ntuple definition function"""
152  words = dotRE.split (line)[1:]
153  func = ".".join (words)
154  name = "_".join (words)
155  name = nonAlphaRE.sub ('', name)
156  return name, func
157 
158 
159 def genObjectDef (mylist, tuple, alias, label, type, etaPhiFound):
160  """Does something, but I can't remembrer what... """
161  print "tuple %s alias %s label %s type %s" % (tuple, alias, label, type)
162  # first get the name of the object
163  firstName = mylist[0][0]
164  match = alphaRE.match (firstName)
165  if not match:
166  raise RuntimeError("firstName doesn't parse correctly. (%s)" \
167  % firstName)
168  genName = match.group (1)
169  genDef = " ## GenObject %s Definition ##\n[%s]\n" % \
170  (genName, genName)
171  if options.index or not etaPhiFound:
172  # either we told it to always use index OR either eta or phi
173  # is missing.
174  genDef += "-equiv: index,0\n";
175  else:
176  genDef += "-equiv: eta,0.1 phi,0.1 index,100000\n";
177  tupleDef = '[%s:%s:%s label=%s type=%s]\n' % \
178  (genName, tuple, alias, label, type)
179 
180  for variable in mylist:
181  name, func = genObjNameDef (variable[0])
182  typeInfo = variable[1]
183  form = defsDict[ typeInfo ]
184  genDef += form % name + '\n'
185  tupleDef += "%-40s : %s\n" % (name, func)
186  return genDef, tupleDef
187 
188 
189 if __name__ == "__main__":
190  # Setup options parser
191  parser = optparse.OptionParser \
192  ("usage: %prog [options] objectName\n" \
193  "Creates control file for GenObject.")
194  parser.add_option ('--goName', dest='goName', type='string',
195  default='',
196  help='GenObject name')
197  parser.add_option ('--index', dest='index', action='store_true',
198  help='use index for matching')
199  parser.add_option ('--label', dest='label', type='string',
200  default = 'dummyLabel',
201  help="Tell GO to set an label")
202  parser.add_option ('--output', dest='output', type='string',
203  default = '',
204  help="Output (Default 'objectName.txt')")
205  parser.add_option ('--precision', dest='precision', type='string',
206  default = '1e-5',
207  help="precision to use for floats (default %default)")
208  parser.add_option ('--privateMemberData', dest='privateMemberData',
209  action='store_true',
210  help='include private member data (NOT for comparisons)')
211  parser.add_option ('--tupleName', dest='tupleName', type='string',
212  default = 'reco',
213  help="Tuple name (default '%default')")
214  parser.add_option ('--type', dest='type', type='string',
215  default = 'dummyType',
216  help="Tell GO to set an type")
217  parser.add_option ('--verbose', dest='verbose', action='store_true',
218  help='Verbose output')
219  options, args = parser.parse_args()
220  defsDict['float'] += options.precision
221  from Validation.Tools.GenObject import GenObject
222  options.type = GenObject.decodeNonAlphanumerics (options.type)
223  if len (args) < 1:
224  raise RuntimeError("Need to provide object name.")
225  #
226  objectName = GenObject.decodeNonAlphanumerics (args[0])
227  goName = options.goName or colonRE.sub ('', objectName)
228  outputFile = options.output or goName + '.txt'
229  ROOT.gROOT.SetBatch()
230  # load the right libraries, etc.
231  ROOT.gSystem.Load("libFWCoreFWLite")
232  ROOT.gSystem.Load("libDataFormatsFWLite")
233  #ROOT.gSystem.Load("libReflexDict")
234  ROOT.FWLiteEnabler.enable()
235  mylist, etaPhiFound = getObjectList (objectName, goName, options.verbose,
236  options.privateMemberData)
237  if not len (mylist):
238  print "There are no member functions that are useful for comparison."
239  sys.exit (GenObject.uselessReturnCode)
240  targetFile = open (outputFile, 'w')
241  genDef, tupleDef = genObjectDef (mylist,
242  options.tupleName,
243  goName,
244  options.label,
245  options.type,
246  etaPhiFound)
247  targetFile.write (startString)
248  targetFile.write (genDef)
249  targetFile.write (defTemplate % {'objs':'reco', 'OBJS':'RECO'})
250  targetFile.write (tupleDef)
251  print "Vetoed types:"
252  pprint.pprint ( sorted( list(vetoedTypes) ) )
def genObjectDef(mylist, tuple, alias, label, type, etaPhiFound)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run
def getObjectList(objectName, base, verbose=False, memberData=False)