File indexing completed on 2025-01-30 09:16:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 from __future__ import absolute_import, unicode_literals
0014 import os
0015 import sys
0016 import optparse
0017 import logging
0018 import errno
0019 import io
0020
0021 logger = logging.getLogger(__name__)
0022
0023
0024 class ComponentDumper:
0025 def __init__(self):
0026 os.environ['DD4HEP_TRACE'] = 'ON'
0027 self.all_components = []
0028
0029 def scanPath(self):
0030 ldp = os.environ['LD_LIBRARY_PATH'].split(':')
0031 for p in ldp:
0032 if len(p):
0033 logger.info('+== Search component directory: ' + p)
0034 files = os.listdir(p)
0035 for f in files:
0036 fname = p + os.sep + f
0037 ext = os.path.splitext(fname)[-1].lower()
0038 if ext == '.components':
0039 self.readComponents(fname)
0040 elif ext == '.rootmap':
0041 self.dumpDictionaries(fname)
0042
0043 def readComponents(self, fname):
0044 logger.info('+== Search component file: ' + fname)
0045 file = io.open(fname, "r")
0046 lines = file.readlines()
0047 dirname = os.path.dirname(fname)
0048 for line in lines:
0049 line = line[:-1]
0050 if len(line) > 2 and (line[0:2] == '//' or line[0] == '#'):
0051 continue
0052 lib, comp = line.split(':')
0053 self.all_components.append([dirname + os.sep + lib, comp])
0054 file.close()
0055
0056 def searchDuplicates(self, summary_only=False):
0057 entries = {}
0058 component_count = 0
0059 duplicate_count = 0
0060 for lib, comp in self.all_components:
0061 if comp in entries:
0062 dupl = entries[comp]
0063 if dupl[1] == 0:
0064 if not summary_only:
0065 logger.info('+' + ('===' * 40))
0066 logger.info('| Component entry: ' + comp + ' in library: ' + dupl[0])
0067 entries[comp][1] = 1
0068 if not summary_only:
0069 logger.info('| --> Duplicate factory declaration in: ' + lib)
0070 duplicate_count = duplicate_count + 1
0071 continue
0072 entries[comp] = [lib, 0]
0073 component_count = component_count + 1
0074 logger.info('+' + ('===' * 40))
0075 logger.info('| Found %d dd4hep factory entries and %d DUPLICATES in component files.' %
0076 (component_count, duplicate_count,))
0077 logger.info('+' + ('===' * 40))
0078
0079 def dumpInventory(self, summary_only=False, dump=True, load=False, interactive=True):
0080 entries = {}
0081 do_load = load
0082 library_count = 0
0083 component_count = 0
0084 for lib, comp in self.all_components:
0085 if lib not in entries:
0086 entries[lib] = [comp]
0087 library_count = library_count + 1
0088 component_count = component_count + 1
0089 continue
0090 entries[lib].append(comp)
0091 component_count = component_count + 1
0092 if not summary_only:
0093 for lib, comp in entries.items():
0094 if dump:
0095 logger.info('+== Component library: ' + lib)
0096 count = 0
0097 for c in comp:
0098 count = count + 1
0099 if dump:
0100 logger.info('| %-3d Component: %s' % (count, c,))
0101 if do_load:
0102 ret = 'D'
0103 if interactive:
0104 try:
0105 ret = input("<CR> to DUMP the list of components \n"
0106 "<Q> to QUIT \n"
0107 "<D> to DUMP the list of components \n"
0108 "<S> to SKIP this particular library\n"
0109 "<L> to no longer LOAD libraries \n")
0110 except Exception:
0111 ret = 'D'
0112 if not len(ret):
0113 ret = 'D'
0114 if ret[0].upper() == 'Q':
0115 sys.exit(0)
0116 elif ret[0].upper() == 'D':
0117 gSystem.Load(lib)
0118 elif ret[0].upper() == 'L':
0119 do_load = False
0120 logger.info('+' + ('===' * 40))
0121 logger.info('| Found %d dd4hep factory libraries with %d components.' % (library_count, component_count,))
0122 logger.info('+' + ('===' * 40))
0123
0124 def dumpDictionaries(self, fname):
0125 pass
0126
0127
0128 parser = optparse.OptionParser()
0129 parser.description = "DD4hep factory checks."
0130 parser.formatter.width = 132
0131 parser.add_option("-c", "--check",
0132 action="store_true", dest="check", default=False,
0133 help="Check the components file in the LD_LIBRARY_PATH for duplicates",
0134 metavar="<boolean>")
0135
0136 parser.add_option("-d", "--dump",
0137 action="store_true", dest="dump", default=False,
0138 help="Dump the content of the components files",
0139 metavar="<boolean>")
0140
0141 parser.add_option("-l", "--load",
0142 action="store_true", dest="load", default=False,
0143 help="Load all libraries indicated in the component files",
0144 metavar="<boolean>")
0145
0146 parser.add_option("-n", "--no-interactive",
0147 action="store_false", dest="interactive", default=True,
0148 help="Always load. Do NOT inquire if a library should be loaded or not",
0149 metavar="<boolean>")
0150
0151 (opts, args) = parser.parse_args()
0152
0153 if not (opts.check or opts.dump or opts.load):
0154 logger.info(" %s", parser.format_help())
0155 sys.exit(0)
0156
0157 try:
0158 from ROOT import gROOT
0159 from ROOT import gSystem
0160 gROOT.SetBatch(1)
0161 except ImportError as X:
0162 logger.error('PyROOT interface not accessible: %s', str(X))
0163 sys.exit(errno.ENOENT)
0164
0165 try:
0166 import dd4hep
0167 except ImportError as X:
0168 logger.error('dd4hep python interface not accessible: %s', str(X))
0169 sys.exit(errno.ENOENT)
0170
0171 dmp = ComponentDumper()
0172 dmp.scanPath()
0173 if opts.check:
0174 dmp.searchDuplicates()
0175 if opts.dump or opts.load:
0176 dmp.dumpInventory(dump=opts.dump, load=opts.load, interactive=opts.interactive)
0177 sys.exit(0)