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