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