ATLAS Offline Software
Loading...
Searching...
No Matches
hypoConfigBuilder.py
Go to the documentation of this file.
1# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2
3from TrigHLTJetHypo.FastReductionAlgToolFactory import toolfactory
4
5# import modules concerned with extracting scenario paramters
6# from a scenario string
7from TrigHLTJetHypo.scenario_ht import scenario_ht
8from TrigHLTJetHypo.scenario_dipz import scenario_dipz
9from TrigHLTJetHypo.scenario_htdipz import scenario_htdipz
10from TrigHLTJetHypo.scenario_mult import scenario_mult
11from TrigHLTJetHypo.scenario_dijet import scenario_dijet
12from TrigHLTJetHypo.scenario_fbdjnoshared import scenario_fbdjnoshared
13from TrigHLTJetHypo.scenario_fbdjshared import scenario_fbdjshared
14from TrigHLTJetHypo.scenario_simple import scenario_simple
15
16from TrigHLTJetHypo.prefilter_mask import prefilter_mask
17from TrigHLTJetHypo.prefilter_ptrange import prefilter_ptrange
18from TrigHLTJetHypo.prefilter_maxmult import prefilter_maxmult
19from TrigHLTJetHypo.prefilter_clean import prefilter_clean
20
21from TrigHLTJetHypo.hypoToolDisplay import hypoToolDisplay
22
23
24
25from TrigHLTJetHypo.makeConditionFilterConfigurer import (
26 makeConditionFilterConfigurer,
27)
28
29from TrigHLTJetHypo.make_repeatedCondConfigurer import (
30 make_repeatedCond,
31 make_repeatedCondCfgFromParams,
32)
33
34from DecisionHandling.TrigCompositeUtils import isLegId, getLegIndexInt
35
36from AthenaCommon.Logging import logging
37from AthenaCommon.Constants import DEBUG
38
39import re
40
41logger = logging.getLogger( __name__)
42logger.setLevel(DEBUG)
43
44# Dictionary to interpret / map scenario aliases into actual scenario strings that can be understood by scenario_XX.py
45aliasesDict = {
46 'DJMASS200j20' : 'DIJET20j12ptXX200djmass',
47 'DJMASS350j20' : 'DIJET20j12ptXX350djmass',
48 'DJMASS300j35' : 'DIJET35j12ptXX300djmass',
49 'DJMASS500j35' : 'DIJET35j12ptXX500djmass',
50 'DJMASS700j35' : 'DIJET35j12ptXX700djmass',
51 'DJMASS1000j35' : 'DIJET35j12ptXX1000djmass',
52 'DJMASS700j40' : 'DIJET40j12ptXX700djmass',
53 'DJMASS700j50x0eta240' : 'DIJET50j12ptXX0j12eta240XX700djmass',
54 'DJMASS700j80x0eta240' : 'DIJET80j12ptXX0j12eta240XX700djmass',
55 'DJMASS900j50' : 'DIJET50j12ptXX900djmass',
56 'DJMASS1000j50' : 'DIJET50j12ptXX1000djmass',
57 'DJMASS1000j50dphi240' : 'DIJET50j12ptXX1000djmassXXdjdphi240',
58 'DJMASS900j50dphi240' : 'DIJET50j12ptXX900djmassXXdjdphi240',
59 'DJMASS1000j50dphi200x400deta' : 'DIJET50j12ptXX1000djmassXXdjdphi200XX400djdeta',
60 'DJMASS900j50dphi200x400deta' : 'DIJET50j12ptXX900djmassXXdjdphi200XX400djdeta',
61 'DJMASS1000j50dphi260x200deta' : 'DIJET50j12ptXX1000djmassXXdjdphi260XX200djdeta',
62 'DJMASS900j50dphi260x200deta' : 'DIJET50j12ptXX900djmassXXdjdphi260XX200djdeta',
63 'DJMASS1000j30dphi260x200deta' : 'DIJET30j12ptXX1000djmassXXdjdphi260XX200djdeta',
64 'DJMASS900j30dphi260x200deta' : 'DIJET30j12ptXX900djmassXXdjdphi260XX200djdeta',
65 'DJMASS1000j50x200deta' : 'DIJET50j12ptXX1000djmassXX200djdeta',
66 'DJMASS900j50x200deta' : 'DIJET50j12ptXX900djmassXX200djdeta',
67
68 'DJMASS1000j50dphi260' : 'DIJET50j12ptXX1000djmassXXdjdphi260',
69 'DJMASS900j50dphi260' : 'DIJET50j12ptXX900djmassXXdjdphi260',
70
71}
72
74 """make a repeated condition configurer for the fast reduction
75 root node. This will will have a single accapt all internal node."""
76
77 toolclass, name = toolfactory('all')
78 args = {'name': name}
79 conditionMakers = [toolclass(**args)]
80
81 configurer = make_repeatedCond(tree_id=0,
82 tree_pid=0,
83 clique=-1,
84 conditionMakers=conditionMakers)
85
86 return configurer
87
89 """the parameter object passed in is built in the modules handling
90 scenarios. It contains the information needed to build the
91 configuration AlgTool that intialiases a hypo helper AlgTool"""
92
93 # check that each Condition has a Filter index.
94 # the index is -1 for no Condition filtering.
95 assert len(params.repcondargs) == len(params.filterparam_inds)
96 assert len(params.filterparam_inds) >= len(params.filterparams)
97
98 # FastReducer root node
99 repcondobjs = [make_root_repcondconfig()]
100 for ra in params.repcondargs:
101 repcondobjs.append(make_repeatedCondCfgFromParams(ra))
102
103
104 # filter for FastReducer root node (use position 0)
105 filtConditionMakers = []
106 filtConditionMakerInds = [-1] # no condition filtering for root
107
108 for ra_ind in params.filterparam_inds:
109 if ra_ind != -1:
110 ra = params.filterparams[ra_ind]
111 filtConditionMakers.append(makeConditionFilterConfigurer(ra))
112 filtConditionMakerInds.append(len(filtConditionMakers)-1)
113 else:
114 filtConditionMakerInds.append(-1)
115
116 toolclass, name = toolfactory('HelperToolConfigTool')
117
118 vals = {'name': name,
119 'conditionMakers': repcondobjs,
120 'filterMakers': filtConditionMakers,
121 'filterMakerInds': filtConditionMakerInds,
122 'treeVector': params.treevec,
123 'leafVector': params.leafvec,
124 }
125
126 return toolclass(**vals)
127
128
129def process_simple(chain_parts):
130 """Obtain the paramters needed to build an AlgTool
131 to initialise a jet hypo HelperAlgTool"""
132
133 # obtain a list of parameter objects that will be used
134 # to build a helper config AlgTools
135 helper_params = scenario_simple(chain_parts)
136
137 # build the helper config AlgTools
138 helperconfigobjs = [buildHypoHelperConfigTool(params) for params in
139 helper_params]
140
141 return helperconfigobjs
142
143
144def process_dipz(scenario, chainPartInd):
145 """Obtain the paramters needed to build an AlgTool
146 to initialise a jet hypo HelperAlgTool"""
147
148 # obtain a list of parameter objects that will be used
149 # to build a helper config AlgTools
150 helper_params = scenario_dipz(scenario, chainPartInd)
151
152 # build the helper config AlgTools
153 helperconfigobjs = [buildHypoHelperConfigTool(params) for params in
154 helper_params]
155
156 return helperconfigobjs
157
158def process_ht(scenario, chainPartInd):
159 """Obtain the paramters needed to build an AlgTool
160 to initialise a jet hypo HelperAlgTool"""
161
162 # obtain a list of parameter objects that will be used
163 # to build a helper config AlgTools
164 helper_params = scenario_ht(scenario, chainPartInd)
165
166 # build the helper config AlgTools
167 helperconfigobjs = [buildHypoHelperConfigTool(params) for params in
168 helper_params]
169
170 return helperconfigobjs
171
172def process_htdipz(scenario, chainPartInd):
173 """Obtain the paramters needed to build an AlgTool
174 to initialise a jet hypo HelperAlgTool"""
175
176 # obtain a list of parameter objects that will be used
177 # to build a helper config AlgTools
178 helper_params = scenario_htdipz(scenario, chainPartInd)
179
180 # build the helper config AlgTools
181 helperconfigobjs = [buildHypoHelperConfigTool(params) for params in
182 helper_params]
183
184 return helperconfigobjs
185
186
187def process_mult(scenario, chainPartInd):
188 """Obtain the paramters needed to build an AlgTool
189 to initialise a jet hypo HelperAlgTool"""
190
191 # obtain a list of parameter objects that will be used
192 # to build a helper config AlgTools
193 helper_params = scenario_mult(scenario, chainPartInd)
194
195 # build the helper config AlgTools
196 helperconfigobjs = [buildHypoHelperConfigTool(params) for params in
197 helper_params]
198
199 return helperconfigobjs
200
201
202def process_dijet(scenario, chainPartInd):
203 """Obtain the paramters needed to build an AlgTool
204 to initialise a jet hypo HelperAlgTool"""
205
206 # obtain a list of parameter objects that will be used
207 # to build a helper config AlgTools
208 helper_params = scenario_dijet(scenario, chainPartInd)
209
210 # build the helper config AlgTools
211 helperconfigobjs = [buildHypoHelperConfigTool(params) for params in
212 helper_params]
213
214 return helperconfigobjs
215
216
217def process_fbdjshared(scenario, chainPartInd):
218 """Obtain the paramters needed to build an AlgTool
219 to initialise a jet hypo HelperAlgTool"""
220
221 # obtain a list of parameter objects that will be used
222 # to build a helper config AlgTools
223 helper_params = scenario_fbdjshared(scenario, chainPartInd)
224
225 # build the helper config AlgTools
226 helperconfigobjs = [buildHypoHelperConfigTool(params) for params in
227 helper_params]
228
229 return helperconfigobjs
230
231
232def process_fbdjnoshared(scenario, chainPartInd):
233 """Obtain the paramters needed to build an AlgTool
234 to initialise a jet hypo HelperAlgTool"""
235
236 # obtain a list of parameter objects that will be used
237 # to build a helper config AlgTools
238 helper_params = scenario_fbdjnoshared(scenario, chainPartInd)
239
240 # build the helper config AlgTools
241 helperconfigobjs = [buildHypoHelperConfigTool(params) for params in
242 helper_params]
243
244 return helperconfigobjs
245
246
247def process_nonsimple(scenario, chainPartInd):
248 """Maker a list of helper tool config tool for a non-simple scenario.
249 Note: a non-simple scenario will produce more than HelperToolConfigTool
250 if jet sharing among Conditions is required."""
251
252 # interpret scenario aliases
253 if scenario in aliasesDict.keys(): scenario = aliasesDict[scenario]
254
255 router = {
256 'Z': process_dipz,
257 'HTZ': process_htdipz,
258 'HT': process_ht,
259 'MULT': process_mult,
260 'DIJET': process_dijet,
261 'FBDJSHARED': process_fbdjshared,
262 'FBDJNOSHARED': process_fbdjnoshared,
263 }
264
265 # get scenario stub and make sure is correct
266 pattern = r'^(?P<stub>[A-Z]+)'
267 rgx = re.compile(pattern)
268 m = rgx.match(scenario)
269 assert m is not None,'No scenario stub was found'
270 groupdict = m.groupdict()
271 assert groupdict['stub'] in router,'scenario stub ({}) not recognized'.format(groupdict['stub'])
272
273 return router[groupdict['stub']](scenario, chainPartInd) # list of HelperToolConfigTool
274
275
277 """Create HelperToolConfigTool instances. Each instance
278 configures a FastReduction tree. Chain parts with the 'simple' scenario
279 are used to form a single HelperToolConfigTool. The information
280 may be spread over a number of chain parts.
281
282 There is at most one chain part with a non-simple scenario.
283 This may give rise to > 1 HelperToolConfigTool instance - as this
284 is how jet sharing among Conditions is handled.
285
286 If there are both simple and non-simple scenarios, there will be
287 n HelperToolConfigTool instances, where n >=2: one for the simple
288 scenario chain parts, and n-1 for the non-simple scenario.
289 """
290
291 chain_parts = chain_dict['chainParts']
292
293 simple_chainparts = [
294 cp for cp in chain_parts if cp['hypoScenario'] == 'simple']
295 simple_cpis = [cp['chainPartIndex'] for cp in simple_chainparts]
296 # check that all the simple scenario parts occur before
297 # non-simple scenario chain parts
298
299 if simple_cpis:
300 assert simple_cpis == sorted(simple_cpis), "disordered chain parts"
301 assert simple_cpis[-1] - simple_cpis[0] == len(simple_cpis) - 1, "nonsequential chainParts"
302 helperToolConfigTools = []
303
304 # check for SHARED markers (chainPart['tboundary'] = 'SHARED')
305 # in the list of simple chain parts.
306 # Get a tree configuration each time SHARED == 1 is encountered.
307 if simple_chainparts:
308
309 assert simple_chainparts[-1]['tboundary'] == ''
310
311 tree_cps = []
312 for cp in simple_chainparts:
313 tree_cps.append(cp)
314 if cp['tboundary'] == 'SHARED':
315 helperToolConfigTools.extend(process_simple(tree_cps))
316 tree_cps = []
317
318 # tree_cps cannot be empty here
319 assert tree_cps
320 helperToolConfigTools.extend(process_simple(tree_cps))
321
322 scenario_chainparts =[
323 cp for cp in chain_parts if cp['hypoScenario'] != 'simple']
324
325 if scenario_chainparts:
326 for scenario_chainpart in scenario_chainparts:
327 # scenario_chainpart = scenario_chainparts[0]
328
329 # We only allow threshold != 0 for the simple scenario.
330 assert scenario_chainpart['threshold'] == '0'
331
332 scenario = scenario_chainpart['hypoScenario']
333 # find the chain part index for a non-simple scenario.
334 # assume simple is processed before non-simple, and that
335 # there is at most one non-simple chainpart.
336 # chainPartInd is needed to report passing jets to the
337 # trigger framework.
338 chainPartInd = scenario_chainpart['chainPartIndex']
339
340 helperToolConfigTools.extend(process_nonsimple(scenario,
341 chainPartInd))
342
343 return helperToolConfigTools
344
345
347 """Set up the prefilters fo the chain."""
348
349 pf_strings = []
350 chain_parts = [cp for cp in chain_dict['chainParts'] if
351 cp['signature'] == 'Jet' and 'prefilters' in cp]
352
353 [pf_strings.extend(cp['prefilters']) for cp in chain_parts]
354
355 # if not pre filter strings (pf_strings) are found in the chainDict,
356 # a PassThroughFilter configurer is made.
357
358 if not pf_strings:
359 return []
360
361 # route the prefilter strings to the appropriate handler
362 prefilter_router = {
363 'MASK': prefilter_mask,
364 'PTRANGE': prefilter_ptrange,
365 'MAXMULT': prefilter_maxmult,
366 'CLEAN': prefilter_clean,
367 }
368
369 pattern = r'(?P<stub>[A-Z]*)'
370 rgx = re.compile(pattern)
371
372 filters = []
373 for pf_string in pf_strings:
374 # get prefilter stub and make sure is correct
375 m = rgx.match(pf_string)
376 assert m is not None,'No prefilter stub was found'
377 groupdict = m.groupdict()
378 assert groupdict['stub'] in prefilter_router,'prefilter stub ({}) not recognized'.format(groupdict['stub'])
379 filters.append(prefilter_router[groupdict['stub']](pf_string))
380
381 return filters
382
383
384def getLabelIndices(chain_dict):
385
386 start_index = 0
387 if isLegId(chain_dict['chainName']):
388 start_index = getLegIndexInt(chain_dict['chainName'])
389
390 end_index = start_index + len(chain_dict['chainParts'])
391
392 return start_index, end_index
393
394
395def hypotool_from_chaindict(chain_dict, visit_debug=False):
396
397 toolfactory.reset()
398
399 if visit_debug:
400 fn = chain_dict['chainName'] + '_chaindict.log'
401 from pprint import pprint
402 with open(fn, 'w') as fh:
403 pprint(chain_dict, fh)
404
405
406 helperToolConfigTools = make_fastreduction_configurers(chain_dict)
407
408 prefilterMakers = make_prefilter_configurers(chain_dict)
409
410 toolclass, name = toolfactory('helper_tool')
411 args = {'name': name,
412 'HypoConfigurers': helperToolConfigTools,
413 'prefilterMakers': prefilterMakers
414 }
415
416 helper_tool = toolclass(**args)
417
418 toolclass, name = toolfactory('hypo_tool')
419
420 startLabelIndex, endLabelIndex = getLabelIndices(chain_dict)
421
422 args = {'name': chain_dict['chainName'],
423 # for reporting passing jets:
424 'visit_debug': visit_debug,
425 'helper_tool': helper_tool,
426 'chain_name': chain_dict['chainName'],
427 'startLabelIndex': startLabelIndex,
428 'endLabelIndex': endLabelIndex,
429 }
430
431 hypo_tool = toolclass(**args)
432 hypo_tool.visit_debug = visit_debug
433
434 if (visit_debug):
435 hypoToolDisplay(hypo_tool,
436 do_dot=True)
437
438 return hypo_tool
439
440if __name__ == '__main__':
441 cd = {'EBstep': '',
442 'L1item': 'L1_EM22VHI',
443 'alignmentGroups': ['Egamma', 'JetMET', 'JetMET'],
444 'chainCounter': 1451,
445 'chainMultiplicities': [1, 2, 2],
446 'chainName': 'leg001_HLT_g25_medium_2j35_pf_ftf_0eta490_bdl1r77_2j35_pf_ftf_0eta490_L1EM22VHI',
447 'chainNameHash': 4053501929,
448 'chainParts': [{'L1threshold': 'FSNOSEED',
449 'addInfo': [],
450 'alignmentGroup': 'JetMET',
451 'bConfig': [],
452 'bMatching': [],
453 'bTag': 'bdl1r77',
454 'bTracking': '',
455 'bsel': '',
456 'tausel': '',
457 'chainPartIndex': 1,
458 'chainPartName': '2j35_pf_ftf_0eta490_bdl1r77',
459 'clusterCalib': 'em',
460 'constitMod': '',
461 'constitType': 'pf',
462 'etaRange': '0eta490',
463 'exotHypo': [],
464 'extra': '',
465 'hypoScenario': 'simple',
466 'ionopt': 'noion',
467 'jetCalib': 'default',
468 'jvt': '',
469 'momCuts': '',
470 'multiplicity': '2',
471 'prefilters': [],
472 'recoAlg': 'a4',
473 'scan': 'FS',
474 'sigFolder': ['Bjet'],
475 'signature': 'Bjet',
476 'smc': 'nosmc',
477 'subSigs': ['Bjet'],
478 'tboundary': '',
479 'threshold': '35',
480 'topo': [],
481 'trigType': 'j',
482 'trkopt': 'ftf',
483 'trkpresel': 'nopresel'},
484 {'L1threshold': 'FSNOSEED',
485 'addInfo': [],
486 'alignmentGroup': 'JetMET',
487 'bConfig': [],
488 'bMatching': [],
489 'bTag': '',
490 'bTracking': '',
491 'bsel': '',
492 'tausel': '',
493 'chainPartIndex': 2,
494 'chainPartName': '2j35_pf_ftf_0eta490',
495 'clusterCalib': 'em',
496 'constitMod': '',
497 'constitType': 'pf',
498 'etaRange': '0eta490',
499 'exotHypo': [],
500 'extra': '',
501 'hypoScenario': 'simple',
502 'ionopt': 'noion',
503 'jetCalib': 'default',
504 'jvt': '',
505 'momCuts': '',
506 'multiplicity': '2',
507 'prefilters': [],
508 'recoAlg': 'a4',
509 'scan': 'FS',
510 'sigFolder': ['Jet'],
511 'signature': 'Jet',
512 'smc': 'nosmc',
513 'subSigs': ['Jet'],
514 'tboundary': '',
515 'threshold': '35',
516 'topo': [],
517 'trigType': 'j',
518 'trkopt': 'ftf',
519 'trkpresel': 'nopresel'}],
520 'eventBuildType': '',
521 'extraComboHypos': [],
522 'groups': ['Support:Legacy', 'RATE:EgammaBjet', 'BW:BJet'],
523 'mergingOffset': -1,
524 'mergingOrder': [],
525 'mergingStrategy': 'auto',
526 'monGroups': [],
527 'prescale': 1,
528 'sigDicts': {'Bjet': ['Bjet'], 'Egamma': ['Photon'], 'Jet': ['Jet']},
529 'sigFolder': [],
530 'signature': 'Bjet',
531 'signatures': ['Photon', 'Bjet', 'Jet'],
532 'stream': ['Main'],
533 'subSigs': [],
534 'topo': []}
535
537
538
bool isLegId(const HLT::Identifier &legIdentifier)
Recognise whether the chain ID is a leg ID.
process_fbdjnoshared(scenario, chainPartInd)
process_htdipz(scenario, chainPartInd)
make_fastreduction_configurers(chain_dict)
hypotool_from_chaindict(chain_dict, visit_debug=False)
process_ht(scenario, chainPartInd)
process_mult(scenario, chainPartInd)
process_dijet(scenario, chainPartInd)
process_nonsimple(scenario, chainPartInd)
process_dipz(scenario, chainPartInd)
process_fbdjshared(scenario, chainPartInd)