ATLAS Offline Software
Loading...
Searching...
No Matches
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
18import sys, json, copy
19from CoolConvUtilities import AtlCoolLib
20from PyCool import cool
21
22class 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
30def runLBtoDB(run,lb):
31 """Turns run number and lumibock into integrer needed by the database"""
32 return (run<<32) + lb
33
34def 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
51class 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
131def 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
205if __name__=="__main__":
206 main()
if(febId1==febId2)
__init__(self, folder, folderName, spec, tag)
makeFolderAndSpec(db, folderName, tag)