ATLAS Offline Software
TrigJetMonitorAlgorithm.py
Go to the documentation of this file.
1 #
2 # Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 #
4 
5 '''@file MTMonitoring.py
6 @authors P-A. Delsart, Jona Bossio
7 @date 03/04/2020
8 @brief Python configuration for the Run III Trigger Jet Monitoring
9 '''
10 
11 from AthenaCommon.Logging import logging
12 logger = logging.getLogger(__name__)
13 
14 from TrigDecisionTool.TrigDecisionToolConfig import getRun3NavigationContainerFromInput
15 
16 from JetMonitoring.JetStandardHistoSpecs import knownHistos
17 import math
18 import re
19 import copy
20 
21 
22 
25 
26 copySuffix = "copied" # suffix for jet containters that are duplicated for monitoring
27 
28 
31 
32 OfflineJetCollections = dict()
33 
34 OfflineJetCollections['pp'] = {
35  'AntiKt4EMTopoJets' : { 'MatchTo' : 'AntiKt4EMPFlowJets' },
36  'AntiKt4EMPFlowJets' : { 'MatchTo' : 'NONE' },
37  #'AntiKt10LCTopoTrimmedPtFrac5SmallR20Jets' : { 'MatchTo' : 'NONE' }, # Remove until ATR-25800 is fixed
38 }
39 
40 OfflineJetCollections['HI'] = {
41  'AntiKt4HIJets' : { 'MatchTo' : 'AntiKt4HIJets' },
42 }
43 
44 
47 
48 # The MatchedTo list must be either empty of length 2, and contain the names of an offline collection
49 # and an HLT collection. These names can be the empty string.
50 
51 # the strings in L1JetCollections are jet container names.
52 L1JetCollections = dict()
53 
54 match_smallRL1_OfflineJets_List = ['AntiKt4EMPFlowJets', 'HLT_AntiKt4EMPFlowJets_subresjesgscIS_ftf']
55 # temporarily modified to use small-R offline jet in turn-on to fix tier0 jet mon crash ATR-25800!! - throws exception if < 2 jet collections provided
56 match_largeRL1_OfflineJets_List = ['AntiKt4EMPFlowJets', 'HLT_AntiKt10EMPFlowCSSKSoftDropBeta100Zcut10Jets_jes_ftf']
57 match_HIL1_OfflineJets_List = ['AntiKt4HIJets', 'HLT_AntiKt4HIJets']
58 
59 L1JetCollections['pp'] = {
60 
61  'LVL1JetRoIs' : {
62  'MatchTo' : match_smallRL1_OfflineJets_List},
63 
64  'L1_jFexSRJetRoI': {'MatchTo': match_smallRL1_OfflineJets_List},
65 
66  'L1_gFexSRJetRoI': {'MatchTo': match_smallRL1_OfflineJets_List},
67 
68  'L1_gFexLRJetRoI': {'MatchTo': match_largeRL1_OfflineJets_List},
69 }
70 
71 L1JetCollections['HI'] = {
72  'LVL1JetRoIs' : {'MatchTo' : match_HIL1_OfflineJets_List},
73  'L1_jFexSRJetRoI': {'MatchTo': match_HIL1_OfflineJets_List},
74  'L1_gFexSRJetRoI': {'MatchTo': match_HIL1_OfflineJets_List},
75 }
76 
77 for case in L1JetCollections.keys():
78  try:
79  items = L1JetCollections[case].items()
80  except (AttributeError, TypeError):
81  raise RuntimeError('L1JetCollections for %s is not a mapping type'%case)
82 
83  for k, d in items:
84  try:
85  d_items = d.items()
86  except (AttributeError, TypeError):
87  raise RuntimeError('L1JetCollections value for %s is not a mapping type'%case)
88 
89  if 'MatchTo' not in d:
90  errmsg = 'L1Collections entry %s has no (possibly empty) MatchType list' % (
91  str(k))
92  raise RuntimeError(errmsg)
93 
94 # Now seeing new L1 containers of differing types. These types
95 # are explicit in the C++ JetMatcher algorithm, and correspond
96 # top different attributes of that algorithm.
97 #
98 # l1Coll2MatcherKey supplies the python name of
99 # C++ component attribute.
100 
101 l1Coll2MatcherKey = {
102  'LVL1JetRoIs': 'L1JetContainerName1',
103  'L1_jFexSRJetRoI': 'L1jFexSRJetRoIContainerName',
104  'L1_gFexSRJetRoI': 'L1gFexJetRoIContainerName',
105  'L1_gFexLRJetRoI': 'L1gFexJetRoIContainerName',
106 }
107 
108 for case in L1JetCollections.keys():
109  for k, d in L1JetCollections[case].items():
110  if d['MatchTo']: # exists by previous checks. check if empty.
111  if k not in l1Coll2MatcherKey:
112  errmsg = 'Match(es) to an L1 container requested entry '\
113  '%s but no C++ MatcherAlg attribute name provided' % (str(k),)
114  raise RuntimeError(errmsg)
115 
116 
117 # the values of Chain2L1JetCollDict are keys of L1JetCollections.
118 # the keys of Chain2L1JetCollDict are used to select events before histograms are filled
119 
120 Chain2L1JetCollDict = dict()
121 
122 Chain2L1JetCollDict['pp'] = { # set L1 jet collection name for L1 jet chains
123  'L1_J15': ['LVL1JetRoIs'],
124  'L1_J20': ['LVL1JetRoIs'],
125  'L1_J100': ['LVL1JetRoIs'],
126 
127  'L1_jJ40': ['L1_jFexSRJetRoI'],
128  'L1_jJ50': ['L1_jFexSRJetRoI'],
129  'L1_jJ160': ['L1_jFexSRJetRoI'],
130  'L1_jJ85p0ETA21_3jJ40p0ETA25': ['L1_jFexSRJetRoI'],
131  'L1_3jJ70p0ETA23': ['L1_jFexSRJetRoI'],
132  'L1_4jJ40': ['L1_jFexSRJetRoI'],
133 
134  'L1_gJ20': ['L1_gFexSRJetRoI'],
135  'L1_gJ50': ['L1_gFexSRJetRoI'],
136  'L1_gJ100': ['L1_gFexSRJetRoI'],
137 
138  'L1_gJ160': ['L1_gFexSRJetRoI'],
139 
140  'L1_gLJ80': ['L1_gFexLRJetRoI'],
141  'L1_gLJ120': ['L1_gFexLRJetRoI'],
142  'L1_gLJ140': ['L1_gFexLRJetRoI'],
143 
144  'L1_SC111-CjJ40': ['L1_jFexSRJetRoI'],
145  'L1_HT190-jJ40s5pETA21': ['L1_jFexSRJetRoI'],
146 }
147 
148 Chain2L1JetCollDict['HI'] = {
149  'L1_J15': ['LVL1JetRoIs'],
150  'L1_J20': ['LVL1JetRoIs'],
151  'L1_J100': ['LVL1JetRoIs'],
152 }
153 
154 
155 Legacy2PhaseIjJThresholdDict = {
156  'J5' : 'jJ20',
157  'J12' : 'jJ30',
158  'J15' : 'jJ40',
159  '4J15' : '4jJ40',
160  'J20' : 'jJ50',
161  'J25' : 'jJ55',
162  'J30' : 'jJ60',
163  'J35' : 'jJ70',
164  'J40' : 'jJ80',
165  'J45' : 'jJ85',
166  'J50' : 'jJ90',
167  'J75' : 'jJ125',
168  'J85' : 'jJ140',
169  'J100' : 'jJ160',
170  'J120' : 'jJ180',
171  'J400' : 'jJ500',
172 }
173 Legacy2PhaseIgJThresholdDict = {
174  'J5' : 'gJ20',
175  'J12' : 'gJ30',
176  'J15' : 'gJ40',
177  '4J15' : '4gJ40',
178  'J20' : 'gJ50',
179  'J25' : 'gJ55',
180  'J30' : 'gJ60',
181  'J35' : 'gJ70',
182  'J40' : 'gJ80',
183  'J45' : 'gJ85',
184  'J50' : 'gJ90',
185  'J75' : 'gJ125',
186  'J85' : 'gJ140',
187  'J100' : 'gJ160',
188  'J120' : 'gJ180',
189  'J400' : 'gJ500',
190 }
191 
192 Legacy2PhaseIgLJThresholdDict = {
193  'J100' : 'gLJ140'
194 }
195 
196 
199 
200 # List of HLT jet collections (stating
201 # which should be matched and to which offline jet collection
202 
203 JetCollections = dict()
204 
205 JetCollections['pp'] = {
206  'HLT_AntiKt4EMTopoJets_subjesIS' : { 'MatchTo' : 'AntiKt4EMPFlowJets'}, # default small-R EM
207  'HLT_AntiKt4EMTopoJets_subjesIS_fastftag' : { 'MatchTo' : 'NONE'}, # small-R EM jets with RoI tracking & fast flavour tagging
208  'HLT_AntiKt4EMTopoJets_subresjesgscIS_ftf' : { 'MatchTo' : 'AntiKt4EMPFlowJets'}, # a4 calo jet w/ FTF
209  'HLT_AntiKt4EMTopoJets_subjesgscIS_ftf' : { 'MatchTo' : 'AntiKt4EMPFlowJets'}, # a4 calo jet w/ calo+track GSC, reconstructed by MET
210  'HLT_AntiKt4EMPFlowJets_subjesgscIS_ftf' : { 'MatchTo' : 'AntiKt4EMPFlowJets'}, # a4 pflow w/ calo+track GSC, reconstructed by MET
211  'HLT_AntiKt4EMPFlowJets_subresjesgscIS_ftf' : { 'MatchTo' : 'AntiKt4EMPFlowJets'}, # a4 pflow w/ residual + calo+track GSC
212  'HLT_AntiKt4EMPFlowJets_nojcalib_ftf' : { 'MatchTo' : 'NONE'}, # a4 pflow nojcalib
213  'HLT_AntiKt10EMTopoRCJets_subjesIS' : { 'MatchTo' : 'NONE'}, # a10r
214  'HLT_AntiKt10LCTopoJets_subjes' : { 'MatchTo' : 'NONE'}, # a10
215  'HLT_AntiKt10LCTopoTrimmedPtFrac4SmallR20Jets_jes' : { 'MatchTo' : 'NONE'}, # a10t
216  'HLT_AntiKt10EMPFlowCSSKSoftDropBeta100Zcut10Jets_nojcalib_ftf' : { 'MatchTo' : 'NONE'}, # a10sd pflow cssk nojcalib
217  'HLT_AntiKt10EMPFlowCSSKSoftDropBeta100Zcut10Jets_jes_ftf' : { 'MatchTo' : 'NONE'}, # a10sd pflow cssk jes
218 }
219 
220 JetCollections['HI'] = {
221  'HLT_AntiKt4HIJets' : {'MatchTo': 'AntiKt4HIJets'},
222  'HLT_AntiKt4EMTopoJets_subjesIS' : {'MatchTo': 'AntiKt4HIJets'},
223  'HLT_AntiKt4EMPFlowJets_jes_ftf' : {'MatchTo': 'AntiKt4HIJets'}
224 }
225 
226 
227 def getChains2Monitor(inputFlags, monMode):
228 
229  Chains2Monitor = dict()
230  from TrigConfigSvc.TriggerConfigAccess import getHLTMonitoringAccess
231  monAccess = getHLTMonitoringAccess(inputFlags)
232 
233  # set HLT jet collection, reference chain and offline jet collection
234  # for turn-on curves
235  ListOfMonChains = monAccess.monitoredChains(signatures="jetMon", monLevels = ["shifter","t0"])
236 
237  default_dict = {"HLTColl": "NONE", "RefChain": "NONE" ,"OfflineColl": "NONE"}
238  Chains2Monitor[monMode] = dict((chain, default_dict.copy()) for chain in ListOfMonChains)
239 
240  if monMode == 'HI':
241  for chainName in Chains2Monitor['HI']:
242  if '_ion_' in chainName:
243  Chains2Monitor['HI'][chainName]["HLTColl"] = "HLT_AntiKt4HIJets"
244  Chains2Monitor['HI'][chainName]["OfflineColl"] = "AntiKt4HIJets"
245  else:
246  Chains2Monitor['HI'][chainName]["HLTColl"] = "HLT_AntiKt4EMTopoJets_subjesIS"
247  Chains2Monitor['HI'][chainName]["OfflineColl"] = "AntiKt4EMPFlowJets"
248  elif monMode == "pp":
249  # logic to define HLTColl, RefChain, OfflineColl
250  for chainName in Chains2Monitor['pp']:
251  Chains2Monitor['pp'][chainName]["HLTColl"] = "HLT_AntiKt4EMTopoJets_subjesIS"
252  if '_pf_' in chainName and 'a10' not in chainName:
253  Chains2Monitor['pp'][chainName]["HLTColl"] = "HLT_AntiKt4EMPFlowJets_subresjesgscIS_ftf"
254  Chains2Monitor['pp'][chainName]["OfflineColl"] = "AntiKt4EMPFlowJets"
255  elif 'a10' in chainName:
256  if 'a10t' in chainName: Chains2Monitor['pp'][chainName]["HLTColl"] = "HLT_AntiKt10LCTopoTrimmedPtFrac4SmallR20Jets_jes"
257  elif 'sd_cssk_pf' in chainName: Chains2Monitor['pp'][chainName]["HLTColl"] = "HLT_AntiKt10EMPFlowCSSKSoftDropBeta100Zcut10Jets_jes_ftf"
258  elif 'a10r' in chainName: Chains2Monitor['pp'][chainName]["HLTColl"] = "HLT_AntiKt10EMTopoRCJets_subjesIS"
259  else: Chains2Monitor['pp'][chainName]["HLTColl"] = "HLT_AntiKt10LCTopoJets_subjes"
260  elif '_noalg_' in chainName:
261  Chains2Monitor['pp'][chainName]["RefChain"] = "HLT_j45_pf_ftf_preselj20_L1jJ40" # temporarily modify to using small-R jet in turn-on for both small and large-R jets to fix tier0 jet mon crash ATR-25800!!
262  Chains2Monitor['pp'][chainName]["OfflineColl"] = "AntiKt4EMPFlowJets"
263  if 'gLJ' in chainName: Chains2Monitor['pp'][chainName]["HLTColl"] = "HLT_AntiKt10EMPFlowCSSKSoftDropBeta100Zcut10Jets_jes_ftf"
264  else: continue
265 
266  # only HLT_noalg get efficiency curves by default, so...
267  # these are additional hard-coded chains for efficiency monitoring
268  if Chains2Monitor['pp'].get('HLT_j420_L1J100'): Chains2Monitor['pp']['HLT_j420_L1J100'].update({"RefChain": "HLT_j85_L1J20", "OfflineColl": "AntiKt4EMPFlowJets"})
269  if Chains2Monitor['pp'].get('HLT_3j200_L1J100'): Chains2Monitor['pp']['HLT_3j200_L1J100'].update({"RefChain": "HLT_j85_L1J20", "OfflineColl": "AntiKt4EMPFlowJets"})
270  if Chains2Monitor['pp'].get('HLT_4j120_L13J50'): Chains2Monitor['pp']['HLT_4j120_L13J50'].update({"RefChain": "HLT_j85_L1J20", "OfflineColl": "AntiKt4EMPFlowJets"})
271  if Chains2Monitor['pp'].get('HLT_5j80_pf_ftf_presel5j50_L14J15'): Chains2Monitor['pp']['HLT_5j80_pf_ftf_presel5j50_L14J15'].update({"RefChain": "HLT_j45_pf_ftf_preselj20_L1J15", "OfflineColl": "AntiKt4EMPFlowJets"})
272  if Chains2Monitor['pp'].get('HLT_j400_pf_ftf_L1J100'): Chains2Monitor['pp']['HLT_j400_pf_ftf_L1J100'].update({"RefChain": "HLT_j85_pf_ftf_preselj50_L1J20", "OfflineColl": "AntiKt4EMPFlowJets"})
273  if Chains2Monitor['pp'].get('HLT_j400_pf_ftf_preselj225_L1J100'): Chains2Monitor['pp']['HLT_j400_pf_ftf_preselj225_L1J100'].update({"RefChain": "HLT_j85_pf_ftf_preselj50_L1J20", "OfflineColl": "AntiKt4EMPFlowJets"})
274 
275  if Chains2Monitor['pp'].get('HLT_j420_L1jJ160'): Chains2Monitor['pp']['HLT_j420_L1jJ160'].update({"RefChain": "HLT_j85_L1jJ50", "OfflineColl": "AntiKt4EMPFlowJets"})
276  if Chains2Monitor['pp'].get('HLT_3j200_L1jJ160'): Chains2Monitor['pp']['HLT_3j200_L1jJ160'].update({"RefChain": "HLT_j85_L1jJ50", "OfflineColl": "AntiKt4EMPFlowJets"})
277  if Chains2Monitor['pp'].get('HLT_4j120_L13jJ90'): Chains2Monitor['pp']['HLT_4j120_L13jJ90'].update({"RefChain": "HLT_j85_L1jJ50", "OfflineColl": "AntiKt4EMPFlowJets"})
278  if Chains2Monitor['pp'].get('HLT_5j80_pf_ftf_presel5j50_L14jJ40'): Chains2Monitor['pp']['HLT_5j80_pf_ftf_presel5j50_L14jJ40'].update({"RefChain": "HLT_j45_pf_ftf_preselj20_L1jJ40", "OfflineColl": "AntiKt4EMPFlowJets"})
279  if Chains2Monitor['pp'].get('HLT_j400_pf_ftf_L1jJ160'): Chains2Monitor['pp']['HLT_j400_pf_ftf_L1jJ160'].update({"RefChain": "HLT_j85_pf_ftf_preselj50_L1jJ50", "OfflineColl": "AntiKt4EMPFlowJets"})
280  if Chains2Monitor['pp'].get('HLT_j400_pf_ftf_preselj225_L1jJ160'): Chains2Monitor['pp']['HLT_j400_pf_ftf_preselj225_L1jJ160'].update({"RefChain": "HLT_j85_pf_ftf_preselj50_L1jJ50", "OfflineColl": "AntiKt4EMPFlowJets"})
281 
282  else:
283  errmsg = 'Returned empty Chains2Monitor due to invalid monMode'
284  raise RuntimeError(errmsg)
285  return Chains2Monitor
286 
287 
290 
291 def getEtaRange(chain):
292  etaMin,etaMax = 0,2.5 # central jets by default
293  if 'eta' in chain:
294  etaParts = chain.split('eta')
295  etaMinTemp = etaParts[0].split('_')
296  etaMin = etaMinTemp[len(etaMinTemp)-1]
297  etaMin = int(etaMin)/10
298  etaMax = etaParts[1].split('_')[0]
299  etaMax = int(etaMax)/10
300  return etaMin,etaMax
301 
302 def getBinningFromThreshold(chain,varname):
303  #default binning if nothing below applies
304  xbins, xmin, xmax = 160,0.,800000.
305  #pt and et binning based on threshold
306  if varname == "pt" or varname == "et":
307  if 'noalg' in chain:
308  if 'jJ500' in chain or 'J400' in chain: return 160,xmin,800000
309  else: return 100,xmin,500000 # good enough for L1 jJ40 & jJ100
310  else:
311  #threshold = int(chain.split("_")[1].split('j')[1])
312  threshold = int(re.search(r'\d+',chain.split("_")[1].split('j')[1]).group())
313  if threshold < 50:
314  return 40, 0., 100000.
315  if threshold < 120:
316  return 36, 20000., 200000.
317 
318  xbins = 40
319  xmin = 50000.+100000.*(int(threshold/100)-1) #example: threshold = 330 -> 250 to 450; threshold = 420 -> 350 to 550
320  if threshold % 100 == 0: #gives enough low bins if threshold is an exact divider of 100 GeV such as 3j200
321  xmin = 1000.*(threshold - 100.)
322  xmax = xmin + 200000.
323  if "a10" in chain: # efficiency curve broader for large-R jets
324  xmin = xmin - 50000.
325  xmax = xmax + 50000.
326  if "pf" in chain:
327  xmax = xmax + 50000. # needed to include efficiency plateau for large-R PFlow chains
328  if "smc" in chain:
329  xmax = xmax + 50000. # efficiency plateau even higher for a10 pdf smc chains due to imperfect calibration
330  #mass binning for large-R smc chains
331  elif varname == "m":
332  xbins, xmin, xmax = 35, 30000., 100000.
333  return xbins, xmin, xmax
334 
335 def getHTBinning(chain,binwidth):
336  parts = chain.split('HT')
337  threshold = parts[1].split('_')[0]
338  if 'XX' in threshold:
339  threshold = threshold.split('XX')[0]
340  xmin = int(0.9 * int(threshold)) # xmin to make the threshold visible
341  xmax = xmin + 500
342  xbins = int((xmax-xmin)/binwidth)-1
343  return xbins, xmin, xmax
344 
345 # Add fast flavour-tag monitoring.
346 # Adds a 20 GeV jet pT cut to avoid FPE WARNINGS from jets below min jet pT for RoI track association
347 def addFlavourTagVariables(conf, network_prefix, flavs="cub"):
348  cutname='pt20'
349  fillerTools = []
350  for f in flavs:
351  xvar = f"{network_prefix}_p{f}"
352  varname = f"ftag_p{f}"
353  fillerTools += [HistoSpec(varname, xvar=xvar, bins=(70, -0.2, 1.2), title=f"{varname};{varname};;Entries")]
354  fastDipsSelectSpec = SelectSpec(f"{network_prefix}_{cutname}", '20<pt:GeV&|eta|<3.2', path='NoTriggerSelection/'+cutname, FillerTools=fillerTools)
355  conf.appendHistos(fastDipsSelectSpec)
356 
357 
360 from JetMonitoring.JetMonitoringConfig import JetMonAlgSpec, HistoSpec, EventHistoSpec, SelectSpec, ToolSpec #VarSpec can be added to define specific/custom variables
361 from AthenaConfiguration.ComponentFactory import CompFactory
362 
363 # All offline jet collections
364 ExtraOfflineHists = [
365  "EMFrac",
366  "HECFrac",
367  "Jvt",
368  "JVFCorr",
369  "JvtRpt",
370  "NumTrkPt1000[0]",
371  "TrackWidthPt1000[0]",
372  "SumPtTrkPt500[0]",
373 ]
374 
375 # All online small-R jet collections
376 ExtraSmallROnlineHists = [
377  HistoSpec('et:GeV;eta', (100,0,750, 50,-5,5) , title='#eta vs E_{T};E_{T} [GeV];#eta;Entries'),
378  "EMFrac",
379  "HECFrac",
380  "DetectorEta",
381  "ActiveArea",
382  "EM3Frac",
383  "Tile0Frac",
384  "LooseBad",
385 ]
386 
387 # All online large-R jet collections
388 ExtraLargeROnlineHists = [
389 ]
390 
391 ExtraOnlineNJetHists = [
392  "njets",
393  "njetsEt20Eta0_32",
394  "njetsEt30Eta0_32",
395  "njetsEt50Eta0_32",
396  "njetsEt80Eta0_32",
397  "njetsPt20Eta0_32",
398  "njetsPt30Eta0_32",
399  "njetsPt50Eta0_32",
400  "njetsPt80Eta0_32",
401 ]
402 
403 # Kinematics at different scales for offline and small-R online jet collections
404 OfflineScaleMomenta = [ "ConstitScale", "EMScale", "PileupScale", "EtaJESScale"]
405 OnlineScaleMomenta = [ "ConstitScale" ]
406 for var in [ "pt", "eta", "m" ]:
407  for offlinescale in OfflineScaleMomenta:
408  ExtraOfflineHists.append("Jet"+offlinescale+"Momentum_"+var)
409  for onlinescale in OnlineScaleMomenta:
410  ExtraSmallROnlineHists.append("Jet"+onlinescale+"Momentum_"+var)
411 
412 OnlineScaleMomenta.append("") #Adding this for convenience in the jet matching loop below
413 OfflineScaleMomenta.append("")
414 
415 
416 def getJetCopyAlg(injets,outjets):
417  '''
418  Schedules JetCopier tool to make a shallow copy of
419  the original offline/HLT jet container, for the JetMatcherAlg to decorate.
420  This prevents our jet monitoring from decorating
421  the original jet containers, which may end up being
422  persistified in AOD/ESD (ATLASRECTS-7168,ATR-27980,ATR-26076)
423  '''
424  jcopy = CompFactory.JetCopier(
425  "copier",
426  InputJets = injets,
427  DecorDeps=[],
428  ShallowCopy=True,
429  ShallowIO=True)
430 
431  jprovider = CompFactory.JetRecAlg(
432  "jetalg_copy_"+outjets,
433  Provider = jcopy,
434  Modifiers = [],
435  OutputContainer = outjets,
436  MonTool = None)
437 
438  return jprovider
439 
440 def getL1JetCopyAlg(injets,outjets):
441  '''
442  Schedules L1JetCopyAlgorithm to make a shallow copy of
443  the original L1 jet container, for the JetMatcherAlg to decorate.
444  This prevents our jet monitoring from decorating
445  the original jet containers, which may end up being
446  persistified in AOD/ESD (ATLASRECTS-7168,ATR-27980,ATR-26076).
447  The L1JetCopyAlgorithm is a templated class (e.g. L1JetCopyAlgorithm<JTM_JetRoIContainer>).
448  The python class name is what is generated by Athena during build time.
449  The template types are defined in JTMContainers.h.
450  '''
451  jcopy_alg = None
452  jcopy_alg_name = "l1jetcopy_alg_"+injets
453  if injets == "LVL1JetRoIs":
454  jcopy_alg = CompFactory.L1JetCopyAlgorithm_JTM_JetRoIContainer_(jcopy_alg_name)
455  elif injets == "L1_jFexSRJetRoI":
456  jcopy_alg = CompFactory.L1JetCopyAlgorithm_JTM_jFexSRJetRoIContainer_(jcopy_alg_name)
457  elif injets in ["L1_gFexSRJetRoI", "L1_gFexLRJetRoI"]:
458  jcopy_alg = CompFactory.L1JetCopyAlgorithm_JTM_gFexJetRoIContainer_(jcopy_alg_name)
459  else:
460  raise ValueError(f"L1 jet container {injets} not recognised")
461  jcopy_alg.JetInContainerName = injets
462  jcopy_alg.JetOutContainerName = outjets
463 
464  return jcopy_alg
465 
466 def TrigJetMonConfig(inputFlags):
467 
468  from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
469  cfg = ComponentAccumulator()
470 
471  monMode = 'pp'
472  if inputFlags.Reco.EnableHI: monMode = 'HI'
473 
474  Chains2Monitor = getChains2Monitor(inputFlags, monMode)
475 
476  # Protections
477  # Add missing jet collections to JetCollections dict
478  # (this can happen if a given chain uses a jet collection that is not listed in JetCollections)
479  # TODO: make more general
480  for chain,chaindict in Chains2Monitor[monMode].items():
481  if chaindict['HLTColl'] not in JetCollections[case]: # chain will not be monitored unless HLT collection is present in JetCollections
482  JetCollections[case][chaindict['HLTColl']] = {'MatchTo': 'NONE'}
483 
484  # Match HLT jets to offline jets
485  CopiedJetCollections = copy.deepcopy(JetCollections)
486  for hltColl,collDict in JetCollections[monMode].items():
487  if collDict['MatchTo'] != 'NONE':
488  copiedhltColl = f'{hltColl}_{copySuffix}'
489  CopiedJetCollections[monMode][copiedhltColl] = CopiedJetCollections[monMode].pop(hltColl)
490  jetcopyalg = getJetCopyAlg(hltColl,copiedhltColl)
491  jetcopyalg.ExtraInputs.add(('xAOD::TrigCompositeContainer',
492  'StoreGateSvc+%s' % getRun3NavigationContainerFromInput(inputFlags)))
493  cfg.addEventAlgo(jetcopyalg)
494  for jetcalibscale in OnlineScaleMomenta:
495  scalestring = "_"+jetcalibscale if jetcalibscale != "" else ""
496  name = 'Matching_{}{}_{}'.format(hltColl,scalestring,collDict['MatchTo'])
497  alg = CompFactory.JetMatcherAlg(name,
498  JetContainerName1=copiedhltColl,
499  JetContainerName2=collDict['MatchTo'],
500  JetCalibScale=jetcalibscale)
501 
502  alg.ExtraInputs.add(('xAOD::TrigCompositeContainer',
503  'StoreGateSvc+%s' % getRun3NavigationContainerFromInput(inputFlags)))
504  cfg.addEventAlgo(alg)
505 
506  # Match offline to offline jets
507  CopiedOfflineJetCollections = copy.deepcopy(OfflineJetCollections)
508  for offjetColl,collDict in OfflineJetCollections[monMode].items():
509  if collDict['MatchTo'] != 'NONE':
510  copiedjetcoll = f'{offjetColl}_{copySuffix}'
511  CopiedOfflineJetCollections[monMode][copiedjetcoll] = CopiedOfflineJetCollections[monMode].pop(offjetColl)
512  jetcopyalg = getJetCopyAlg(offjetColl,copiedjetcoll)
513  cfg.addEventAlgo(jetcopyalg)
514  for jetcalibscale in OfflineScaleMomenta:
515  scalestring = "_"+jetcalibscale if jetcalibscale != "" else ""
516  name = 'Matching_{}{}_{}'.format(offjetColl,scalestring,collDict['MatchTo'])
517  alg = CompFactory.JetMatcherAlg(name,
518  JetContainerName1=copiedjetcoll,
519  JetContainerName2=collDict['MatchTo'],
520  JetCalibScale=jetcalibscale)
521 
522  alg.ExtraInputs.add(('xAOD::TrigCompositeContainer',
523  'StoreGateSvc+%s' % getRun3NavigationContainerFromInput(inputFlags)))
524  cfg.addEventAlgo(alg)
525 
526  # Make copy of every L1 jet collection
527  # Then match L1 to offline as well as HLT jets
528  CopiedL1JetCollections = copy.deepcopy(L1JetCollections)
529  for l1jetColl,collDict in L1JetCollections[monMode].items():
530  copiedl1jetColl = f'{l1jetColl}_{copySuffix}'
531  CopiedL1JetCollections[monMode][copiedl1jetColl] = CopiedL1JetCollections[monMode].pop(l1jetColl)
532  l1jetcopyalg = getL1JetCopyAlg(l1jetColl,copiedl1jetColl)
533  l1jetcopyalg.ExtraInputs.add(('xAOD::TrigCompositeContainer',
534  'StoreGateSvc+%s' % getRun3NavigationContainerFromInput(inputFlags)))
535  cfg.addEventAlgo(l1jetcopyalg)
536  for matchjetcoll in collDict['MatchTo']:
537 
538  kwds = {'name': 'Matching_{}_{}'.format(l1jetColl,matchjetcoll),
539  l1Coll2MatcherKey[l1jetColl]: copiedl1jetColl,
540  'JetContainerName2': matchjetcoll,
541  'MatchL1': True
542  }
543 
544  alg = CompFactory.JetMatcherAlg(**kwds)
545  alg.ExtraInputs.add(('xAOD::TrigCompositeContainer',
546  'StoreGateSvc+%s' % getRun3NavigationContainerFromInput(inputFlags)))
547  cfg.addEventAlgo(alg)
548 
549  # The following class will make a sequence, configure algorithms, and link
550  # them to GenericMonitoringTools
551  from AthenaMonitoring import AthMonitorCfgHelper
552  helper = AthMonitorCfgHelper(inputFlags,'TrigJetMonitorAlgorithm')
553  # Configure filter tools
554  from AthenaMonitoring.EventFlagFilterToolConfig import EventFlagFilterToolCfg
555  from AthenaMonitoring.BadLBFilterToolConfig import LArBadLBFilterToolCfg
556  # Loop over L1 jet collections
557  for jetcoll in CopiedL1JetCollections[monMode]:
558  l1jetconf = l1JetMonitoringConfig(inputFlags,jetcoll,CopiedL1JetCollections,monMode,'',True)
559  alg=l1jetconf.toAlg(helper)
560  alg.FilterTools = [ EventFlagFilterToolCfg(inputFlags),helper.resobj.popToolsAndMerge(LArBadLBFilterToolCfg(inputFlags))]
561 
562  # Loop over L1 jet chains
563  for chain,jetcolls in Chain2L1JetCollDict[monMode].items():
564  for jetcoll in jetcolls:
565  l1chainconf = l1JetMonitoringConfig(inputFlags,jetcoll,L1JetCollections,monMode,chain)
566  alg=l1chainconf.toAlg(helper)
567  alg.FilterTools = [ EventFlagFilterToolCfg(inputFlags),helper.resobj.popToolsAndMerge(LArBadLBFilterToolCfg(inputFlags))]
568 
569  # Loop over offline jet collections
570  for jetcoll in CopiedOfflineJetCollections[monMode]:
571  offlineMonitorConf = jetMonitoringConfig(inputFlags,jetcoll,CopiedOfflineJetCollections,monMode)
572  alg=offlineMonitorConf.toAlg(helper)
573  alg.FilterTools = [ EventFlagFilterToolCfg(inputFlags),helper.resobj.popToolsAndMerge(LArBadLBFilterToolCfg(inputFlags))]
574 
575  # Loop over HLT jet collections
576  for jetcoll in CopiedJetCollections[monMode]:
577  monitorConf = jetMonitoringConfig(inputFlags,jetcoll,CopiedJetCollections,monMode)
578  # then we turn the full specification into properly configured algorithm and tools.
579  # we use the method 'toAlg()' defined for the specialized dictionnary 'JetMonAlgSpec'
580  monitorConf.toAlg(helper)
581 
582  # Loop over HLT jet chains
583  for chain,chainDict in Chains2Monitor[monMode].items():
584  jetcoll = chainDict['HLTColl']
585  # kinematic plots
586  # only use passing jets
587  chainMonitorConfT = jetChainMonitoringConfig(inputFlags,jetcoll,chain,True)
588  alg=chainMonitorConfT.toAlg(helper)
589  alg.FilterTools = [ EventFlagFilterToolCfg(inputFlags),helper.resobj.popToolsAndMerge(LArBadLBFilterToolCfg(inputFlags))]
590  # all jets
591  chainMonitorConfF = jetChainMonitoringConfig(inputFlags,jetcoll,chain,False)
592  alg=chainMonitorConfF.toAlg(helper)
593  alg.FilterTools = [ EventFlagFilterToolCfg(inputFlags),helper.resobj.popToolsAndMerge(LArBadLBFilterToolCfg(inputFlags))]
594  # efficiency plots
595  if chainDict['RefChain'] != 'NONE' and chainDict['OfflineColl'] != 'NONE':
596  effMonitorConf = jetEfficiencyMonitoringConfig(inputFlags,jetcoll,chainDict['OfflineColl'],chain,chainDict['RefChain'])
597  effMonitorConf.toAlg(helper)
598 
599  cfg.merge(helper.result())
600  return cfg
601 
602 
603 # Basic selection of histograms common for online and offline jets
604 def basicJetMonAlgSpec(jetcoll,isOnline):
605  # we use a specialized dictionnary (JetMonAlgSpec) which will be translated into the final C++ tool
606  path = 'NoTriggerSelection' if isOnline else 'standardHistos/'
607  minNjetBin = 1 if isOnline else 0
608 
609  TopLevelDir = 'HLT/JetMon/'
610  TopLevelDir += 'Online/' if isOnline else 'Offline/'
611 
612  jetcollFolder = jetcoll
613  jetcollFolder=jetcoll.replace(f"_{copySuffix}","")
614  Conf = JetMonAlgSpec(jetcoll+"Mon",JetContainerName = jetcoll, defaultPath = path, topLevelDir=TopLevelDir, bottomLevelDir=jetcollFolder, failureOnMissingContainer=False)
615 
616  # Now start filling the histo spec list
617  knownHistos['phi_tight'] = HistoSpec('phi_tight',
618  (50,-math.pi,math.pi),
619  title='#phi;#phi;Entries',
620  xvar='phi')
621  Conf.appendHistos(
622  # See knownHistos in JetStandardHistoSpecs.py
623  # for the list of standard specification.
624  "pt",
625  "m",
626  "eta",
627  "phi",
628  "phi_tight",
629  "e",
630  "et",
631  # or we can directly add our custom histo specification in the form of a HistoSpec:
632  # the basic call is : HistoSpec( variable, histobins, title='histotile;xtitle,ytitle')
633 
634  # Say we want a 2nd 'pt' plot but with a different binning than in the standard spec.
635  # WARNING : we can not re-use the same spec name in a given JetMonitoringAlg !!!
636  # so we give a new name AND we specify the actual variable with the argument 'xvar'
637  # (the ':GeV' means the variable is to be set at GeV scale)
638  #HistoSpec( 'lowpt', (100,0,150) , title='p_{T};p_{T} [GeV];', xvar='pt:GeV'),
639  # An equivalent solution would have been to clone the existing spec like in :
640  # knownHistos.pt.clone('lowpt',bins= (100,0,200) ),
641 
642  # 2D histos are usually refered to by concatenating vars with a ';' as in 'varx;vary'
643  # if the 'vax;vary' alias doesn't exist in knownHistos but 'varx' and 'vary'
644  # do exist, then a spec fot 'vax;vary' will be automatically generated.
645  "pt;m", # mass vs pt
646  "eta;phi", # phi vs eta
647  "eta;e", # energy vs eta
648  "phi;e", # energy vs phi
649  "phi_tight;e", # energy vs phi
650 
651  SelectSpec( 'central', '|eta|<3.2', path, FillerTools = ["pt","et","m"] ),
652  SelectSpec( 'forward', '3.2<|eta|', path, FillerTools = ["pt","et","m"] ),
653  SelectSpec( 'lowmu', 'avgMu<30', path, isEventVariable=True, FillerTools = ["pt","et","m","phi","eta"]),
654  SelectSpec( 'highmu', '30<avgMu', path, isEventVariable=True, FillerTools = ["pt","et","m","phi","eta"]),
655  # To select on multiple variables simultaneously, simply combine the selection strings via &
656  # Example below to select on ET > 100 GeV and |eta| > 3.2:
657  # SelectSpec( 'ETeta', '100<et:GeV&|eta|<3.2', path, FillerTools = ["pt","et","m","eta"] )
658  EventHistoSpec('njets', (25,minNjetBin,25), title='NJets;NJets;Entries' ),
659  EventHistoSpec('njetsPt20', (25,minNjetBin,25), title='NJetsPt20;NJetsPt20;Entries' ),
660  EventHistoSpec('njetsPt50', (25,minNjetBin,25), title='NJetsPt50;NJetsPt50;Entries' ),
661  # Jet multiplicity histograms can be added by using an EventHistoSpec
662  # Their specifications (pT cut, ET cut, eta cuts) must be defined in the knownEventVar dictionary within JetStandardHistoSpecs.py
663  # The following line is an example for a jet multiplicity histogram with ET>40 GeV, 1.0<|eta|<2.0, and binning of (10,0,10):
664  # EventHistoSpec('njetsEt40Eta1_2', (10,0,10), title='NJetsEt40Eta1_2;NJetsEt40Eta1_2;Entries' ),
665 
666  # TProfile2D : just use 3 variables. For now the sytem will automatically
667  # interpret it as a TProfile2D (the 3rd variable being profiled)
668  #"phi;eta;e", # --> Average Energy vs pt and eta
669 
670  # another possible selections : only sub-leading jets and highJVF
671  #SelectSpec( 'subleading',
672  # '', # no selection on variables
673  # SelectedIndex=1, # force 2nd (sub-leading) jet (we would set 0 for leading jets)
674  # path='standardHistos', # force the path where the histos are saved in the final ROOT file
675  # FillerTools = [
676  # "pt",
677  # "m",
678  # ] ),
679  #SelectSpec( 'highJVF',
680  # '0.3<JVF[0]', # JVF is a vector<float> for each jets. Here we cut on the 0th entry of this vector
681  # FillerTools = [
682  # "pt",
683  # ] ),
684  )
685 
686  return Conf
687 
688 def jetMonitoringConfig(inputFlags,jetcoll,jetCollDict,monMode):
689  '''Function to configures some algorithms in the monitoring system.'''
690 
691  isOnline = True if 'HLT' in jetcoll else False
692  conf = basicJetMonAlgSpec(jetcoll,isOnline)
693 
694  jetCollMonDetails = jetCollDict[monMode][jetcoll]
695 
696  # Declare a configuration dictionnary for a JetContainer
697  if isOnline:
698  if 'AntiKt4' in jetcoll or 'a4tcem' in jetcoll:
699  for hist in ExtraSmallROnlineHists: conf.appendHistos(hist)
700  if 'ftf' in jetcoll: # dedicated histograms for FTF chains
701  conf.appendHistos("Jvt")
702  conf.appendHistos("JVFCorr")
703  conf.appendHistos("JvtRpt")
704  conf.appendHistos("SumPtTrkPt500[0]")
705  conf.appendHistos("NumTrkPt1000[0]")
706  conf.appendHistos("TrackWidthPt1000[0]")
707  if 'PF' in jetcoll: # dedicated histograms for online PFlow jets
708  conf.appendHistos("SumPtChargedPFOPt500[0]")
709  conf.appendHistos("fCharged")
710  if "subresjesgscIS" in jetcoll:
711  addFlavourTagVariables(conf,"fastDIPS20211215")
712  addFlavourTagVariables(conf,"GN120230331")
713  addFlavourTagVariables(conf,"tlaGN220240122")
714  if 'fastftag' in jetcoll:
715  addFlavourTagVariables(conf,"fastDips")
716  addFlavourTagVariables(conf, "fastGN120230327")
717  addFlavourTagVariables(conf,"fastGN220240122")
718  addFlavourTagVariables(conf,"fastGNTau20240216", flavs=["tau", "u"])
719  if 'EMTopo' in jetcoll: #dedicated histograms for online EMTopo jets
720  conf.appendHistos("Timing")
721  else:
722  for hist in ExtraLargeROnlineHists: conf.appendHistos(hist)
723  # Add matched jets plots
724  if jetCollMonDetails['MatchTo'] != 'NONE':
725  def defineHistoForHLTJetMatch(conf, parentAlg, monhelper , path):
726  # create a monitoring group with the histo path starting from the parentAlg
727  group = monhelper.addGroup(parentAlg, conf.Group, conf.topLevelDir+'/'+conf.bottomLevelDir+'/NoTriggerSelection/')
728  # define the histograms
729  for histname in [ 'ptdiff', 'energydiff', 'massdiff' ]: #defines which variable difference will be plotted
730  group.defineHistogram(histname,title=histname, type="TH1F",
731  path='MatchedJets_{}'.format(jetCollMonDetails['MatchTo']),
732  xbins=100 , xmin=-100000., xmax=100000. ,)
733 
734  for histname in [ 'ptresp', 'energyresp', 'massresp' ]:
735  group.defineHistogram(histname,title=histname, type="TH1F",
736  path='MatchedJets_{}'.format(jetCollMonDetails['MatchTo']),
737  xbins=100 , xmin=-2., xmax=2. ,)
738 
739  group.defineHistogram('ptresp,ptref;ptresp_vs_ptRef',title='ptresponse vs ptRef', type="TH2F",
740  path='MatchedJets_{}'.format(jetCollMonDetails['MatchTo']),
741  xbins=10 , xmin=-2., xmax=2., ybins=10, ymin=0., ymax=500000.,)
742 
743  group.defineHistogram('ptresp,etaref;ptresp_vs_etaRef',title='ptresponse vs etaRef', type="TH2F",
744  path='MatchedJets_{}'.format(jetCollMonDetails['MatchTo']),
745  xbins=10 , xmin=-2., xmax=2., ybins=10, ymin=-5., ymax=5.,)
746 
747  matchedJetColl = jetCollMonDetails['MatchTo']
748 
749  # we can get specific calibration scales by adding e.g. '_EtaJESScale' to the strings
750  jetmatchKey = '{}.matched_{}'.format(jetcoll,matchedJetColl)
751  jetptdiffKey = '{}.ptdiff_{}'.format(jetcoll,matchedJetColl)
752  jetenergydiffKey = '{}.energydiff_{}'.format(jetcoll,matchedJetColl)
753  jetmassdiffKey = '{}.massdiff_{}'.format(jetcoll,matchedJetColl)
754  jetptrespKey = '{}.ptresp_{}'.format(jetcoll,matchedJetColl)
755  jetenergyrespKey = '{}.energyresp_{}'.format(jetcoll,matchedJetColl)
756  jetmassrespKey = '{}.massresp_{}'.format(jetcoll,matchedJetColl)
757  jetptrefKey = '{}.ptRef_{}'.format(jetcoll,matchedJetColl)
758  jetetarefKey = '{}.etaRef_{}'.format(jetcoll,matchedJetColl)
759  name = 'jetMatched_{}_{}'.format(jetcoll,matchedJetColl)
760  conf.appendHistos(ToolSpec('JetHistoMatchedFiller', name,
761  JetMatchedKey=jetmatchKey, JetPtDiffKey=jetptdiffKey,
762  JetEnergyDiffKey=jetenergydiffKey,
763  JetMassDiffKey=jetmassdiffKey, JetPtRespKey=jetptrespKey,
764  JetEnergyRespKey=jetenergyrespKey, JetMassRespKey=jetmassrespKey,
765  JetPtRefKey=jetptrefKey,JetEtaRefKey=jetetarefKey,
766  defineHistoFunc=defineHistoForHLTJetMatch,Group='matchedJets_'+jetcoll)
767  )
768  else: # offline
769  for hist in ExtraOfflineHists: conf.appendHistos(hist)
770  if 'AntiKt4' in jetcoll and monMode=="pp":
771  conf.appendHistos(SelectSpec('LooseBadFailedJets', 'LooseBad',
772  InverseJetSel=True,
773  FillerTools = ["pt",
774  "phi",
775  "phi_tight",
776  "eta"])) #cleaning variables not applicable for large-R collections
777 
778  if 'PF' in jetcoll: # dedicated histograms for offline PFlow jets
779  conf.appendHistos("SumPtChargedPFOPt500[0]")
780  conf.appendHistos("fCharged")
781  elif 'EMTopo' in jetcoll:
782  conf.appendHistos("Timing")
783  if jetCollMonDetails['MatchTo'] != 'NONE':
784  def defineHistoForOfflineJetMatch(conf, parentAlg, monhelper , path):
785  # create a monitoring group with the histo path starting from the parentAlg
786  group = monhelper.addGroup(parentAlg, conf.Group, conf.topLevelDir+'/'+conf.bottomLevelDir+'/standardHistos/')
787  # define the histograms
788  for histname in [ 'ptdiff', 'energydiff', 'massdiff' ]: #defines which variable difference will be plotted
789  group.defineHistogram(histname,title=histname, type="TH1F",
790  path='MatchedJets_{}'.format(jetCollMonDetails['MatchTo']),
791  xbins=100 , xmin=-100000., xmax=100000. ,)
792 
793  for histname in [ 'ptresp', 'energyresp', 'massresp' ]:
794  group.defineHistogram(histname,title=histname, type="TH1F",
795  path='MatchedJets_{}'.format(jetCollMonDetails['MatchTo']),
796  xbins=100 , xmin=-2., xmax=2. ,)
797 
798  group.defineHistogram('ptresp,ptref;ptresp_vs_ptRef',title='ptresp vs ptRef', type="TH2F",
799  path='MatchedJets_{}'.format(jetCollMonDetails['MatchTo']),
800  xbins=10 , xmin=-2., xmax=2., ybins=10, ymin=0., ymax=500000.,)
801 
802  group.defineHistogram('ptresp,etaref;ptresp_vs_etaRef',title='ptresp vs etaRef', type="TH2F",
803  path='MatchedJets_{}'.format(jetCollMonDetails['MatchTo']),
804  xbins=10 , xmin=-2., xmax=2., ybins=10, ymin=-5., ymax=5.,)
805 
806  matchedJetColl = jetCollMonDetails['MatchTo']
807  jetmatchKey = '{}.matched_{}'.format(jetcoll,matchedJetColl)
808  jetptdiffKey = '{}.ptdiff_{}'.format(jetcoll,matchedJetColl)
809  jetenergydiffKey = '{}.energydiff_{}'.format(jetcoll,matchedJetColl)
810  jetmassdiffKey = '{}.massdiff_{}'.format(jetcoll,matchedJetColl)
811  jetptrespKey = '{}.ptresp_{}'.format(jetcoll,matchedJetColl)
812  jetenergyrespKey = '{}.energyresp_{}'.format(jetcoll,matchedJetColl)
813  jetmassrespKey = '{}.massresp_{}'.format(jetcoll,matchedJetColl)
814  jetptrefKey = '{}.ptRef_{}'.format(jetcoll,matchedJetColl)
815  jetetarefKey = '{}.etaRef_{}'.format(jetcoll,matchedJetColl)
816  name = 'jetMatched_{}_{}'.format(jetcoll,matchedJetColl)
817  conf.appendHistos(ToolSpec('JetHistoMatchedFiller',name,
818  JetMatchedKey=jetmatchKey, JetPtDiffKey=jetptdiffKey,
819  JetEnergyDiffKey=jetenergydiffKey,
820  JetMassDiffKey=jetmassdiffKey, JetPtRespKey=jetptrespKey,
821  JetEnergyRespKey=jetenergyrespKey,
822  JetMassRespKey=jetmassrespKey,
823  JetPtRefKey=jetptrefKey, JetEtaRefKey=jetetarefKey,
824  defineHistoFunc=defineHistoForOfflineJetMatch,Group='matchedJets_'+jetcoll)
825  )
826 
827  return conf
828 
829 def l1JetMonitoringConfig(inputFlags,jetColl, jetDict, monMode,chain='',matched=False):
830 
831  from TrigJetMonitoring.L1JetMonitoringConfig import L1JetMonAlg
832  name = jetColl if chain=='' else jetColl+'_'+chain
833 
834  jetCollKey = jetColl
835  jetColl = jetColl.replace(f"_{copySuffix}","")
836 
837  if not jetDict[monMode][jetCollKey]['MatchTo']:
838  conf = L1JetMonAlg(name,jetColl,jetCollKey,chain)
839  else:
840  assert len(jetDict[monMode][jetCollKey]['MatchTo']) == 2
841 
842  conf = L1JetMonAlg(name,jetColl,jetCollKey,chain,
843  matched,jetDict[monMode][jetCollKey]['MatchTo'][0],
844  jetDict[monMode][jetCollKey]['MatchTo'][1])
845 
846  return conf
847 
848 def jetChainMonitoringConfig(inputFlags,jetcoll,chain,onlyUsePassingJets=True):
849  '''Function to configures some algorithms in the monitoring system.'''
850 
851  jetcollFolder = jetcoll
852  chainFolder = chain
853 
854  #if not athenaMT:
855  # onlyUsePassingJets = False #does not work for legacy samples yet
856  jetMonAlgSpecName = chain+"TrigMon"
857  if not onlyUsePassingJets:
858  chainFolder = chainFolder + "/ExpertHistos"
859  jetMonAlgSpecName = jetMonAlgSpecName + "_ExpertHistos"
860 
861  # Define helper functions to automatize ET & eta selection strings for NJet histograms of chains
862  def getThreshold(parts):
863  return parts[1].split('_')[0]
864 
865  def getEtaRangeString(chain):
866  etaMin, etaMax = 0, 32
867  if 'eta' in chain:
868  etaParts = chain.split('eta')
869  etaMinTemp = etaParts[0].split('_')
870  etaMin = etaMinTemp[len(etaMinTemp)-1]
871  etaMax = etaParts[1].split('_')[0]
872  if int(etaMin) > 0 : etaMin = str(int(int(etaMin)/10))
873  if int(etaMax) > 0 : etaMax = str(int(int(etaMax)/10))
874  return 'Eta{}_{}'.format(etaMin,etaMax)
875 
876  def getNjetHistName(chain):
877  NjetHistName = 'NONE'
878  parts = chain.split('j')
879  # check if it is a multi-threshold multijet chain or a single-threshold multijet chain
880  multiplicity = parts[0].split('_')[1] # for single-threshold multijet chains
881  if (chain.count('_j')-chain.count('_jes')) > 1 or multiplicity != '':
882  NjetHistName = 'njetsEt{}{}'.format(getThreshold(parts),getEtaRangeString(chain))
883  return NjetHistName
884 
885 
886  trigConf = JetMonAlgSpec( # the usual JetMonAlgSpec
887  jetMonAlgSpecName,
888  JetContainerName = jetcoll,
889  TriggerChain = chain,
890  defaultPath = chainFolder,
891  topLevelDir="HLT/JetMon/Online/",
892  bottomLevelDir=jetcollFolder,
893  failureOnMissingContainer=True,
894  onlyPassingJets=onlyUsePassingJets,
895  isExpressStreamJob=inputFlags.Common.doExpressProcessing,
896  )
897 
898  trigConf.appendHistos(
899  "pt",
900  "m",
901  "eta",
902  "et",
903  "phi",
904  "phi_tight",
905 
906  )
907  for hist in ExtraOnlineNJetHists: trigConf.appendHistos(EventHistoSpec(hist, (20,0,25), title=hist+';'+hist+';Entries'))
908  # Add NjetEt and NjetPt histograms for simple scenarios
909  if 'ht' not in chain and 'HT' not in chain and 'dijet' not in chain and 'DIJET' not in chain and 'fbdj' not in chain and 'noalg' not in chain:
910  NjetHistName = getNjetHistName(chain)
911  from JetMonitoring.JetStandardHistoSpecs import knownEventVar
912  if knownEventVar.get(NjetHistName,None) is not None and NjetHistName not in ExtraOnlineNJetHists: #avoids duplication warnings for some chains
913  trigConf.appendHistos(
914  EventHistoSpec(NjetHistName, (25,0,25), title=NjetHistName+';'+NjetHistName+';Entries' ),
915  )
916  NjetHistName = NjetHistName.replace('Et','Pt')
917  if knownEventVar.get(NjetHistName,None) is not None and NjetHistName not in ExtraOnlineNJetHists:
918  trigConf.appendHistos(
919  EventHistoSpec(NjetHistName, (25,0,25), title=NjetHistName+';'+NjetHistName+';Entries' ),
920  )
921  if 'ftf' in chain and 'a10' not in chain: # track-based JVT variables for FTF chains
922  trigConf.appendHistos("Jvt")
923  trigConf.appendHistos("JVFCorr")
924  trigConf.appendHistos("JvtRpt")
925 
926  if 'ht' in chain or 'HT' in chain:
927  def defineHistoForHTChain(conf, parentAlg, monhelper , path):
928  # create a monitoring group with the histo path starting from the parentAlg
929  group = monhelper.addGroup(parentAlg, conf.Group, conf.topLevelDir+jetcollFolder+'/')
930  # define the histograms
931  xbins, xmin, xmax = getHTBinning(chain,25) # bin width in GeV
932  group.defineHistogram("jetHT;HT",title="Jet HT;H_{T} [GeV];Entries", type="TH1F", path=chainFolder, xbins=xbins , xmin=xmin, xmax=xmax ,)
933  trigConf.appendHistos(ToolSpec('JetHistoHTFiller','JetHistoHTFiller_'+chain,MinPt=30.,MaxEta=3.2,FailureOnMissingContainer=False,
934  defineHistoFunc=defineHistoForHTChain,Group='jetHT_'+jetcoll))
935 
936  return trigConf
937 
938 def jetEfficiencyMonitoringConfig(inputFlags,onlinejetcoll,offlinejetcoll,chain,refChain):
939  '''Function to configures some algorithms in the monitoring system.'''
940 
941  jetcollFolder = onlinejetcoll
942  chainFolder = chain
943 
944  # We schedule a new JetAlg which will be acting only when a TriggerChain fired (using the TriggerChain from the base classes).
945  # We'll plot 1 histo build by a dedicated JetHistoTriggEfficiency tool.
946  # So we'll have to explicitely give a specification via the generic dicionnary 'ToolSpec'
947  # This implies defining a little function which declares to the monitoring framework which variables to histogram and how.
948  # this is done here.
949  def defineHistoForJetTrigg(conf, parentAlg, monhelper , path):
950  # create a monitoring group with the histo path starting from the parentAlg
951  group = monhelper.addGroup(parentAlg, conf.Group, conf.topLevelDir+jetcollFolder+'/')
952  # define the histogram, give them individual names so they don't overwrite each other
953  append = "offlineCut_"+conf.name.split("_")[-1] if "offlineCut" in conf.name else "noOfflineCut"
954  histname = "trigEff_vs_"+conf.Var.Name+"_"+append
955  xbins, xmin, xmax = getBinningFromThreshold(chain,conf.Var.Name)
956  group.defineHistogram('trigPassed,jetVar;'+histname, title=histname, type="TEfficiency",
957  path=chainFolder,
958  xbins=xbins , xmin=xmin, xmax=xmax,)
959 
960  # Get jet index and eta selection for offline jets
961  validchain = chain.replace('noalg','j0')
962  parts = validchain.split('j')
963  multiplicity = parts[0].split('_')[1]
964  if multiplicity != '': index = int(multiplicity) - 1 # single-threhold multijet chains
965  else: index = 0 # single-jet chain
966  etaMin,etaMax = getEtaRange(chain)
967 
968  from JetMonitoring.JetMonitoringConfig import retrieveVarToolConf
969  trigConf = JetMonAlgSpec( # the usual JetMonAlgSpec
970  chain+"TrigEffMon",
971  JetContainerName = offlinejetcoll,
972  TriggerChain = refChain, # reference chain
973  defaultPath = chainFolder,
974  topLevelDir = "HLT/JetMon/Online/",
975  bottomLevelDir = jetcollFolder,
976  failureOnMissingContainer = True,
977  onlyPassingJets = False,
978  )
979  trigConf.appendHistos(
980  SelectSpec( 'eff', '{}<|eta|<{}'.format(etaMin,etaMax), chainFolder, SelectedIndex=index, FillerTools = [
981  # we pass directly the ToolSpec
982  ToolSpec('JetHistoTriggEfficiency', chain,
983  # below we pass the Properties of this JetHistoTriggEfficiency tool :
984  Group='jetTrigGroup_'+chain,
985  Var=retrieveVarToolConf("pt"), # In this context we can not just pass a str alias to describe a histo variable
986  # so we use retrieveVarToolConf("pt") which returns a full specification for the "pt" histo variable.
987  ProbeTrigChain=chain,defineHistoFunc=defineHistoForJetTrigg),
988  ] ),
989  )
990 
991  if 'smc' in chain:
992  trigConf.appendHistos(
993  SelectSpec( 'm50', '50<m:GeV&{}<|eta|<{}'.format(etaMin,etaMax), chainFolder, SelectedIndex=index, FillerTools = [
994  ToolSpec('JetHistoTriggEfficiency', chain+'_offlineCut_m50',
995  Group='jetTrigGroup_'+chain+'_m50',
996  Var=retrieveVarToolConf("pt"), # In this context we can not just pass a str alias to describe a histo variable
997  ProbeTrigChain=chain,defineHistoFunc=defineHistoForJetTrigg
998  ),
999  ] ),
1000  SelectSpec( 'et500', '500<et:GeV&{}<|eta|<{}'.format(etaMin,etaMax), chainFolder, SelectedIndex=index, FillerTools = [
1001  ToolSpec('JetHistoTriggEfficiency', chain+'_offlineCut_et500',
1002  Group='jetTrigGroup_'+chain+'_et500',
1003  Var=retrieveVarToolConf("m"), # In this context we can not just pass a str alias to describe a histo variable
1004  SortJets=True,
1005  ProbeTrigChain=chain,defineHistoFunc=defineHistoForJetTrigg
1006  ),
1007  ] ),
1008  )
1009 
1010  return trigConf
1011 
1012 if __name__=='__main__':
1013 
1014  import sys,argparse
1015 
1016  # Read arguments
1017  parser = argparse.ArgumentParser()
1018  parser.add_argument('--runTruthReco', action='store_true', dest='runTruthReco', default=False)
1019  parser.add_argument('--genOfflineR10PF', action='store_true', dest='genOfflineR10PF', default=False)
1020  parser.add_argument('--printDetailedConfig', action='store_true', dest='printDetailedConfig', default=False)
1021  parser.add_argument('--input', action='store', dest='inputFile')
1022  args = parser.parse_args()
1023  RunTruth = args.runTruthReco
1024  GenOfflineR10PF = args.genOfflineR10PF
1025  PrintDetailedConfig = args.printDetailedConfig
1026 
1027  # Input file
1028  if args.inputFile is not None: inputFile = args.inputFile
1029  else:
1030  logger.error('ERROR: No input file provided, exiting')
1031  sys.exit(0)
1032 
1033  # Setup logs
1034  from AthenaCommon.Logging import log
1035  from AthenaCommon.Constants import INFO #,DEBUG
1036  log.setLevel(INFO)
1037 
1038  # Set the Athena configuration flags
1039  from AthenaConfiguration.AllConfigFlags import initConfigFlags
1041  flags.Input.Files = [inputFile]
1042  flags.Input.isMC = True
1043  flags.Output.HISTFileName = 'AthenaMTMonitorOutput.root'
1044  flags.lock()
1045 
1046  monMode = 'pp'
1047  if flags.Reco.EnableHI: monMode = 'HI'
1048 
1049  Chains2Monitor = getChains2Monitor(flags, monMode)
1050 
1051  # Protections
1052  # Add missing jet collections to JetCollections dict
1053  # (this can happen if a given chain uses a jet collection that is not listed in JetCollections)
1054  # TODO: make more general
1055  for chain,chaindict in Chains2Monitor[monMode].items():
1056  if chaindict['HLTColl'] not in JetCollections[case]: # chain will not be monitored unless HLT collection is present in JetCollections
1057  JetCollections[case][chaindict['HLTColl']] = {'MatchTo': 'NONE'}
1058 
1059  # Initialize configuration object, add accumulator, merge, and run.
1060  from AthenaConfiguration.MainServicesConfig import MainServicesCfg
1061  from AthenaPoolCnvSvc.PoolReadConfig import PoolReadCfg
1062  cfg = MainServicesCfg(flags)
1063 
1064  # Define the output list
1065  outputlist = ["xAOD::EventInfo#*","xAOD::VertexContainer#*","xAOD::JetContainer#AntiKt4*Jets","xAOD::JetAuxContainer#AntiKt4*JetsAux.-PseudoJet","xAOD::JetContainer#HLT_*","xAOD::JetAuxContainer#HLT_*Aux.-PseudoJet","xAOD::ShallowAuxContainer#HLT_*Aux.-PseudoJet"]
1066  # Reconstruct small-R truth jets
1067  if RunTruth:
1068  from JetRecConfig.StandardSmallRJets import AntiKt4Truth # import the standard definitions
1069  # Add the components from our jet reconstruction job
1070  from JetRecConfig.JetRecConfig import JetRecCfg
1071  comp = JetRecCfg(AntiKt4Truth,flags)
1072  cfg.merge(comp)
1073  # add jets to the output list
1074  key = "{0}Jets".format(AntiKt4Truth.basename)
1075  outputlist += ["xAOD::JetContainer#"+key,"xAOD::JetAuxContainer#"+key+"Aux.-PseudoJet"]
1076 
1077  # Reconstruct offline large-R PFlow CSSK+SD jets
1078  if GenOfflineR10PF:
1079  from JetRecConfig.JetDefinition import JetConstitSeq, JetDefinition, xAODType
1080  EMPFlowCSSK = JetConstitSeq("EMPFlowCSSK", xAODType.ParticleFlow, ["CorrectPFO","CS","SK","CHS"], "JetETMissParticleFlowObjects", "CSSKParticleFlowObjects", label="EMPFlowCSSK")
1081  AntiKt10EMPFlowCSSK = JetDefinition("AntiKt",1.0,EMPFlowCSSK,ptmin=2e3,)
1082  AntiKt10EMPFlowCSSK.modifiers = ["ConstitFourMom","Sort","Filter:2000"]
1083  from JetRecConfig.JetGrooming import JetSoftDrop
1084  from JetRecConfig.StandardLargeRJets import standardrecomods,substrmods
1085  AntiKt10EMPFlowCSSKSoftDrop = JetSoftDrop(AntiKt10EMPFlowCSSK,modifiers=standardrecomods+substrmods,ZCut=0.1,Beta=1.0) # standard SoftDrop
1086  # Add the components from our jet reconstruction job
1087  from JetRecConfig.JetRecConfig import JetRecCfg
1088  comp = JetRecCfg(AntiKt10EMPFlowCSSKSoftDrop,flags)
1089  cfg.merge(comp)
1090  # add jets to the output list
1091  key = "{0}Jets".format(AntiKt10EMPFlowCSSKSoftDrop.basename)
1092  outputlist += ["xAOD::JetContainer#"+key,"xAOD::JetAuxContainer#"+key+"Aux.-PseudoJet"]
1093 
1094  # Write new jet collections to AOD
1095  if RunTruth or GenOfflineR10PF:
1096  # Get the output stream components
1097  from OutputStreamAthenaPool.OutputStreamConfig import OutputStreamCfg
1098  cfg.merge(OutputStreamCfg(flags,"xAOD",ItemList=outputlist))
1099 
1100  cfg.merge(PoolReadCfg(flags))
1101 
1102  # The following class will make a sequence, configure algorithms, and link
1103  # them to GenericMonitoringTools
1104  from AthenaMonitoring import AthMonitorCfgHelper
1105  helper = AthMonitorCfgHelper(flags,'TrigJetMonitorAlgorithm')
1106  cfg.merge(helper.result()) # merge it to add the sequence needed to add matchers
1107 
1108  # Match HLT jets to offline jets
1109  for hltColl,collDict in JetCollections[monMode].items():
1110  if collDict['MatchTo'] != 'NONE':
1111  for jetcalibscale in OnlineScaleMomenta:
1112  scalestring = "_"+jetcalibscale if jetcalibscale != "" else ""
1113  name = 'Matching_{}{}_{}'.format(hltColl,scalestring,collDict['MatchTo'])
1114  alg = CompFactory.JetMatcherAlg(name, JetContainerName1=hltColl,JetContainerName2=collDict['MatchTo'],JetCalibScale=jetcalibscale)
1115  alg.ExtraInputs.add(('xAOD::TrigCompositeContainer','StoreGateSvc+%s' % getRun3NavigationContainerFromInput(flags)))
1116  cfg.addEventAlgo(alg,sequenceName='AthMonSeq_TrigJetMonitorAlgorithm') # Add matchers to monitoring alg sequence
1117 
1118  # Match offline to offline jets
1119  for offjetColl,collDict in OfflineJetCollections[monMode].items():
1120  if collDict['MatchTo'] != 'NONE':
1121  for jetcalibscale in OfflineScaleMomenta:
1122  scalestring = "_"+jetcalibscale if jetcalibscale != "" else ""
1123  name = 'Matching_{}{}_{}'.format(offjetColl,scalestring,collDict['MatchTo'])
1124  alg = CompFactory.JetMatcherAlg(name, JetContainerName1=offjetColl,JetContainerName2=collDict['MatchTo'],JetCalibScale=jetcalibscale)
1125  alg.ExtraInputs.add(('xAOD::TrigCompositeContainer','StoreGateSvc+%s' % getRun3NavigationContainerFromInput(flags)))
1126  cfg.addEventAlgo(alg,sequenceName='AthMonSeq_TrigJetMonitorAlgorithm')
1127 
1128  # Match L1 to offline as well as HLT jets
1129  for l1jetColl,collDict in L1JetCollections[monMode].items():
1130  for matchjetcoll in collDict['MatchTo']:
1131  if matchjetcoll != 'NONE':
1132  name = 'Matching_{}_{}'.format(l1jetColl,matchjetcoll)
1133  alg = CompFactory.JetMatcherAlg(name, L1JetContainerName1=l1jetColl,JetContainerName2=matchjetcoll,MatchL1=True)
1134  alg.ExtraInputs.add(('xAOD::TrigCompositeContainer','StoreGateSvc+%s' % getRun3NavigationContainerFromInput(flags)))
1135  cfg.addEventAlgo(alg,sequenceName='AthMonSeq_TrigJetMonitorAlgorithm')
1136 
1137  # Loop over L1 jet collectoins
1138  for jetcoll in L1JetCollections[monMode]:
1139  l1jetconf = l1JetMonitoringConfig(flags,jetcoll,L1JetCollections,monMode,'',True)
1140  l1jetconf.toAlg(helper)
1141 
1142  # Loop over L1 jet chains
1143  for chain,jetcoll in Chain2L1JetCollDict[monMode].items():
1144  l1chainconf = l1JetMonitoringConfig(flags,jetcoll,L1JetCollections,monMode,chain)
1145  l1chainconf.toAlg(helper)
1146 
1147  # Loop over offline jet collections
1148  for jetcoll in OfflineJetCollections[monMode]:
1149  offlineMonitorConf = jetMonitoringConfig(flags,jetcoll,OfflineJetCollections,monMode)
1150  offlineMonitorConf.toAlg(helper)
1151 
1152  # Loop over HLT jet collections
1153  for jetcoll in JetCollections[monMode]:
1154  monitorConf = jetMonitoringConfig(flags,jetcoll,JetCollections,monMode)
1155  # then we turn the full specification into properly configured algorithm and tools.
1156  # we use the method 'toAlg()' defined for the specialized dictionnary 'JetMonAlgSpec'
1157  monitorConf.toAlg(helper)
1158 
1159  # Loop over HLT jet chains
1160  for chain,chainDict in Chains2Monitor[monMode].items():
1161  jetcoll = chainDict['HLTColl']
1162  # kinematic plots
1163  # only passing jets
1164  chainMonitorConfT = jetChainMonitoringConfig(flags,jetcoll,chain,True)
1165  chainMonitorConfT.toAlg(helper)
1166  # all jets
1167  chainMonitorConfF = jetChainMonitoringConfig(flags,jetcoll,chain,False)
1168  chainMonitorConfF.toAlg(helper)
1169  # efficiency plots
1170  if chainDict['RefChain'] != 'NONE' and chainDict['OfflineColl'] != 'NONE':
1171  effMonitorConf = jetEfficiencyMonitoringConfig(flags, jetcoll,
1172  chainDict['OfflineColl'], chain,
1173  chainDict['RefChain'])
1174  effMonitorConf.toAlg(helper)
1175 
1176  cfg.merge(helper.result())
1177 
1178  # Print config
1179  cfg.printConfig(withDetails=PrintDetailedConfig)
1180 
1181  cfg.run()
TrigJetMonitorAlgorithm.getEtaRange
def getEtaRange(chain)
Helpful functions.
Definition: TrigJetMonitorAlgorithm.py:291
TrigJetMonitorAlgorithm.getJetCopyAlg
def getJetCopyAlg(injets, outjets)
Definition: TrigJetMonitorAlgorithm.py:416
python.JetAnalysisCommon.ComponentAccumulator
ComponentAccumulator
Definition: JetAnalysisCommon.py:302
vtune_athena.format
format
Definition: vtune_athena.py:14
python.OutputStreamConfig.OutputStreamCfg
def OutputStreamCfg(flags, streamName, ItemList=[], MetadataItemList=[], disableEventTag=False, trigNavThinningSvc=None, takeItemsFromInput=False, extendProvenanceRecord=True, AcceptAlgs=[], HelperTools=[])
Definition: OutputStreamConfig.py:12
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.TriggerConfigAccess.getHLTMonitoringAccess
HLTMonitoringAccess getHLTMonitoringAccess(flags=None)
Definition: TriggerConfigAccess.py:256
TrigJetMonitorAlgorithm.getHTBinning
def getHTBinning(chain, binwidth)
Definition: TrigJetMonitorAlgorithm.py:335
TrigJetMonitorAlgorithm.jetChainMonitoringConfig
def jetChainMonitoringConfig(inputFlags, jetcoll, chain, onlyUsePassingJets=True)
Definition: TrigJetMonitorAlgorithm.py:848
TrigJetMonitorAlgorithm.getChains2Monitor
def getChains2Monitor(inputFlags, monMode)
Definition: TrigJetMonitorAlgorithm.py:227
TrigJetMonitorAlgorithm.l1JetMonitoringConfig
def l1JetMonitoringConfig(inputFlags, jetColl, jetDict, monMode, chain='', matched=False)
Definition: TrigJetMonitorAlgorithm.py:829
TrigJetMonitorAlgorithm.TrigJetMonConfig
def TrigJetMonConfig(inputFlags)
Definition: TrigJetMonitorAlgorithm.py:466
TrigJetMonitorAlgorithm.jetMonitoringConfig
def jetMonitoringConfig(inputFlags, jetcoll, jetCollDict, monMode)
Definition: TrigJetMonitorAlgorithm.py:688
TrigJetMonitorAlgorithm.getBinningFromThreshold
def getBinningFromThreshold(chain, varname)
Definition: TrigJetMonitorAlgorithm.py:302
TrigJetMonitorAlgorithm.addFlavourTagVariables
def addFlavourTagVariables(conf, network_prefix, flavs="cub")
Definition: TrigJetMonitorAlgorithm.py:347
JetMonitoringConfig.retrieveVarToolConf
def retrieveVarToolConf(alias)
Definition: JetMonitoringConfig.py:584
python.BadLBFilterToolConfig.LArBadLBFilterToolCfg
def LArBadLBFilterToolCfg(inputFlags, origDbTag=None)
Definition: BadLBFilterToolConfig.py:100
python.TrigDecisionToolConfig.getRun3NavigationContainerFromInput
def getRun3NavigationContainerFromInput(flags)
Definition: TrigDecisionToolConfig.py:75
python.KeyStore.dict
def dict(self)
Definition: KeyStore.py:321
TrigJetMonitorAlgorithm.jetEfficiencyMonitoringConfig
def jetEfficiencyMonitoringConfig(inputFlags, onlinejetcoll, offlinejetcoll, chain, refChain)
Definition: TrigJetMonitorAlgorithm.py:938
python.JetRecConfig.JetRecCfg
def JetRecCfg(flags, jetdef, returnConfiguredDef=False)
Top level functions returning ComponentAccumulator out of JetDefinition.
Definition: JetRecConfig.py:37
python.MainServicesConfig.MainServicesCfg
def MainServicesCfg(flags, LoopMgr='AthenaEventLoopMgr')
Definition: MainServicesConfig.py:252
Constants
some useful constants -------------------------------------------------—
TrigJetMonitorAlgorithm.items
items
Definition: TrigJetMonitorAlgorithm.py:79
TrigJetMonitorAlgorithm.basicJetMonAlgSpec
def basicJetMonAlgSpec(jetcoll, isOnline)
Definition: TrigJetMonitorAlgorithm.py:604
dqt_zlumi_pandas.update
update
Definition: dqt_zlumi_pandas.py:42
CaloLCW_tf.group
group
Definition: CaloLCW_tf.py:28
python.AllConfigFlags.initConfigFlags
def initConfigFlags()
Definition: AllConfigFlags.py:19
python.EventFlagFilterToolConfig.EventFlagFilterToolCfg
def EventFlagFilterToolCfg(flags, name="EventFlagFilter", doLAr=True, doTile=True, doSCT=True, doCore=True, alwaysReturnTrue=False)
Definition: EventFlagFilterToolConfig.py:5
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:127
getThreshold
CP::CorrectionCode getThreshold(Int_t &threshold, const std::string &trigger)
Definition: MuonTriggerSFRootCoreTest.cxx:48
str
Definition: BTagTrackIpAccessor.cxx:11
python.PoolReadConfig.PoolReadCfg
def PoolReadCfg(flags)
Definition: PoolReadConfig.py:69
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
TrigJetMonitorAlgorithm.getL1JetCopyAlg
def getL1JetCopyAlg(injets, outjets)
Definition: TrigJetMonitorAlgorithm.py:440