CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/Validation/Tools/scripts/summarizeEdmComparisonLogfiles.py

Go to the documentation of this file.
00001 #! /usr/bin/env python
00002 
00003 import optparse
00004 import os
00005 from glob import glob
00006 import re
00007 import pprint
00008 import commands
00009 countRE = re.compile (r'^count_(\w+)')
00010 avoid = ['index', 'print']
00011 
00012 def summaryOK (summary):
00013     """returns a tuple.  First value is true if summary hasn't found
00014     any problems, else false."""
00015     retval = True
00016     count    = -1
00017     compared = summary.get('eventsCompared', -1)
00018     if len( summary.keys()) != 2:
00019         retval = False
00020     for key,value in summary.iteritems():
00021         if countRE.search(key):
00022             count = value
00023     return (retval, {'count':count, 'compared':compared})
00024 
00025 if __name__ == "__main__":
00026 
00027     # compile regexs
00028     percentRE      = re.compile (r'%')
00029     startOutputRE  = re.compile (r'^Summary$')
00030     success1RE     = re.compile (r"{'eventsCompared':\s+(\d+),\s+'count_(\S+)':\s+(\d+)\s*}")
00031     success2RE     = re.compile (r"{'count_(\S+)':\s+(\d+),\s+'eventsCompared':\s+(\d+)\s*}")
00032     loadingSoRE    = re.compile (r'loading (genobjectrootlibs/\w+)')
00033     creatingSoRE   = re.compile (r'creating shared library (\S+)')
00034     compRootRE     = re.compile (r' --compRoot=(\S+)')
00035     descriptionRE  = re.compile (r'^edmOneToOneComparison.py (\w+).txt')
00036     edmCommandRE  = re.compile (r'^(edmOneToOneComparison.py .+?)\s*$')
00037     # problem regexs
00038     labelErrorRE   = re.compile (r"labelDict = GenObject._ntupleDict\[tupleName\]\['_label'\]")
00039     missingLabelRE = re.compile (r'not able to get')
00040     terminatedRE   = re.compile (r'Terminated\s+\$EXE\s+\$@')
00041     cppExceptionRE = re.compile (r'\(C\+\+ exception\)')
00042     missingCfgRE   = re.compile (r"raise.+Can't open configuration")
00043     finishRE       = re.compile (r'finish')
00044     dummyRE        = re.compile (r'edm::Wrapper<dummyType>')
00045     noEdmWrapperRE = re.compile (r"'ROOT' has no attribute 'edm::Wrapper")
00046     uint32RE       = re.compile (r"Config file parser error 'operatoruint32_t")
00047     nonSpacesRE    = re.compile (r'\S')
00048     problemDict = { 'labelDict'    : labelErrorRE,
00049                     'missingLabel' : missingLabelRE,
00050                     'terminate'    : terminatedRE,
00051                     'uint32'       : uint32RE,
00052                     'cppException' : cppExceptionRE,
00053                     'missingCfg'   : missingCfgRE,
00054                     'noEdmWrapper' : noEdmWrapperRE,
00055                     'dummy'        : dummyRE,
00056                     'operator'     : re.compile (r"onfig file parser error 'operator"),
00057                     'useless'      : re.compile (r'no member functions that are useful'),
00058                     'lazy'         : re.compile (r': Assertion'),
00059                     'detset'       : re.compile (r"AttributeError: 'edm::DetSet"),
00060                     'doubleint'    : re.compile (r'AttributeError: (int|double)'),
00061                     'finish'       : finishRE}
00062 
00063     parser = optparse.OptionParser ("Usage: %prog logfilePrefix [directory]")
00064     parser.add_option ("--counts", dest="counts",
00065                        action="store_true", default=False,
00066                        help="Display counts only.")
00067     parser.add_option ('--mismatch', dest='mismatch',
00068                        action='store_true',
00069                        help='Displays only mismatch output')
00070     parser.add_option ("--diffTree", dest="diffTree",
00071                        action="store_true", default=False,
00072                        help="Shows diffTree printout.")
00073     parser.add_option ('--makeCompRoot', dest='makeCompRoot',
00074                        action='store_true',
00075                        help='Prints commands to make compRoot files for difftree')
00076     parser.add_option ("--problem", dest="problem", type='string',
00077                        help="Displays problems matching PROBLEM")
00078 
00079     options, args = parser.parse_args()
00080     if not 1 <= len (args) <= 2:
00081         raise RuntimeError, "Must give directory and log file prefix"
00082     logfilePrefix = percentRE.sub ('*', args[0])
00083     if logfilePrefix[-1] != '*':
00084         logfilePrefix += '*'
00085     cwd = os.getcwd()
00086     logdir = ''
00087     if len (args) == 2:
00088         logdir = args[1]
00089         os.chdir (logdir)
00090     files        = glob (logfilePrefix)
00091     if logdir:
00092         oldFiles = files
00093         files = []
00094         for filename in oldFiles:
00095             files.append (logdir + '/' + filename)
00096         os.chdir (cwd)
00097     totalFiles   = len (files)
00098     problems     = {}
00099     succeeded    = 0
00100     weird        = 0
00101     problemTypes = {}
00102     successes    = {}
00103     objectName   = ''
00104     compRoot     = ''
00105     soName       = ''
00106     command      = ''
00107     diffOutput   = {}
00108     goShlib      = ''
00109     for log in files:
00110         problemSet = set()
00111         source = open (log, 'r')
00112         ran = False
00113         success = False
00114         reading = False
00115         summaryLines = ''
00116         for line in source:
00117             line = line.rstrip('\n')
00118             match = edmCommandRE.search (line)
00119             if match:
00120                 command = match.group(1)
00121             match = loadingSoRE.search (line)
00122             if match:
00123                 goShlib = match.group(1)                
00124             match = creatingSoRE.search (line)
00125             if match:
00126                 goShlib = match.group(1)                
00127             if options.diffTree:
00128                 match = descriptionRE.search (line)
00129                 if match:
00130                     objectName = match.group(1)
00131                 match = compRootRE.search (line)
00132                 if match:
00133                     compRoot = match.group(1)
00134                 match = loadingSoRE.search (line)
00135                 if match:
00136                     soName = match.group(1)
00137             if reading:
00138                 if not nonSpacesRE.search(line):
00139                     reading = False
00140                     continue
00141                 summaryLines += line
00142             if startOutputRE.search(line):
00143                 ran     = True
00144                 reading = True
00145                 continue
00146             if success1RE.search (line) or success2RE.search(line):
00147                 success = True
00148                 continue
00149             for key, regex in problemDict.iteritems():
00150                 #print "considering %s for %s" % (key, line)
00151                 if regex.search(line):
00152                     if key in problemSet:
00153                         continue
00154                     problemSet.add (key)
00155                     problems.setdefault(log,[]).append(key)
00156                     if not problemTypes.has_key(key):
00157                         problemTypes[key] = 1
00158                     else:
00159                         problemTypes[key] += 1
00160             key = ''
00161         source.close()
00162         
00163         if summaryLines:
00164             summary = eval (summaryLines)
00165             ok = summaryOK (summary)
00166         else:
00167             ok = (False,)
00168             summary = None
00169         if ran and success:
00170             succeeded += 1
00171             if not ok[0]:
00172                 weird += 1
00173             else:
00174                 successes[log] = pprint.pformat (summary, indent=4)
00175         else:
00176             if ok[0]:
00177                 weird += 1
00178         if not problems.has_key (log) and not ok[0]:
00179             if not ok[0] and summary:
00180                 key = 'mismatch'                
00181                 problems[log] = pprint.pformat (summary, indent=4)
00182                 #pprint.pprint (summary, indent=4)
00183                 if objectName and compRoot and soName:
00184                     # do the diffTree magic
00185                     varNames = summary.get(objectName, {}).\
00186                                get('_var', {}).keys()
00187                     variables = ['eta', 'phi']
00188                     for var in sorted (varNames):
00189                         if var not in variables and var not in avoid:
00190                             variables.append (var)
00191                     diffCmd = 'diffTreeTool.py --skipUndefined %s %s %s' \
00192                               % (compRoot, soName, " ".join(variables))
00193                     # print diffCmd
00194                     diffOutput[log] = diffCmd
00195             else:
00196                 problems[log] = ['other','ran:%s' % ran,
00197                                   'success:%s' % success]
00198                 key = 'other'
00199             if not problemTypes.has_key(key):
00200                 problemTypes[key] = 1
00201             else:
00202                 problemTypes[key] += 1
00203     mismatches = problemTypes.get('mismatch', 0)
00204     if problemTypes.has_key ('mismatch'):
00205         del problemTypes['mismatch']
00206     print "total:      ", len (files)
00207     print "success:    ", succeeded
00208     print "mismatches: ", mismatches
00209     print "weird:      ", weird
00210     print "Tool issue types:"
00211     total = 0
00212     for key, value in sorted (problemTypes.iteritems()):
00213         print "  %-15s: %4d" % (key, value)
00214         total += value
00215     print " ", '-'*13, " : ----"
00216     print "  %-15s: %4d + %d + %d + %d = %d" \
00217           % ('total', total, succeeded, mismatches, weird,
00218              total + succeeded + mismatches + weird)
00219     
00220     if not options.counts:
00221         print "\nDetailed Problems list:"
00222         for key, problemList in sorted (problems.iteritems()):
00223             if options.problem and problemList[0] != options.problem:
00224                 continue
00225             if options.mismatch and not isinstance (problemList, str):
00226                 continue
00227             #if options.mismatch and 
00228             print "   %s:\n   %s\n" % (key, problemList)
00229             if options.mismatch and goShlib and compRoot:
00230                 print "diffTree %s %s" % (goShlib, compRoot)
00231             diffCmd = diffOutput.get(key)
00232             if diffCmd:                
00233                 print commands.getoutput (diffCmd)
00234         if not options.problem and not options.mismatch:
00235             print "\n", '='*78, '\n'
00236             print "Success list:"
00237             for key, successesList in sorted (successes.iteritems()):
00238                 print "   %s:\n   %s\n" % (key, successesList)