File indexing completed on 2026-09-17 08:25:33
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 import os
0014 import sys
0015 import optparse
0016 import logging
0017 import errno
0018 import io
0019
0020 logger = logging.getLogger(__name__)
0021
0022
0023 class ComponentDumper:
0024 def __init__(self):
0025 os.environ['DD4HEP_TRACE'] = 'ON'
0026 self.all_components = []
0027
0028 def scanPath(self):
0029 ldp = os.getenv("LD_LIBRARY_PATH",
0030 "/usr/lib64:/usr/lib/:/usr/local/lib:/usr/lib64/root:/usr/lib/root:/usr/local/lib/root").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)