CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/Validation/Tools/scripts/useReflexToDescribeForGenObject.py

Go to the documentation of this file.
00001 #!/usr/bin/env python
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     # The autoloader needs an object before it loads its dictionary.
00066     # So let's give it one.
00067     rootObjConstructor = getattr (ROOT, objectName)
00068     obj = rootObjConstructor()
00069     alreadySeenFunction = set()
00070     etaFound, phiFound = False, False
00071     global vetoedTypes
00072     retval = []
00073     # Put the current class on the queue and start the while loop
00074     reflexList = [ ROOT.Reflex.Type.ByName (objectName) ]
00075     if verbose: print reflexList
00076     while reflexList:
00077         reflex = reflexList.pop (0) # get first element
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             # if we've already seen this, don't bother again
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             # make sure this is an allowed return type
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             # only bother printout out lines where it is a const function
00109             # and has no input parameters.            
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     # first get the name of the object
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         # either we told it to always use index OR either eta or phi
00156         # is missing.
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     # Setup options parser
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     # load the right libraries, etc.
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) ) )