ATLAS Offline Software
Loading...
Searching...
No Matches
ScanNtupleHandler.py
Go to the documentation of this file.
1# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2
3#
4# ScanNtupleHandler.py
5#
6# Definition of vdM scan ntuple
7#
8
9# Utility to unpack BCID blobs
10from CoolLumiUtilities.CoolBCIDData import LumiBCIDData
11
12from ROOT import TFile, TTree, gROOT, AddressOf
13from array import array
14
16
17 def __init__(self):
18
19 self.fileName = 'scan.root'
20 self.treeName = 'vdMScanData'
21 self.file = None
22 self.tree = None
23
24 self.bcidData = LumiBCIDData()
25
26 # Master list of tags to give to algorithms
27 self.algDict = dict()
28 self.algDict[0] = 'pref'
29 self.algDict[101] = 'lucidEvtAND'
30 self.algDict[102] = 'lucidEvtOR'
31 self.algDict[103] = 'lucidHitOR'
32 self.algDict[104] = 'lucidHitAND'
33 self.algDict[105] = 'lucidEvtA'
34 self.algDict[106] = 'lucidEvtC'
35
36 self.algDict[111] = 'lucBiEvtAND'
37 self.algDict[112] = 'lucBiEvtOR'
38 self.algDict[113] = 'lucBiHitOR'
39 self.algDict[115] = 'lucBiEvtA'
40 self.algDict[116] = 'lucBiEvtC'
41
42 self.algDict[121] = 'lucModEvtAND'
43 self.algDict[122] = 'lucModEvtOR'
44 self.algDict[123] = 'lucModHitOR'
45 self.algDict[124] = 'lucModHitAND'
46 self.algDict[125] = 'lucModEvtA'
47 self.algDict[126] = 'lucModEvtC'
48
49 self.algDict[131] = 'lucBiPMTA1'
50 self.algDict[132] = 'lucBiPMTA5'
51 self.algDict[133] = 'lucBiPMTA9'
52 self.algDict[134] = 'lucBiPMTA13'
53 self.algDict[135] = 'lucBiPMTC1'
54 self.algDict[136] = 'lucBiPMTC5'
55 self.algDict[137] = 'lucBiPMTC9'
56 self.algDict[138] = 'lucBiPMTC13'
57
58 self.algDict[151] = 'lucChA'
59 self.algDict[152] = 'lucChC'
60 self.algDict[153] = 'lucBiChA'
61 self.algDict[154] = 'lucBiChC'
62 self.algDict[155] = 'lucFibChA'
63 self.algDict[156] = 'lucFibChC'
64
65 self.algDict[201] = 'bcmHEvtOR'
66 self.algDict[202] = 'bcmHEvtAND'
67 self.algDict[205] = 'bcmHORA'
68 self.algDict[206] = 'bcmHORC'
69
70 self.algDict[211] = 'bcmVEvtOR'
71 self.algDict[212] = 'bcmVEvtAND'
72 self.algDict[215] = 'bcmVORA'
73 self.algDict[216] = 'bcmVORC'
74
75 self.algDict[221] = 'bcmTEvtOR'
76 self.algDict[222] = 'bcmTEvtAND'
77 #self.algDict[225] = 'bcmTORA'
78 #self.algDict[226] = 'bcmTORC'
79
80 self.algDict[231] = 'bcmHEarlyOR'
81 self.algDict[235] = 'bcmHEarlyA'
82 self.algDict[236] = 'bcmHEarlyC'
83
84 self.algDict[241] = 'bcmVEarlyOR'
85 self.algDict[245] = 'bcmVEarlyA'
86 self.algDict[246] = 'bcmVEarlyC'
87
88 self.algDict[301] = 'mbtsEvtOR'
89 self.algDict[302] = 'mbtsEvtAND'
90 self.algDict[303] = 'mbtsEvt2'
91
92 self.algDict[501] = 'fcalA'
93 self.algDict[502] = 'fcalC'
94
95 # Algorithms with bunch-by-bunch information
96 self.bbbAlgDict = dict()
97 self.bbbAlgDict[101] = 'lucidEvtAND'
98 self.bbbAlgDict[102] = 'lucidEvtOR'
99 self.bbbAlgDict[103] = 'lucidHitOR'
100 self.bbbAlgDict[104] = 'lucidHitAND'
101 self.bbbAlgDict[105] = 'lucidEvtA'
102 self.bbbAlgDict[106] = 'lucidEvtC'
103
104 self.bbbAlgDict[111] = 'lucBiEvtAND'
105 self.bbbAlgDict[112] = 'lucBiEvtOR'
106 self.bbbAlgDict[113] = 'lucBiHitOR'
107 self.bbbAlgDict[114] = 'lucBiHitAND'
108 self.bbbAlgDict[115] = 'lucBiEvtA'
109 self.bbbAlgDict[116] = 'lucBiEvtC'
110
111 self.bbbAlgDict[121] = 'lucModEvtAND'
112 self.bbbAlgDict[122] = 'lucModEvtOR'
113 self.bbbAlgDict[123] = 'lucModHitOR'
114 self.bbbAlgDict[125] = 'lucModEvtA'
115 self.bbbAlgDict[126] = 'lucModEvtC'
116
117 self.bbbAlgDict[131] = 'lucBiPMTA1'
118 self.bbbAlgDict[132] = 'lucBiPMTA5'
119 self.bbbAlgDict[133] = 'lucBiPMTA9'
120 self.bbbAlgDict[134] = 'lucBiPMTA13'
121 self.bbbAlgDict[135] = 'lucBiPMTC1'
122 self.bbbAlgDict[136] = 'lucBiPMTC5'
123 self.bbbAlgDict[137] = 'lucBiPMTC9'
124 self.bbbAlgDict[138] = 'lucBiPMTC13'
125
126 self.bbbAlgDict[151] = 'lucChA'
127 self.bbbAlgDict[152] = 'lucChC'
128 self.bbbAlgDict[153] = 'lucBiChA'
129 self.bbbAlgDict[154] = 'lucBiChC'
130 self.bbbAlgDict[155] = 'lucFibChA'
131 self.bbbAlgDict[156] = 'lucFibChC'
132
133 self.bbbAlgDict[201] = 'bcmHEvtOR'
134 self.bbbAlgDict[202] = 'bcmHEvtAND'
135 self.bbbAlgDict[205] = 'bcmHORA'
136 self.bbbAlgDict[206] = 'bcmHORC'
137
138 self.bbbAlgDict[211] = 'bcmVEvtOR'
139 self.bbbAlgDict[212] = 'bcmVEvtAND'
140 self.bbbAlgDict[215] = 'bcmVORA'
141 self.bbbAlgDict[216] = 'bcmVORC'
142
143 self.bbbAlgDict[221] = 'bcmTEvtOR'
144 self.bbbAlgDict[222] = 'bcmTEvtAND'
145 #self.bbbAlgDict[225] = 'bcmTORA'
146 #self.bbbAlgDict[226] = 'bcmTORC'
147
148 self.bbbAlgDict[231] = 'bcmHEarlyOR'
149 self.bbbAlgDict[235] = 'bcmHEarlyA'
150 self.bbbAlgDict[236] = 'bcmHEarlyC'
151
152 self.bbbAlgDict[241] = 'bcmVEarlyOR'
153 self.bbbAlgDict[245] = 'bcmVEarlyA'
154 self.bbbAlgDict[246] = 'bcmVEarlyC'
155
156 def open(self):
157 print('ScanNtupleHandler.open() called')
158
159 self.file = TFile(self.fileName, 'recreate')
160 self.tree = TTree(self.treeName, self.treeName)
161
162 def init(self):
163 print('ScanNtupleHandler.init() called')
164
165 self.initScanData()
166 self.initBeamPosition()
167 self.initFillParams()
168 self.initLbdata()
169 self.initBunchData()
170 self.initBunchLumi()
171 self.initLumiData()
172 self.initLiveData()
173
174 # Must pass data object as a reference where extracted COOL data can be found
175 # This relies on naming conventions, such as:
176 # data.scanData
177 # data.beamData
178 # data.fillData
179 # data.lbdataData
180 #
181 # Each of these should be a list of IObject values as returned by CoolDataReader
182 def fill(self, data):
183 print('ScanNtupleHandler.fill() called')
184
185 nfilled = 0
186 # First we need to fill the scan data
187 for obj in data.scanData.data:
188
189 # Make cuts here if desired?
190
191 # Clear out the BCID object
192 self.bcidData.clear()
193
194 # Fill the scan data
195 self.fillScanData(obj)
196
197 # Now fill other data.
198 # Must match by IOV, so pass original scan data object, and the relevant data list
199
200 # BEAMPOSITION
201 self.fillBeamPosition(obj, data.beamData.data)
202
203 # FILLPARAMS
204 self.fillFillParams(obj, data.fillData.data)
205
206 # LBDATA
207 self.fillLbdata(obj, data.lbdataData.data)
208
209 # BUNCHDATA
210 self.fillBunchData(obj, data.bunchData.data)
211
212 # BUNCHLUMI
213 self.fillBunchLumi(obj, data.bunchLumi.data)
214
215 # LUMINOSITY
216 self.fillLumiData(obj, data.lumiData.data)
217
218 self.tree.Fill()
219 nfilled += 1
220
221 print('ScanNtupleHandler.fill() - filled', nfilled, 'entries')
222
223 def close(self):
224 print('ScanNtupleHandler.close() called')
225
226 self.file.Write()
227 self.file.Close()
228
229 def initScanData(self):
230
231 #
232 # Define SCANDATA tree
233 # Time is in ms
234 structStr = "struct ScanDataStruct {\
235 ULong64_t fStartTime;\
236 ULong64_t fEndTime;\
237 UInt_t fScanRun;\
238 UInt_t fScanLB;\
239 Float_t fStepProgress;\
240 Float_t fScanningIP;\
241 Float_t fAcquisitionFlag;\
242 Float_t fMovingBeam;\
243 Float_t fNominalSeparation;\
244 Float_t fScanInPlane;\
245 };"
246
247 # Replace sizes if needed
248 gROOT.ProcessLine(structStr)
249 from ROOT import ScanDataStruct
250 self.scanDataStruct = ScanDataStruct()
251
252 # l = 64 bit unsigned int, L = 64 bit signed int
253 self.tree.Branch('SCANDATA', self.scanDataStruct, 'StartTime/l:EndTime/l:ScanRun/i:ScanLB/i:StepProgress/F:ScanningIP/F:AcquisitionFlag/F:MovingBeam/F:NominalSeparation/F:ScanInPlane/F')
254
255 # Pass an IObject object for a single ntuple entry
256 def fillScanData(self, obj):
257 self.scanDataStruct.fStartTime = obj.since() # Time in ns
258 self.scanDataStruct.fEndTime = obj.until() # Time in ns
259 self.scanDataStruct.fScanRun = obj.payload()['RunLB'] >> 32
260 self.scanDataStruct.fScanLB = obj.payload()['RunLB']&0xFFFFFFFF
261 self.scanDataStruct.fStepProgress = obj.payload()['StepProgress']
262 self.scanDataStruct.fScanningIP = obj.payload()['ScanningIP']
263 self.scanDataStruct.fAcquisitionFlag = obj.payload()['AcquisitionFlag']
264 self.scanDataStruct.fMovingBeam = obj.payload()['MovingBeam']
265 self.scanDataStruct.fNominalSeparation = obj.payload()['NominalSeparation']
266 self.scanDataStruct.fScanInPlane = obj.payload()['ScanInPlane']
267
269
270 #
271 # Define BEAMPOSITION tree
272 gROOT.ProcessLine("struct BeamPositionStruct {\
273 Float_t fB1PositionH;\
274 Float_t fB1PositionV;\
275 Float_t fB2PositionH;\
276 Float_t fB2PositionV;\
277 Float_t fB1AngleH;\
278 Float_t fB1AngleV;\
279 Float_t fB2AngleH;\
280 Float_t fB2AngleV;\
281 };")
282 from ROOT import BeamPositionStruct
283 self.beamPositionStruct = BeamPositionStruct()
284
285 self.tree.Branch('BEAMPOSITION', self.beamPositionStruct, 'B1PositionH/F:B1PositionV/F:B2PositionH/F:B2PositionV/F:B1AngleH/F:B1AngleV/F:B2AngleH/F:B2AngleV/F')
286
287 def fillBeamPosition(self, timeobj, data):
288
289 # Must match by IOV
290 # These should match exactly, so just look for the same start time
291 found = False
292 for obj in data:
293 if timeobj.since() != obj.since(): continue
294
295 found = True
296 self.beamPositionStruct.fB1PositionH = obj.payload()['B1_PositionAtIP_H']
297 self.beamPositionStruct.fB1PositionV = obj.payload()['B1_PositionAtIP_V']
298 self.beamPositionStruct.fB2PositionH = obj.payload()['B2_PositionAtIP_H']
299 self.beamPositionStruct.fB2PositionV = obj.payload()['B2_PositionAtIP_V']
300 self.beamPositionStruct.fB1AngleH = obj.payload()['B1_AngleAtIP_H']
301 self.beamPositionStruct.fB1AngleV = obj.payload()['B1_AngleAtIP_V']
302 self.beamPositionStruct.fB2AngleH = obj.payload()['B2_AngleAtIP_H']
303 self.beamPositionStruct.fB2AngleV = obj.payload()['B2_AngleAtIP_V']
304 break
305
306 if not found:
307 print("scanNtupleHandler.fillBeamPosition - Didn't find beam position data to match scan data!")
308 self.beamPositionStruct.fB1PositionH = 0.
309 self.beamPositionStruct.fB1PositionV = 0.
310 self.beamPositionStruct.fB2PositionH = 0.
311 self.beamPositionStruct.fB2PositionV = 0.
312 self.beamPositionStruct.fB1AngleH = 0.
313 self.beamPositionStruct.fB1AngleV = 0.
314 self.beamPositionStruct.fB2AngleH = 0.
315 self.beamPositionStruct.fB2AngleV = 0.
316
317
318 def initFillParams(self):
319
320 #
321 # Define FILLPARAMS tree
322 gROOT.ProcessLine("struct FillParamsStruct {\
323 Int_t fB1Bunches;\
324 Int_t fB1BCIDs[3564];\
325 Int_t fB2Bunches;\
326 Int_t fB2BCIDs[3564];\
327 Int_t fLuminousBunches;\
328 Int_t fLuminousBCIDs[3564];\
329 };")
330 from ROOT import FillParamsStruct
331 self.fillParamsStruct = FillParamsStruct()
332
333 self.fillParamsStruct.fB1Bunches = 0
334 self.fillParamsStruct.fB2Bunches = 0
335 self.fillParamsStruct.fLuminousBunches = 0
336 # self.fB1BCIDs = array('i', 3564*[0])
337 # self.fB2BCIDs = array('i', 3564*[0])
338 # self.fLuminousBCIDs = array('i', 3564*[0])
339
340 self.tree.Branch('FILLPARAMSB1', AddressOf(self.fillParamsStruct, 'fB1Bunches'), 'B1Bunches/I:B1BCIDs[B1Bunches]/I')
341 self.tree.Branch('FILLPARAMSB2', AddressOf(self.fillParamsStruct, 'fB2Bunches'), 'B2Bunches/I:B2BCIDs[B2Bunches]/I')
342 self.tree.Branch('FILLPARAMS', AddressOf(self.fillParamsStruct, 'fLuminousBunches'), 'LuminousBunches/I:LuminousBCIDs[LuminousBunches]/I')
343
344 print('Defined FillParams data type')
345 #print 'type(fB1Bunches):', type(self.fillParamsStruct.fB1Bunches)
346 #print 'type(fB1BCIDs):', type(self.fillParamsStruct.fB1BCIDs)
347
348 def fillFillParams(self, timeobj, data):
349
350 # Must match by IOV
351 # FILLPARAMS is slow LHC data, so look for range that encloses start of timeobj IOV
352 found = False
353 for obj in data:
354 # Check that start of scan step is enclosed in object IOV
355 if timeobj.since() < obj.since(): continue
356 if timeobj.since() >= obj.until(): continue
357
358 found = True
359 self.fillParamsStruct.fB1Bunches = obj.payload()['Beam1Bunches']
360 self.fillParamsStruct.fB2Bunches = obj.payload()['Beam2Bunches']
361 self.fillParamsStruct.fLuminousBunches = obj.payload()['LuminousBunches']
362
363 # Now need to unpack the BCID blob
364 self.bcidData.fillMask(obj.payload())
365
366 # Get the BCID lists and enter into ntuple arrays
367
368 # self.fillParamsStruct.fB1BCIDs = array('i', list(self.bcidData.b1BCID))
369 i = 0
370 for bcid in self.bcidData.b1BCID:
371 self.fillParamsStruct.fB1BCIDs[i] = bcid
372 i += 1
373
374 # self.fillParamsStruct.fB2BCIDs = array('i', list(self.bcidData.b2BCID))
375 i = 0
376 for bcid in self.bcidData.b2BCID:
377 self.fillParamsStruct.fB2BCIDs[i] = bcid
378 i += 1
379
380 # self.fillParamsStruct.fLuminousBCIDs = array('i', list(self.bcidData.colBCID))
381 i = 0
382 for bcid in self.bcidData.colBCID:
383 self.fillParamsStruct.fLuminousBCIDs[i] = bcid
384 i += 1
385
386 if not found:
387 print("scanNtupleHandler.fillFillParams - Didn't find FILLPARAMS data to match scan data!")
388 self.fillParamsStruct.fB1Bunches = 0
389 self.fillParamsStruct.fB2Bunches = 0
390 self.fillParamsStruct.fLuminousBunches = 0
391
392 for i in range(3564):
393 self.fillParamsStruct.fB1BCIDs[i] = 0
394 self.fillParamsStruct.fB2BCIDs[i] = 0
395 self.fillParamsStruct.fLuminousBCIDs[i] = 0
396
397 def initLbdata(self):
398
399 #
400 # Define LBDATA tree
401 gROOT.ProcessLine("struct LbdataStruct {\
402 Float_t fB1IntensityBPTX;\
403 Float_t fB2IntensityBPTX;\
404 Float_t fB1IntensityAllBPTX;\
405 Float_t fB2IntensityAllBPTX;\
406 Float_t fB1IntensityBCT;\
407 Float_t fB2IntensityBCT;\
408 Float_t fB1IntensityAllBCT;\
409 Float_t fB2IntensityAllBCT;\
410 Float_t fB1IntensityAllDCCT;\
411 Float_t fB2IntensityAllDCCT;\
412 };")
413 from ROOT import LbdataStruct
414 self.lbdataStruct = LbdataStruct()
415
416 self.tree.Branch('BPTX_LBDATA', AddressOf(self.lbdataStruct, 'fB1IntensityBPTX'), 'BPTX_B1Intensity/F:BPTX_B2Intensity/F:BPTX_B1IntensityAll/F:BPTX_B2IntensityAll/F')
417 self.tree.Branch('BCT_LBDATA', AddressOf(self.lbdataStruct, 'fB1IntensityBCT'), 'BCT_B1Intensity/F:BCT_B2Intensity/F:BCT_B1IntensityAll/F:BCT_B2IntensityAll/F')
418 self.tree.Branch('DCCT_LBDATA', AddressOf(self.lbdataStruct, 'fB1IntensityAllDCCT'), 'DCCT_B1IntensityAll/F:DCCT_B2IntensityAll/F')
419
420 def fillLbdata(self, timeobj, data):
421
422 # Must match by IOV
423 # LBDATA is fast data, so just match directly
424 foundBPTX = False
425 foundBCT = False
426 foundDCCT = False
427
428 for obj in data:
429 if timeobj.since() != obj.since(): continue
430
431 if obj.channelId() == 0:
432 foundBPTX = True
433
434 self.lbdataStruct.fB1IntensityBPTX = obj.payload()['Beam1Intensity']
435 self.lbdataStruct.fB2IntensityBPTX = obj.payload()['Beam2Intensity']
436 self.lbdataStruct.fB1IntensityAllBPTX = obj.payload()['Beam1IntensityAll']
437 self.lbdataStruct.fB2IntensityAllBPTX = obj.payload()['Beam2IntensityAll']
438
439 elif obj.channelId() == 1:
440 foundBCT = True
441
442 self.lbdataStruct.fB1IntensityBCT = obj.payload()['Beam1Intensity']
443 self.lbdataStruct.fB2IntensityBCT = obj.payload()['Beam2Intensity']
444 self.lbdataStruct.fB1IntensityAllBCT = obj.payload()['Beam1IntensityAll']
445 self.lbdataStruct.fB2IntensityAllBCT = obj.payload()['Beam2IntensityAll']
446
447 elif obj.channelId() == 2:
448 foundDCCT = True
449
450 self.lbdataStruct.fB1IntensityAllDCCT = obj.payload()['Beam1IntensityAll']
451 self.lbdataStruct.fB2IntensityAllDCCT = obj.payload()['Beam2IntensityAll']
452
453 else:
454 print('scanNtupleHandler.fillLbdata - Found unknown channel', obj.channelId(), '!')
455
456 if foundBCT and foundBPTX and foundDCCT : break
457
458
459 if (not foundBPTX) and (not foundBCT) and (not foundDCCT):
460 print("scanNtupleHandler.fillLBdata - Couldn't find LBDATA!")
461 elif not foundBCT:
462 print("scanNtupleHandler.fillLBdata - Couldn't find BCT data in LBDATA!")
463 elif not foundBPTX:
464 print("scanNtupleHandler.fillLBdata - Couldn't find BPTX data in LBDATA!")
465 elif not foundDCCT:
466 print("scanNtupleHandler.fillLBdata - Couldn't find DCCT data in LBDATA!")
467
468 if not foundBCT:
469 self.lbdataStruct.fB1IntensityBCT = 0.
470 self.lbdataStruct.fB2IntensityBCT = 0.
471 self.lbdataStruct.fB1IntensityAllBCT = 0.
472 self.lbdataStruct.fB2IntensityAllBCT = 0.
473
474 if not foundBPTX:
475 self.lbdataStruct.fB1IntensityBPTX = 0.
476 self.lbdataStruct.fB2IntensityBPTX = 0.
477 self.lbdataStruct.fB1IntensityAllBPTX = 0.
478 self.lbdataStruct.fB2IntensityAllBPTX = 0.
479
480 if not foundDCCT:
481 self.lbdataStruct.fB1IntensityAllDCCT = 0.
482 self.lbdataStruct.fB2IntensityAllDCCT = 0.
483
484 def initBunchData(self):
485
486 #
487 # Define BUNCHDATA tree
488 gROOT.ProcessLine("struct BunchDataStruct {\
489 UInt_t fValidBPTX;\
490 Float_t fB1BunchAverageBPTX;\
491 Float_t fB2BunchAverageBPTX;\
492 Int_t fB1BunchesBPTX;\
493 Int_t fB2BunchesBPTX;\
494 Float_t fB1BunchIntensitiesBPTX[3564];\
495 Int_t fB1BCIDsBPTX[3564];\
496 Float_t fB2BunchIntensitiesBPTX[3564];\
497 Int_t fB2BCIDsBPTX[3564];\
498 UInt_t fValidBCT;\
499 Float_t fB1BunchAverageBCT;\
500 Float_t fB2BunchAverageBCT;\
501 Int_t fB1BunchesBCT;\
502 Int_t fB2BunchesBCT;\
503 Int_t fB1BCIDsBCT[3564];\
504 Float_t fB1BunchIntensitiesBCT[3564];\
505 Int_t fB2BCIDsBCT[3564];\
506 Float_t fB2BunchIntensitiesBCT[3564];\
507 };")
508 from ROOT import BunchDataStruct
509 self.bunchDataStruct = BunchDataStruct()
510
511 # Not sure why this is necessary
512 self.bunchDataStruct.fB1BunchesBPTX = 0
513 self.bunchDataStruct.fB2BunchesBPTX = 0
514 self.bunchDataStruct.fB1BunchesBCT = 0
515 self.bunchDataStruct.fB2BunchesBCT = 0
516
517 self.tree.Branch('BCT_BUNCHDATA', AddressOf(self.bunchDataStruct, 'fValidBCT'), 'BCT_Valid/i:BCT_B1BunchAverage/F:BCT_B2BunchAverage/F:BCT_B1Bunches/I:BCT_B2Bunches/I')
518 self.tree.Branch('BCT_B1BCID', AddressOf(self.bunchDataStruct, 'fB1BCIDsBCT'), 'BCT_B1BCID[BCT_B1Bunches]/I')
519 self.tree.Branch('BCT_B2BCID', AddressOf(self.bunchDataStruct, 'fB2BCIDsBCT'), 'BCT_B2BCID[BCT_B2Bunches]/I')
520 self.tree.Branch('BCT_B1BunchIntensity', AddressOf(self.bunchDataStruct, 'fB1BunchIntensitiesBCT'), 'BCT_B1BunchIntensity[BCT_B1Bunches]/F')
521 self.tree.Branch('BCT_B2BunchIntensity', AddressOf(self.bunchDataStruct, 'fB2BunchIntensitiesBCT'), 'BCT_B2BunchIntensity[BCT_B2Bunches]/F')
522
523 self.tree.Branch('BPTX_BUNCHDATA', AddressOf(self.bunchDataStruct, 'fValidBPTX'), 'BPTX_Valid/i:BPTX_B1BunchAverage/F:BPTX_B2BunchAverage/F:BPTX_B1Bunches/I:BPTX_B2Bunches/I')
524 self.tree.Branch('BPTX_B1BCID', AddressOf(self.bunchDataStruct, 'fB1BCIDsBPTX'), 'BPTX_B1BCID[BPTX_B1Bunches]/I')
525 self.tree.Branch('BPTX_B2BCID', AddressOf(self.bunchDataStruct, 'fB2BCIDsBPTX'), 'BPTX_B2BCID[BPTX_B2Bunches]/I')
526 self.tree.Branch('BPTX_B1BunchIntensity', AddressOf(self.bunchDataStruct, 'fB1BunchIntensitiesBPTX'), 'BPTX_B1BunchIntensity[BPTX_B1Bunches]/F')
527 self.tree.Branch('BPTX_B2BunchIntensity', AddressOf(self.bunchDataStruct, 'fB2BunchIntensitiesBPTX'), 'BPTX_B2BunchIntensity[BPTX_B2Bunches]/F')
528
529
530 def fillBunchData(self, timeobj, data):
531
532 # Must match by IOV
533 # LBDATA is fast data, so just match directly
534 foundBPTX = False
535 foundBCT = False
536
537 for obj in data:
538 if timeobj.since() != obj.since(): continue
539
540 # Now need to unpack the BCID blob
541 self.bcidData.fillCurrents(obj.payload())
542
543 if obj.channelId() == 0:
544 foundBPTX = True
545
546 self.bunchDataStruct.fB1BunchAverageBPTX = obj.payload()['B1BunchAverage']
547 self.bunchDataStruct.fB2BunchAverageBPTX = obj.payload()['B2BunchAverage']
548 self.bunchDataStruct.fValidBPTX = obj.payload()['Valid']
549
550 self.bunchDataStruct.fB1BunchesBPTX = len(self.bcidData.b1Curr)
551 # Following line causes problems?
552 # Try the brute force apprach again.
553 # self.bunchDataStruct.fB1BCIDsBPTX = array('i', self.bcidData.b1Curr.keys())
554 # self.bunchDataStruct.fB1BunchIntensitiesBPTX = array('f', self.bcidData.b1Curr.values())
555
556 i = 0
557 for (bcid, val) in self.bcidData.b1Curr.iteritems():
558 self.bunchDataStruct.fB1BCIDsBPTX[i] = bcid
559 self.bunchDataStruct.fB1BunchIntensitiesBPTX[i] = val
560 i += 1
561
562 self.bunchDataStruct.fB2BunchesBPTX = len(self.bcidData.b2Curr)
563 # self.bunchDataStruct.fB2BCIDsBPTX = array('i', self.bcidData.b2Curr.keys())
564 # self.bunchDataStruct.fB2BunchIntensitiesBPTX = array('f', self.bcidData.b2Curr.values())
565
566 i = 0
567 for (bcid, val) in self.bcidData.b2Curr.iteritems():
568 self.bunchDataStruct.fB2BCIDsBPTX[i] = bcid
569 self.bunchDataStruct.fB2BunchIntensitiesBPTX[i] = val
570 i += 1
571
572 elif obj.channelId() == 1:
573 foundBCT = True
574
575 self.bunchDataStruct.fB1BunchAverageBCT = obj.payload()['B1BunchAverage']
576 self.bunchDataStruct.fB2BunchAverageBCT = obj.payload()['B2BunchAverage']
577 self.bunchDataStruct.fValidBCT = obj.payload()['Valid']
578
579 self.bunchDataStruct.fB1BunchesBCT = len(self.bcidData.b1Curr)
580 #self.bunchDataStruct.fB1BCIDsBCT = array('i', self.bcidData.b1Curr.keys())
581 #self.bunchDataStruct.fB1BunchIntensitiesBCT = array('f', self.bcidData.b1Curr.values())
582
583 i = 0
584 for (bcid, val) in self.bcidData.b1Curr.iteritems():
585 self.bunchDataStruct.fB1BCIDsBCT[i] = bcid
586 self.bunchDataStruct.fB1BunchIntensitiesBCT[i] = val
587 i += 1
588
589 self.bunchDataStruct.fB2BunchesBCT = len(self.bcidData.b2Curr)
590 # self.bunchDataStruct.fB2BCIDsBCT = array('i', self.bcidData.b2Curr.keys())
591 # self.bunchDataStruct.fB2BunchIntensitiesBCT = array('f', self.bcidData.b2Curr.values())
592
593 i = 0
594 for (bcid, val) in self.bcidData.b2Curr.iteritems():
595 self.bunchDataStruct.fB2BCIDsBCT[i] = bcid
596 self.bunchDataStruct.fB2BunchIntensitiesBCT[i] = val
597 i += 1
598
599 else:
600 print('scanNtupleHandler.fillLbdata - Found unknown channel', obj.channelId(), '!')
601
602 if foundBCT and foundBPTX: break
603
604
605 if (not foundBPTX) and (not foundBCT):
606 print("scanNtupleHandler.fillBunchData - Couldn't find BUNCHDATA!")
607 elif not foundBCT:
608 print("scanNtupleHandler.fillBunchData - Couldn't find BCT data in BUNCHDATA!")
609 elif not foundBPTX:
610 print("scanNtupleHandler.fillBunchData - Couldn't find BPTX data in BUNCHDATA!")
611
612 if not foundBCT:
613 self.bunchDataStruct.fB1BunchAverageBCT = 0.
614 self.bunchDataStruct.fB2BunchAverageBCT = 0.
615 self.bunchDataStruct.fValidBCT = -1
616 self.bunchDataStruct.fB1BunchesBCT = 0
617 self.bunchDataStruct.fB2BunchesBCT = 0
618
619 if not foundBPTX:
620 self.bunchDataStruct.fB1BunchAverageBPTX = 0.
621 self.bunchDataStruct.fB2BunchAverageBPTX = 0.
622 self.bunchDataStruct.fValidBPTX = -1
623 self.bunchDataStruct.fB1BunchesBPTX = 0
624 self.bunchDataStruct.fB2BunchesBPTX = 0
625
626 # print 'BCT Avg:', self.bunchDataStruct.fB1BunchAverageBCT
627 # for i in range(self.bunchDataStruct.fB1BunchesBCT):
628 # print ' BCID:', self.bunchDataStruct.fB1BCIDsBCT[i], self.bunchDataStruct.fB2BunchIntensitiesBCT[i]
629
630 def initBunchLumi(self):
631
632 #
633 # Define BUNCHDATA tree
634 gROOT.ProcessLine("struct BunchLumiStruct {\
635 UInt_t fChannel;\
636 UInt_t fValid;\
637 Float_t fAverageRawInstLum;\
638 Int_t fLuminousBunches;\
639 Int_t fLuminousBCIDs[3564];\
640 Float_t fBunchRawInstLum[3564];\
641 };")
642 from ROOT import BunchLumiStruct
643
644 self.bunchLumiStruct = dict()
645 self.fLuminousBCIDs = dict()
646 self.fBunchRawInstLum = dict()
647
648 for (chId, algstr) in self.bbbAlgDict.iteritems():
649 print('scanNtupleHandler.initLumiData - initializing', algstr, 'as channel', chId)
650 self.bunchLumiStruct[chId] = BunchLumiStruct()
651 self.bunchLumiStruct[chId].fLuminousBunches = 0
652
653 self.fLuminousBCIDs[chId] = array('i', 3564*[0])
654 self.fBunchRawInstLum[chId] = array('f', 3564*[0.])
655
656 branchString1 = 'ALG_Channel/i:ALG_Valid/i:ALG_AverageRawInstLum/F:ALG_LuminousBunches/I'
657 branchString2 = 'ALG_LuminousBCIDs[ALG_LuminousBunches]/I'
658 branchString3 = 'ALG_BunchRawInstLum[ALG_LuminousBunches]/F'
659
660 self.tree.Branch(algstr+'_BUNCHDATA', self.bunchLumiStruct[chId], branchString1.replace('ALG', algstr))
661 #self.tree.Branch(algstr+'_BCID', AddressOf(self.bunchLumiStruct[chId], 'fLuminousBCIDs'), branchString2.replace('ALG', algstr))
662 #self.tree.Branch(algstr+'_BunchRawInstLum', AddressOf(self.bunchLumiStruct[chId], 'fBunchRawInstLum'), branchString3.replace('ALG', algstr))
663 self.tree.Branch(algstr+'_BCID', self.fLuminousBCIDs[chId], branchString2.replace('ALG', algstr))
664 self.tree.Branch(algstr+'_BunchRawInstLum', self.fBunchRawInstLum[chId], branchString3.replace('ALG', algstr))
665
666 def fillBunchLumi(self, timeobj, data):
667
668 # Must match by IOV - exact match
669 # Keep track of every algorithm separately
670 foundAny = False
671
672 found = dict()
673 for chId in self.bbbAlgDict.iterkeys():
674 found[chId] = False
675
676 for obj in data:
677 if timeobj.since() != obj.since(): continue
678
679 # Figure out which channel
680 chId = obj.channelId()
681 if chId not in self.bbbAlgDict:
682 print('scanNtupleHandler.fillBunchLumi - Unknown lumi channel', chId, '!')
683 continue
684
685 foundAny = True
686
687 # Unpack lumi blob
688 self.bcidData.fillRawLumi(obj.payload())
689
690 found[chId] = True
691 self.bunchLumiStruct[chId].fChannel = obj.channelId()
692 self.bunchLumiStruct[chId].fValid = obj.payload()['Valid']
693 self.bunchLumiStruct[chId].fAverageRawInstLum = obj.payload()['AverageRawInstLum']
694
695 self.bunchLumiStruct[chId].fLuminousBunches = len(self.bcidData.rawLumi)
696 #self.fLuminousBCIDs[chId] = array('i', self.bcidData.rawLumi.keys())
697 #self.fBunchRawInstLum[chId] = array('f', self.bcidData.rawLumi.values())
698 #if obj.channelId() == 102:
699 # print 'Channel: %d, Luminous bunches: %d' % (obj.channelId(), len(self.bcidData.rawLumi))
700
701 i = 0
702 bcidList = self.bcidData.rawLumi.keys()
703 for bcid in sorted(bcidList):
704 val = self.bcidData.rawLumi[bcid]
705 self.fLuminousBCIDs[chId][i] = bcid
706 self.fBunchRawInstLum[chId][i] = val
707 i += 1
708
709# self.bunchLumiStruct[chId].fLuminousBCIDs[i] = bcid
710# self.bunchLumiStruct[chId].fBunchRawInstLum[i] = val
711
712 if not foundAny:
713 print('scanNtupleHandler.fillBunchLumi - Found no BUNCHLUMIS data to match IOV!')
714
715 else:
716 for (chId, algstr) in self.bbbAlgDict.iteritems():
717 if not found[chId]:
718 print('scanNtupleHandler.fillBunchLumi - Found no BUNCHLUMIS data for', algstr, '!')
719
720 for chId in self.bbbAlgDict.iterkeys():
721 if not found[chId]:
722 self.bunchLumiStruct[chId].fChannel = chId
723 self.bunchLumiStruct[chId].fValid = 0xFFFFFFFF
724 self.bunchLumiStruct[chId].fAverageRawInstLum = 0.
725 self.bunchLumiStruct[chId].fLuminousBunches = 0
726
727 def initLumiData(self):
728 print('scanNtupleHandler.initLumiData() called')
729
730 #
731 # Define LUMINOSITY tree
732 # Try to abstract this for different lumi algorithms
733 gROOT.ProcessLine("struct LumiDataStruct {\
734 UInt_t fChannel;\
735 Float_t fLBAvInstLumPhys;\
736 Float_t fLBAvEvtsPerBXPhys;\
737 Float_t fLBAvRawInstLumPhys;\
738 Float_t fLBAvInstLumAll;\
739 Float_t fLBAvRawInstLumAll;\
740 Float_t fLBAvEvtsPerBXAll;\
741 Float_t fLBAvOLCInstLum;\
742 Float_t fLBAvOLCRawInstLum;\
743 Float_t fLBAvOLCEvtsPerBX;\
744 UInt_t fNOrbPhys;\
745 UInt_t fNOrbAll;\
746 UInt_t fNOrbOLC;\
747 UInt_t fDetectorState;\
748 UInt_t fValid;\
749 };")
750 from ROOT import LumiDataStruct
751
752 self.lumiStruct = dict()
753 for (chId, algstr) in self.algDict.iteritems():
754 print('scanNtupleHandler.initLumiData - initializing', algstr, 'as channel', chId)
755 self.lumiStruct[chId] = LumiDataStruct()
756 branchString = 'ALG_LumiChannel/i:ALG_LBAvInstLumPhys/F:ALG_LBAvEvtsPerBXPhys/F:ALG_LBAvRawInstLumPhys/F:ALG_LBAvInstLumAll/F:ALG_LBAvRawInstLumAll/F:ALG_LBAvEvtsPerBXAll/F:ALG_LBAvOLCInstLum/F:ALG_LBAvOLCRawInstLum/F:ALG_LBAvOLCEvtsPerBX/F:ALG_NOrbPhys/i:ALG_NOrbAll/i:ALG_NOrbOLC/i:ALG_DetectorState/i:ALG_LumiValid/i'
757
758 self.tree.Branch(algstr+'_LUMI', self.lumiStruct[chId], branchString.replace('ALG', algstr))
759
760 def fillLumiData(self, timeobj, data):
761
762 # Must match by IOV - exact match
763 # Keep track of every algorithm separately
764 foundAny = False
765
766 found = dict()
767 liveDict = dict()
768
769 for chId in self.algDict.iterkeys():
770 found[chId] = False
771
772 for obj in data:
773 if timeobj.since() != obj.since(): continue
774
775 # Figure out which channel
776 chId = obj.channelId()
777 if chId == 5:
778 continue # Ignore CMS luminosity
779
780 elif chId >= 50 and chId <=70:
781 liveDict[chId] = obj.payload()['LBAvOLCInstLum']
782 continue
783
784 elif chId not in self.algDict:
785 print('scanNtupleHandler.fillLumiData - Unknown lumi channel', chId, '!')
786 continue
787
788 foundAny = True
789
790 # Fill the data for this algorithm
791 found[chId] = True
792 self.lumiStruct[chId].fChannel = obj.channelId()
793 self.lumiStruct[chId].fLBAvInstLumPhys = obj.payload()['LBAvInstLumPhys']
794 self.lumiStruct[chId].fLBAvEvtsPerBXPhys = obj.payload()['LBAvEvtsPerBXPhys']
795 self.lumiStruct[chId].fLBAvRawInstLumPhys = obj.payload()['LBAvRawInstLumPhys']
796 self.lumiStruct[chId].fLBAvInstLumAll = obj.payload()['LBAvInstLumAll']
797 self.lumiStruct[chId].fLBAvEvtsPerBXAll = obj.payload()['LBAvEvtsPerBXAll']
798 self.lumiStruct[chId].fLBAvRawInstLumAll = obj.payload()['LBAvRawInstLumAll']
799 self.lumiStruct[chId].fLBAvOLCInstLum = obj.payload()['LBAvOLCInstLum']
800 self.lumiStruct[chId].fLBAvOLCEvtsPerBX = obj.payload()['LBAvOLCEvtsPerBX']
801 self.lumiStruct[chId].fLBAvOLCRawInstLum = obj.payload()['LBAvOLCRawInstLum']
802 self.lumiStruct[chId].fDetectorState = obj.payload()['DetectorState']
803 try:
804 self.lumiStruct[chId].fNOrbPhys = obj.payload()['NOrbPhys']
805 self.lumiStruct[chId].fNOrbAll = obj.payload()['NOrbAll']
806 self.lumiStruct[chId].fNOrbOLC = obj.payload()['NOrbOLC']
807 except Exception as e:
808 print(e)
809 self.lumiStruct[chId].fNOrbPhys = 0
810 self.lumiStruct[chId].fNOrbAll = 0
811 self.lumiStruct[chId].fNOrbOLC = 0
812
813 self.lumiStruct[chId].fValid = obj.payload()['Valid']
814
815 if not foundAny:
816 print('scanNtupleHandler.fillLumiData - Found no LUMINOSITY data to match IOV!')
817
818 else:
819 for (chId, algstr) in self.algDict.iteritems():
820 if not found[chId]:
821 print('scanNtupleHandler.fillLumiData - Found no LUMINOSITY data for', algstr, '!')
822
823 for chId in self.algDict.iterkeys():
824 if not found[chId]:
825 self.lumiStruct[chId].fChannel = chId
826 self.lumiStruct[chId].fLBAvInstLumPhys = 0.
827 self.lumiStruct[chId].fLBAvEvtsPerBXPhys = 0.
828 self.lumiStruct[chId].fLBAvRawInstLumPhys = 0.
829 self.lumiStruct[chId].fLBAvInstLumAll = 0.
830 self.lumiStruct[chId].fLBAvEvtsPerBXAll = 0.
831 self.lumiStruct[chId].fLBAvRawInstLumAll = 0.
832 self.lumiStruct[chId].fLBAvOLCInstLum = 0.
833 self.lumiStruct[chId].fLBAvOLCEvtsPerBX = 0.
834 self.lumiStruct[chId].fLBAvOLCRawInstLum = 0.
835 self.lumiStruct[chId].fNOrbPhys = 0
836 self.lumiStruct[chId].fNOrbAll = 0
837 self.lumiStruct[chId].fNOrbOLC = 0
838 self.lumiStruct[chId].fDetectorState = 0
839 self.lumiStruct[chId].fValid = 0xFFFFFFFF
840
841 # Fill the livefraction data (if present)
842 self.fillLive(liveDict, 50, 51, self.liveDataStruct.fRD0_Filled)
843 self.fillLive(liveDict, 54, 55, self.liveDataStruct.fMBTS_1_1)
844 self.fillLive(liveDict, 56, 57, self.liveDataStruct.fMBTS_2)
845 self.fillLive(liveDict, 58, 59, self.liveDataStruct.fEM12)
846 self.fillLive(liveDict, 60, 61, self.liveDataStruct.fRD0_BGRP9)
847 self.fillLive(liveDict, 62, 63, self.liveDataStruct.fMBTS_1_BGRP9)
848 self.fillLive(liveDict, 66, 67, self.liveDataStruct.fMBTS_2_BGRP9)
849
850 print(self.liveDataStruct.fEM12)
851
852 def fillLive(self, liveDict, denchan, numchan, dest):
853 num = liveDict.get(numchan, 0.)
854 den = liveDict.get(denchan, 0.)
855 if den > 0.:
856 dest = num/den
857 else:
858 dest = 0. # noqa: F841
859
860 self.liveDataStruct.fRD0_Filled = 0.
861
862
863 def initLiveData(self):
864
865 #
866 # Define LIVEDATA tree
867 gROOT.ProcessLine("struct LiveDataStruct {\
868 Float_t fRD0_Filled;\
869 Float_t fMBTS_1_1;\
870 Float_t fMBTS_2;\
871 Float_t fEM12;\
872 Float_t fRD0_BGRP9;\
873 Float_t fMBTS_1_BGRP9;\
874 Float_t fMBTS_2_BGRP9;\
875 };")
876 from ROOT import LiveDataStruct
877 self.liveDataStruct = LiveDataStruct()
878
879 self.tree.Branch('LiveFractions', AddressOf(self.liveDataStruct, 'fRD0_Filled'), 'RD0_Filled/f,MBTS_1_1/f,MBTS_2/f,EM12/f,RD0_BGRP9/f,MBTS_1_BGRP9/f,MBTS_2_BGRP9/f')
880
881
void print(char *figname, TCanvas *c1)
STL class.
fillLive(self, liveDict, denchan, numchan, dest)