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