ATLAS Offline Software
toolFromAlgData.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 
4 
5 # This module contains code to process AlgData objects in order to
6 # configure AlgTools that run L1Topo Algorithms.
7 #
8 # entrance point: toolFromAlgData
9 
10 from AthenaConfiguration.ComponentFactory import CompFactory
11 from AthenaMonitoringKernel.GenericMonitoringTool import GenericMonitoringTool
12 
13 # needed to translate symbolic names in the menu to numric values
14 import L1TopoHardware.L1TopoHardware as HW
15 
16 from AthenaCommon.Logging import logging
17 logger = logging.getLogger(__name__)
18 from AthenaCommon.Constants import VERBOSE
19 logger.setLevel(VERBOSE)
20 
21 import sys
22 
23 do_dump = True # flag to enable dump information to the local run directory
24 
25 # writeHandleKeys specifies how the L1Topo AlgTools are interconnected
26 # via the event store.
27 writeHandleKeys = {}
28 
29 
30 def toolFromAlgData(flags, alg_data):
31 
32  if alg_data is None:
33  logger.error('Attempting to build an AlgTool from None')
34  sys.exit(1)
35 
36  return {'INPUT': inputToolFromAlgData,
37  'COUNT': countToolFromAlgData,
38  'SORT': sortToolFromAlgData,
39  'DECISION': decisionToolFromAlgData,
40  }[alg_data.globalL1AlgType](flags, alg_data)
41 
42 
43 def klass(ad):
44  return ad.menu['klass']
45 
46 
47 def fixedValue(ad, var):
48  """helper function to extract values from a L1MenuAccessor object"""
49 
50  # Menu has entries like
51  # ('MaxTob1',
52  # OrderedDict([('value',
53  # ':eEmOutputWidthSelect:'),
54  # ('position', 2)])),
55  # The numeric values for "XXX: values are found in L1TopoHardware
56 
57  val = ad.menu[
58  'fixedParameters'][
59  'generics'][
60  var][
61  'value']
62  if isinstance(val, str):
63  if val.startswith(':') and val.endswith(':'):
64  val = getattr(HW, val[1:-1]).value
65  return val
66 
67 
68 def variableValue(ad, var):
69  """helper function to extract values from a L1MenuAccessor object"""
70 
71  vps = ad.menu['variableParameters']
72  for vp in vps:
73  if vp['name'] == var:
74  return vp['value']
75 
76 
77 
78 def countAlgValue(ad, var):
79  """helper function to extract values from a L1MenuAccessor object"""
80 
81  return ad.menu[var]
82 
83 
84 
85 def inputToolFromAlgData(flags, ad):
86  """Input Algs read in FEX outputs and output TOBs of various types."""
87 
88  # partial dump of an AlgData object with globalL1AlgType set to INPUT
89  #
90  # --
91  # 'globalL1AlgType: INPUT\n'
92  # 'inputs: []\n'
93  # "outputs: ['cTAU']\n"
94  # 'input_sns: []\n'
95  # 'sn: 240\n'
96  # 'numResultBits: None\n'
97  # threshold: None
98  # threshold_flavour: None
99 
100  # tool to run the concrete input alg
101  tool = None
102  out0 = ad.outputs[0]
103  write_handle = '_'.join([ad.klass, out0, str(ad.sn)])
104  writeHandleKeys[ad.sn] =write_handle
105 
106  # The following if - elseif structure specifies the Input Algorithms
107  # currently implemented
108  if out0 == 'jJetTobs':
109  name = 'jJetInputAlgTool_'+ out0
110  tool = CompFactory.GlobalSim.jJetInputAlgTool(name)
111 
112  elif out0 == 'eEmTobs':
113  name = 'eEmInputAlgTool_'+ out0
114  tool = CompFactory.GlobalSim.eEmInputAlgTool(name)
115  elif out0 == 'cTAU':
116  name = 'cTauInputAlgTool_' + out0
117  tool = CompFactory.GlobalSim.cTauInputAlgTool(name)
118  elif out0 == 'jXE':
119  name = 'jXEInputAlgTool_' + out0
120  tool = CompFactory.GlobalSim.jXEInputAlgTool(name)
121  monTool = GenericMonitoringTool(flags, "MonTool_" + ad.name)
122 
123  monTool.defineHistogram('jXETOBPt', path='EXPERT', type='TH1I',
124  title='jXE TOB Pt;p_{T} [GeV];',
125  xbins=200, xmin=0, xmax=2000)
126 
127  monTool.defineHistogram('jXETOBPhi', path='EXPERT', type='TH1I',
128  title='jXE TOB Phi;#phi;',
129  xbins=64, xmin=-3.2, xmax=3.2)
130 
131  tool.monTool = monTool
132  else:
133  logger.error('Unsupported input alg type ' + str(out0))
134  raise RuntimeError(
135  'toolFromAlgData: Unsupported input alg type ' + str(out0))
136 
137  tool.TOBArrayWriteKey = writeHandleKeys[ad.sn]
138  return tool
139 
140 def countToolFromAlgData(flags, ad):
141  """Count Algorithms write out a Count object determined
142  from TOBS produced by a single Input Algorithm."""
143 
144  # The following dictionary specifies the Count Algorithms currently
145  # implemented
146  countToolSelector = {
147  'cTauMultiplicity': CompFactory.GlobalSim.cTauMultiplicityAlgTool,
148  ('EnergyThreshold', 'jXE'): CompFactory.GlobalSim.EnergyThresholdAlgTool_jXE,
149  }
150 
151  # Note: the name of the owning component
152  # will be prepended to the AlgTool name
153  key = None
154  if ad.klass == 'EnergyThreshold':
155  key = (ad.klass, ad.inputs[0]) # eg ('EnergyThreshold', 'jXE')
156 
157  else:
158  key = ad.klass
159 
160  tool = countToolSelector[key](ad.name)
161  tool.alg_instance_name = ad.name
162  tool.nbits = int(countAlgValue(ad, 'nbits'))
163  tool.TOBArrayReadKey = writeHandleKeys[ad.input_sns[0]]
164  tool.CountWriteKey = ad.name + '_Count_' + str(ad.sn)
165  writeHandleKeys[ad.sn] = tool.CountWriteKey
166 
167  if ad.klass in ('EnergyThreshold',):
168 
169  # magic numbers from the original C++ calculation
170  tool.hundredMeVThreshold = int(ad.threshold)*10 + 5
171 
172  if ad.klass == 'cTauMultiplicity':
173  tool.do_dump = do_dump
174  monTool = GenericMonitoringTool(flags, "MonTool_" + ad.name)
175 
176  threshold_name = countAlgValue(ad, 'threshold')
177  title = "cTauMultiplicity_accept #eta Et_" + threshold_name
178 
179  monTool.defineHistogram("accept_eta,accept_et",
180  path="EXPERT",
181  type="TH2F",
182  title=title,
183  xbins=200, xmin=-200, xmax=200,
184  ybins=100, ymin=0, ymax=100)
185 
186  title_stub = "cTauMultiplicityc " + threshold_name + " "
187  title = title_stub + "counts"
188  monTool.defineHistogram("counts",
189  path="EXPERT",
190  type="TH1F",
191  title=title,
192  xbins=15, xmin=0, xmax=15)
193 
194  title = title_stub + "TOB Et"
195  monTool.defineHistogram("Et",
196  path="EXPERT",
197  type="TH1F",
198  title=title,
199  xbins=200, xmin=0, xmax=400)
200 
201 
202  title = title_stub + "#phi #eta"
203  monTool.defineHistogram("phi,eta",
204  path="EXPERT",
205  type="TH2F",
206  title=title,
207  xbins=200, xmin=0, xmax=400,
208  ybins=128, ymin=0, ymax=128)
209 
210 
211  title = title_stub + "Et #eta"
212  monTool.defineHistogram("Et,eta",
213  path="EXPERT",
214  type="TH2F",
215  title=title,
216  xbins=200, xmin=0, xmax=200,
217  ybins=200, ymin=0, ymax=400)
218 
219  title = title_stub + "loose partial isolation"
220  monTool.defineHistogram("iso_loose",
221  path="EXPERT",
222  type="TH1F",
223  title=title,
224  xbins=200, xmin=0, xmax=10)
225 
226  title = title_stub + "medium partial isolation"
227  monTool.defineHistogram("iso_medium",
228  path="EXPERT",
229  type="TH1F",
230  title=title,
231  xbins=200, xmin=0, xmax=10)
232 
233 
234  title = title_stub + "tight partial isolation"
235  monTool.defineHistogram("iso_tight",
236  path="EXPERT",
237  type="TH1F",
238  title=title,
239  xbins=200, xmin=0, xmax=10)
240 
241  tool.monTool = monTool
242 
243  return tool
244 
245 def sortToolFromAlgData(flags, ad):
246  """Sort Algorithms write out a GenericTOBArray produced by sorting,
247  and possibly selecting, TOBs produced by an Input Algorithm"""
248 
249 
250  # The following dictionary specifies the Sort Algorithms currently
251  # implemented
252  sortToolSelector = {
253  'eEmSelect': CompFactory.GlobalSim.eEmSelectAlgTool,
254  'jJetSelect': CompFactory.GlobalSim.jJetSelectAlgTool,
255  }
256 
257 
258  # Note: owning component name will be prepended to the AlgTool name
259  tool = sortToolSelector[ad.klass](ad.name)
260  out0 = ad.outputs[0] # node number (int)
261  tool.alg_instance_name = ad.name
262  tool.TOBArrayReadKey = writeHandleKeys[ad.input_sns[0]]
263  writeHandleKeys[ad.sn] = ad.klass+ '_' + out0 + '_' + str(ad.sn)
264  tool.TOBArrayWriteKey = writeHandleKeys[ad.sn]
265  if klass(ad) == 'eEmSelect':
266  tool.InputWidth = int(fixedValue(ad, 'InputWidth'))
267  tool.MinET = int(variableValue(ad, 'MinET'))
268  tool.REtaMin = int(variableValue(ad,'REtaMin'))
269  tool.RHadMin = int(variableValue(ad, 'RHadMin'))
270  tool.WsTotMin = int(variableValue(ad, 'WsTotMin'))
271 
272  if klass(ad) == 'jJetSelect':
273  tool.InputWidth = int(fixedValue(ad, 'InputWidth'))
274  tool.MinET = int(variableValue(ad, 'MinET'))
275  tool.MinEta = int(variableValue(ad,'MinEta'))
276  tool.MaxEta = int(variableValue(ad,'MaxEta'))
277 
278  # tool.sortAlgTool = sortAlgTool
279 
280  return tool
281 
282 def decisionToolFromAlgData(flags, ad):
283  """Decision Algorithms all write out a L1Topo Decision object
284  determined by processing the outputs of 1 or more Sort Algorithms.
285  They also write out a vector of GenericTOBs."""
286 
287 
288  # The following dictionary specifies the Decision Algorithms currently
289  # implemented
290 
291  decisionToolSelector = {
292  'DeltaRSqrIncl2': CompFactory.GlobalSim.DeltaRSqrIncl2AlgTool,
293  'SimpleCone': CompFactory.GlobalSim.SimpleConeAlgTool,
294  }
295 
296  tool = decisionToolSelector[ad.klass](ad.name)
297  tool.alg_instance_name = ad.name
298 
299  assert len(ad.outputs) == 1
300  writeHandleKeys[ad.sn] = ad.klass + '_'+ ad.outputs[0] + '_' + str(ad.sn)
301  tool.TOBArrayVectorWriteKey = writeHandleKeys[ad.sn]
302  tool.DecisionWriteKey = ad.name + '_Decision_' + str(ad.sn)
303 
304  if klass(ad) == 'DeltaRSqrIncl2':
305  tool.TOBArrayReadKey0 = writeHandleKeys[ad.input_sns[0]]
306  tool.TOBArrayReadKey1 = writeHandleKeys[ad.input_sns[1]]
307 
308  tool.MaxTOB1 = int(fixedValue(ad, 'InputWidth1'))
309  tool.MaxTOB2 = int(fixedValue(ad, 'InputWidth2'))
310  tool.NumResultBits = fixedValue(ad, 'NumResultBits')
311 
312  tool.MinET1 = [int(variableValue(ad, 'MinET1'))]
313  tool.MinET2 = [int(variableValue(ad, 'MinET2'))]
314  tool.DeltaRMin = [int(variableValue(ad, 'DeltaRMin'))]
315  tool.DeltaRMax = [int(variableValue(ad, 'DeltaRMax'))]
316 
317  # unclear how the menu stores cut values when there is more
318  # than one result bit. Examined menus all have 1 for this variable
319  assert tool.NumResultBits == 1
320 
321  tool.NumResultBits = int(fixedValue(ad, 'NumResultBits'))
322 
323  monTool = GenericMonitoringTool(flags, "MonTool_" + ad.name)
324  for i in range(tool.NumResultBits):
325 
326  label = ad.name + "_pass_by_bit_" + str(i)
327  monTool.defineHistogram(label,
328  path="EXPERT", type="TH1F",
329  title="DeltaR pass, bit " + str(i),
330  xbins=10, xmin=0, xmax=100.)
331 
332  label = ad.name + "_fail_by_bit_" + str(i)
333  monTool.defineHistogram(label,
334  path="EXPERT", type="TH1F",
335  title="DeltaR fail, bit " + str(i),
336  xbins=10, xmin=0, xmax=100.)
337  tool.monTool = monTool
338  tool.do_dump = do_dump
339 
340 
341 
342  if klass(ad) == 'SimpleCone':
343 
344  tool.TOBArrayReadKey = writeHandleKeys[ad.input_sns[0]]
345 
346  tool.InputWidth = int(fixedValue(ad, 'InputWidth'))
347  tool.MaxRSqr = int(variableValue(ad, 'MaxRSqr'))
348  tool.MinET = int(variableValue(ad, 'MinET'))
349 
350  # in some previous version of the menu NumResultBits was set to 1.
351  # not sure how the list of cuts is specified if NumResultBits > 1
352  # now hardwire NumResultBits=1
353  numResultBits = 1
354 
355 
356  tool.MinSumET = [int(variableValue(ad, 'MinSumET'))]
357 
358 
359  monTool = GenericMonitoringTool(flags, "MonTool_" + ad.name)
360  for i in range(numResultBits):
361  monTool.defineHistogram(ad.name+"_pass_by_bit_" + str(i),
362  path="EXPERT", type="TH1F",
363  title="ET pass, bit " + str(i),
364  xbins=10, xmin=0, xmax=100.)
365 
366  monTool.defineHistogram(ad.name+"_fail_by_bit_" + str(i),
367  path="EXPERT", type="TH1F",
368  title="ET fail, bit " + str(i),
369  xbins=10, xmin=0, xmax=100.)
370  tool.monTool = monTool
371 
372 
373  return tool
374 
toolFromAlgData.sortToolFromAlgData
def sortToolFromAlgData(flags, ad)
Definition: toolFromAlgData.py:245
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
toolFromAlgData.klass
def klass(ad)
Definition: toolFromAlgData.py:43
toolFromAlgData.countAlgValue
def countAlgValue(ad, var)
Definition: toolFromAlgData.py:78
klass
This class describe the base functionalities of a HypoTool used by the ComboAlg.
toolFromAlgData.countToolFromAlgData
def countToolFromAlgData(flags, ad)
Definition: toolFromAlgData.py:140
toolFromAlgData.variableValue
def variableValue(ad, var)
Definition: toolFromAlgData.py:68
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
Constants
some useful constants -------------------------------------------------—
toolFromAlgData.decisionToolFromAlgData
def decisionToolFromAlgData(flags, ad)
Definition: toolFromAlgData.py:282
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
GenericMonitoringTool
Definition: GenericMonitoringTool.py:1
toolFromAlgData.fixedValue
def fixedValue(ad, var)
Definition: toolFromAlgData.py:47
str
Definition: BTagTrackIpAccessor.cxx:11
toolFromAlgData.inputToolFromAlgData
def inputToolFromAlgData(flags, ad)
Definition: toolFromAlgData.py:85
toolFromAlgData.toolFromAlgData
def toolFromAlgData(flags, alg_data)
Definition: toolFromAlgData.py:30