Back to home page

Project CMSSW displayed by LXR

 
 

    


Warning, /FWCore/PythonUtilities/scripts/edmDumpEventContent is written in an unsupported language. File is not indexed.

0001 #! /usr/bin/env python3
0002 
0003 from builtins import object
0004 import os
0005 import sys
0006 import copy
0007 from argparse import ArgumentParser
0008 import re
0009 import copy
0010 import subprocess
0011 
0012 # define regex
0013 wrapperRE      = re.compile (r'edm::Wrapper<(.+)\s*>$')
0014 trailingDotRE  = re.compile (r'\.$')
0015 underscoreRE   = re.compile (r'_')
0016 leadingSlashRE = re.compile (r'^/')
0017 webRE          = re.compile (r'^\w+://')
0018 
0019 def getOutput (command):
0020     '''Given an input command, returns STDOUT and STDERR'''
0021     proc = subprocess.Popen(command,
0022                             shell=True,
0023                             stdout=subprocess.PIPE,
0024                             stderr=subprocess.PIPE
0025                             )
0026     return proc.communicate()
0027 
0028 
0029 def expandFilename (filename, options):
0030     '''Intelligently guesses as to whether or not it is given an PFN
0031     or LFN.  Returns PFN.'''
0032     # if this is a web address, don't modify it
0033     if webRE.search (filename):
0034         return filename
0035     # if it doesn't start with a slash, return it as is
0036     if not leadingSlashRE.search (filename):
0037         return filename
0038     # if the file exists locally AND 'lfn' option is not given, return
0039     # as is
0040     if not options.lfn and os.path.exists (filename):
0041         return filename
0042     # OK.  If we're here, then we probably have an LFN.  Convert it
0043     stdout, stderr = getOutput ('edmFileUtil -d %s' % filename)
0044     if stdout:
0045         return stdout.strip()
0046     raise RuntimeError("Could not successfully run 'edmFileUtil.' Error %s" \
0047           % stderr)
0048 
0049 
0050 class Branch (object):
0051     # default options
0052     form = "%(type)5s  %(module)5s  %(label)5s  %(process)5s"
0053     mode = 'normal'
0054     forceColumns = False
0055     inQuotes = ['module', 'label', 'process']
0056 
0057     def __init__ (self, branchInfo, regexList = None):
0058         """Takes the needed information from Root's Branch Info"""
0059         match = wrapperRE.match( branchInfo.GetTypeName() )
0060         if match:
0061             self.type = match.group (1)
0062         else:
0063             # this isn't a type we're interested in
0064             raise ValueError("Not edm::Wrapper")
0065         name = trailingDotRE.sub ('', branchInfo.GetName())
0066         pieces = underscoreRE.split (name)
0067         if len (pieces) != 4:
0068             raise ValueError("%s not formatted as expected" % name)
0069         self.typeString = pieces[0] # not currently used
0070         self.module     = pieces[1]
0071         self.label      = pieces[2]
0072         self.process    = pieces[3]
0073         self.fullname   = "_".join (pieces)
0074         self.splitlevel = branchInfo.GetSplitLevel()
0075         # if we're past a regex list, then make sure we've got a match
0076         if not regexList:
0077             # nothing more to do
0078             return
0079         found = False
0080         for regex in regexList:
0081             # search the branch name
0082             if regex.search (self.fullname):
0083                 found = True
0084                 break
0085             if regex.search (self.type):
0086                 found = True
0087                 break
0088         if not found:
0089             raise ValueError("%s does not match regexs provided" \
0090                   % self.fullname)
0091 
0092         
0093     def __str__ (self):
0094         """String representation """
0095         copyDict = copy.copy (self.__dict__)
0096         for key in Branch.inQuotes:
0097             copyDict[key] = '"%s"' % copyDict[key]
0098         return Branch.form % copyDict
0099     
0100     
0101     @staticmethod
0102     def _setForm (branchList):
0103         '''Loop through lists and set widths and form appropriately'''
0104         # each item in this dictionary is a variable in Branch where
0105         # we want to keep track of the length.  The first number in
0106         # the list is the maximum length of all of the Branch items in
0107         # the list.  The second entry is the maximum length that it
0108         # should take IFF we are enforcing maximum length.
0109         lengthDict = { 'type'    : [7, 35],
0110                        'module'  : [7, 25],
0111                        'label'   : [7, 15],
0112                        'process' : [7, 15],
0113                        'fullname': [7, 50]}
0114         # Since we want this script to print out the columns in the
0115         # order that we want and not some random order, we specify
0116         # that order here.
0117         order = ['type', 'module', 'label', 'process']
0118         for obj in branchList:
0119             for key, twoList in lengthDict.items():
0120                 attribute = getattr (obj, key)
0121                 if len (attribute) + 2 > twoList[0]:
0122                     twoList[0] = len (attribute) + 2
0123         totalLength = 0
0124         for twoList in list(lengthDict.values()):
0125             totalLength += twoList[0]
0126         useMin = True
0127         if Branch.forceColumns or totalLength < 70:
0128             useMin = False
0129         Branch.form = ""
0130         if Branch.mode == 'name':
0131             # name
0132             Branch.form += '%(fullname)s'
0133         else:
0134             for piece in order:
0135                 Branch.form += '%('
0136                 Branch.form +=  piece
0137                 if useMin:
0138                     Branch.form += ')-%ds   ' % min ( lengthDict[piece] )
0139                 else:
0140                     Branch.form += ')-%ds   ' % lengthDict[piece][0]
0141         if Branch.mode == 'all':
0142             # name
0143             Branch.form += '     %('
0144             if useMin:
0145                 Branch.form += 'fullname)-%ds' % min ( lengthDict['fullname'] )
0146             else:
0147                 Branch.form += 'fullname)-%ds' % lengthDict['fullname'][0]
0148             # split level
0149             Branch.form += '     %(splitlevel)s'
0150 
0151 
0152     @staticmethod
0153     def printList (branchList):
0154         '''Print out nicely formatted list of all branches'''
0155         Branch._setForm (branchList)
0156         title = Branch.form % {'type'     : 'Type',
0157                                'module'   : 'Module',
0158                                'label'    : 'Label',
0159                                'process'  : 'Process',
0160                                'fullname' : 'Full Name',
0161                                'splitlevel' : 'Split level'}
0162         print(title)
0163         print('-' * len(title))
0164         for branch in branchList:
0165             print(branch)
0166 
0167 #branches = ''
0168 if __name__ == "__main__":
0169 
0170     parser = ArgumentParser(description="Prints out info on edm file.")
0171     nameAllGroup = parser.add_mutually_exclusive_group()
0172     nameAllGroup.add_argument('--name', dest='name', action='store_true',
0173                               help='print out only branch names')
0174     nameAllGroup.add_argument('--all',  dest='all',  action='store_true',
0175                               help='Print out everything: type, module, label, '\
0176                               'process, branch name, and branch split level')
0177     parser.add_argument('--lfn', dest='lfn', action='store_true',
0178                         help="Force LFN2PFN translation (usually not necessary)")
0179     lumiRunGroup = parser.add_mutually_exclusive_group()
0180     lumiRunGroup.add_argument('--lumi', dest='lumi', action='store_true',
0181                               help="Look at 'lumi' tree")
0182     lumiRunGroup.add_argument('--run', dest='run', action='store_true',
0183                               help="Look at 'run' tree")
0184     parser.add_argument("--regex", dest='regex', action="append",
0185                         type=str, default=[],
0186                         help="Filter results based on regex")
0187     parser.add_argument('--skipping', dest='skipping', action='store_true',
0188                         help="Print out branches being skipped")
0189     parser.add_argument('--forceColumns', dest='forceColumns',
0190                         action='store_true',
0191                         help="Forces printouts to be in nice columns")
0192     parser.add_argument("templates", metavar="templates.root", type=str)
0193     options = parser.parse_args()
0194     filename = expandFilename (options.templates, options)
0195     ###################
0196     # process options #
0197     ###################
0198     if options.name:
0199         Branch.mode = 'name'
0200     elif options.all:
0201         Branch.mode = 'all'
0202     Branch.forceColumns = options.forceColumns
0203 
0204     treeName = 'Events'
0205     if options.lumi:
0206         treeName = 'LuminosityBlocks'
0207     elif options.run:
0208         treeName = 'Runs'
0209     regexList = []
0210     # are we asked to filter this list?
0211     for regexString in options.regex:
0212         regexList.append( re.compile( regexString, re.IGNORECASE ) )
0213     # Because PyRoot is, well, greedy, we want to make sure we have
0214     # setup and parsed the command line options before importing ROOT
0215     # otherwise ROOT will try and do this for us.
0216     import ROOT
0217     ROOT.gROOT.SetBatch() # setting batch mode
0218     # Here we turn off stderr so that we don't get all of the errors
0219     # saying we don't have a dictionary for all of the objects in the
0220     # root file.  When we've loaded the file, we turn it back on
0221     oldStderr = os.dup( sys.stderr.fileno() )
0222     newStderr = open ( '/dev/null', 'w')
0223     os.dup2( newStderr.fileno(), sys.stderr.fileno() )
0224     rootfile = ROOT.TFile.Open( filename )
0225     os.dup2( oldStderr, sys.stderr.fileno() )
0226     if not rootfile:
0227         raise RuntimeError("Could not open file '%s'." % filename)
0228     Tree = rootfile.Get (treeName)
0229     branches = Tree.GetListOfBranches()
0230     branchList = []
0231     for branchInfo in branches:
0232         try:
0233             branch = Branch (branchInfo, regexList)
0234         except Exception as detail:
0235             if options.skipping:
0236                 print("Skipping ", detail)
0237             continue
0238         branchList.append (branch)
0239     Branch.printList (branchList)
0240     rootfile.Close()
0241     del rootfile