ATLAS Offline Software
Loading...
Searching...
No Matches
mergeEnergyRamps.py
Go to the documentation of this file.
2# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3#
4
5import ROOT
6import sys
7import time
8
9from PyCool import cool
10from optparse import OptionParser
11
12
14
15 def __init__(self):
16 self.coolIdPath=ROOT.PathResolver.find_calib_file("TrigT1Calo/COOLIdDump_v1.txt")
17 input = open(self.coolIdPath)
20
21 for line in input.readlines():
22 parts = line.split(' ')
23 emCool = parts[4].rstrip()
24 hadCool = parts[5].rstrip()
25 self.list_of_channels_em[(parts[0],parts[1])] = '0x'+emCool
26 self.list_of_channels_had[(parts[0],parts[1])] = '0x'+hadCool
27
28 input.close()
29
31
33 self.UNIX2COOL = 1000000000
34
35 # get database service and open database
36 dbSvc = cool.DatabaseSvcFactory.databaseService()
37
38 dbString = 'oracle://ATLAS_COOLPROD;schema=ATLAS_COOLONL_TRIGGER;dbname=CONDBR2'
39 try:
40 db = dbSvc.openDatabase(dbString, False)
41 except Exception as e:
42 print ('Error: Problem opening database', e)
43 sys.exit(1)
44
45 folder_name = "/TRIGGER/Receivers/RxPpmIdMap"
46 folder=db.getFolder(folder_name)
47
48 startUtime = int(time.time())
49 endUtime = int(time.time())
50 startValKey = startUtime * self.UNIX2COOL
51 endValKey = endUtime * self.UNIX2COOL
52 chsel = cool.ChannelSelection(0,sys.maxsize)
53
54 try:
55 itr=folder.browseObjects(startValKey, endValKey, chsel)
56 except Exception as e:
57 print (e)
58 sys.exit(1)
59
60 for row in itr:
61 ReceiverId = hex(int(row.channelId()))
62 payload = row.payload()
63 PPMId = hex(int(payload['ppmid']))
64 self.receiver_to_ppm_map[ReceiverId]= PPMId
65
66# print (self.receiver_to_ppm_map)
67 # close database
68 db.closeDatabase()
69
70
71 def getPPMfromReceiver(self,ReceiverId):
72
73 if ReceiverId in self.receiver_to_ppm_map:
74 return self.receiver_to_ppm_map[ReceiverId]
75 else:
76 return ''
77
78 def getReceiverfromPPM(self,PPMId,strategy_string=None):
79
80 ReceiverChannels = [item[0] for item in self.receiver_to_ppm_map.items() if item[1]==PPMId]
81
82 if strategy_string is None:
83 print (" Warning! in getReceiverfromPPM no runtype give, using default!")
84 return ReceiverChannels[0]
85
86 if self.isPPMFCAL(PPMId) and self.isCoolHad(PPMId): # pick correct FCAL23 channel
87
88 if strategy_string == "GainOneOvEmbFcalHighEta":
89 for channel in ReceiverChannels:
90 if self.getFCAL23RecEta(channel) == 'HighEta':
91 return channel
92 if strategy_string == "GainOneOvEmecFcalLowEta":
93 for channel in ReceiverChannels:
94 if self.getFCAL23RecEta(channel) == 'LowEta':
95 return channel
96
97 elif self.isPPMOverlap(PPMId):
98
99 if strategy_string == "GainOneOvEmbFcalHighEta":
100 for channel in ReceiverChannels:
101 if self.getOverlapLayer(channel) == 'EMB':
102 return channel
103 if strategy_string == "GainOneOvEmecFcalLowEta":
104 for channel in ReceiverChannels:
105 if self.getOverlapLayer(channel) == 'EMEC':
106 return channel
107
108 else:
109 return ReceiverChannels[0]
110
111 def getCoolEm(self,i_eta,i_phi):
112 if (str(i_eta),str(i_phi)) in self.list_of_channels_em:
113 cool = self.list_of_channels_em[(str(i_eta),str(i_phi))]
114 cool.rstrip()
115 cool.lstrip()
116 return (cool)
117 else:
118 return ('')
119
120
121 def getCoolHad(self,i_eta,i_phi):
122 if (str(i_eta),str(i_phi)) in self.list_of_channels_had:
123 cool = self.list_of_channels_had[(str(i_eta),str(i_phi))]
124 cool.rstrip()
125 cool.lstrip()
126 return (cool)
127 else:
128 return ('')
129
130 def isCoolEm(self,CoolId):
131 return (CoolId in self.list_of_channels_em.values())
132
133 def isCoolHad(self,CoolId):
134 return (CoolId in self.list_of_channels_had.values())
135
136 def getEtaBin(self,CoolId):
137 if self.isCoolEm(CoolId):
138 channel = [item[0] for item in self.list_of_channels_em.items() if item[1]==CoolId]
139 return int(channel[0][0])
140 elif self.isCoolHad(CoolId):
141 channel = [item[0] for item in self.list_of_channels_had.items() if item[1]==CoolId]
142 return int(channel[0][0])
143 else:
144 return -1
145
146 def getPhiBin(self,CoolId):
147 if self.isCoolEm(CoolId):
148 channel = [item[0] for item in self.list_of_channels_em.items() if item[1]==CoolId]
149 return int(channel[0][1])
150 elif self.isCoolHad(CoolId):
151 channel = [item[0] for item in self.list_of_channels_had.items() if item[1]==CoolId]
152 return int(channel[0][1])
153 else:
154 return -1
155
156 def getMissingReceiverChannels(self, channel_list):
157
158 missing_channels= [channel for channel in self.receiver_to_ppm_map.keys() if channel not in channel_list]
159 return missing_channels
160
161
162 def getReceiverCMCP(self,ReceiverId):
163
164 recI=int(ReceiverId,16)
165
166 crate = recI/1024
167 recI = recI - crate*1024
168
169 module = recI/64
170 recI = recI - module*64
171
172 conn = recI/16
173 recI = recI - conn*16
174
175 pair = recI
176
177 return [crate,module,conn,pair]
178
179 def isPPMFCAL(self,CoolId):
180
181 eta_bin = self.getEtaBin(CoolId)
182
183 if eta_bin >= 32 or eta_bin <= -36:
184 return True
185 else:
186 return False
187
188
189 def isPPMOverlap(self,CoolId):
190
191 eta_bin = self.getEtaBin(CoolId)
192 if self.isCoolEm(CoolId) is True and (eta_bin == 14 or eta_bin == -15):
193 return True
194 else:
195 return False
196
197 def getOverlapLayer(self,RecCoolId):
198
199 ppm_id = self.getPPMfromReceiver(RecCoolId)
200
201 if not self.isPPMOverlap(ppm_id):
202 return None
203
204 cabling = self.getReceiverCMCP(RecCoolId)
205 if cabling[0] < 2: # unconnected channel has barrel crate nr.
206 return 'Unconnected'
207 elif cabling[2] == 0:
208 return 'EMEC'
209 elif cabling[2] == 2:
210 return 'EMB'
211 else:
212 print ("Error in GetOverlapLayer, can't determine layer!")
213 return None
214
215 def getFCAL23RecEta(self,RecCoolId):
216
217 ppm_id = self.getPPMfromReceiver(RecCoolId)
218
219 if (not self.isPPMFCAL(ppm_id)) or (not self.isCoolHad(ppm_id)):
220 return None
221 eta_bin = self.getEtaBin(ppm_id)
222
223 RecCoolInt = int(RecCoolId,16)
224 if RecCoolInt%2 == 1:
225 isRecOdd = True
226 else:
227 isRecOdd = False
228
229 if eta_bin>0:
230 if isRecOdd:
231 return 'LowEta'
232 else:
233 return 'HighEta'
234 else:
235 if isRecOdd:
236 return 'HighEta'
237 else:
238 return 'LowEta'
239
240
241def WriteSqlite(name,input_dict):
242
243 UNIX2COOL = 1000000000
244
245 dbSvc = cool.DatabaseSvcFactory.databaseService()
246 connectString = 'sqlite://;schema='+name+';dbname=L1CALO'
247# folder_name="/TRIGGER/Receivers/Factors/CalibGains"
248
249
250 print ('\nrecreating database file:',name)
251 dbSvc.dropDatabase( connectString )
252 db = dbSvc.createDatabase( connectString )
253
254 spec = cool.RecordSpecification()
255 spec.extend("factor", cool.StorageType.Float)
256 spec.extend("status", cool.StorageType.UInt32 )
257 folderSpec = cool.FolderSpecification(cool.FolderVersioning.SINGLE_VERSION, spec)
258
259 now = int(time.time())
260
261 since = now*UNIX2COOL
262 until = cool.ValidityKeyMax
263 db.createFolderSet('/TRIGGER')
264 db.createFolderSet('/TRIGGER/Receivers')
265 db.createFolderSet('/TRIGGER/Receivers/Factors')
266
267 folder_description = '<timeStamp>time</timeStamp><addrHeader><address_header service_type="71" clid="1238547719"/></addrHeader><typeName>CondAttrListCollection</typeName>'
268 f = db.createFolder( "/TRIGGER/Receivers/Factors/CalibGains", folderSpec, folder_description)
269
270 print (" Now creating sqlite file for ", len(input_dict.keys()), " channels")
271 for i in input_dict.keys():
272 data = cool.Record( spec )
273 data['factor'] = input_dict[i][0]
274 data['status'] = input_dict[i][1]
275 f.storeObject(since,until, data, int(i,16) )
276
277 db.closeDatabase()
278
280
281 def __init__(self,name,geometryMapper):
282
283# self.cut_gain_low = 0.5
284# self.cut_gain_high = 1.6
285# self.cut_offset_low = -10.
286# self.cut_offset_high = 10.
287
288 self.cut_gain_low = 0. # all gains that are not completly crazy...
290 self.cut_offset_low = -100.
291 self.cut_offset_high = 100.
292
293 self.geometry_convertor = geometryMapper
294
295 self.run_nr = None #will come later
296 self.strategy = None #later
297
302
303 self.UNIX2COOL = 1000000000
304
305 # get database service and open database
306 dbSvc = cool.DatabaseSvcFactory.databaseService()
307
308 dbString='sqlite://;schema='+name+';dbname=L1CALO'
309 try:
310 db = dbSvc.openDatabase(dbString, False)
311 except Exception as e:
312 print ('Error: Problem opening database', e)
313 sys.exit(1)
314
315 folder_name = '/TRIGGER/L1Calo/V1/Results/EnergyScanResults'
316 folder=db.getFolder(folder_name)
317
318 startUtime = int(time.time())
319 endUtime = int(time.time())
320 startValKey = startUtime * self.UNIX2COOL
321 endValKey = endUtime * self.UNIX2COOL
322 chsel = cool.ChannelSelection(0,sys.maxsize)
323
324 try:
325 itr=folder.browseObjects(startValKey, endValKey, chsel)
326 except Exception as e:
327 print (e)
328 sys.exit(1)
329
330 for row in itr:
331 CoolId = hex(int(row.channelId()))
332 payload = row.payload()
333 self.measured_gains[CoolId] = payload['Slope']
334 self.measured_chi2[CoolId] = payload['Chi2']
335 self.measured_offset[CoolId] = payload['Offset']
336 self.measured_error_code[CoolId] = payload['ErrorCode']
337
338# print (self.measured_gains)
339
340 folder_gen_name = '/TRIGGER/L1Calo/V1/Results/EnergyScanRunInfo'
341 folder_gen=db.getFolder(folder_gen_name)
342
343 try:
344 itr=folder_gen.browseObjects(startValKey, endValKey, chsel)
345 except Exception as e:
346 print (e)
347 sys.exit(1)
348
349 for row in itr:
350 payload = row.payload()
351 self.run_nr = payload['RunNumber']
352 self.strategy = payload['GainStrategy']
353
354
355 # close database
356 db.closeDatabase()
357
358 def getGoodGains(self):
359
360 good_gains={}
361
362 for i in self.measured_gains.keys():
363
364 if ((self.measured_gains[i] > self.cut_gain_low and self.measured_gains[i] < self.cut_gain_high) and
365 (self.measured_offset[i] > self.cut_offset_low and self.measured_offset[i] < self.cut_offset_high) and
366# not (self.geometry_convertor.isCoolHad(i) and self.geometry_convertor.isPPMFCAL(i)) ):
367 not (self.geometry_convertor.isPPMFCAL(i)) ):
368
369 good_gains[i]=[self.measured_gains[i],self.measured_error_code[i]]
370
371 elif self.geometry_convertor.isPPMFCAL(i):
372 good_gains[i]=[self.measured_gains[i]/2,self.measured_error_code[i]]
373
374 else:
375 print ("GainsFromSqlite::getGoodGains have rejected channel ", i)
376
377 return good_gains # these are gains as a function of PPM Cool
378
379
381 def __init__(self):
382
384 self.UNIX2COOL = 1000000000
385
386 # get database service and open database
387 dbSvc = cool.DatabaseSvcFactory.databaseService()
388
389 dbString = 'oracle://ATLAS_COOLPROD;schema=ATLAS_COOLONL_TRIGGER;dbname=CONDBR2'
390 try:
391 db = dbSvc.openDatabase(dbString, False)
392 except Exception as e:
393 print ('Error: Problem opening database', e)
394 sys.exit(1)
395
396 folder_name = "/TRIGGER/Receivers/Factors/CalibGains"
397 folder=db.getFolder(folder_name)
398
399 startUtime = int(time.time())
400 endUtime = int(time.time())
401 startValKey = startUtime * self.UNIX2COOL
402 endValKey = endUtime * self.UNIX2COOL
403 chsel = cool.ChannelSelection(0,sys.maxsize)
404
405 try:
406 itr=folder.browseObjects(startValKey, endValKey, chsel)
407 except Exception as e:
408 print (e)
409 sys.exit(1)
410
411 for row in itr:
412 ReceiverId = hex(int(row.channelId()))
413 payload = row.payload()
414 gain = payload['factor']
415 self.default_gains[ReceiverId]=gain
416
417 def getGoodGains(self):
418 return self.default_gains
419
420
421def merge_gains(gains1,gains2,gains3,reference_gains,forced_list,geometry_map,writeAllChannels):
422
423 output_gains={}
424
425 n_files_Tile = 0
426 n_files_LowEta_EMEC = 0
427 n_files_HighEta_EMB = 0
428
429#loop over gains3, fill in
430
431 if gains3 is not None:
432 good_gains=gains3.getGoodGains()
433 print (" Using run ", gains3.run_nr, " run strategy= ", gains3.strategy )
434
435 if gains3.strategy == "GainOne":
436 n_files_Tile = n_files_Tile + 1
437 if gains3.strategy == "GainOneOvEmecFcalLowEta":
438 n_files_LowEta_EMEC = n_files_LowEta_EMEC + 1
439 if gains3.strategy == "GainOneOvEmbFcalHighEta":
440 n_files_HighEta_EMB = n_files_HighEta_EMB + 1
441
442
443 for ppm_channel in good_gains.keys():
444 gain = good_gains[ppm_channel][0]
445 error_code = good_gains[ppm_channel][1]
446 rec_chan = geometry_map.getReceiverfromPPM(ppm_channel,gains3.strategy)
447 output_gains[rec_chan]=[gain,error_code]
448 else:
449 print ("Ignoring File 3, probably not specified" )
450
451#loop over gains2, fill in
452
453 if gains2 is not None:
454 good_gains=gains2.getGoodGains()
455 print (" Using run ", gains2.run_nr, " run strategy= ", gains2.strategy )
456
457 if gains2.strategy == "GainOne":
458 n_files_Tile = n_files_Tile + 1
459 if gains2.strategy == "GainOneOvEmecFcalLowEta":
460 n_files_LowEta_EMEC = n_files_LowEta_EMEC + 1
461 if gains2.strategy == "GainOneOvEmbFcalHighEta":
462 n_files_HighEta_EMB = n_files_HighEta_EMB + 1
463
464 for ppm_channel in good_gains.keys():
465 gain = good_gains[ppm_channel][0]
466 error_code = good_gains[ppm_channel][1]
467 rec_chan = geometry_map.getReceiverfromPPM(ppm_channel,gains2.strategy)
468 output_gains[rec_chan]=[gain,error_code]
469 else:
470 print ("Ignoring File 2, probably not specified" )
471
472
473#loop over gains 1, fill in
474
475 if gains1 is not None:
476 good_gains=gains1.getGoodGains()
477 print (" Using run ", gains1.run_nr, " run strategy= ", gains1.strategy )
478
479 if gains1.strategy == "GainOne":
480 n_files_Tile = n_files_Tile + 1
481 if gains1.strategy == "GainOneOvEmecFcalLowEta":
482 n_files_LowEta_EMEC = n_files_LowEta_EMEC + 1
483 if gains1.strategy == "GainOneOvEmbFcalHighEta":
484 n_files_HighEta_EMB = n_files_HighEta_EMB + 1
485
486 for ppm_channel in good_gains.keys():
487 gain = good_gains[ppm_channel][0]
488 error_code = good_gains[ppm_channel][1]
489 rec_chan = geometry_map.getReceiverfromPPM(ppm_channel,gains1.strategy)
490 output_gains[rec_chan]=[gain,error_code]
491 else:
492 print ("Ignoring File 1, probably not specified" )
493
494
495#read in forced list, overwrite
496
497 if forced_list is not None:
498 myfile = open(forced_list,'r')
499 for line in myfile.readlines():
500 line.rstrip()
501 line.lstrip()
502 line_cont = line.split(' ')
503 line_cont = [iii for iii in line_cont if not iii == '']
504 rec_chan = line_cont[0]
505 gain = float(line_cont[1])
506 error_code = 10 # code for forced channels
507 output_gains[rec_chan]=[gain,error_code]
508 print ("forcing channel ", rec_chan, " to value ", gain )
509 else:
510 print ("Ignoring forced channel list")
511
512#check channels that haven't been found yet, take them from reference
513
514 if writeAllChannels:
515
516 print ("Adding gains for missing channels from Oracle" )
517 missing_channels = geometry_convertor.getMissingReceiverChannels(output_gains.keys())
518 default_gains = reference_gains.getGoodGains()
519 for channel in missing_channels:
520 gain = default_gains[channel]
521 error_code = 100
522 output_gains[channel]=[gain,error_code]
523
524# print ("missing receiver=",channel, "PPM=", geometry_map.getPPMfromReceiver(channel) )
525
526 if (not n_files_Tile == 1) or (not n_files_LowEta_EMEC == 1) or (not n_files_HighEta_EMB == 1):
527 print ("WARNING! input files do not allow to calibrate all partitions, using defaults where needed" )
528
529 return output_gains
530
531
532
533if __name__ == "__main__":
534
535 print ("Starting mergeEnergyRamps")
536
537 parser = OptionParser()
538
539 parser.add_option("-1","--FirstFile" ,action="store",type="string",dest="input_file1",help="Name of input file")
540 parser.add_option("-2","--SecondFile" ,action="store",type="string",dest="input_file2",help="Name of input file")
541 parser.add_option("-3","--ThirdFile" ,action="store",type="string",dest="input_file3",help="Name of input file")
542 parser.add_option("-f","--ForcedChannels",action="store",type="string",dest="forced_file",help="Name of input file")
543 parser.add_option("-o","--OutputFile" ,action="store",type="string",dest="output_file",help="Name of input file")
544 parser.add_option("-A","--WriteAllChannels",action="store_true",dest="writeAllChannels",help="Writes all channels to .sqlite file")
545
546 (options, args) = parser.parse_args()
547
548 geometry_convertor = L1CaloGeometryConvertor()
549 geometry_convertor.LoadReceiverPPMMap()
550
551 print ("Processing inputs")
552
553 if options.input_file1 is not None:
554 gains_1 = GainsFromSqlite(options.input_file1,geometry_convertor)
555 else:
556 gains_1 = None
557
558 if options.input_file2 is not None:
559 gains_2 = GainsFromSqlite(options.input_file2,geometry_convertor)
560 else:
561 gains_2 = None
562
563 if options.input_file3 is not None:
564 gains_3 = GainsFromSqlite(options.input_file3,geometry_convertor)
565 else:
566 gains_3 = None
567
568 print ("Reading reference")
569 gains_reference = GainsFromOracle()
570
571 print ("Merging gains")
572 if options.writeAllChannels:
573 print ("Will write out gains for all channels")
574 else:
575 print ("Will write out gains only for updated channels" )
576
577 gains_to_load = merge_gains(gains_1,gains_2,gains_3,gains_reference,options.forced_file,geometry_convertor,options.writeAllChannels)
578
579 if options.output_file is not None:
580 output_file_name = options.output_file
581 else:
582 output_file_name = "MergedGains.sqlite"
583
584 print ("Writing output file ",output_file_name , " this may take some time ... :-( " )
585 WriteSqlite(output_file_name,gains_to_load)
586
587# print (gains_to_load )
588
589# for i in gains_to_load.keys():
590# print (i, " ", gains_to_load[i])
591# print (int(i,16))
592
593 print ("Finished!")
__init__(self, name, geometryMapper)
getReceiverfromPPM(self, PPMId, strategy_string=None)
merge_gains(gains1, gains2, gains3, reference_gains, forced_list, geometry_map, writeAllChannels)
WriteSqlite(name, input_dict)