ATLAS Offline Software
TrigNtupleHandler.py
Go to the documentation of this file.
1 #!/bin/env python
2 
3 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
4 #
5 # AtlDataSumNtuple
6 #
7 # Eric Torrence - September 2011
8 #
9 # Contents:
10 # NtupleHandler - Utility to define and fill the per-BCID ntuple
11 #
12 
13 import os
14 import array
15 from ROOT import TObject, TFile, TTree, gROOT, AddressOf
16 
18 
19  def __init__(self):
20 
21  self.fileName = 'lumi.root'
22  self.treeName = 'lumiData'
23  self.file = None
24  self.tree = None
25  self.updatemode = False
26 
27  # Flag showing whether BCID data is initialized
28  self.bcidData = False
29 
30  # Flag showing whether L1 trigger counts are initialized
31  self.l1TrigData = True
32 
33  def open(self, update=True):
34  print('NtupleHandler.open() called')
35 
36  if os.path.exists(self.fileName) and update:
37  print('Opening %s for updating' % self.fileName)
38  self.updatemode = True
39  self.file = TFile(self.fileName, 'update')
40  self.tree = self.file.Get(self.treeName)
41 
42  else:
43  print('Creating %s for writing' % self.fileName)
44  self.updatemode = False
45  self.file = TFile(self.fileName, 'create')
46  self.tree = TTree(self.treeName, self.treeName)
47 
48 
49  def close(self):
50  print('ScanNtupleHandler.close() called')
51 
52  self.tree.Write('', TObject.kOverwrite)
53  self.file.Close()
54 
55  def init(self):
56  print('ScanNtupleHandler.init() called')
57 
58  self.initLBData()
59  self.initBCIDData()
60 
61  def save(self):
62  self.tree.Fill()
63 
64  def readLastEntry(self):
65  entries = self.tree.GetEntries()
66  self.tree.GetEntry(entries-1)
67 
68  # Fill information from LumiLBData object
69  def fillLumi(self, lumi):
70 
71  # Erase any old data
72  self.clear()
73 
74  # Time in COOL format (ns)
75  self.lbData.coolStartTime = lumi.startTime.timerunlb()
76  self.lbData.coolEndTime = lumi.endTime.timerunlb()
77  # Time in seconds
78  self.lbData.startTime = lumi.startTime.timerunlb()/1.E9
79  self.lbData.endTime = lumi.endTime.timerunlb()/1.E9
80  # LB duration in seconds
81  self.lbData.lbTime = (lumi.endTime.timerunlb() - lumi.startTime.timerunlb())/1.E9
82 
83  self.lbData.run = lumi.runLB.run
84  self.lbData.lb = lumi.runLB.lb
85 
86  # Need to fill these elsewhere
87  # self.lbData.fill = 0
88  # self.lbData.eBeam = 0.
89  # self.lbData.stable = False
90  # self.lbData.ready = False
91  # self.lbData.physics = False
92 
93  # if lumi.onlEvtsPerBX > 0.:
94  # self.lbData.muToLumi = lumi.onlInstLumi/lumi.onlEvtsPerBX
95 
96  self.lbData.onlInstLum = lumi.onlInstLumi
97  self.lbData.onlInstLumAll = lumi.onlInstLumiAll
98  self.lbData.onlEvtsPerBX = lumi.onlEvtsPerBX
99 
100  self.lbData.onlPrefChan = lumi.onlPrefChan
101  self.lbData.onlValid = lumi.onlValid
102  self.lbData.olcValid = lumi.olcValid
103 
104  self.lbData.nColl = lumi.bcid.nbcol()
105  self.lbData.nBeam1 = lumi.bcid.nb1()
106  self.lbData.nBeam2 = lumi.bcid.nb2()
107  self.lbData.qBeam1Col = lumi.IBeam1
108  self.lbData.qBeam2Col = lumi.IBeam2
109  self.lbData.qBeam1All = lumi.IBeam1All
110  self.lbData.qBeam2All = lumi.IBeam2All
111 
112  self.lbData.specLumi = lumi.specLumi
113  self.lbData.geomLumi = lumi.geomLumi
114  self.lbData.maxEvtsPerBX = lumi.maxEvtsPerBX
115 
116  self.lbData.l1LiveFrac = lumi.l1Livefrac
117 
118  # Get this from the veto folders
119  # self.lbData.avgLiveFrac = -1.
120  # self.lbData.lumiWtLiveFrac = -1.
121 
122  self.lbData.matched = lumi.matched
123 
124  if not self.bcidData: return
125 
126  # And fill the per-BCID values
127  for (bcid, caliLumi) in lumi.bcid.caliLumi.iteritems():
128  self.lumiDel[int(bcid)] = caliLumi
129 
130  for (bcid, q) in lumi.bcid.b1Curr.iteritems():
131  self.qBeam1[int(bcid)] = q
132 
133  for (bcid, q) in lumi.bcid.b2Curr.iteritems():
134  self.qBeam2[int(bcid)] = q
135 
136  i=0
137  for bcid in sorted(list(lumi.bcid.b1BCID)):
138  self.b1BCID[i] = bcid
139  i += 1
140 
141  i=0
142  for bcid in sorted(list(lumi.bcid.b2BCID)):
143  self.b2BCID[i] = bcid
144  i += 1
145 
146  i=0
147  for bcid in sorted(list(lumi.bcid.colBCID)):
148  self.colBCID[i] = bcid
149  i += 1
150 
151  # Still need live fraction
152 
153  # Pass TriggerL1Data object for lumi block filled by TriggerHandler
154  # Also need mapping of channel names to channel values
155  def fillL1Trig(self, trigData, trigChan):
156  for (trig, chan) in trigChan.iteritems():
157  self.l1TBP[chan] = trigData.TBP[trig]
158  self.l1TAP[chan] = trigData.TAP[trig]
159  self.l1TAV[chan] = trigData.TAV[trig]
160 
161  def defineBranch(self, name, type):
162  self.tree.Branch(name, AddressOf(self.lbData, name), name+'/'+type)
163 
164  def loadBranch(self, name):
165  branch = self.tree.GetBranch(name)
166  branch.SetAddress(AddressOf(self.lbData, name))
167 
168  def initLBData(self):
169 
170  # Define the main lumiblock data
171  # Time is in ns
172 
173 # ULong64_t startTime;\
174 # ULong64_t endTime;\
175 
176  LBDataStructStr = "struct LBDataStruct {\
177  ULong64_t coolStartTime;\
178  ULong64_t coolEndTime;\
179  Double_t startTime;\
180  Double_t endTime;\
181  Float_t lbTime;\
182  UInt_t fill;\
183  UInt_t run;\
184  UInt_t lb;\
185  Float_t eBeam;\
186  Bool_t stable;\
187  Bool_t ready;\
188  Bool_t physics;\
189  Bool_t larVeto;\
190  \
191  UInt_t onlValid;\
192  UInt_t olcValid;\
193  UInt_t onlPrefChan;\
194  Float_t muToLumi;\
195  Float_t onlInstLum;\
196  Float_t onlInstLumAll;\
197  Float_t onlEvtsPerBX;\
198  \
199  UInt_t nColl;\
200  UInt_t nBeam1;\
201  UInt_t nBeam2;\
202  Float_t qBeam1Col;\
203  Float_t qBeam2Col;\
204  Float_t qBeam1All;\
205  Float_t qBeam2All;\
206  \
207  Float_t specLumi;\
208  Float_t geomLumi;\
209  Float_t maxEvtsPerBX;\
210  \
211  Float_t l1LiveFrac;\
212  Float_t avgLiveFrac;\
213  Float_t lumiWtLiveFrac;\
214  \
215  UInt_t matched;\
216  };"
217 
218  # Replace sizes if needed
219  gROOT.ProcessLine(LBDataStructStr)
220  from ROOT import LBDataStruct
221  self.lbData = LBDataStruct()
222 
223  self.varList = []
224 
225  self.varList.append(('startTime', 'D'))
226  self.varList.append(('endTime', 'D'))
227  self.varList.append(('coolStartTime', 'l'))
228  self.varList.append(('coolEndTime', 'l'))
229  self.varList.append(('lbTime', 'F'))
230 
231  self.varList.append(('fill', 'i'))
232  self.varList.append(('run', 'i'))
233  self.varList.append(('lb', 'i'))
234  self.varList.append(('eBeam', 'F'))
235 
236  # Boolean status flags
237  self.varList.append(('stable', 'O'))
238  self.varList.append(('ready', 'O'))
239  self.varList.append(('physics', 'O'))
240  self.varList.append(('larVeto', 'O'))
241 
242  # Luminosity information
243  self.varList.append(('onlPrefChan', 'i'))
244  self.varList.append(('muToLumi', 'F'))
245  self.varList.append(('onlInstLum', 'F'))
246  self.varList.append(('onlInstLumAll', 'F'))
247  self.varList.append(('onlEvtsPerBX', 'F'))
248  self.varList.append(('onlValid', 'i')) # From LBLESTONL & 0x3FF
249  self.varList.append(('olcValid', 'i')) # From LUMINOSITY
250 
251  # Total bunch information
252  self.varList.append(('nColl', 'i'))
253  self.varList.append(('nBeam1', 'i'))
254  self.varList.append(('nBeam2', 'i'))
255  self.varList.append(('qBeam1Col', 'F')) # Total charge colliding
256  self.varList.append(('qBeam2Col', 'F'))
257  self.varList.append(('qBeam1All', 'F')) # Total charge in all BCIDs
258  self.varList.append(('qBeam2All', 'F'))
259 
260  self.varList.append(('specLumi', 'F'))
261  self.varList.append(('geomLumi', 'F'))
262  self.varList.append(('maxEvtsPerBX', 'F'))
263 
264  # Livetime information
265  self.varList.append(('l1LiveFrac', 'F'))
266  self.varList.append(('avgLiveFrac', 'F'))
267  self.varList.append(('lumiWtLiveFrac', 'F')) # lumi-weighted per-BCID livefraction
268 
269  # Where the lumi information came from
270  self.varList.append(('matched', 'i'))
271 
272  for (var, type) in self.varList:
273  if self.updatemode:
274  self.loadBranch(var)
275 
276  else:
277  self.defineBranch(var, type)
278 
279  def initBCIDData(self):
280 
281  self.bcidData = True
282 
283  # Delivered luminosity
284  self.lumiDel = array.array('f', (0.,)*3564)
285  self.qBeam1 = array.array('f', (0.,)*3564) # Charge per BCID
286  self.qBeam2 = array.array('f', (0.,)*3564)
287  self.liveFrac = array.array('f', (0.,)*3564) # Deadtime
288 
289  if self.updatemode:
290  self.tree.GetBranch('lumiDel').SetAddress(self.lumiDel)
291  self.tree.GetBranch('qBeam1').SetAddress(self.qBeam1)
292  self.tree.GetBranch('qBeam2').SetAddress(self.qBeam2)
293  self.tree.GetBranch('liveFrac').SetAddress(self.liveFrac)
294 
295 
296  else:
297  self.tree.Branch('lumiDel', self.lumiDel, 'lumiDel[3564]/F')
298  self.tree.Branch('qBeam1', self.qBeam1, 'qBeam1[3564]/F')
299  self.tree.Branch('qBeam2', self.qBeam2, 'qBeam2[3564]/F')
300  self.tree.Branch('liveFrac', self.liveFrac, 'liveFrac[3564]/F') # Per-BCID livetime from lumi counters
301 
302  # BCID arrays (unsigned shorts)
303  self.b1BCID = array.array('H', (0,)*3564)
304  self.b2BCID = array.array('H', (0,)*3564)
305  self.colBCID = array.array('H', (0,)*3564)
306 
307  if self.updatemode:
308  self.tree.GetBranch('b1BCID').SetAddress(self.b1BCID)
309  self.tree.GetBranch('b2BCID').SetAddress(self.b2BCID)
310  self.tree.GetBranch('colBCID').SetAddress(self.colBCID)
311  else:
312  self.tree.Branch('b1BCID', self.b1BCID, 'b1BCID[nBeam1]/s') # Unsigned short
313  self.tree.Branch('b2BCID', self.b2BCID, 'b2BCID[nBeam2]/s') # Unsigned short
314  self.tree.Branch('colBCID', self.colBCID, 'colBCID[nColl]/s') # Unsigned short
315 
316  def initL1TrigData(self):
317 
318  self.l1TrigData = True
319 
320  # Counts by channel ID
321  self.l1TBP = array.array('I', (0,)*256)
322  self.l1TAP = array.array('I', (0,)*256)
323  self.l1TAV = array.array('I', (0,)*256)
324 
325  if self.updatemode:
326  self.tree.GetBranch('l1TBP').SetAddress(self.l1TBP)
327  self.tree.GetBranch('l1TAP').SetAddress(self.l1TAP)
328  self.tree.GetBranch('l1TAV').SetAddress(self.l1TAV)
329 
330  else:
331  self.tree.Branch('l1TBP', self.l1TBP, 'l1TBP[256]/i')
332  self.tree.Branch('l1TAP', self.l1TAP, 'l1TAP[256]/i')
333  self.tree.Branch('l1TAV', self.l1TAV, 'l1TAV[256]/i')
334 
335 
336  # Set all ntuple variables to default values
337  def clear(self):
338 
339  self.lbData.startTime = 0
340  self.lbData.endTime = 0
341  self.lbData.lbTime = 0.
342  self.lbData.fill = 0
343  self.lbData.run = 0
344  self.lbData.lb = 0
345  self.lbData.eBeam = 0.
346 
347  self.lbData.stable = False
348  self.lbData.ready = False
349  self.lbData.physics = False
350  self.lbData.larVeto = False
351 
352  self.lbData.onlPrefChan = 0
353  self.lbData.muToLumi = 0.
354  self.lbData.onlInstLum = -1.
355  self.lbData.onlInstLumAll = -1.
356  self.lbData.onlEvtsPerBX = -1.
357  self.lbData.onlValid = 0xFFFFFF
358  self.lbData.olcValid = 0xFFFFFF
359 
360  self.lbData.nColl = 0
361  self.lbData.nBeam1 = 0
362  self.lbData.nBeam2 = 0
363  self.lbData.qBeam1Col = -1.
364  self.lbData.qBeam2Col = -1.
365  self.lbData.qBeam1All = -1.
366  self.lbData.qBeam2All = -1.
367 
368  self.lbData.specLumi = -1.
369  self.lbData.geomLumi = -1.
370  self.lbData.maxEvtsPerBX = -1.
371 
372  self.lbData.l1LiveFrac = -1.
373  self.lbData.avgLiveFrac = -1.
374  self.lbData.lumiWtLiveFrac = -1.
375 
376  self.lbData.matched = 0
377 
378  if self.bcidData:
379 
380  # Per-BCID arrays
381  for i in range(3564):
382  self.lumiDel[i] = 0.
383  self.qBeam1[i] = 0.
384  self.qBeam2[i] = 0.
385  self.liveFrac[i] = 0.
386  self.b1BCID[i] = 0
387  self.b2BCID[i] = 0
388  self.colBCID[i] = 0
389 
390  if self.l1TrigData:
391 
392  # L1 trigger counts
393  for i in range(256):
394  self.l1TBP[i] = 0
395  self.l1TAP[i] = 0
396  self.l1TAV[i] = 0
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename R::value_type > sorted(const R &r, PROJ proj={})
Helper function to create a sorted vector from an unsorted range.
python.TrigNtupleHandler.TrigNtupleHandler.fillL1Trig
def fillL1Trig(self, trigData, trigChan)
Definition: TrigNtupleHandler.py:155
python.TrigNtupleHandler.TrigNtupleHandler.init
def init(self)
Definition: TrigNtupleHandler.py:55
python.TrigNtupleHandler.TrigNtupleHandler.qBeam1
qBeam1
Definition: TrigNtupleHandler.py:285
python.TrigNtupleHandler.TrigNtupleHandler.lumiDel
lumiDel
Definition: TrigNtupleHandler.py:284
python.TrigNtupleHandler.TrigNtupleHandler.colBCID
colBCID
Definition: TrigNtupleHandler.py:305
GetEntries
TGraphErrors * GetEntries(TH2F *histo)
Definition: TRTCalib_makeplots.cxx:4019
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
python.TrigNtupleHandler.TrigNtupleHandler.liveFrac
liveFrac
Definition: TrigNtupleHandler.py:287
python.TrigNtupleHandler.TrigNtupleHandler.bcidData
bcidData
Definition: TrigNtupleHandler.py:28
Get
T * Get(TFile &f, const std::string &n, const std::string &dir="", const chainmap_t *chainmap=0, std::vector< std::string > *saved=0)
get a histogram given a path, and an optional initial directory if histogram is not found,...
Definition: comparitor.cxx:181
python.TrigNtupleHandler.TrigNtupleHandler.l1TBP
l1TBP
Definition: TrigNtupleHandler.py:321
python.TrigNtupleHandler.TrigNtupleHandler.defineBranch
def defineBranch(self, name, type)
Definition: TrigNtupleHandler.py:161
python.TrigNtupleHandler.TrigNtupleHandler.fileName
fileName
Definition: TrigNtupleHandler.py:21
python.TrigNtupleHandler.TrigNtupleHandler.l1TAP
l1TAP
Definition: TrigNtupleHandler.py:322
python.TrigNtupleHandler.TrigNtupleHandler.readLastEntry
def readLastEntry(self)
Definition: TrigNtupleHandler.py:64
python.TrigNtupleHandler.TrigNtupleHandler.open
def open(self, update=True)
Definition: TrigNtupleHandler.py:33
python.TrigNtupleHandler.TrigNtupleHandler.lbData
lbData
Definition: TrigNtupleHandler.py:221
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:194
python.TrigNtupleHandler.TrigNtupleHandler.close
def close(self)
Definition: TrigNtupleHandler.py:49
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
python.TrigNtupleHandler.TrigNtupleHandler.file
file
Definition: TrigNtupleHandler.py:23
python.TrigNtupleHandler.TrigNtupleHandler.__init__
def __init__(self)
Definition: TrigNtupleHandler.py:19
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:26
python.TrigNtupleHandler.TrigNtupleHandler.initBCIDData
def initBCIDData(self)
Definition: TrigNtupleHandler.py:279
python.TrigNtupleHandler.TrigNtupleHandler.b1BCID
b1BCID
Definition: TrigNtupleHandler.py:303
python.TrigNtupleHandler.TrigNtupleHandler.tree
tree
Definition: TrigNtupleHandler.py:24
python.TrigNtupleHandler.TrigNtupleHandler
Definition: TrigNtupleHandler.py:17
python.TrigNtupleHandler.TrigNtupleHandler.loadBranch
def loadBranch(self, name)
Definition: TrigNtupleHandler.py:164
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
python.TrigNtupleHandler.TrigNtupleHandler.b2BCID
b2BCID
Definition: TrigNtupleHandler.py:304
python.TrigNtupleHandler.TrigNtupleHandler.qBeam2
qBeam2
Definition: TrigNtupleHandler.py:286
python.TrigNtupleHandler.TrigNtupleHandler.l1TrigData
l1TrigData
Definition: TrigNtupleHandler.py:31
python.TrigNtupleHandler.TrigNtupleHandler.varList
varList
Definition: TrigNtupleHandler.py:223
python.TrigNtupleHandler.TrigNtupleHandler.fillLumi
def fillLumi(self, lumi)
Definition: TrigNtupleHandler.py:69
python.TrigNtupleHandler.TrigNtupleHandler.l1TAV
l1TAV
Definition: TrigNtupleHandler.py:323
python.TrigNtupleHandler.TrigNtupleHandler.initL1TrigData
def initL1TrigData(self)
Definition: TrigNtupleHandler.py:316
python.TrigNtupleHandler.TrigNtupleHandler.initLBData
def initLBData(self)
Definition: TrigNtupleHandler.py:168
python.TrigNtupleHandler.TrigNtupleHandler.updatemode
updatemode
Definition: TrigNtupleHandler.py:25
python.TrigNtupleHandler.TrigNtupleHandler.save
def save(self)
Definition: TrigNtupleHandler.py:61
python.TrigNtupleHandler.TrigNtupleHandler.treeName
treeName
Definition: TrigNtupleHandler.py:22
python.TrigNtupleHandler.TrigNtupleHandler.clear
def clear(self)
Definition: TrigNtupleHandler.py:337