00001
00002
00003 import ROOT
00004 import re
00005 import pprint
00006 import sys
00007 import inspect
00008 import optparse
00009
00010 defsDict = {
00011 'int' : '%-40s : form=%%%%8d type=int',
00012 'float' : '%-40s : form=%%%%7.2f prec=',
00013 'str' : '%-40s : form=%%%%20s type=string',
00014 'long' : '%-40s : form=%%%%10d type=long',
00015 }
00016
00017 root2GOtypeDict = {
00018 'int' : 'int',
00019 'float' : 'float',
00020 'double' : 'float',
00021 'long' : 'long',
00022 'long int' : 'long',
00023 'unsigned int' : 'int',
00024 'bool' : 'int',
00025 'string' : 'str',
00026 'std::basic_string<char>' : 'str',
00027 }
00028
00029 startString = """
00030 # -*- sh -*- For Font lock mode
00031
00032 ###########################
00033 ## GenObject Definitions ##
00034 ###########################
00035
00036 # GenObject 'event' definition
00037 [runevent singleton]
00038 run: type=int
00039 event: type=int
00040 """
00041
00042 defTemplate = """
00043 #####################
00044 ## %(OBJS)s Definition ##
00045 #####################
00046
00047 # Nickname and Tree
00048 [%(objs)s:FWLite]
00049
00050 # 'reco'-tupe 'runevent' 'tofill' information
00051 [runevent:%(objs)s:EventAuxiliary shortcut=eventAuxiliary()]
00052 run: run()
00053 event: event()
00054
00055 """
00056
00057 colonRE = re.compile (r':')
00058 dotRE = re.compile (r'\.')
00059 nonAlphaRE = re.compile (r'\W')
00060 alphaRE = re.compile (r'(\w+)')
00061 vetoedTypes = set()
00062
00063 def getObjectList (objectName, base, verbose = False, memberData = False):
00064 """Get a list of interesting things from this object"""
00065
00066
00067 rootObjConstructor = getattr (ROOT, objectName)
00068 obj = rootObjConstructor()
00069 alreadySeenFunction = set()
00070 etaFound, phiFound = False, False
00071 global vetoedTypes
00072 retval = []
00073
00074 reflexList = [ ROOT.Reflex.Type.ByName (objectName) ]
00075 if verbose: print reflexList
00076 while reflexList:
00077 reflex = reflexList.pop (0)
00078 print "Looking at %s" % reflex.Name (0xffffffff)
00079 if verbose:
00080 print "baseSize", reflex.BaseSize()
00081 print "FunctionMemberSize", reflex.FunctionMemberSize()
00082 for baseIndex in range( reflex.BaseSize() ) :
00083 reflexList.append( reflex.BaseAt(baseIndex).ToType() )
00084 for index in range( reflex.FunctionMemberSize() ):
00085 funcMember = reflex.FunctionMemberAt (index)
00086
00087 name = funcMember.Name()
00088 if verbose:
00089 print "name", name
00090 if name == 'eta':
00091 etaFound = True
00092 elif name == 'phi':
00093 phiFound = True
00094 if name in alreadySeenFunction:
00095 continue
00096
00097 returnType = funcMember.TypeOf().ReturnType().Name (0xffffffff)
00098 goType = root2GOtypeDict.get (returnType, None)
00099 if verbose:
00100 print " type", returnType, goType
00101 if not goType:
00102 vetoedTypes.add (returnType)
00103 if verbose:
00104 print " skipped"
00105 continue
00106 elif verbose:
00107 print " good"
00108
00109
00110 if funcMember.IsConst() and not funcMember.FunctionParameterSize():
00111 retval.append( ("%s.%s()" % (base, name), goType))
00112 alreadySeenFunction.add( name )
00113 if verbose:
00114 print " added"
00115 elif verbose:
00116 print " failed IsConst() and FunctionParameterSize()"
00117 if not memberData:
00118 continue
00119 for index in range( reflex.DataMemberSize() ):
00120 data = reflex.DataMemberAt( index );
00121 name = data.Name()
00122 dataType = data.MemberType().__class__.__name__
00123 goType = root2GOtypeDict.get (dataType, None)
00124 if not goType:
00125 continue
00126 if verbose:
00127 print "name", name, "dataType", dataType, "goType", goType
00128 retval.append ( ("%s.%s" % (base, name), goType) )
00129 retval.sort()
00130 return retval, etaFound and phiFound
00131
00132
00133 def genObjNameDef (line):
00134 """Returns GenObject name and ntuple definition function"""
00135 words = dotRE.split (line)[1:]
00136 func = ".".join (words)
00137 name = "_".join (words)
00138 name = nonAlphaRE.sub ('', name)
00139 return name, func
00140
00141
00142 def genObjectDef (mylist, tuple, alias, label, type, etaPhiFound):
00143 """Does something, but I can't remembrer what... """
00144 print "tuple %s alias %s label %s type %s" % (tuple, alias, label, type)
00145
00146 firstName = mylist[0][0]
00147 match = alphaRE.match (firstName)
00148 if not match:
00149 raise RuntimeError, "firstName doesn't parse correctly. (%s)" \
00150 % firstName
00151 genName = match.group (1)
00152 genDef = " ## GenObject %s Definition ##\n[%s]\n" % \
00153 (genName, genName)
00154 if options.index or not etaPhiFound:
00155
00156
00157 genDef += "-equiv: index,0\n";
00158 else:
00159 genDef += "-equiv: eta,0.1 phi,0.1 index,100000\n";
00160 tupleDef = '[%s:%s:%s label=%s type=%s]\n' % \
00161 (genName, tuple, alias, label, type)
00162
00163 for variable in mylist:
00164 name, func = genObjNameDef (variable[0])
00165 typeInfo = variable[1]
00166 form = defsDict[ typeInfo ]
00167 genDef += form % name + '\n'
00168 tupleDef += "%-40s : %s\n" % (name, func)
00169 return genDef, tupleDef
00170
00171
00172 if __name__ == "__main__":
00173
00174 parser = optparse.OptionParser \
00175 ("usage: %prog [options] objectName\n" \
00176 "Creates control file for GenObject.")
00177 parser.add_option ('--goName', dest='goName', type='string',
00178 default='',
00179 help='GenObject name')
00180 parser.add_option ('--index', dest='index', action='store_true',
00181 help='use index for matching')
00182 parser.add_option ('--label', dest='label', type='string',
00183 default = 'dummyLabel',
00184 help="Tell GO to set an label")
00185 parser.add_option ('--output', dest='output', type='string',
00186 default = '',
00187 help="Output (Default 'objectName.txt')")
00188 parser.add_option ('--precision', dest='precision', type='string',
00189 default = '1e-5',
00190 help="precision to use for floats (default %default)")
00191 parser.add_option ('--privateMemberData', dest='privateMemberData',
00192 action='store_true',
00193 help='include private member data (NOT for comparisons)')
00194 parser.add_option ('--tupleName', dest='tupleName', type='string',
00195 default = 'reco',
00196 help="Tuple name (default '%default')")
00197 parser.add_option ('--type', dest='type', type='string',
00198 default = 'dummyType',
00199 help="Tell GO to set an type")
00200 parser.add_option ('--verbose', dest='verbose', action='store_true',
00201 help='Verbose output')
00202 options, args = parser.parse_args()
00203 defsDict['float'] += options.precision
00204 from Validation.Tools.GenObject import GenObject
00205 options.type = GenObject.decodeNonAlphanumerics (options.type)
00206 if len (args) < 1:
00207 raise RuntimeError, "Need to provide object name."
00208
00209 objectName = GenObject.decodeNonAlphanumerics (args[0])
00210 goName = options.goName or colonRE.sub ('', objectName)
00211 outputFile = options.output or goName + '.txt'
00212 ROOT.gROOT.SetBatch()
00213
00214 ROOT.gSystem.Load("libFWCoreFWLite")
00215 ROOT.gSystem.Load("libDataFormatsFWLite")
00216 ROOT.gSystem.Load("libReflexDict")
00217 ROOT.AutoLibraryLoader.enable()
00218 mylist, etaPhiFound = getObjectList (objectName, goName, options.verbose,
00219 options.privateMemberData)
00220 if not len (mylist):
00221 print "There are no member functions that are useful for comparison."
00222 sys.exit (GenObject.uselessReturnCode)
00223 targetFile = open (outputFile, 'w')
00224 genDef, tupleDef = genObjectDef (mylist,
00225 options.tupleName,
00226 goName,
00227 options.label,
00228 options.type,
00229 etaPhiFound)
00230 targetFile.write (startString)
00231 targetFile.write (genDef)
00232 targetFile.write (defTemplate % {'objs':'reco', 'OBJS':'RECO'})
00233 targetFile.write (tupleDef)
00234 print "Vetoed types:"
00235 pprint.pprint ( sorted( list(vetoedTypes) ) )