ATLAS Offline Software
AFPAlignDBCreate.py
Go to the documentation of this file.
1 #!/bin/env python
2 
3 # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
4 
5 # file AFPAlignDBCreate.py
6 # author Petr Balek <petr.balek@cern.ch>
7 # date 2021-02-27
8 #
9 # brief A python script that generates COOL database with alignment constants for AFP. A lot of inspiration obtained in InnerDetector/InDetConditions/InDetBeamSpotService/utils/beamSpot_set.py
10 # usage 0. setup Athena environment (setupATLAS, asetup ...)
11 # 1. run this script:
12 # python AFPAlignDBCreate.py
13 # 2. check the output:
14 # AtlCoolConsole.py "sqlite://;schema=Example.db;dbname=CONDBR2"
15 # 3. check "testAFPDB.py" for more testing
16 
17 
18 
19 import sys, json, copy
20 from CoolConvUtilities import AtlCoolLib
21 from PyCool import cool
22 
23 # AFPDBBase is no longer needed, partially replaced by AtlCoolLib
24 #from AFP_DBTools.AFPDBBase import AFPDBRecordBase, AFPDBTableBase
25 
26 class folderBulk():
27  """A class to store database folder, its specification, and its tag at the same place, so they won't be mixed up"""
28  def __init__ (self, folder,folderName,spec,tag):
29  self.folder=folder
30  self.folderName=folderName
31  self.spec=spec
32  self.tag=tag
33 
34 def runLBtoDB(run,lb):
35  """Turns run number and lumibock into integrer needed by the database"""
36  return (run<<32) + lb
37 
38 def makeFolderAndSpec(db,folderName,tag):
39  """A function that will ensure a folder is in the database, it creates it if necessary. Also defines content of the folders. There are two folders: one for local constants and one for global constants. They both contain single entry of a long string"""
40 
41  spec=cool.RecordSpecification()
42 
43  # each folder contain just a single entry, this string will be JSON entry
44  spec.extend("data",cool.StorageType.String64k)
45 
46  runLumi=True
47 
48  # if there are more channels, use "CondAttrListCollection"; if there is only one channel, use "AthenaAttributeList"
49  # it's also possible to use "CondAttrListCollection" if there's only one channel
50  folder=AtlCoolLib.ensureFolder(db,folderName,spec,AtlCoolLib.athenaDesc(runLumi,'CondAttrListCollection'),cool.FolderVersioning.MULTI_VERSION)
51 
52  if(folder is None):
53  sys.exit(1)
54 
55  return folderBulk(folder, folderName, spec, tag)
56 
57 class AFPDBDict():
58  """A class to create a dictionary, fill it with zeros in the constructor and to overwrite zeros later"""
59  def __init__ (self, folderBlk):
60  if(folderBlk.folderName=="/FWD/Onl/AFP/Align/Local"):
61  emptydict={"stationID":0, "layerID":-1, "shiftX":0.0, "shiftY":0.0, "shiftZ":0.0, "alpha":0.0, "beta":0.0, "gamma":0.0}
62  elif(folderBlk.folderName=="/FWD/Onl/AFP/Align/Global"):
63  emptydict={"stationID":0, "alignType":"None", "shiftX":0.0, "shiftY":0.0, "shiftZ":0.0, "alpha":0.0, "beta":0.0, "gamma":0.0}
64  else:
65  print ("unknown folder %s, please edit \"AFPDBDict\" class constructor, exiting now" % folderBlk.folderName)
66  sys.exit(1)
67 
68  self.mydict={"author":"Petr Balek",
69  "version":"AFP_DB_v2",
70  "nchannels":16,
71  "data": dict.fromkeys(range(0, 16))}
72 
73  for i in range(0, 16):
74  self.mydict["data"][i]=copy.deepcopy(emptydict)
75  self.mydict["data"][i]["stationID"]=i//4
76  if(folderBlk.folderName=="/FWD/Onl/AFP/Align/Local"):
77  self.mydict["data"][i]["layerID"]=i%4
78  if(folderBlk.folderName=="/FWD/Onl/AFP/Align/Global"):
79  if i%4==0: self.mydict["data"][i]["alignType"]="tracker"
80  if i%4==1: self.mydict["data"][i]["alignType"]="beam"
81  if i%4==2: self.mydict["data"][i]["alignType"]="RP"
82  if i%4==3: self.mydict["data"][i]["alignType"]="correction"
83 
84  def append(self, stationID, layerID=-1, alignType="None", shiftX=0.0, shiftY=0.0, shiftZ=0.0, alpha=0.0, beta=0.0, gamma=0.0):
85  """A function that overwrites one slice of the alignment constants in the dictionary. Local constants have to have layerID defined, while alignType is undefined. Global constants have to have alignType defined (tracker/RP/beam/correction) and layerID undefined."""
86 
87  # perform some simple check so basic mistakes are avoided
88  if(layerID==-1 and alignType=="None"):
89  print ("cannot save payload, got layerID=%d and alignType=%s; one of them has to be specified" % layerID, alignType)
90  sys.exit(1)
91  elif(layerID!=-1 and alignType!="None"):
92  print ("cannot save payload, got layerID=%d and alignType=%s; one of them should not be specified" % layerID, alignType)
93  sys.exit(1)
94 
95  if(stationID<0 or stationID>=4):
96  print ("cannot save payload, got stationID=%d, unknown" % stationID)
97  sys.exit(1)
98 
99  channel=0
100  # station 0 occupies channels 0-3, station 1 occupies channels 4-7, ..., and station 3 occupies channels 12-15
101  # if you are insterested in e.g. "beam" constants, look at channels 1, 5, 9, and 13
102  if(alignType!="None"):
103  channel=stationID*4
104  if(alignType=="tracker"):
105  channel+=0
106  elif(alignType=="beam"):
107  channel+=1
108  elif(alignType=="RP"):
109  channel+=2
110  elif(alignType=="correction"):
111  channel+=3
112  else:
113  print ("cannot save payload, got alignType=%s, unknown" % alignType)
114  sys.exit(1)
115 
116  # overwrite it
117  self.mydict["data"][channel]['alignType']=alignType
118 
119  # station 0 again occupies channels 0-3 etc.
120  if(layerID!=-1):
121  channel=stationID*4
122  if(0<=layerID and layerID<4):
123  channel+=layerID
124  else:
125  print ("cannot save payload, got layerID=%d, unknown" % layerID)
126  sys.exit(1)
127 
128  # overwrite it
129  self.mydict["data"][channel]['layerID']=layerID
130 
131  # overwrite it
132  mydict_helper=self.mydict["data"][channel]
133  mydict_helper['shiftX'], mydict_helper['shiftY'], mydict_helper['shiftZ'] = shiftX, shiftY, shiftZ
134  mydict_helper['alpha'], mydict_helper['beta'], mydict_helper['gamma'] = alpha, beta, gamma
135  mydict_helper['stationID']=stationID
136 
137 
138  def savePayload(self, folderBlk, fromRun=-2, fromLB=0):
139  """A function to transform the dictionary to JSON and save it in IOV from a given run and LB; upper limits are undefined and the maximum value (until beginning of a next entry) is used."""
140 
141  # perform some simple check so basic mistakes are avoided
142  if(fromRun<=0):
143  print ("cannot save payload, got fromRun=%d, it has to be positive" % fromRun)
144  sys.exit(1)
145 
146  # transform run nr. and LB to the right integers
147  since=runLBtoDB(run=fromRun,lb=fromLB)
148  until=cool.ValidityKeyMax
149 
150  # provided set of constants have to be the right one for the provided specification
151  payload=cool.Record(folderBlk.spec)
152  # transform dictionary to JSON
153  payload["data"]=json.dumps(self.mydict, indent = 1)
154  # save everything (that "0" stands for channel nr. 0, there is only 1 real channel in the DB)
155  folderBlk.folder.storeObject(since,until,payload,0,folderBlk.tag)
156 
157 
158 def main():
159  dbFile = "Example.db"
160  dbName = "CONDBR2"
161 
162  # remove the old db file so that we can write the new one
163  try:
164  import os
165  os.remove(dbFile)
166  except IOError:
167  pass
168 
169  # get database service and open database
170  dbSvc = cool.DatabaseSvcFactory.databaseService()
171 
172  # database accessed via physical name
173  dbString = "sqlite://;schema=%s;dbname=%s" % (dbFile, dbName)
174  try:
175  db = dbSvc.createDatabase(dbString)
176  except Exception as e:
177  print ('Problem creating database', e)
178  sys.exit(-1)
179  print ("Created database", dbString)
180 
181  # define the folder in the database, its specification and its tag
182  folderBlkLoc_03=makeFolderAndSpec(db,folderName="/FWD/Onl/AFP/Align/Local", tag="AFPAlignLoc-03")
183  folderBlkGlob_03=makeFolderAndSpec(db,folderName="/FWD/Onl/AFP/Align/Global", tag="AFPAlignGlob-03")
184 
185  # copy everything from the xml file here
186  # https://gitlab.cern.ch/afp/AfpAnalysisToolbox/-/blob/master/AfpAnalysisTools/share/align.xml
187  # zeros for Run3; RP constants from https://indico.cern.ch/event/1138072/contributions/4774895/attachments/2405515/4114924/Trzebinski_ARP_Run3_Optics.pdf
188  # "toRun" is not used but it's kept here for better clarity
189 
190 
191  # update July 30, 2021
192  fromRun = 203302
193  myDict = AFPDBDict(folderBlk=folderBlkLoc_03)
194  myDict.savePayload(folderBlk=folderBlkLoc_03, fromRun=fromRun)
195 
196  fromRun = 329484
197  myDict = AFPDBDict(folderBlkLoc_03)
198  myDict.append(stationID=0, layerID=1, shiftX=17.1313e-3, shiftY=-46.7438e-3, shiftZ=0.0000, alpha=2.9785e-3, beta=0.0000, gamma=0.0000)
199  myDict.append(stationID=0, layerID=2, shiftX=15.7960e-3, shiftY=-53.7707e-3, shiftZ=0.0000, alpha=3.3048e-3, beta=0.0000, gamma=0.0000)
200  myDict.append(stationID=0, layerID=3, shiftX=0.0000, shiftY=0.0000, shiftZ=0.0000, alpha=0.0000, beta=0.0000, gamma=0.0000)
201  myDict.append(stationID=1, layerID=1, shiftX=138.0070e-3, shiftY=6.0528e-3, shiftZ=0.0000, alpha=-1.4420e-3, beta=0.0000, gamma=0.0000)
202  myDict.append(stationID=1, layerID=2, shiftX=-80.6720e-3, shiftY=24.1310e-3, shiftZ=0.0000, alpha=-3.6605e-3, beta=0.0000, gamma=0.0000)
203  myDict.append(stationID=1, layerID=3, shiftX=-51.5111e-3, shiftY=-32.9151e-3, shiftZ=0.0000, alpha=1.0762e-3, beta=0.0000, gamma=0.0000)
204  myDict.append(stationID=2, layerID=1, shiftX=149.6927e-3, shiftY=103.5674e-3, shiftZ=0.0000, alpha=-3.9565e-3, beta=0.0000, gamma=0.0000)
205  myDict.append(stationID=2, layerID=2, shiftX=144.1316e-3, shiftY=88.0891e-3, shiftZ=0.0000, alpha=3.3219e-3, beta=0.0000, gamma=0.0000)
206  myDict.append(stationID=2, layerID=3, shiftX=47.8090e-3, shiftY=153.5737e-3, shiftZ=0.0000, alpha=5.1961e-3, beta=0.0000, gamma=0.0000)
207  myDict.append(stationID=3, layerID=1, shiftX=0.0000, shiftY=0.0000, shiftZ=0.0000, alpha=0.0000, beta=0.0000, gamma=0.0000)
208  myDict.append(stationID=3, layerID=2, shiftX=-153.0397e-3,shiftY=132.8483e-3, shiftZ=0.0000, alpha=-3.9787e-3, beta=0.0000, gamma=0.0000)
209  myDict.append(stationID=3, layerID=3, shiftX=13.9500e-3, shiftY=136.9500e-3, shiftZ=0.0000, alpha=0.3829e-3, beta=0.0000, gamma=0.0000)
210  myDict.savePayload(folderBlk=folderBlkLoc_03, fromRun=fromRun)
211 
212  fromRun = 413300
213  myDict = AFPDBDict(folderBlk=folderBlkLoc_03)
214  myDict.savePayload(folderBlk=folderBlkLoc_03, fromRun=fromRun)
215 
216 
217  # fromRun, toRun = 203302, 203302
218  fromRun = 203302
219  myDict = AFPDBDict(folderBlk=folderBlkGlob_03)
220  myDict.append(stationID=0, alignType="RP", shiftX=-2.34, shiftY=-13.22)
221  myDict.append(stationID=1, alignType="RP", shiftX=-3.68, shiftY=-13.28)
222  myDict.append(stationID=2, alignType="RP", shiftX=-3.61, shiftY=-10.09)
223  myDict.append(stationID=3, alignType="RP", shiftX=-2.39, shiftY=-10.53)
224  myDict.savePayload(folderBlk=folderBlkGlob_03, fromRun=fromRun)
225 
226  # fromRun, toRun = 329484, 330470
227  fromRun = 329484
228  myDict = AFPDBDict(folderBlk=folderBlkGlob_03)
229  myDict.append(stationID=0, alignType="tracker", shiftX=-0.5)
230  myDict.append(stationID=1, alignType="tracker", shiftX=-0.5)
231  myDict.append(stationID=2, alignType="tracker", shiftX=-0.5)
232  myDict.append(stationID=3, alignType="tracker", shiftX=-0.5)
233  myDict.append(stationID=0, alignType="beam", shiftX=-1.045)
234  myDict.append(stationID=1, alignType="beam", shiftX=-0.864)
235  myDict.append(stationID=2, alignType="beam", shiftX=-1.155)
236  myDict.append(stationID=3, alignType="beam", shiftX=-0.891)
237  myDict.append(stationID=0, alignType="RP", shiftX=-3.16)
238  myDict.append(stationID=1, alignType="RP", shiftX=-4.07)
239  myDict.append(stationID=2, alignType="RP", shiftX=-4.26)
240  myDict.append(stationID=3, alignType="RP", shiftX=-2.93)
241  myDict.append(stationID=0, alignType="correction", shiftX=-0.420)
242  myDict.append(stationID=1, alignType="correction", shiftX=-0.320)
243  myDict.append(stationID=2, alignType="correction", shiftX=-0.220)
244  myDict.append(stationID=3, alignType="correction", shiftX=-0.320)
245  myDict.savePayload(folderBlk=folderBlkGlob_03, fromRun=fromRun)
246 
247  # fromRun, toRun = 331020, 335302
248  fromRun = 331020
249  myDict = AFPDBDict(folderBlk=folderBlkGlob_03)
250  myDict.append(stationID=0, alignType="tracker", shiftX=-0.5)
251  myDict.append(stationID=1, alignType="tracker", shiftX=-0.5)
252  myDict.append(stationID=2, alignType="tracker", shiftX=-0.5)
253  myDict.append(stationID=3, alignType="tracker", shiftX=-0.5)
254  myDict.append(stationID=0, alignType="beam", shiftX=-1.045)
255  myDict.append(stationID=1, alignType="beam", shiftX=-0.864)
256  myDict.append(stationID=2, alignType="beam", shiftX=-1.155)
257  myDict.append(stationID=3, alignType="beam", shiftX=-0.891)
258  myDict.append(stationID=0, alignType="RP", shiftX=-2.65)
259  myDict.append(stationID=1, alignType="RP", shiftX=-3.57)
260  myDict.append(stationID=2, alignType="RP", shiftX=-3.76)
261  myDict.append(stationID=3, alignType="RP", shiftX=-2.43)
262  myDict.append(stationID=0, alignType="correction", shiftX=-0.420)
263  myDict.append(stationID=1, alignType="correction", shiftX=-0.320)
264  myDict.append(stationID=2, alignType="correction", shiftX=-0.220)
265  myDict.append(stationID=3, alignType="correction", shiftX=-0.320)
266  myDict.savePayload(folderBlk=folderBlkGlob_03, fromRun=fromRun)
267 
268  # fromRun, toRun = 336288, 341692
269  fromRun = 336288
270  myDict = AFPDBDict(folderBlk=folderBlkGlob_03)
271  myDict.append(stationID=0, alignType="tracker", shiftX=-0.5)
272  myDict.append(stationID=1, alignType="tracker", shiftX=-0.5)
273  myDict.append(stationID=2, alignType="tracker", shiftX=-0.5)
274  myDict.append(stationID=3, alignType="tracker", shiftX=-0.5)
275  myDict.append(stationID=0, alignType="beam", shiftX=-1.045)
276  myDict.append(stationID=1, alignType="beam", shiftX=-0.864)
277  myDict.append(stationID=2, alignType="beam", shiftX=-1.155)
278  myDict.append(stationID=3, alignType="beam", shiftX=-0.891)
279  myDict.append(stationID=0, alignType="RP", shiftX=-2.38)
280  myDict.append(stationID=1, alignType="RP", shiftX=-3.60)
281  myDict.append(stationID=2, alignType="RP", shiftX=-3.87)
282  myDict.append(stationID=3, alignType="RP", shiftX=-2.23)
283  myDict.append(stationID=0, alignType="correction", shiftX=-0.420)
284  myDict.append(stationID=1, alignType="correction", shiftX=-0.320)
285  myDict.append(stationID=2, alignType="correction", shiftX=-0.220)
286  myDict.append(stationID=3, alignType="correction", shiftX=-0.320)
287  myDict.savePayload(folderBlk=folderBlkGlob_03, fromRun=fromRun)
288 
289  # fromRun, toRun = 347955, 348002
290  fromRun = 347955
291  myDict = AFPDBDict(folderBlk=folderBlkGlob_03)
292  myDict.append(stationID=0, alignType="RP", shiftX=-2.34, shiftY=-13.22)
293  myDict.append(stationID=1, alignType="RP", shiftX=-3.68, shiftY=-13.28)
294  myDict.append(stationID=2, alignType="RP", shiftX=-6.46, shiftY=-5.47)
295  myDict.append(stationID=3, alignType="RP", shiftX=-6.79, shiftY=-5.03)
296  myDict.savePayload(folderBlk=folderBlkGlob_03, fromRun=fromRun)
297 
298  fromRun = 413300
299  myDict = AFPDBDict(folderBlk=folderBlkGlob_03)
300  myDict.append(stationID=0, alignType="tracker", shiftX=-0.5)
301  myDict.append(stationID=1, alignType="tracker", shiftX=-0.5)
302  myDict.append(stationID=2, alignType="tracker", shiftX=-0.5)
303  myDict.append(stationID=3, alignType="tracker", shiftX=-0.5)
304  myDict.append(stationID=0, alignType="RP", shiftX=-1.509)
305  myDict.append(stationID=1, alignType="RP", shiftX=-2.315)
306  myDict.append(stationID=2, alignType="RP", shiftX=-2.325)
307  myDict.append(stationID=3, alignType="RP", shiftX=-1.5)
308  myDict.savePayload(folderBlk=folderBlkGlob_03, fromRun=fromRun)
309 
310  print ("\nClose database")
311  db.closeDatabase()
312 
313 
314 if __name__=="__main__":
315  main()
AFPAlignDBCreate.folderBulk.__init__
def __init__(self, folder, folderName, spec, tag)
Definition: AFPAlignDBCreate.py:28
AFPAlignDBCreate.AFPDBDict
Definition: AFPAlignDBCreate.py:57
AFPAlignDBCreate.AFPDBDict.__init__
def __init__(self, folderBlk)
Definition: AFPAlignDBCreate.py:59
AFPAlignDBCreate.AFPDBDict.mydict
mydict
Definition: AFPAlignDBCreate.py:68
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:194
AFPAlignDBCreate.folderBulk.spec
spec
Definition: AFPAlignDBCreate.py:31
AFPAlignDBCreate.folderBulk.tag
tag
Definition: AFPAlignDBCreate.py:32
AFPAlignDBCreate.folderBulk.folder
folder
Definition: AFPAlignDBCreate.py:29
AFPAlignDBCreate.AFPDBDict.append
def append(self, stationID, layerID=-1, alignType="None", shiftX=0.0, shiftY=0.0, shiftZ=0.0, alpha=0.0, beta=0.0, gamma=0.0)
Definition: AFPAlignDBCreate.py:84
AFPAlignDBCreate.AFPDBDict.savePayload
def savePayload(self, folderBlk, fromRun=-2, fromLB=0)
Definition: AFPAlignDBCreate.py:138
AFPAlignDBCreate.folderBulk.folderName
folderName
Definition: AFPAlignDBCreate.py:30
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:567
AFPAlignDBCreate.main
def main()
Definition: AFPAlignDBCreate.py:158
AFPAlignDBCreate.makeFolderAndSpec
def makeFolderAndSpec(db, folderName, tag)
Definition: AFPAlignDBCreate.py:38
AFPAlignDBCreate.runLBtoDB
def runLBtoDB(run, lb)
Definition: AFPAlignDBCreate.py:34
AFPAlignDBCreate.folderBulk
Definition: AFPAlignDBCreate.py:26