ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Control
CLIDComps
python
clidGenerator.py
Go to the documentation of this file.
1
# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
2
3
7
import
string, re, os, csv
8
9
# CLID assignment was originally based on the builtin hash() function.
10
# However, the results of that are not standardized, and in fact changed
11
# between py2 and py3. (In py3, hash(s) can return differing values
12
# from run to run.) This is an implementation of the py2 string hashing
13
# algorithm, so we can give the same results for py2 vs. py3.
14
def
py2_hash
(s):
15
if
len(s) == 0:
return
0
16
x = ord(s[0]) << 7
17
for
c
in
s:
18
x = (1000003*x) ^ ord(c)
19
x ^= len(s)
20
x &= 0xffffffff
21
if
x == 0xffffffff:
22
x = 0xfffffffe
23
return
x
24
25
26
class
clidGenerator
(object):
27
"""Athena CLID Generator"""
28
# CLID Mask: Determines bits used for CLID
29
__mask = 0x0FFFFFFF
30
# CLID Repositories - Dictionaries of CLID<=>Name
31
__clidRep = {} # Lookup by CLID
32
__clidTid = {} # Lookup by CLID
33
__nameRep = {} # Lookup by ClassName
34
__tidRep = {} # Lookup by typeid-name
35
36
def __init__(self, db, debug=False):
37
self.setCLIDDB(db, debug)
38
self.readdb()
39
40
def cleardb(self):
41
clidGenerator.__clidRep = {} # Lookup by CLID
42
clidGenerator.__nameRep = {} # Lookup by ClassName
43
44
def readdb(self):
45
"""
Read CLID DataBase file"""
46
try:
47
for cliddb in self.__cliddbs:
48
if os.path.isfile(cliddb):
49
with open(cliddb, 'r') as f_cliddb:
50
for row in csv.reader (f_cliddb, delimiter=';'):
51
row = [i.strip() for i in row]
52
if len(row) >= 2:
53
clid = int(row[0])
54
class_name = row[1]
55
tid_name = row[2] if len(row)>2 else class_name
56
57
self.__clidRep[clid] = class_name
58
self.__clidTid[clid] = tid_name
59
self.__nameRep[class_name] = clid
60
self.__tidRep [tid_name] = clid
61
62
else:
63
print ("No CLID DataBase file <%s> " % cliddb)
64
except Exception as err:
65
print ("Error reading from CLID DataBase files <%s>:\n%s " % (
66
self.__cliddbs,
67
err))
68
69
def setCLIDDB(self, db, debug):
70
"""Initializes a CLID Generator object with a CLID Database"""
71
if db:
72
self.__cliddbs = search_files(db, os.getenv('DATAPATH'))
73
if debug: print ("Using specified CLID DataBase files %s " % self.__cliddbs)
74
elif os.getenv('CLIDDB'):
75
# CLID DataBase (Default = clid.db)
76
self.__cliddbs.append(os.getenv('CLIDDB'))
77
if debug: print ("Using DataBase file from CLIDDB env variable %s " % self.__cliddbs)
78
else:
79
self.__cliddbs = search_files('clid.db', os.getenv('DATAPATH'))
80
if debug: print ("Using DataBase file from DATAPATH %s " % self.__cliddbs)
81
82
def writedb(self,db):
83
"""Read CLID DataBase file"""
84
output = open(db,'w')
85
for k in self.__clidRep.keys():
86
output.write("%d "%k+self.__clidRep[k]+"\n")
87
output.close()
88
89
def genClidFromName(self,className):
90
"""Generate CLID from ClassName: A recursive hash with a bit
91
mask and validity range. Will check collisions against and
92
update CLID Repository."""
93
n = self.demangleClassName(className)
94
c = self.getClidFromName(className)
95
if c:
96
return c
97
c = py2_hash(className) & self.__mask
98
if c < 10001 or c > self.__mask:
99
c = self.genClidFromName(className+'_')
100
if self.isCollection(className):
101
c += 0x40000000
102
if c in self.__clidRep:
103
if n != self.__clidRep[c]:
104
c = self.genClidFromName(className+'_')
105
else:
106
self.__clidRep[c] = n
107
self.__clidTid[c] = n # make typeid name the same than class-name
108
self.__nameRep[n] = c
109
self.__tidRep [n] = c # idem
110
return c
111
112
def getClidFromName(self,className):
113
"""Get the CLID in the repository of class name <className>"""
114
return self.__nameRep.get(className, None)
115
116
def getClidFromTid(self,tidName):
117
"""Get the CLID in the repository of typeid name <tidName>"""
118
return self.__tidRep.get(tidName, None)
119
120
def getNameFromClid(self,clid):
121
"""Get the class name in the repository with CLID <clid>"""
122
return self.__clidRep.get(clid, None)
123
124
def getTidFromClid(self,clid):
125
"""Get the typeid name in the repository with CLID <clid>"""
126
return self.__clidTid.get(clid, None)
127
128
def demangleClassName(self,s):
129
return s
130
# pat = re.compile('\s*(.?)__*\s*')
131
# n = pat.findall(s)
132
# if n:
133
# return n[0]
134
# else:
135
# return s
136
137
def isCollection(self,className):
138
collMatch = re.search(r'.*?Collection_*|.*?Container_*',className)
139
return collMatch
140
141
def findPattern(self,s):
142
"""Find the regular expression pattern s in dictionary."""
143
# pat = re.compile('^'+s+'$')
144
pat = re.compile(s)
145
results = {}
146
for k in self.__clidRep.keys():
147
if pat.match(str(k)) or pat.match(self.__clidRep[k]):
148
results[k] = self.__clidRep[k]
149
return results
150
151
def search_file(filename, search_path, pathsep=os.pathsep):
152
"""Given a search path, find file with requested name """
153
for path in string.split(search_path, pathsep):
154
candidate = os.path.join(path, filename)
155
if os.path.exists(candidate): return os.path.abspath(candidate)
156
return None
157
158
def search_files(filename, search_path, pathsep=os.pathsep):
159
"""Given a search path, find file with requested name """
160
clidFiles = []
161
for path in search_path.split(pathsep):
162
candidate = os.path.join(path, filename)
163
if os.path.exists(candidate): clidFiles.append(os.path.abspath(candidate))
164
return clidFiles
python.clidGenerator.clidGenerator
Athena CLID Generator Class.
Definition
clidGenerator.py:26
python.clidGenerator.py2_hash
py2_hash(s)
Definition
clidGenerator.py:14
Generated on
for ATLAS Offline Software by
1.17.0