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