ATLAS Offline Software
TriggerHandler.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 # TriggerHandler
6 #
7 # Eric Torrence - October 2011
8 #
9 # Contents:
10 # TriggerL1Data - L1 data object
11 # TriggerHandler - utility tool to find trigger-based information from COOL
12 #
13 
14 from __future__ import print_function
15 import sys
16 import time
17 import calendar
18 
19 from PyCool import cool
20 from CoolLumiUtilities.CoolDataReader import CoolDataReader
21 
22 #
23 # Data object to hold L1 trigger count information
24 #
26 
27  def __init__(self):
28 
29  self.clear()
30 
31  def clear(self):
32  # Dictionaries keyed by L1 trigger name
33  self.TBP = dict()
34  self.TAP = dict()
35  self.TAV = dict()
36 
37  self.startTime = 0.
38  self.endtime = 0.
39  self.runlb = 0
40 
41  # Duration of this lumi block (in seconds)
42  self.dtime = 0.
43 
44 # Main LumiHandler class for retrieving luminosity data from DB
45 
47 
48  def __init__(self):
49 
50  # Database parameters
51  self.menuReader = CoolDataReader('COOLONL_TRIGGER/COMP200', '/TRIGGER/LVL1/Menu')
52  self.countsReader = CoolDataReader('COOLONL_TRIGGER/COMP200', '/TRIGGER/LUMI/LVL1COUNTERS')
53  self.lbtimeReader = CoolDataReader('COOLONL_TRIGGER/COMP200', '/TRIGGER/LUMI/LBTIME')
54  self.lblbReader = CoolDataReader('COOLONL_TRIGGER/COMP200', '/TRIGGER/LUMI/LBLB')
55 
56  self.verbose = False
57  #self.verbose = True
58 
59  # Dict of all TrigL1Data objects for the given time interval (keyed by RunLB IOV)
60  self.trigL1Dict = dict()
61 
62  self.allL1Triggers = False
63 
64  # List of all trigger items to read
65  self.trigList = ['L1_MBTS_2', 'L1_EM30']
66 
67  # Dictionary of trigger channel number keyed by trigger name
68  self.trigChan = dict()
69  self.chanTrig = dict() # reverse order
70 
71  # Store the lumi block times
72  self.lblbDict = dict()
73 
74  # Clear all data
75  def clear(self):
76 
77  # Clear trigger dict
78  self.trigL1Dict.clear()
79 
80  # Find trigger information in iovrange by time
81  def loadData(self, startIOV, endIOV):
82 
83  self.clear()
84 
85  # Runlist holds specific runs in this time range
86  self.runlist = []
87 
88  if self.verbose: print('Searching for trigger information for max IOVRange', timeString(startIOV), timeString(endIOV))
89 
90  # Load the run based information as we fundamentally need to do this by run number
91 
92  # Prepare the lbtime reader
93  self.lbtimeReader.setIOVRange(startIOV, endIOV)
94  self.lbtimeReader.readData()
95 
96  for obj in self.lbtimeReader.data:
97 
98  runnum = int(obj.payload()['Run'])
99 
100  if runnum not in self.runlist:
101  self.runlist.append(runnum)
102 
103  # Loop over each run, getting the trigger counts/Lumi
104  # Must do this by run, as trigger menu can change
105  # Here we are storing this in a separate list
106  for runnum in self.runlist:
107  self.loadDataByRun(runnum, clear=False)
108 
109 
110  # Find trigger information by run
111  def loadDataByRun(self, runnum, clear=True):
112 
113  if self.verbose:
114  print('TriggerHandler.loadDataByRun(%d) called' % runnum)
115 
116  if clear:
117  self.clear()
118 
119  # Figure out the channel mappings for the L1 trigger items
120  self.loadTrigChannels(runnum)
121 
122  # Get the LB durations
123  self.loadLBLBData(runnum)
124 
125  # Third, get the trigger counts
126  self.loadTrigCounts(runnum)
127 
128  # Read LBLB data
129  def loadLBLBData(self, runnum):
130 
131  if self.verbose:
132  print('TriggerHandler.loadLBLBData(%d) called' % runnum)
133 
134  self.lblbDict.clear()
135  self.lblbReader.setIOVRangeFromRun(runnum)
136  self.lblbReader.readData()
137 
138  for obj in self.lblbReader.data:
139  self.lblbDict[obj.since()] = (obj.payload()['StartTime'], obj.payload()['EndTime'])
140 
141  # Read trigger channel mappings
142  # Fills self.trigChan based on values in self.trigList
143  def loadTrigChannels(self, runnum):
144 
145  if self.verbose:
146  print('TriggerHandler.loadTrigChannels(%d) called' % runnum)
147 
148  # Trigger channels keyed by name
149  self.trigChan = dict()
150 
151  # Trigger name keyed by channel
152  self.chanTrig = dict()
153 
154  for trig in self.trigList:
155  self.trigChan[trig] = -1
156 
157  self.menuReader.setIOVRangeFromRun(runnum)
158  self.menuReader.readData()
159 
160  for obj in self.menuReader.data:
161 
162  if self.verbose or True: print(int(obj.channelId()), obj.payload()['ItemName'])
163 
164  trigName = obj.payload()['ItemName']
165  trigChan = int(obj.channelId())
166 
167  if self.allL1Triggers or self.trigList.count(trigName) > 0:
168  self.trigChan[trigName] = trigChan
169  self.chanTrig[trigChan] = trigName
170 
171  for trig in self.trigList:
172  if self.trigChan[trig] == -1:
173  print("Couldn't find", trig, "in run", str(runnum))
174 
175  if self.verbose:
176  for (trig, chan) in self.trigChan.iteritems():
177  print('Found', trig, 'in channel', chan)
178 
179  # Load all trigger counts for the given run
180  # Fills counts for all triggers with channels found in self.trigChan
181  def loadTrigCounts(self, runnum):
182 
183  if self.verbose:
184  print('TriggerHandler.loadTrigCounts(%d) called' % runnum)
185 
186  self.countsReader.setIOVRangeFromRun(runnum)
187 
188  # Build channel list
189  chanList = self.trigChan.values()
190  chanList.sort()
191 
192  nMaxChan = 50
193  nChanBlock = 0
194  chanBlock = []
195 
196  # Skip any trigger we didn't find
197  tmpList = []
198  for chan in chanList:
199  if chan < 0: continue
200  tmpList.append( chan )
201  chanList = tmpList
202 
203  if self.verbose:
204  print('breaking up', len(chanList), 'into', nMaxChan, 'for run', runnum)
205 
206  # There is a 50 item limit somehow hardcoded into browseObjects.
207  # Use this code from Elliot to get around the limitation.
208 
209  # Break up list of indices into blocks:
210  for x in range(0, len(chanList), nMaxChan):
211  top = min([x+nMaxChan, len(chanList)])
212 
213  if self.verbose:
214  print('Initializing block [%d] from %d to %d' % (nChanBlock, x, top))
215 
216  chanBlock.append( chanList[x:top] )
217  nChanBlock += 1
218 
219  for x in range(nChanBlock):
220  if self.verbose: print('Channel Selector', chanBlock[x])
221  self.countsReader.setChannel(chanBlock[x])
222  self.countsReader.readData()
223 
224  for obj in self.countsReader.data:
225 
226  since = obj.since()
227  until = obj.until()
228  if self.verbose:
229  print(runLBString(since), runLBString(until), obj.channelId(), obj.payload()['BeforePrescale'], obj.payload()['AfterPrescale'], obj.payload()['L1Accept'])
230 
231  # use the string as the dictionary key
232  ss = since
233  chan = int(obj.channelId())
234  trig = self.chanTrig.get(chan, "")
235  if len(trig) == 0:
236  print('TriggerHandler.loadTrigCounts(%d) - found unknown channel %d in %s!' % (runnum, chan, runLBString(ss)))
237  continue
238 
239  if ss not in self.trigL1Dict:
240  self.trigL1Dict[ss] = TriggerL1Data()
241  self.trigL1Dict[ss].runlb = obj.since()
242  self.trigL1Dict[ss].startTime = self.lblbDict.get(ss, (0., 0.))[0]
243  self.trigL1Dict[ss].endTime = self.lblbDict.get(ss, (0., 0.))[1]
244  self.trigL1Dict[ss].dtime = (self.trigL1Dict[ss].endTime - self.trigL1Dict[ss].startTime)/1.E9
245 
246  self.trigL1Dict[ss].TBP[trig] = obj.payload()['BeforePrescale']
247  self.trigL1Dict[ss].TAP[trig] = obj.payload()['AfterPrescale']
248  self.trigL1Dict[ss].TAV[trig] = obj.payload()['L1Accept']
249 
250 def timeVal(val):
251  "Convert argument to time in seconds, treating as a literal or date"
252  try:
253  a=int(val)
254  return a
255  except ValueError:
256  try:
257  ts=time.strptime(val,'%Y-%m-%d:%H:%M:%S/%Z')
258  return int(calendar.timegm(ts))*1000000000
259 
260  # Try again with UTC attached
261  except ValueError:
262  try:
263  ts=time.strptime(val+'/UTC', '%Y-%m-%d:%H:%M:%S/%Z')
264  return int(calendar.timegm(ts))*1000000000
265 
266  except ValueError:
267  print("ERROR in time specification:",val,"- use e.g. 2007-05-25:14:01:00/UTC")
268  sys.exit(-1)
269 
270 def timeString(iovkey):
271  "Convert the IOVtime (63 bit) to a string representing timestamp"
272  if (iovkey==cool.ValidityKeyMin):
273  return "ValidityKeyMin"
274  elif (iovkey==cool.ValidityKeyMax):
275  return "ValidityKeyMax"
276  else:
277  # Round to avoid bias if microseconds exist
278  stime=int(round(iovkey/1000000000))
279  return time.strftime('%Y-%m-%d:%H:%M:%S/UTC', time.gmtime(stime))
280 
281 def runLBString(iovkey):
282  "Convert the IOVtime (63 bit) to a string representing timestamp"
283  if (iovkey==cool.ValidityKeyMin):
284  return "ValidityKeyMin"
285  elif (iovkey==cool.ValidityKeyMax):
286  return "ValidityKeyMax"
287  else:
288  # Round to avoid bias if microseconds exist
289  run = iovkey >> 32
290  lb = iovkey & 0xFFFFFFFF
291  return "%d/%d" % (run, lb)
292 
293 
294 # Executed from the command line, for testing only
295 if __name__ == '__main__':
297  th.verbose = True
298  th.allL1Triggers = True
299  tstart = '2011-10-16:06:00:00'
300  tend = '2011-10-17:04:00:00'
301 
302  th.loadData(timeVal(tstart), timeVal(tend))
python.TriggerHandler.TriggerHandler
Definition: TriggerHandler.py:46
python.Bindings.iteritems
iteritems
Definition: Control/AthenaPython/python/Bindings.py:820
python.TriggerHandler.TriggerL1Data.runlb
runlb
Definition: TriggerHandler.py:39
python.TriggerHandler.TriggerHandler.lbtimeReader
lbtimeReader
Definition: TriggerHandler.py:53
python.TriggerHandler.TriggerL1Data.startTime
startTime
Definition: TriggerHandler.py:37
python.TriggerHandler.TriggerHandler.menuReader
menuReader
Definition: TriggerHandler.py:51
python.TriggerHandler.TriggerHandler.lblbReader
lblbReader
Definition: TriggerHandler.py:54
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.TriggerHandler.TriggerHandler.trigChan
trigChan
Definition: TriggerHandler.py:68
python.TriggerHandler.TriggerHandler.loadDataByRun
def loadDataByRun(self, runnum, clear=True)
Definition: TriggerHandler.py:111
python.TriggerHandler.TriggerL1Data.TAV
TAV
Definition: TriggerHandler.py:35
python.TriggerHandler.TriggerHandler.clear
def clear(self)
Definition: TriggerHandler.py:75
MuonGM::round
float round(const float toRound, const unsigned int decimals)
Definition: Mdt.cxx:27
python.TriggerHandler.TriggerHandler.lblbDict
lblbDict
Definition: TriggerHandler.py:72
python.TriggerHandler.timeVal
def timeVal(val)
Definition: TriggerHandler.py:250
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
python.TriggerHandler.TriggerL1Data.endtime
endtime
Definition: TriggerHandler.py:38
python.TriggerHandler.TriggerL1Data
Definition: TriggerHandler.py:25
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
python.TriggerHandler.timeString
def timeString(iovkey)
Definition: TriggerHandler.py:270
python.TriggerHandler.TriggerL1Data.TBP
TBP
Definition: TriggerHandler.py:33
python.Bindings.values
values
Definition: Control/AthenaPython/python/Bindings.py:805
python.TriggerHandler.TriggerHandler.chanTrig
chanTrig
Definition: TriggerHandler.py:69
python.TriggerHandler.TriggerL1Data.dtime
dtime
Definition: TriggerHandler.py:42
python.TriggerHandler.TriggerHandler.countsReader
countsReader
Definition: TriggerHandler.py:52
python.TriggerHandler.TriggerL1Data.clear
def clear(self)
Definition: TriggerHandler.py:31
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
python.TriggerHandler.TriggerHandler.allL1Triggers
allL1Triggers
Definition: TriggerHandler.py:62
python.TriggerHandler.TriggerHandler.__init__
def __init__(self)
Definition: TriggerHandler.py:48
python.TriggerHandler.TriggerHandler.verbose
verbose
Definition: TriggerHandler.py:56
min
#define min(a, b)
Definition: cfImp.cxx:40
python.TriggerHandler.TriggerHandler.runlist
runlist
Definition: TriggerHandler.py:86
python.TriggerHandler.TriggerHandler.loadData
def loadData(self, startIOV, endIOV)
Definition: TriggerHandler.py:81
python.TriggerHandler.TriggerHandler.loadTrigChannels
def loadTrigChannels(self, runnum)
Definition: TriggerHandler.py:143
python.TriggerHandler.TriggerL1Data.__init__
def __init__(self)
Definition: TriggerHandler.py:27
python.TriggerHandler.TriggerHandler.trigL1Dict
trigL1Dict
Definition: TriggerHandler.py:60
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:127
python.TriggerHandler.TriggerL1Data.TAP
TAP
Definition: TriggerHandler.py:34
python.TriggerHandler.TriggerHandler.loadTrigCounts
def loadTrigCounts(self, runnum)
Definition: TriggerHandler.py:181
str
Definition: BTagTrackIpAccessor.cxx:11
dbg::print
void print(std::FILE *stream, std::format_string< Args... > fmt, Args &&... args)
Definition: SGImplSvc.cxx:70
python.TriggerHandler.TriggerHandler.loadLBLBData
def loadLBLBData(self, runnum)
Definition: TriggerHandler.py:129
python.TriggerHandler.TriggerHandler.trigList
trigList
Definition: TriggerHandler.py:65
python.TriggerHandler.runLBString
def runLBString(iovkey)
Definition: TriggerHandler.py:281