ATLAS Offline Software
dbgAnalysis.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
4 
5 # @brief: Pre and Post debug_stream analysis operations for trigger transform
6 # @details: Code to carry out operations that are needed for running
7 # the trigger debug_stream analysis in transform
8 # @author: Carlos Chavez
9 
10 import os
11 import eformat
12 from TrigTransform.dbgEventInfo import dbgEventInfo
13 from TrigConfStorage.TriggerCoolUtil import TriggerCoolUtil
14 from TrigConfIO.L1TriggerConfigAccess import L1MenuAccess
15 from TrigConfIO.HLTTriggerConfigAccess import HLTMenuAccess
16 
17 from ROOT import TFile, TH1F
18 
19 import logging
20 msg = logging.getLogger("PyJobTransforms." + __name__)
21 
22 # As an optional argument dictionary with config data extracted from arguments can be passed
23 def dbgPreRun(inputFileList, outputFileList, argdict = None):
24  msg.info('Running debug_stream analysis PreRun operations on files :{0} '.format(inputFileList))
25  msg.info('Running debug_stream analysis PreRun, histogram output in :{0} '.format(outputFileList))
26 
27  # Open root output file
28  outFile = outputFileList[0]
29  hfile = TFile(outFile, 'RECREATE')
30 
31  maxEvents = argdict.get('maxEvents')
32  maxEvents = maxEvents.value.get('first') if maxEvents else -1
33 
34  skipEvents = argdict.get('skipEvents')
35  skipEvents = skipEvents.value.get('first') if skipEvents else 0
36 
37  # Initialize dbgEventInfo, this is the main event analysis class
38  eventInfo = dbgEventInfo('_Pre', inputFileList.value[0])
39  data = []
40  l1Info = []
41  hltInfo = []
42  configKeys = None
43  for inputFile in inputFileList.value:
44  bsfile = eformat.istream(inputFile)
45  n = 0
46  isFirstEvent = True
47 
48  bsfile = bsfile[skipEvents:skipEvents+maxEvents] if maxEvents > -1 else bsfile[skipEvents:]
49 
50  for event in bsfile:
51 
52  if isFirstEvent:
53  runNumber = event.run_no() if event.run_no() else int(inputFile.split(".")[1])
54  configKeys = getHLTConfigKeys(runNumber, argdict)
55 
56  if not argdict.get('useDB'):
57  msg.debug("Reading chains and items from database is skipped (missing --useDB=True)")
58  l1Info, hltInfo = ([], [])
59  else:
60  l1Info, hltInfo = TriggerDBInfo(configKeys.get('DB'), configKeys.get('SMK'))
61 
62  isFirstEvent = False
63 
64  # Log the details of first 5 events
65  n += 1
66  if n < 5:
67  data = [event.run_no(), event.lumi_block(), event.global_id(),
68  event.lvl1_id(), event.bc_time_seconds(), event.bc_time_nanoseconds()]
69  msg.info('Event details :%s', data)
70 
71  # Run debug event analysis and fill output TTree
72  eventInfo.eventCount(event)
73  eventInfo.eventInfo(event, l1Info, hltInfo)
74  eventInfo.eventConfig(configKeys, event)
75  eventInfo.fillTree()
76 
77  # Close output TFile
78  hfile.Write()
79  hfile.Close()
80 
81  msg.info('Finished running debug_stream analysis PreRun operations')
82 
83  dbAlias = configKeys.get('DB')
84 
85  # Check release format, if relInfo is 'unknown' then print error
86  if 'REL' in configKeys:
87  # Returns the local asetupString from runs in input files and to be used by asetup
88  return getAsetupString(configKeys['REL']), dbAlias
89  else:
90  msg.warn("Release not found in configuration - asetup string won't be created")
91 
92  # Without release and project asetup string is not available
93  return None, dbAlias
94 
95 
96 def dbgPostRun(inputFile, outputFile, argdict = None, isSplitStream=False):
97  msg.info('Running debug_stream analysis PostRun operations on files :{0} '.format(inputFile))
98  msg.info('Running debug_stream analysis PostRun, histogram output in :{0} '.format(outputFile))
99 
100  # Open root output file
101  hfile = TFile(outputFile, 'UPDATE')
102 
103  # Inicialize dbgEventInfo, this is the main event analysis class
104  if isSplitStream:
105  eventInfo = dbgEventInfo('_Pos_Split', inputFile)
106  else:
107  eventInfo = dbgEventInfo('_Pos', inputFile)
108  data = []
109  l1Info = []
110  hltInfo = []
111  configKeys = None
112 
113  bsfile = eformat.istream(inputFile)
114  n = 0
115  isFirstEvent = True
116 
117  for event in bsfile:
118  # If fist event get l1 and hlt counter and chain info from DB
119  if isFirstEvent:
120  configKeys = getHLTConfigKeys(event.run_no(), argdict)
121 
122  if not argdict.get('useDB'):
123  msg.debug("Reading chains and items from database is skipped (missing --useDB=True)")
124  l1Info, hltInfo = ([], [])
125  else:
126  l1Info, hltInfo = TriggerDBInfo(configKeys.get('DB'), configKeys.get('SMK'))
127 
128  isFirstEvent = False
129 
130  # Log the details of first 5 events
131  n += 1
132  if n < 5:
133  data = [event.run_no(), event.lumi_block(), event.global_id(),
134  event.lvl1_id(), event.bc_time_seconds(), event.bc_time_nanoseconds()]
135  msg.info('Event details :{0}'.format(data))
136 
137  # Run debug event analysis and fill output TTree
138  eventInfo.eventCount(event)
139  eventInfo.eventInfo(event, l1Info, hltInfo)
140  eventInfo.eventConfig(configKeys, event)
141  eventInfo.fillTree()
142 
143  # Close output TFile
144  hfile.Write()
145  hfile.Close()
146  msg.info('Finished running debug_stream analysis PostRun operations')
147 
148 
149 def TriggerDBInfo(dbalias = None, smk = None):
150  l1Info = []
151  hltInfo = []
152 
153  if not dbalias or not smk:
154  msg.warn("Reading chains and items from database is skipped (config keys are not available)")
155  return (l1Info, hltInfo)
156 
157  # L1 DB Info
158  try:
159  l1Cfg = L1MenuAccess(dbalias = dbalias, smkey = smk)
160 
161  # Create map id to item and then fill the array
162  # that on i spot has item with i ctpid
163  l1Items = l1Cfg.items()
164  l1ItemsMap = {}
165  for item in l1Items:
166  ctpid = l1Items[item]['ctpid']
167  l1ItemsMap[ctpid] = item
168 
169  l1Info = (max(l1ItemsMap.keys()) + 1) * [0]
170 
171  for item in l1ItemsMap:
172  l1Info[item] = l1ItemsMap[item]
173 
174  except RuntimeError:
175  msg.info("Database for L1 Menu not available")
176 
177  # HLT DB Info
178  try:
179  hltCfg = HLTMenuAccess(dbalias = dbalias, smkey = smk)
180  hltChains = hltCfg.chains()
181  hltChainsMap = {}
182  for chain in hltChains:
183  counter = hltChains[chain]['counter']
184  hltChainsMap[counter] = chain
185 
186  hltInfo = (max(hltChainsMap.keys()) + 1) * [0]
187 
188  for chain in hltChainsMap:
189  hltInfo[chain] = hltChainsMap[chain]
190  except RuntimeError:
191  msg.info("Database for HLT Menu not available")
192 
193 
194  return (l1Info, hltInfo)
195 
196 
197 def getAsetupString(release):
198 
199  asetupString = release
200 
201  # If TestArea is for tzero (tzero/software/patches/AtlasP1HLT-RELEASE),
202  # then returns tzero/software/patches/AtlasP1HLT-release where release is
203  # the parameter given to this function getAsetupString(release)
204  if os.environ['TestArea']:
205  TestArea = os.environ['TestArea']
206  if TestArea.find('tzero/software/patches/AthenaP1-') > 0:
207  testarea = TestArea.split('-')
208  TestArea = testarea[0] + '-' + release
209  asetupString += ' --testarea ' + TestArea
210 
211  return asetupString
212 
213 
214 def getHLTConfigKeys(runNumber = None, args = None):
215  '''
216  Returns map with config keys:
217  DB - database alias
218  REL - release
219  SMK - Super Master Key
220  HLTPSK - HLT Prescale key
221  '''
222 
223  dbconn = TriggerCoolUtil.GetConnection("CONDBR2")
224  configKeys = TriggerCoolUtil.getHLTConfigKeys(dbconn, [[runNumber, runNumber]])
225 
226  if configKeys and runNumber in configKeys.keys():
227  configKeys = configKeys[runNumber]
228 
229  configKeys['HLTPSK'] = TriggerCoolUtil.getHLTPrescaleKeys(dbconn, [[runNumber, runNumber]])[runNumber]['HLTPSK2']
230 
231  msg.info("Found config keys %s", configKeys)
232  else:
233  msg.info("Config keys not found in COOL")
234  configKeys = getHLTConfigFromArgs(args)
235 
236  if 'DB' in configKeys:
237  if 'DBserver' in args and configKeys['DB'] != args['DBserver'].value:
238  msg.warn("Different database read from config keys ({0}) and from args ({1})".format(configKeys['DB'], args['DBserver'].value))
239  msg.warn("Database {0} from config keys will be used.".format(configKeys['DB']))
240 
241  return configKeys
242 
243 
245  '''
246  Prepare dictionary with data extracted from arguments if available. Contains:
247  DB - database alias
248  SMK - Super Master Key
249  HLTPSC - HLT Prescale key
250  '''
251 
252  configKeys = {}
253 
254  try:
255  configKeys['DB'] = args['DBserver'].value
256  configKeys['SMK'] = int(args['DBsmkey'].value)
257  configKeys['HLTPSK'] = int(args['DBhltpskey'].value)
258 
259  msg.info("Found config keys in args %s", configKeys)
260 
261  except KeyError:
262  msg.warn("Config keys not found in argdict")
263  return {}
264 
265  return configKeys
266 
267 def getHltDecision(accepted, rejected, outputFile):
268  '''
269  Add HLT_accepted_events and HLT_rejected_events to outputFile
270  '''
271 
272  # Open root output file
273  hfile = TFile(outputFile, 'UPDATE')
274  # Define a new histogram called HLT_rejected_events
275  HLT_rejected_events = TH1F("HLT_rejected_events", "HLT_rejected_events", 3, 0.0, 3.0)
276  # Define a new histogram called HLT_accepted_events
277  HLT_accepted_events = TH1F("HLT_accepted_events", "HLT_accepted_events", 3, 0.0, 3.0)
278 
279  # Fill the histogram if events are rejected by the HLT
280  # HLT_rejected_events are assigned the value 1
281  # If all events are accepted the Histogram is empty
282  HLT_rejected_events.Fill(1, rejected)
283 
284  # Fill the histogram if events are accepted by the HLT
285  # HLT_accepted_events are assigned the value 1
286  # If all events are rejected the Histogram is empty
287  HLT_accepted_events.Fill(1, accepted)
288 
289  # Close output TFile
290  hfile.Write("", TFile.kOverwrite)
291  hfile.Close()
292  return msg.info("Added HLT_accepted_events and HLT_rejeceted_events to %s", outputFile)
293 
python.dbgAnalysis.dbgPreRun
def dbgPreRun(inputFileList, outputFileList, argdict=None)
Definition: dbgAnalysis.py:23
max
#define max(a, b)
Definition: cfImp.cxx:41
vtune_athena.format
format
Definition: vtune_athena.py:14
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.dbgAnalysis.getHLTConfigKeys
def getHLTConfigKeys(runNumber=None, args=None)
Definition: dbgAnalysis.py:214
python.dbgAnalysis.getHltDecision
def getHltDecision(accepted, rejected, outputFile)
Definition: dbgAnalysis.py:267
python.dbgAnalysis.TriggerDBInfo
def TriggerDBInfo(dbalias=None, smk=None)
Definition: dbgAnalysis.py:149
python.dbgAnalysis.dbgPostRun
def dbgPostRun(inputFile, outputFile, argdict=None, isSplitStream=False)
Definition: dbgAnalysis.py:96
python.dbgAnalysis.getAsetupString
def getAsetupString(release)
Definition: dbgAnalysis.py:197
python.dbgAnalysis.getHLTConfigFromArgs
def getHLTConfigFromArgs(args)
Definition: dbgAnalysis.py:244
python.TrigEgammaMonitorHelper.TH1F
def TH1F(name, title, nxbins, bins_par2, bins_par3=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:24