ATLAS Offline Software
AFPToFDBCreate.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 AFPToFDBCreate.py
6 # author Petr Balek <petr.balek@cern.ch>
7 # date 2022-06-02
8 #
9 # brief A python script that generates COOL database with ToF parameters for AFP.
10 # usage 0. setup Athena environment (setupATLAS, asetup ...)
11 # 1. run this script:
12 # python AFPToFDBCreate.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 import sys, json, copy
19 from CoolConvUtilities import AtlCoolLib
20 from PyCool import cool
21 
22 class folderBulk():
23  """A class to store database folder, its specification, and its tag at the same place, so they won't be mixed up"""
24  def __init__ (self, folder,folderName,spec,tag):
25  self.folder=folder
26  self.folderName=folderName
27  self.spec=spec
28  self.tag=tag
29 
30 def runLBtoDB(run,lb):
31  """Turns run number and lumibock into integrer needed by the database"""
32  return (run<<32) + lb
33 
34 def makeFolderAndSpec(db,folderName,tag):
35  """A function that will ensure a folder is in the database, it creates it if necessary. Also defines content of the folders. It contains only a single entry of a long string"""
36 
37  spec=cool.RecordSpecification()
38 
39  # each folder contain just a single entry, this string will be JSON entry
40  spec.extend("data",cool.StorageType.String64k)
41 
42  runLumi=True
43 
44  # if there are more channels, use "CondAttrListCollection"; if there is only one channel, use "AthenaAttributeList"
45  # it's also possible to use "CondAttrListCollection" if there's only one channel
46  folder=AtlCoolLib.ensureFolder(db,folderName,spec,AtlCoolLib.athenaDesc(runLumi,'CondAttrListCollection'),cool.FolderVersioning.MULTI_VERSION)
47 
48  if(folder is None):
49  sys.exit(1)
50 
51  return folderBulk(folder, folderName, spec, tag)
52 
53 class AFPDBDict():
54  """A class to create a dictionary, fill it with zeros in the constructor and to overwrite zeros later"""
55  def __init__ (self, folderBlk):
56  if(folderBlk.folderName=="/FWD/Onl/AFP/ToFParameters/Local"):
57  emptydict={"stationID":0, "trainID":-1, "barID":-1, "barWeight":1.0, "barTimeOffset":0.0}
58  nchannels=32
59  elif(folderBlk.folderName=="/FWD/Onl/AFP/ToFParameters/Vertex"):
60  emptydict={"stationID":0, "timeGlobalOffset":0.0, "timeOffset":(0.0,0.0,0.0,0.0), "timeSlope":(0.0,0.0,0.0,0.0), "trainEdge":(0.0,0.0,0.0,0.0,0.0)}
61  nchannels=2
62  else:
63  print ("unknown folder %s, please edit \"AFPDBDict\" class constructor, exiting now" % folderBlk.folderName)
64  sys.exit(1)
65 
66  self.mydict={"author":"Petr Balek",
67  "version":"AFP_DB_v2",
68  "nchannels":nchannels,
69  "data": dict.fromkeys(range(0, nchannels))}
70 
71  for i in range(0, nchannels):
72  self.mydict["data"][i]=copy.deepcopy(emptydict)
73  if(folderBlk.folderName=="/FWD/Onl/AFP/ToFParameters/Local"):
74  self.mydict["data"][i]["stationID"]=(i//16)*3
75  self.mydict["data"][i]["trainID"]=(i%16)//4
76  self.mydict["data"][i]["barID"]=i%4
77  if(folderBlk.folderName=="/FWD/Onl/AFP/ToFParameters/Vertex"):
78  self.mydict["data"][i]["stationID"]=i*3
79 
80  def append(self, stationID, trainID=-1, barID=-1, barWeight=1.0, barTimeOffset=0.0, timeGlobalOffset=0.0, timeOffset=(0.,0.,0.,0.), timeSlope=(0.,0.,0.,0.), trainEdge=(0.,0.,0.,0.,0.)):
81  """A function that overwrites one slice of the ToF parameters in the dictionary. Local ToF parameters have to have both trainID and barID defined, Vertex ToF parameters neither."""
82 
83  # perform some simple check so basic mistakes are avoided
84  if(stationID!=0 and stationID!=3):
85  print ("cannot save payload, got stationID=%d, unknown" % stationID)
86  sys.exit(1)
87 
88  trainValid=True if 0<=trainID and trainID<4 else False
89  barValid = True if 0<=barID and barID<4 else False
90  if(trainValid!=barValid):
91  # a.k.a. "trainValid xor barValid"
92  print ("cannot save payload, got trainID=%d, barID=%d" % (trainID,barID))
93  sys.exit(1)
94 
95  if trainValid:
96  # local ToF parameters
97  # station 0 occupies channels 0-16, station 3 occupies channels 17-32
98  # train 0 occupies channels 0-3 / 17-20, train 1 occupies channels 4-7 / 21-24, ...
99  # bar 0 occupies the first channel of the train, bar 1 occupies the second channel of the train, ...
100  channel=(stationID//3)*16+trainID*4+barID
101 
102  # overwrite it
103  mydict_helper=self.mydict["data"][channel]
104  mydict_helper['stationID'], mydict_helper['trainID'], mydict_helper['barID'] = stationID, trainID, barID
105  mydict_helper['barWeight'], mydict_helper['barTimeOffset'] = barWeight, barTimeOffset
106  else:
107  # vertex ToF parameters
108  # station 0 occupies channel 0, station 3 occupies channels 1
109  channel=stationID//3
110 
111  # overwrite it
112  mydict_helper=self.mydict["data"][channel]
113  mydict_helper['stationID']=stationID
114  mydict_helper['timeGlobalOffset'], mydict_helper['timeOffset'] = timeGlobalOffset, timeOffset
115  mydict_helper['timeSlope'], mydict_helper['trainEdge'] = timeSlope, trainEdge
116 
117 
118  def savePayload(self, folderBlk, fromRun=-2, fromLB=0):
119  """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."""
120 
121  # perform some simple check so basic mistakes are avoided
122  if(fromRun<=0):
123  print ("cannot save payload, got fromRun=%d, it has to be positive" % fromRun)
124  sys.exit(1)
125 
126  # transform run nr. and LB to the right integers
127  since=runLBtoDB(run=fromRun,lb=fromLB)
128  until=cool.ValidityKeyMax
129 
130  # provided set of constants have to be the right one for the provided specification
131  payload=cool.Record(folderBlk.spec)
132  # transform dictionary to JSON
133  payload["data"]=json.dumps(self.mydict, indent = 1)
134  # save everything (that "0" stands for channel nr. 0, there is only 1 real channel in the DB)
135  folderBlk.folder.storeObject(since,until,payload,0,folderBlk.tag)
136 
137 
138 def main():
139  dbFile = "Example.db"
140  dbName = "CONDBR2"
141 
142  # remove the old db file so that we can write the new one
143  try:
144  import os
145  os.remove(dbFile)
146  except IOError:
147  pass
148 
149  # get database service and open database
150  dbSvc = cool.DatabaseSvcFactory.databaseService()
151 
152  # database accessed via physical name
153  dbString = "sqlite://;schema=%s;dbname=%s" % (dbFile, dbName)
154  try:
155  db = dbSvc.createDatabase(dbString)
156  except Exception as e:
157  print ('Problem creating database', e)
158  sys.exit(-1)
159  print ("Created database", dbString)
160 
161  # define the folder in the database, its specification and its tag
162  folderBlkLoc_01=makeFolderAndSpec(db,folderName="/FWD/Onl/AFP/ToFParameters/Local", tag="AFPToFLoc-01")
163  folderBlkVtx_01=makeFolderAndSpec(db,folderName="/FWD/Onl/AFP/ToFParameters/Vertex", tag="AFPToFVtx-01")
164 
165 
166  # have the same IOV as alignment
167  fromRun = 203302
168  myDict = AFPDBDict(folderBlkLoc_01)
169  myDict.append(stationID=0, trainID=0, barID=0, barWeight=1.0, barTimeOffset=1494.0)
170  myDict.append(stationID=0, trainID=0, barID=1, barWeight=1.0, barTimeOffset=1500.0)
171  myDict.append(stationID=0, trainID=0, barID=2, barWeight=1.0, barTimeOffset=1500.0)
172  myDict.append(stationID=0, trainID=0, barID=3, barWeight=1.0, barTimeOffset=1500.0)
173  myDict.append(stationID=0, trainID=1, barID=0, barWeight=1.0, barTimeOffset=1500.0)
174  myDict.append(stationID=0, trainID=1, barID=1, barWeight=1.0, barTimeOffset=1500.0)
175  myDict.append(stationID=0, trainID=1, barID=2, barWeight=1.0, barTimeOffset=1500.0)
176  myDict.append(stationID=0, trainID=1, barID=3, barWeight=1.0, barTimeOffset=1500.0)
177  myDict.append(stationID=0, trainID=2, barID=0, barWeight=1.0, barTimeOffset=1500.0)
178  myDict.append(stationID=0, trainID=2, barID=1, barWeight=1.0, barTimeOffset=1500.0)
179  myDict.append(stationID=0, trainID=2, barID=2, barWeight=1.0, barTimeOffset=1500.0)
180  myDict.append(stationID=0, trainID=2, barID=3, barWeight=1.0, barTimeOffset=1500.0)
181  myDict.append(stationID=0, trainID=3, barID=0, barWeight=1.0, barTimeOffset=1500.0)
182  myDict.append(stationID=0, trainID=3, barID=1, barWeight=1.0, barTimeOffset=1500.0)
183  myDict.append(stationID=0, trainID=3, barID=2, barWeight=1.0, barTimeOffset=1500.0)
184  myDict.append(stationID=0, trainID=3, barID=3, barWeight=1.0, barTimeOffset=1500.0)
185  myDict.append(stationID=3, trainID=0, barID=0, barWeight=1.0, barTimeOffset=1500.0)
186  myDict.append(stationID=3, trainID=0, barID=1, barWeight=1.0, barTimeOffset=1500.0)
187  myDict.append(stationID=3, trainID=0, barID=2, barWeight=1.0, barTimeOffset=1500.0)
188  myDict.append(stationID=3, trainID=0, barID=3, barWeight=1.0, barTimeOffset=1500.0)
189  myDict.append(stationID=3, trainID=1, barID=0, barWeight=1.0, barTimeOffset=1500.0)
190  myDict.append(stationID=3, trainID=1, barID=1, barWeight=1.0, barTimeOffset=1500.0)
191  myDict.append(stationID=3, trainID=1, barID=2, barWeight=1.0, barTimeOffset=1500.0)
192  myDict.append(stationID=3, trainID=1, barID=3, barWeight=1.0, barTimeOffset=1500.0)
193  myDict.append(stationID=3, trainID=2, barID=0, barWeight=1.0, barTimeOffset=1500.0)
194  myDict.append(stationID=3, trainID=2, barID=1, barWeight=1.0, barTimeOffset=1500.0)
195  myDict.append(stationID=3, trainID=2, barID=2, barWeight=1.0, barTimeOffset=1500.0)
196  myDict.append(stationID=3, trainID=2, barID=3, barWeight=1.0, barTimeOffset=1500.0)
197  myDict.append(stationID=3, trainID=3, barID=0, barWeight=1.0, barTimeOffset=1500.0)
198  myDict.append(stationID=3, trainID=3, barID=1, barWeight=1.0, barTimeOffset=1500.0)
199  myDict.append(stationID=3, trainID=3, barID=2, barWeight=1.0, barTimeOffset=1500.0)
200  myDict.append(stationID=3, trainID=3, barID=3, barWeight=1.0, barTimeOffset=1500.0)
201  myDict.savePayload(folderBlk=folderBlkLoc_01, fromRun=fromRun)
202 
203 
204  # have the same IOV as alignment
205  fromRun = 203302
206  myDict = AFPDBDict(folderBlk=folderBlkVtx_01)
207  myDict.append(stationID=0, timeGlobalOffset=0.0, timeOffset=(64.,45.,25.,11.), timeSlope=(-7.3,-5.0,-4.0,-4.0), trainEdge=(-18.7,-13.2,-8.1,-4.0,-2.5))
208  myDict.append(stationID=3, timeGlobalOffset=5.0, timeOffset=( 2., 9.,14.,12.), timeSlope=( 4.0, 5.0, 3.0, 6.0), trainEdge=(-18.7,-13.2,-8.1,-4.0,-2.5))
209  myDict.savePayload(folderBlk=folderBlkVtx_01, fromRun=fromRun)
210 
211 
212  print ("\nClose database")
213  db.closeDatabase()
214 
215 
216 if __name__=="__main__":
217  main()
AFPToFDBCreate.folderBulk.folder
folder
Definition: AFPToFDBCreate.py:25
AFPToFDBCreate.AFPDBDict
Definition: AFPToFDBCreate.py:53
AFPToFDBCreate.folderBulk.spec
spec
Definition: AFPToFDBCreate.py:27
AFPToFDBCreate.AFPDBDict.mydict
mydict
Definition: AFPToFDBCreate.py:66
AFPToFDBCreate.folderBulk.__init__
def __init__(self, folder, folderName, spec, tag)
Definition: AFPToFDBCreate.py:24
AFPToFDBCreate.folderBulk.tag
tag
Definition: AFPToFDBCreate.py:28
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
AFPToFDBCreate.folderBulk
Definition: AFPToFDBCreate.py:22
AFPToFDBCreate.folderBulk.folderName
folderName
Definition: AFPToFDBCreate.py:26
AFPToFDBCreate.AFPDBDict.savePayload
def savePayload(self, folderBlk, fromRun=-2, fromLB=0)
Definition: AFPToFDBCreate.py:118
AFPToFDBCreate.AFPDBDict.__init__
def __init__(self, folderBlk)
Definition: AFPToFDBCreate.py:55
AFPToFDBCreate.main
def main()
Definition: AFPToFDBCreate.py:138
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:567
AFPToFDBCreate.makeFolderAndSpec
def makeFolderAndSpec(db, folderName, tag)
Definition: AFPToFDBCreate.py:34
AFPToFDBCreate.runLBtoDB
def runLBtoDB(run, lb)
Definition: AFPToFDBCreate.py:30
AFPToFDBCreate.AFPDBDict.append
def append(self, stationID, trainID=-1, barID=-1, barWeight=1.0, barTimeOffset=0.0, timeGlobalOffset=0.0, timeOffset=(0., 0., 0., 0.), timeSlope=(0., 0., 0., 0.), trainEdge=(0., 0., 0., 0., 0.))
Definition: AFPToFDBCreate.py:80