ATLAS Offline Software
AFPToFMCDBCreate.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 AFPToFMCDBCreate.py
6 # author Petr Balek <petr.balek@cern.ch>
7 # date 2022-07-19
8 #
9 # brief A python script that generates COOL database with ToF parameters for AFP. This version of DB is intended to be used in MC simulations. Each tag has one entry with IOV from 0 to infinite. The tags reflect various alignments through data-taking.
10 # usage 0. setup Athena environment (setupATLAS, asetup ...)
11 # 1. run this script:
12 # python AFPToFMCDBCreate.py
13 # 2. check the output:
14 # AtlCoolConsole.py "sqlite://;schema=ExampleMC.db;dbname=OFLP200"
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  # if there are more channels, use "CondAttrListCollection"; if there is only one channel, use "AthenaAttributeList"
43  # it's also possible to use "CondAttrListCollection" if there's only one channel
44  folder=AtlCoolLib.ensureFolder(db,folderName,spec,AtlCoolLib.athenaDesc(True,'CondAttrListCollection'),cool.FolderVersioning.MULTI_VERSION)
45 
46  if(folder is None):
47  sys.exit(1)
48 
49  return folderBulk(folder, folderName, spec, tag)
50 
51 class AFPDBDict():
52  """A class to create a dictionary, fill it with zeros in the constructor and to overwrite zeros later"""
53  def __init__ (self, folderBlk):
54  if(folderBlk.folderName=="/FWD/AFP/ToFParameters/Local"):
55  emptydict={"stationID":0, "trainID":-1, "barID":-1, "barWeight":1.0, "barTimeOffset":0.0}
56  nchannels=32
57  elif(folderBlk.folderName=="/FWD/AFP/ToFParameters/Vertex"):
58  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)}
59  nchannels=2
60  else:
61  print ("unknown folder %s, please edit \"AFPDBDict\" class constructor, exiting now" % folderBlk.folderName)
62  sys.exit(1)
63 
64  self.mydict={"author":"Petr Balek",
65  "version":"AFP_DB_v2",
66  "nchannels":nchannels,
67  "data": dict.fromkeys(range(0, nchannels))}
68 
69  for i in range(0, nchannels):
70  self.mydict["data"][i]=copy.deepcopy(emptydict)
71  if(folderBlk.folderName=="/FWD/AFP/ToFParameters/Local"):
72  self.mydict["data"][i]["stationID"]=(i//16)*3
73  self.mydict["data"][i]["trainID"]=(i%16)//4
74  self.mydict["data"][i]["barID"]=i%4
75  if(folderBlk.folderName=="/FWD/AFP/ToFParameters/Vertex"):
76  self.mydict["data"][i]["stationID"]=i*3
77 
78  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.)):
79  """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."""
80 
81  # perform some simple check so basic mistakes are avoided
82  if(stationID!=0 and stationID!=3):
83  print ("cannot save payload, got stationID=%d, unknown" % stationID)
84  sys.exit(1)
85 
86  trainValid=True if 0<=trainID and trainID<4 else False
87  barValid = True if 0<=barID and barID<4 else False
88  if(trainValid!=barValid):
89  # a.k.a. "trainValid xor barValid"
90  print ("cannot save payload, got trainID=%d, barID=%d" % (trainID,barID))
91  sys.exit(1)
92 
93  if trainValid:
94  # local ToF parameters
95  # station 0 occupies channels 0-16, station 3 occupies channels 17-32
96  # train 0 occupies channels 0-3 / 17-20, train 1 occupies channels 4-7 / 21-24, ...
97  # bar 0 occupies the first channel of the train, bar 1 occupies the second channel of the train, ...
98  channel=(stationID//3)*16+trainID*4+barID
99 
100  # overwrite it
101  mydict_helper=self.mydict["data"][channel]
102  mydict_helper['stationID'], mydict_helper['trainID'], mydict_helper['barID'] = stationID, trainID, barID
103  mydict_helper['barWeight'], mydict_helper['barTimeOffset'] = barWeight, barTimeOffset
104  else:
105  # vertex ToF parameters
106  # station 0 occupies channel 0, station 3 occupies channels 1
107  channel=stationID//3
108 
109  # overwrite it
110  mydict_helper=self.mydict["data"][channel]
111  mydict_helper['stationID']=stationID
112  mydict_helper['timeGlobalOffset'], mydict_helper['timeOffset'] = timeGlobalOffset, timeOffset
113  mydict_helper['timeSlope'], mydict_helper['trainEdge'] = timeSlope, trainEdge
114 
115 
116  def savePayload(self, folderBlk):
117  """A function to transform the dictionary to JSON and save it in IOV from 0 to infinity; technically, upper limits are undefined and the maximum value (until beginning of a next entry) is used."""
118 
119  # transform run nr. and LB to the right integers
120  since=runLBtoDB(0,0)
121  until=cool.ValidityKeyMax
122 
123  # provided set of constants have to be the right one for the provided specification
124  payload=cool.Record(folderBlk.spec)
125  # transform dictionary to JSON
126  payload["data"]=json.dumps(self.mydict, indent = 1)
127  # save everything (that "0" stands for channel nr. 0, there is only 1 real channel in the DB)
128  folderBlk.folder.storeObject(since,until,payload,0,folderBlk.tag)
129 
130 
131 def main():
132  dbFile = "ExampleMC.db"
133  dbName = "OFLP200"
134 
135  # remove the old db file so that we can write the new one
136  try:
137  import os
138  os.remove(dbFile)
139  except IOError:
140  pass
141 
142  # get database service and open database
143  dbSvc = cool.DatabaseSvcFactory.databaseService()
144 
145  # database accessed via physical name
146  dbString = "sqlite://;schema=%s;dbname=%s" % (dbFile, dbName)
147  try:
148  db = dbSvc.createDatabase(dbString)
149  except Exception as e:
150  print ('Problem creating database', e)
151  sys.exit(-1)
152  print ("Created database", dbString)
153 
154  # define the folder in the database, its specification and its tag
155  folderBlkLoc_ideal_01=makeFolderAndSpec(db,folderName="/FWD/AFP/ToFParameters/Local", tag="AFPMCToFLoc-ideal-01")
156  folderBlkVtx_ideal_01=makeFolderAndSpec(db,folderName="/FWD/AFP/ToFParameters/Vertex", tag="AFPMCToFVtx-ideal-01")
157 
158 
159  myDict = AFPDBDict(folderBlkLoc_ideal_01)
160  myDict.append(stationID=0, trainID=0, barID=0, barWeight=1.0, barTimeOffset=1494.0)
161  myDict.append(stationID=0, trainID=0, barID=1, barWeight=1.0, barTimeOffset=1500.0)
162  myDict.append(stationID=0, trainID=0, barID=2, barWeight=1.0, barTimeOffset=1500.0)
163  myDict.append(stationID=0, trainID=0, barID=3, barWeight=1.0, barTimeOffset=1500.0)
164  myDict.append(stationID=0, trainID=1, barID=0, barWeight=1.0, barTimeOffset=1500.0)
165  myDict.append(stationID=0, trainID=1, barID=1, barWeight=1.0, barTimeOffset=1500.0)
166  myDict.append(stationID=0, trainID=1, barID=2, barWeight=1.0, barTimeOffset=1500.0)
167  myDict.append(stationID=0, trainID=1, barID=3, barWeight=1.0, barTimeOffset=1500.0)
168  myDict.append(stationID=0, trainID=2, barID=0, barWeight=1.0, barTimeOffset=1500.0)
169  myDict.append(stationID=0, trainID=2, barID=1, barWeight=1.0, barTimeOffset=1500.0)
170  myDict.append(stationID=0, trainID=2, barID=2, barWeight=1.0, barTimeOffset=1500.0)
171  myDict.append(stationID=0, trainID=2, barID=3, barWeight=1.0, barTimeOffset=1500.0)
172  myDict.append(stationID=0, trainID=3, barID=0, barWeight=1.0, barTimeOffset=1500.0)
173  myDict.append(stationID=0, trainID=3, barID=1, barWeight=1.0, barTimeOffset=1500.0)
174  myDict.append(stationID=0, trainID=3, barID=2, barWeight=1.0, barTimeOffset=1500.0)
175  myDict.append(stationID=0, trainID=3, barID=3, barWeight=1.0, barTimeOffset=1500.0)
176  myDict.append(stationID=3, trainID=0, barID=0, barWeight=1.0, barTimeOffset=1500.0)
177  myDict.append(stationID=3, trainID=0, barID=1, barWeight=1.0, barTimeOffset=1500.0)
178  myDict.append(stationID=3, trainID=0, barID=2, barWeight=1.0, barTimeOffset=1500.0)
179  myDict.append(stationID=3, trainID=0, barID=3, barWeight=1.0, barTimeOffset=1500.0)
180  myDict.append(stationID=3, trainID=1, barID=0, barWeight=1.0, barTimeOffset=1500.0)
181  myDict.append(stationID=3, trainID=1, barID=1, barWeight=1.0, barTimeOffset=1500.0)
182  myDict.append(stationID=3, trainID=1, barID=2, barWeight=1.0, barTimeOffset=1500.0)
183  myDict.append(stationID=3, trainID=1, barID=3, barWeight=1.0, barTimeOffset=1500.0)
184  myDict.append(stationID=3, trainID=2, barID=0, barWeight=1.0, barTimeOffset=1500.0)
185  myDict.append(stationID=3, trainID=2, barID=1, barWeight=1.0, barTimeOffset=1500.0)
186  myDict.append(stationID=3, trainID=2, barID=2, barWeight=1.0, barTimeOffset=1500.0)
187  myDict.append(stationID=3, trainID=2, barID=3, barWeight=1.0, barTimeOffset=1500.0)
188  myDict.append(stationID=3, trainID=3, barID=0, barWeight=1.0, barTimeOffset=1500.0)
189  myDict.append(stationID=3, trainID=3, barID=1, barWeight=1.0, barTimeOffset=1500.0)
190  myDict.append(stationID=3, trainID=3, barID=2, barWeight=1.0, barTimeOffset=1500.0)
191  myDict.append(stationID=3, trainID=3, barID=3, barWeight=1.0, barTimeOffset=1500.0)
192  myDict.savePayload(folderBlk=folderBlkLoc_ideal_01)
193 
194 
195  myDict = AFPDBDict(folderBlk=folderBlkVtx_ideal_01)
196  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))
197  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))
198  myDict.savePayload(folderBlk=folderBlkVtx_ideal_01)
199 
200 
201  print ("\nClose database")
202  db.closeDatabase()
203 
204 
205 if __name__=="__main__":
206  main()
AFPToFMCDBCreate.folderBulk.folderName
folderName
Definition: AFPToFMCDBCreate.py:26
AFPToFMCDBCreate.AFPDBDict.mydict
mydict
Definition: AFPToFMCDBCreate.py:64
AFPToFMCDBCreate.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: AFPToFMCDBCreate.py:78
AFPToFMCDBCreate.folderBulk.tag
tag
Definition: AFPToFMCDBCreate.py:28
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
AFPToFMCDBCreate.AFPDBDict.__init__
def __init__(self, folderBlk)
Definition: AFPToFMCDBCreate.py:53
AFPToFMCDBCreate.runLBtoDB
def runLBtoDB(run, lb)
Definition: AFPToFMCDBCreate.py:30
AFPToFMCDBCreate.makeFolderAndSpec
def makeFolderAndSpec(db, folderName, tag)
Definition: AFPToFMCDBCreate.py:34
AFPToFMCDBCreate.folderBulk.spec
spec
Definition: AFPToFMCDBCreate.py:27
AFPToFMCDBCreate.folderBulk.folder
folder
Definition: AFPToFMCDBCreate.py:25
AFPToFMCDBCreate.AFPDBDict.savePayload
def savePayload(self, folderBlk)
Definition: AFPToFMCDBCreate.py:116
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:567
AFPToFMCDBCreate.folderBulk
Definition: AFPToFMCDBCreate.py:22
AFPToFMCDBCreate.main
def main()
Definition: AFPToFMCDBCreate.py:131
AFPToFMCDBCreate.folderBulk.__init__
def __init__(self, folder, folderName, spec, tag)
Definition: AFPToFMCDBCreate.py:24
AFPToFMCDBCreate.AFPDBDict
Definition: AFPToFMCDBCreate.py:51