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