File indexing completed on 2023-03-17 11:29:15
0001
0002
0003 from __future__ import print_function
0004 from builtins import range
0005 import ROOT
0006 import re
0007 import pprint
0008 import sys
0009 import inspect
0010 import optparse
0011
0012 defsDict = {
0013 'int' : '%-40s : form=%%%%8d type=int',
0014 'float' : '%-40s : form=%%%%7.2f prec=',
0015 'str' : '%-40s : form=%%%%20s type=string',
0016 'long' : '%-40s : form=%%%%10d type=long',
0017 }
0018
0019 root2GOtypeDict = {
0020 'int' : 'int',
0021 'float' : 'float',
0022 'double' : 'float',
0023 'long' : 'long',
0024 'long int' : 'long',
0025 'unsigned int' : 'int',
0026 'bool' : 'int',
0027 'string' : 'str',
0028 'std::basic_string<char>' : 'str',
0029 }
0030
0031 startString = """
0032 # -*- sh -*- For Font lock mode
0033
0034 ###########################
0035 ## GenObject Definitions ##
0036 ###########################
0037
0038 # GenObject 'event' definition
0039 [runevent singleton]
0040 run: type=int
0041 event: type=int
0042 """
0043
0044 defTemplate = """
0045 #####################
0046 ## %(OBJS)s Definition ##
0047 #####################
0048
0049 # Nickname and Tree
0050 [%(objs)s:FWLite]
0051
0052 # 'reco'-tupe 'runevent' 'tofill' information
0053 [runevent:%(objs)s:EventAuxiliary shortcut=eventAuxiliary()]
0054 run: run()
0055 event: event()
0056
0057 """
0058
0059 colonRE = re.compile (r':')
0060 dotRE = re.compile (r'\.')
0061 nonAlphaRE = re.compile (r'\W')
0062 alphaRE = re.compile (r'(\w+)')
0063 vetoedTypes = set()
0064
0065 def getObjectList (objectName, base, verbose = False, memberData = False):
0066 """Get a list of interesting things from this object"""
0067
0068
0069 try:
0070 rootObjConstructor = getattr (ROOT, objectName)
0071 except AttributeError as missingAttr:
0072 if str(missingAttr) in ['double', 'int']:
0073 print("Do not need to describe doubles or ints")
0074 sys.exit(0)
0075 else:
0076 raise
0077
0078 obj = rootObjConstructor()
0079 alreadySeenFunction = set()
0080 vetoedFunction = set()
0081 etaFound, phiFound = False, False
0082 global vetoedTypes
0083 retval = []
0084
0085 classList = [ ROOT.TClass.GetClass(objectName) ]
0086 if verbose: print(classList)
0087
0088 while classList:
0089 alreadySeenFunction.update(vetoedFunction)
0090 vetoedFunction.clear()
0091 oneclass = classList.pop (0)
0092 print("Looking at %s" % oneclass.GetName ())
0093 bases = oneclass.GetListOfBases()
0094 funcs = oneclass.GetListOfMethods()
0095 if verbose:
0096 print("baseSize", bases.GetSize())
0097 print("FunctionMemberSize", funcs.GetSize())
0098 for baseIndex in range( bases.GetSize() ) :
0099 classList.append( bases.At(baseIndex).GetClassPointer() )
0100 for index in range( funcs.GetSize() ):
0101 funcMember = funcs.At (index)
0102
0103 name = funcMember.GetName()
0104 if verbose:
0105 print("name", name)
0106 if name == 'eta':
0107 etaFound = True
0108 elif name == 'phi':
0109 phiFound = True
0110 if name in alreadySeenFunction:
0111 continue
0112
0113 returnType = funcMember.GetReturnTypeName()
0114 goType = root2GOtypeDict.get (returnType, None)
0115 if verbose:
0116 print(" type", returnType, goType)
0117 if not goType:
0118 vetoedTypes.add (returnType)
0119 if verbose:
0120 print(" skipped")
0121 continue
0122 elif verbose:
0123 print(" good")
0124
0125
0126 if funcMember.Property() & ROOT.kIsConstMethod and not funcMember.GetNargs():
0127 retval.append( ("%s.%s()" % (base, name), goType))
0128 alreadySeenFunction.add( name )
0129 if verbose:
0130 print(" added")
0131 else :
0132 vetoedFunction.add( name )
0133 if verbose:
0134 print(" failed IsConst() and GetNargs()")
0135 if not memberData:
0136 continue
0137 dataList = oneclass.GetListOfDataMembers()
0138 for index in range( dataList.GetSize() ):
0139 data = dataList.At( index );
0140 name = data.GetName()
0141 dataType = data.GetTypeName()
0142 goType = root2GOtypeDict.get (dataType, None)
0143 if not goType:
0144 continue
0145 if verbose:
0146 print("name", name, "dataType", dataType, "goType", goType)
0147 retval.append ( ("%s.%s" % (base, name), goType) )
0148 retval.sort()
0149 return retval, etaFound and phiFound
0150
0151
0152 def genObjNameDef (line):
0153 """Returns GenObject name and ntuple definition function"""
0154 words = dotRE.split (line)[1:]
0155 func = ".".join (words)
0156 name = "_".join (words)
0157 name = nonAlphaRE.sub ('', name)
0158 return name, func
0159
0160
0161 def genObjectDef (mylist, tuple, alias, label, type, etaPhiFound):
0162 """Does something, but I can't remembrer what... """
0163 print("tuple %s alias %s label %s type %s" % (tuple, alias, label, type))
0164
0165 firstName = mylist[0][0]
0166 match = alphaRE.match (firstName)
0167 if not match:
0168 raise RuntimeError("firstName doesn't parse correctly. (%s)" \
0169 % firstName)
0170 genName = match.group (1)
0171 genDef = " ## GenObject %s Definition ##\n[%s]\n" % \
0172 (genName, genName)
0173 if options.index or not etaPhiFound:
0174
0175
0176 genDef += "-equiv: index,0\n";
0177 else:
0178 genDef += "-equiv: eta,0.1 phi,0.1 index,100000\n";
0179 tupleDef = '[%s:%s:%s label=%s type=%s]\n' % \
0180 (genName, tuple, alias, label, type)
0181
0182 for variable in mylist:
0183 name, func = genObjNameDef (variable[0])
0184 typeInfo = variable[1]
0185 form = defsDict[ typeInfo ]
0186 genDef += form % name + '\n'
0187 tupleDef += "%-40s : %s\n" % (name, func)
0188 return genDef, tupleDef
0189
0190
0191 if __name__ == "__main__":
0192
0193 parser = optparse.OptionParser \
0194 ("usage: %prog [options] objectName\n" \
0195 "Creates control file for GenObject.")
0196 parser.add_option ('--goName', dest='goName', type='string',
0197 default='',
0198 help='GenObject name')
0199 parser.add_option ('--index', dest='index', action='store_true',
0200 help='use index for matching')
0201 parser.add_option ('--label', dest='label', type='string',
0202 default = 'dummyLabel',
0203 help="Tell GO to set an label")
0204 parser.add_option ('--output', dest='output', type='string',
0205 default = '',
0206 help="Output (Default 'objectName.txt')")
0207 parser.add_option ('--precision', dest='precision', type='string',
0208 default = '1e-5',
0209 help="precision to use for floats (default %default)")
0210 parser.add_option ('--privateMemberData', dest='privateMemberData',
0211 action='store_true',
0212 help='include private member data (NOT for comparisons)')
0213 parser.add_option ('--tupleName', dest='tupleName', type='string',
0214 default = 'reco',
0215 help="Tuple name (default '%default')")
0216 parser.add_option ('--type', dest='type', type='string',
0217 default = 'dummyType',
0218 help="Tell GO to set an type")
0219 parser.add_option ('--verbose', dest='verbose', action='store_true',
0220 help='Verbose output')
0221 options, args = parser.parse_args()
0222 defsDict['float'] += options.precision
0223 from Validation.Tools.GenObject import GenObject
0224 options.type = GenObject.decodeNonAlphanumerics (options.type)
0225 if len (args) < 1:
0226 raise RuntimeError("Need to provide object name.")
0227
0228 objectName = GenObject.decodeNonAlphanumerics (args[0])
0229 goName = options.goName or colonRE.sub ('', objectName)
0230 outputFile = options.output or goName + '.txt'
0231 ROOT.gROOT.SetBatch()
0232
0233 ROOT.gSystem.Load("libFWCoreFWLite")
0234 ROOT.gSystem.Load("libDataFormatsFWLite")
0235
0236 ROOT.FWLiteEnabler.enable()
0237 mylist, etaPhiFound = getObjectList (objectName, goName, options.verbose,
0238 options.privateMemberData)
0239 if not len (mylist):
0240 print("There are no member functions that are useful for comparison.")
0241 sys.exit (GenObject.uselessReturnCode)
0242 targetFile = open (outputFile, 'w')
0243 genDef, tupleDef = genObjectDef (mylist,
0244 options.tupleName,
0245 goName,
0246 options.label,
0247 options.type,
0248 etaPhiFound)
0249 targetFile.write (startString)
0250 targetFile.write (genDef)
0251 targetFile.write (defTemplate % {'objs':'reco', 'OBJS':'RECO'})
0252 targetFile.write (tupleDef)
0253 print("Vetoed types:")
0254 pprint.pprint ( sorted( list(vetoedTypes) ) )