ATLAS Offline Software
Loading...
Searching...
No Matches
AtlasGeoDBInterface.py
Go to the documentation of this file.
1# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2
3from AthenaCommon import Logging
4
5import coral
6import os
7
8# -------------------------------------------------------------------------------------
9# AtlasGeoDBInterface : Interface with the geometry DB
10# -------------------------------------------------------------------------------------
11
13
14 def __init__(self,dbTag,verbose=False):
15
16 self.dbGeoTag=dbTag
17 self.dbGeoTagId=""
18 self.dbSession=0
19 self.dbSchema=0
20 self.bVerbose=verbose
21
23
24 def __del__(self):
25
26 Logging.log.verbose("-> close DB connection")
27 del self.dbSession
28
29
30 def ConnectToDB(self):
31
32 svc = coral.ConnectionService()
33 svcconfig = svc.configuration()
34 svcconfig.disablePoolAutomaticCleanUp()
35 svcconfig.setConnectionTimeOut(0)
36
37 # Check that the FRONTIER_SERVER is set properly, if not reduce the retrial period and time out values
38 if not ('FRONTIER_SERVER' in os.environ and os.environ['FRONTIER_SERVER']):
39 svcconfig.setConnectionRetrialPeriod(1)
40 svcconfig.setConnectionRetrialTimeOut(1)
41 else:
42 svcconfig.setConnectionRetrialPeriod(300)
43 svcconfig.setConnectionRetrialTimeOut(3600)
44
45 self.dbSession = svc.connect( 'ATLASDD', accessMode = coral.access_ReadOnly )
46 transaction = self.dbSession.transaction()
47
48 self.dbSchema = self.dbSession.nominalSchema()
49 transaction.start(True)
50
52
53 self.ConnectToDB()
56
57
59 """ Read the geometry Id corresponding to the geometry tag name in order to collect the child node Id's """
60
61 query = self.dbSchema.tableHandle("HVS_TAG2NODE").newQuery()
62
63 query.addToOutputList('TAG_NAME')
64 query.addToOutputList('TAG_ID')
65
66 bindstag2node = coral.AttributeList()
67 bindstag2node.extend('tagN','string')
68 bindstag2node[0].setData(self.dbGeoTag)
69 condString='TAG_NAME=:tagN'
70
71 query.setCondition(condString,bindstag2node)
72
73 for currentRow in iter(query.execute()):
74 for i in range(0,currentRow.size()):
75 if currentRow[i].specification().name()=="TAG_ID":
76 Logging.log.verbose("*** GeoTagId ******** "+str(currentRow))
77 self.dbGeoTagId=currentRow[i].data()
78 continue
79
80 del query
81 return
82
83
84 def AnalyseDBRequestOutput_Query(self,request,keyName=""):
85 """ Analyze request output -> return a list of dictionaries and a list of parameter types """
86
87 dataList=[]
88 typeList=[]
89
90 # Loop over row
91 iCmpt=0
92 for row in iter(request.execute()):
93 dictLoc={}
94 # loop over parameters read fron the DB
95 for j in range(0,row.size()):
96 name=row[j].specification().name()
97 paramType=row[j].specification().typeName()
98 value=row[j].data()
99 dictLoc[name]=value
100 # collect parameter name/types
101 if iCmpt==0: typeList.append((name,paramType))
102 iCmpt+=1
103 dataList.append(dictLoc)
104
105 # return datalist as a list of dictionaries ( 1 dictionary per line)
106 if keyName=="":
107 return dataList,typeList
108
109 # reorganize dataList as a dictionary with keys based on the keyName input parameter
110 dataDict={}
111 for d in dataList:
112 k=d[keyName]
113 v=[d[paramName] for paramName,tmp in typeList if paramName!=keyName]
114 dataDict[k]=v
115
116 return dataDict,typeList
117
118
120 """ Read tag and node versions defined for the geometry tag """
121
122 # Proceed by looping over the chilg Id's as long as childs are defined
123
124 bStopLoop=False
125 tagDictGbl={}
126
127 # Check if the geometry tag was found in the DB
128 if self.dbGeoTagId=="":
129 Logging.log.error("The geometry tag %s could not be found in the database.", self.dbGeoTag)
130 Logging.log.error("Its name might be misspelled and/or the script might access a local DB that is not up to date.")
131 import sys
132 sys.exit()
133
134 # Get node ids for the geometry tag
135 tagIdList=[int(self.dbGeoTagId)] # start with the geometry tag Id
136
137 # Loop while child tags are found
138 while not bStopLoop :
139
140 query0 = self.dbSchema.newQuery()
141
142 query0.addToOutputList('C.NODE_NAME',"nodename")
143 query0.addToOutputList('A.TAG_NAME',"tagname")
144 query0.addToOutputList('A.TAG_ID',"tagid")
145
146 query0.addToTableList( "HVS_TAG2NODE","A" )
147 query0.addToTableList( "HVS_LTAG2LTAG","B")
148 query0.addToTableList( "HVS_NODE","C" )
149
150 bindstag2node = coral.AttributeList()
151 condString="C.NODE_ID=A.NODE_ID AND A.TAG_ID=B.CHILD_TAG and B.PARENT_TAG IN (%s)" % str(tagIdList)[1:-1]
152 Logging.log.verbose("----------------------------\n"+condString)
153 query0.setCondition(condString,bindstag2node)
154
155 # Analyze the output and collect the new tag and node versions
156 dictRes,paramType=self.AnalyseDBRequestOutput_Query(query0,"nodename")
157 tagDictGbl.update(dictRes)
158 del query0
159
160 if len(dictRes.keys())==0:
161 # No child found
162 bStopLoop=True
163 else:
164 # create child Id's list for the next loop
165 tagIdList=[int(dictRes[k][1]) for k in dictRes.keys()]
166
167
168 self.TagAndNodeVersionDict.update(tagDictGbl)
169
170
171 def GetCurrentLeafContent(self, leafName):
172 """ Read a DB table content and return 3 lists :
173 - dbId : the data_id list corresponding to each entry in the table
174 - dbContent : the table values as a dictionary with keys corresponding to the dbId list
175 - paramName : the name of the table parameters """
176
177 upLeafName=leafName.upper()
178
179 # check if table is defined in the current geometry
180 if leafName not in self.TagAndNodeVersionDict:
181 dbId=[]
182 dbContent={}
183 paramName=[]
184 return dbId,dbContent,paramName
185
186
187 # ------ leafName_DATA_ID entries
188 leafTagId=self.TagAndNodeVersionDict[leafName][1]
189
190 query = self.dbSchema.tableHandle(upLeafName+"_DATA2TAG").newQuery()
191 query.addToOutputList(upLeafName+'_DATA_ID')
192
193 bindstag2node = coral.AttributeList()
194 condString=upLeafName+'_TAG_ID='+str(leafTagId)
195 query.setCondition(condString,bindstag2node)
196
197 dictRes,typeList=self.AnalyseDBRequestOutput_Query(query)
198 dataIdList=[int(s[upLeafName+'_DATA_ID']) for s in dictRes]
199 del query
200
201 # ------- values corresponding to leafName_DATA_ entries
202
203 query = self.dbSchema.tableHandle(upLeafName+"_DATA").newQuery()
204
205 condString=upLeafName+'_DATA_ID IN ('+str(dataIdList)[1:-1]+") ORDER BY "+upLeafName+"_DATA_ID"
206 query.setCondition(condString,bindstag2node)
207
208 dictRes,typeList=self.AnalyseDBRequestOutput_Query(query)
209 del query
210
211 # ------- build output
212 # paramNames : name of the DB parameters (following the table columns order)
213 # dbId : data_id vector
214 # dbContent : table content (key = dbId, value=list of value fooliwin the paramName ranking scheme)
215
216 paramName=[s[0] for s in typeList]
217
218 paramKey=typeList[0][0]
219 dbId=[]
220 dbContent={}
221 for s in dictRes:
222 key=int(s[paramKey])
223 dbId.append(key)
224 v=[s[k[0]] for k in typeList]
225 dbContent[key]=v
226
227 return dbId,dbContent,paramName
228
229# -------------------------------------------------------------------------------------
230# AtlasGeoDBInterface_SQLite : Interface with the SQLite geometry DB
231# -------------------------------------------------------------------------------------
232
233import sqlite3
234
236
237 def __init__(self,geoTag,sqliteDBFullPath,verbose=False):
238
239 self.db=None
240 self.bVerbose=verbose
241
242 if sqliteDBFullPath:
243 self.dbFile=sqliteDBFullPath
244 else:
245 from AthenaCommon.Utils.unixtools import find_datafile
246 pathlist = os.getenv('CALIBPATH').split(os.pathsep)
247 self.dbFile=find_datafile("Geometry/"+geoTag+".db",pathlist)
248
249 def ConnectToDB(self):
250
251 try:
252 self.db=sqlite3.connect(self.dbFile)
253 except Exception as e:
254 Logging.log.fatal(f'Failed to open SQLite database {self.dbFile}. {e}')
255 Logging.log.debug(f'Connected to SQLite database {self.dbFile}')
256
257 def GetData(self,tableName):
258
259 # Check the existence of the table in the DB
260 cur = self.db.cursor()
261 querystring = "SELECT tbl_name FROM sqlite_master WHERE type='table' AND tbl_name='"+tableName+"'"
262 cur.execute(querystring)
263 checkTable = cur.fetchall()
264 if len(checkTable)==0:
265 Logging.log.info(f'Table {tableName} not found in the SQLite DB. Falling back on the default config')
266 return []
267
268 # Fetch the data
269 cur = self.db.cursor()
270 querystring = "SELECT * FROM "+tableName+" order by "+tableName+"_data_id"
271 cur.execute(querystring)
272 rows = cur.fetchall()
273
274 ncols=len(cur.description)
275 dbData=[]
276 for row in rows:
277 dbDataRow={}
278 for i in range(1,ncols):
279 dbDataRow[cur.description[i][0]]=row[i]
280 Logging.log.debug(f'Fetched Data Row for {tableName}')
281 Logging.log.debug(f'{dbDataRow}')
282 dbData.append(dbDataRow)
283
284 return dbData
__init__(self, geoTag, sqliteDBFullPath, verbose=False)
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177