ATLAS Offline Software
EventSelectionConfig.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 
3 from AnalysisAlgorithmsConfig.ConfigBlock import ConfigBlock
4 from AsgAnalysisAlgorithms.AsgAnalysisConfig import makeEventCutFlowConfig
5 from AnalysisAlgorithmsConfig.ConfigAccumulator import DataType
6 
7 
8 class EventSelectionMergerConfig(ConfigBlock):
9  """ConfigBlock for merging the output of various selection streams"""
10 
11  def __init__(self):
12  super(EventSelectionMergerConfig, self).__init__()
13  self.addOption('selections', [], type=list,
14  info="the selection decisions (list of strings) to unify into a "
15  "final decision (internally: selection_1 || selection_2 || ...). "
16  "The default is [] (empty list).")
17  self.addOption('noFilter', False, type=bool,
18  info="do not apply an event filter. The default is False, i.e. "
19  "remove events not passing the full list of selection cuts.")
20 
21  def instanceName (self) :
22  """Return the instance name for this block"""
23  return '' # I think there is only one instance of this block, not sure what the name ought to be
24 
25  def makeAlgs(self, config):
26  if not ( isinstance(self.selections, list) and self.selections and all(isinstance(item, str) for item in self.selections) ):
27  print('EventSelectionMerger: selections = ', self.selections)
28  raise ValueError('EventSelectionMerger requires a non-empty list of selection strings to be '
29  'passed as `selections`!')
30  alg = config.createAlgorithm('CP::SaveFilterAlg', 'EventSelectionMerger' + self.selections[0].split("_%SYS%")[0])
31  alg.FilterDescription = 'events passing at least one EventSelection algorithm'
32  alg.eventDecisionOutputDecoration = 'ignore_anySelection_%SYS%'
33  alg.selection = '||'.join([sel+',as_char' for sel in self.selections if sel])
34  alg.noFilter = self.noFilter
35  alg.selectionName = 'pass_anySelection_%SYS%'
36  alg.decorationName = 'ntuplepass_anySelection_%SYS%'
37 
38 class EventSelectionConfig(ConfigBlock):
39  """ConfigBlock for interpreting text-based event selections"""
40 
41  def __init__(self):
42  super(EventSelectionConfig, self).__init__()
43  self.addOption('name', '', type=str,
44  noneAction='error',
45  info="the name of the event selection, used to uniquely identify "
46  "the EventSelectionConfig block.")
47  self.addOption('electrons', "", type=str,
48  info="the input electron container, with a possible selection, in "
49  "the format container or container.selection. The default is '' "
50  "(empty string).")
51  self.addOption('muons', "", type=str,
52  info="the input muon container, with a possible selection, in the "
53  "format container or container.selection. The default is '' "
54  "(empty string).")
55  self.addOption('jets', "", type=str,
56  info="the input jet container, with a possible selection, in the "
57  "format container or container.selection. The default is '' "
58  "(empty string).")
59  self.addOption('largeRjets', "", type=str,
60  info="the large-R jet container, with a possible selection, in "
61  "the format container or container.selection. The default is '' "
62  "(empty string).")
63  self.addOption('photons', "", type=str,
64  info="the input photon container, with a possible selection, in "
65  "the format container or container.selection. The default is '' "
66  "(empty string).")
67  self.addOption('taus', "", type=str,
68  info="the input tau-jet container, with a possible selection, in "
69  "the format container or container.selection. The default is '' "
70  "(empty string).")
71  self.addOption('met', "", type=str,
72  info="he input MET container. The default is '' (empty string).")
73  #TODO: add info string
74  self.addOption('metTerm', "Final", type=str,
75  info="")
76  self.addOption('btagDecoration', "", type=str,
77  info="the b-tagging decoration to use when defining b-jets. "
78  "The default is '' (empty string).")
79  self.addOption('preselection', "", type=str,
80  info="the event-wise selection flag to start this event selection "
81  "from. The default is '' (empty string).")
82  self.addOption('selectionCuts', "", type=str,
83  noneAction='error',
84  info="a single string listing one selection cut per line.")
85  self.addOption('noFilter', False, type=bool,
86  info="do not apply an event filter. The default is False, i.e. "
87  "remove events not passing the full list of selection cuts.")
88  self.addOption('debugMode', False, type=bool,
89  info="whether to create an output branch for every single line "
90  "of the selection cuts. The default is False (only saves the"
91  " final decision).")
92  self.addOption('useDressedProperties', True, type=bool,
93  info="whether to use dressed truth electron and truth muon "
94  "kinematics rather than simple P4 kinematics.")
95  self.step = 0
97  self.cutflow = []
98 
99  def instanceName (self) :
100  """Return the instance name for this block"""
101  return self.name
102 
103  def makeAlgs(self, config):
104  # need to re-initialize here to deal with multiple passes
105  self.step = 0
106  # initialize the pre-selection
107  self.currentDecoration = self.preselection
108  # re-initialize the cutflow
109  self.cutflow = []
110  # read the selection cuts
111  if self.selectionCuts is None:
112  raise ValueError ("[EventSelectionConfig] You must provide the 'selectionCuts' option to 'EventSelectionConfig': "
113  "a single string where each line represents a different selection cut to apply in order.")
114  for line in self.selectionCuts.split("\n"):
115  self.interpret(line, config)
116  config.addEventCutFlow(self.name, self.getCutflow())
117 
118  def interpret(self, text, cfg):
119  text = text.strip()
120  if not text:
121  return
122  if text.startswith("#"):
123  return
124  self.step += 1
125  if "EL_N" in text.split():
126  self.add_NEL_selector(text, cfg)
127  elif "MU_N" in text.split():
128  self.add_NMU_selector(text, cfg)
129  elif "SUM_EL_N_MU_N" in text.split():
130  self.add_SUMNELNMU_selector(text, cfg)
131  elif "SUM_EL_N_MU_N_TAU_N" in text.split():
132  self.add_SUMNLEPTONS_selector(text, cfg)
133  elif "JET_N_GHOST" in text.split():
134  self.add_NJETGHOST_selector(text, cfg)
135  elif "JET_N" in text.split():
136  self.add_NJET_selector(text, cfg)
137  elif "JET_N_BTAG" in text.split():
138  self.add_NBJET_selector(text, cfg)
139  elif "PH_N" in text.split():
140  self.add_NPH_selector(text, cfg)
141  elif "TAU_N" in text.split():
142  self.add_NTAU_selector(text, cfg)
143  elif "LJET_N_GHOST" in text.split():
144  self.add_NLJETGHOST_selector(text, cfg)
145  elif "LJET_N" in text.split():
146  self.add_NLJET_selector(text, cfg)
147  elif "OBJ_N" in text.split():
148  self.add_NOBJ_selector(text, cfg)
149  elif "MET" in text.split():
150  self.add_MET_selector(text, cfg)
151  elif "MWT" in text.split():
152  self.add_MWT_selector(text, cfg)
153  elif "MET+MWT" in text.split():
154  self.add_METMWT_selector(text, cfg)
155  elif "MLL" in text.split():
156  self.add_MLL_selector(text, cfg)
157  elif "MLLWINDOW" in text.split():
158  self.add_MLLWINDOW_selector(text, cfg)
159  elif "OS" in text.split():
160  self.add_OS_selector(text, cfg)
161  elif "SS" in text.split():
162  self.add_SS_selector(text, cfg)
163  elif "MLL_OSSF" in text.split():
164  self.add_MLL_OSSF_selector(text, cfg)
165  elif "LJETMASS_N" in text.split():
166  self.add_NLJETMASS_selector(text, cfg)
167  elif "LJETMASSWINDOW_N" in text.split():
168  self.add_NLJETMASSWINDOW_selector(text, cfg)
169  elif "SAVE" in text.split():
170  self.add_SAVE(text, cfg)
171  elif "IMPORT" in text.split():
172  self.add_IMPORT(text, cfg)
173  elif "EVENTFLAG" in text.split():
174  self.add_EVENTFLAG(text, cfg)
175  elif "GLOBALTRIGMATCH" in text.split():
176  self.add_GLOBALTRIGMATCH(text, cfg)
177  elif "RUN_NUMBER" in text.split():
178  self.add_RUNNUMBER(text, cfg)
179  else:
180  raise ValueError (f"[EventSelectionConfig] The following selection cut is not recognised! --> {text}")
181 
182  def raise_misconfig(self, text, keyword):
183  raise ValueError (f"[EventSelectionConfig] Misconfiguration! Check {keyword} in: {text}")
184 
185  def raise_missinginput(self, collection):
186  raise ValueError (f"[EventSelectionConfig] Misconfiguration! Missing input collection for {collection}")
187 
188  def check_float(self, test, requirePositive=True):
189  try:
190  value = float(test)
191  if not requirePositive or value >= 0:
192  return value
193  else:
194  raise ValueError (f"[EventSelectionConfig] Misconfiguration! Float {test} is not positive!")
195  except ValueError:
196  raise ValueError (f"[EventSelectionConfig] Misconfiguration! {test} should be a float, not {type(test)}!")
197 
198  def check_int(self, test, requirePositive=True):
199  try:
200  value = int(test)
201  if value == float(test):
202  if not requirePositive or value >= 0:
203  return value
204  else:
205  raise ValueError (f"[EventSelectionConfig] Misconfiguration! Int {test} us not positive!")
206  else:
207  raise ValueError (f"[EventSelectionConfig] Misconfiguration! {test} should be an int, not a float!")
208  except ValueError:
209  raise ValueError (f"[EventSelectionConfig] Misconfiguration! {test} should be an int, not {type(test)}")
210 
211  def check_string(self, test):
212  if not isinstance(test, str):
213  raise ValueError (f"[EventSelectionConfig] Misconfiguration! {test} should be a string, not a number!")
214  else:
215  return test
216 
217  def check_sign(self, test):
218  mapping = {
219  "<" : "LT",
220  ">" : "GT",
221  "==": "EQ",
222  ">=": "GE",
223  "<=": "LE"
224  }
225  try:
226  return mapping[test]
227  except KeyError:
228  raise KeyError (f"[EventSelectionConfig] Misconfiguration! {test} should be one of {list(mapping.keys())}")
229 
230  def check_btagging(self, test):
231  test = test.split(":")
232  if len(test) != 2:
233  raise ValueError (f"[EventSelectionConfig] Misconfiguration! {test} should be provided as 'btagger:btagWP'")
234  else:
235  return test
236 
237  def check_ghosts(self, test):
238  test = self.check_string(test)
239  values = test.split("!")
240  ghost_map = {
241  "B": "GhostBHadronsFinalCount",
242  "C": "GhostCHadronsFinalCount",
243  "T": "GhostTQuarksFinalCount",
244  "W": "GhostWBosonsCount",
245  "Z": "GhostZBosonsCount",
246  "H": "GhostHBosonsCount",
247  "TAU": "GhostTausFinalCount"
248  }
249  return [ghost_map.get(value.upper(), value) for value in values]
250 
251  def getCutflow(self):
252  return self.cutflow
253 
254  def setDecorationName(self, algorithm, config, decoration):
255  self.cutflow.append( decoration )
256  if algorithm is not None:
257  algorithm.decorationName = f'{decoration},as_char'
258  self.currentDecoration = decoration
259  if self.debugMode:
260  config.addOutputVar('EventInfo', decoration, decoration.split("_%SYS%")[0])
261  else:
262  if self.currentDecoration:
263  self.currentDecoration += '&&' + decoration
264  else:
265  self.currentDecoration = decoration
266  config.addSelection('EventInfo', '', decoration)
267  return
268 
269  def checkDecorationName(self, decoration):
270  if decoration == '':
271  return decoration
272  decoration = decoration.split("&&")
273  decoration = [sub + ',as_char' if ',as_char' not in sub else sub for sub in decoration]
274  return '&&'.join(decoration)
275 
276  def extendObjectSelection(self, config, container, oldSelection, newSelection):
277  if oldSelection:
278  return oldSelection + "&&" + config.getFullSelection(container, newSelection)
279  else:
280  return config.getFullSelection(container, newSelection)
281 
282  def add_IMPORT(self, text, config):
283  # this is used to import a previous selection
284  items = text.split()
285  if items[0] != "IMPORT":
286  self.raise_misconfig(text, "IMPORT")
287  if len(items) != 2:
288  self.raise_misconfig(text, "number of arguments")
289  region = self.check_string(items[1])
290  if not self.currentDecoration:
291  self.currentDecoration = f'pass_{region}_%SYS%,as_char'
292  else:
293  self.currentDecoration = f'{self.currentDecoration},as_char&&pass_{region}_%SYS%'
294  # for the cutflow, we need to retrieve all the cuts corresponding to this IMPORT
295  imported_cuts = [cut for cut in config.getSelectionCutFlow('EventInfo', '') if cut.startswith(region)]
296  self.cutflow += imported_cuts
297  return
298 
299  def add_NEL_selector(self, text, config):
300  items = text.split()
301  if items[0] != "EL_N":
302  self.raise_misconfig(text, "EL_N")
303  if len(items) != 4 and len(items) != 5:
304  self.raise_misconfig(text, "number of arguments")
305  if not self.electrons:
306  self.raise_missinginput("electrons")
307  thisalg = f'{self.name}_NEL_{self.step}'
308  alg = config.createAlgorithm('CP::NObjectPtSelectorAlg', thisalg)
309  alg.particles, alg.objectSelection = config.readNameAndSelection(self.electrons)
310  if "Truth" in self.electrons:
311  alg.useDressedProperties = self.useDressedProperties
312  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
313  if len(items) == 4:
314  alg.minPt = self.check_float(items[1])
315  alg.sign = self.check_sign(items[2])
316  alg.count = self.check_int(items[3])
317  elif len(items) == 5:
318  extraSel = self.check_string(items[1])
319  alg.objectSelection = self.extendObjectSelection(config, self.electrons.split(".")[0], alg.objectSelection, extraSel)
320  alg.minPt = self.check_float(items[2])
321  alg.sign = self.check_sign(items[3])
322  alg.count = self.check_int(items[4])
323  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
324  return
325 
326  def add_NMU_selector(self, text, config):
327  items = text.split()
328  if items[0] != "MU_N":
329  self.raise_misconfig(text, "MU_N")
330  if len(items) != 4 and len(items) != 5:
331  self.raise_misconfig(text, "number of arguments")
332  if not self.muons:
333  self.raise_missinginput("muons")
334  thisalg = f'{self.name}_NMU_{self.step}'
335  alg = config.createAlgorithm('CP::NObjectPtSelectorAlg', thisalg)
336  alg.particles, alg.objectSelection = config.readNameAndSelection(self.muons)
337  if "Truth" in self.muons:
338  alg.useDressedProperties = self.useDressedProperties
339  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
340  if len(items) == 4:
341  alg.minPt = self.check_float(items[1])
342  alg.sign = self.check_sign(items[2])
343  alg.count = self.check_int(items[3])
344  elif len(items) == 5:
345  extraSel = self.check_string(items[1])
346  alg.objectSelection = self.extendObjectSelection(config, self.muons.split(".")[0], alg.objectSelection, extraSel)
347  alg.minPt = self.check_float(items[2])
348  alg.sign = self.check_sign(items[3])
349  alg.count = self.check_int(items[4])
350  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
351  return
352 
353  def add_SUMNELNMU_selector(self, text, config):
354  items = text.split()
355  if items[0] != "SUM_EL_N_MU_N":
356  self.raise_misconfig(text, "SUM_EL_N_MU_N")
357  if len(items) != 4 and len(items) != 5 and len(items) != 7:
358  self.raise_misconfig(text, "number of arguments")
359  if not self.electrons and not self.muons:
360  self.raise_missinginput("electrons or muons")
361  thisalg = f'{self.name}_SUMNELNMU_{self.step}'
362  alg = config.createAlgorithm('CP::SumNLeptonPtSelectorAlg', thisalg)
363  alg.electrons, alg.electronSelection = config.readNameAndSelection(self.electrons)
364  alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
365  if "Truth" in self.electrons:
366  alg.useDressedProperties = self.useDressedProperties
367  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
368  if len(items) == 4:
369  alg.minPtEl = self.check_float(items[1])
370  alg.minPtMu = self.check_float(items[1])
371  alg.sign = self.check_sign(items[2])
372  alg.count = self.check_int(items[3])
373  elif len(items) == 5:
374  alg.minPtEl = self.check_float(items[1])
375  alg.minPtMu = self.check_float(items[2])
376  alg.sign = self.check_sign(items[3])
377  alg.count = self.check_int(items[4])
378  elif len(items) == 7:
379  extraSelEl = self.check_string(items[1])
380  extraSelMu = self.check_string(items[2])
381  alg.electronSelection = self.extendObjectSelection(config, self.electrons.split(".")[0], alg.electronSelection, extraSelEl)
382  alg.muonSelection = self.extendObjectSelection(config, self.muons.split(".")[0], alg.muonSelection, extraSelMu)
383  alg.minPtEl = self.check_float(items[3])
384  alg.minPtMu = self.check_float(items[4])
385  alg.sign = self.check_sign(items[5])
386  alg.count = self.check_int(items[6])
387  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
388  return
389 
390  def add_SUMNLEPTONS_selector(self, text, config):
391  items = text.split()
392  if items[0] != "SUM_EL_N_MU_N_TAU_N":
393  self.raise_misconfig(text, "SUM_EL_N_MU_N_TAU_N")
394  if len(items) != 4 and len(items) != 6 and len(items) != 9:
395  self.raise_misconfig(text, "number of arguments")
396  if not self.electrons and not self.muons and not self.taus:
397  self.raise_missinginput("electrons, muons or taus")
398  thisalg = f'{self.name}_SUMNLEPTONS_{self.step}'
399  alg = config.createAlgorithm('CP::SumNLeptonPtSelectorAlg', thisalg)
400  alg.electrons, alg.electronSelection = config.readNameAndSelection(self.electrons)
401  alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
402  alg.taus, alg.tauSelection = config.readNameAndSelection(self.taus)
403  if "Truth" in self.electrons:
404  alg.useDressedProperties = self.useDressedProperties
405  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
406  if len(items) == 4:
407  alg.minPtEl = self.check_float(items[1])
408  alg.minPtMu = self.check_float(items[1])
409  alg.minPtTau = self.check_float(items[1])
410  alg.sign = self.check_sign(items[2])
411  alg.count = self.check_int(items[3])
412  elif len(items) == 6:
413  alg.minPtEl = self.check_float(items[1])
414  alg.minPtMu = self.check_float(items[2])
415  alg.minPtTau = self.check_float(items[3])
416  alg.sign = self.check_sign(items[4])
417  alg.count = self.check_int(items[5])
418  elif len(items) == 9:
419  extraSelEl = self.check_string(items[1])
420  extraSelMu = self.check_string(items[2])
421  extraSelTau = self.check_string(items[3])
422  alg.electronSelection = self.extendObjectSelection(config, self.electrons.split(".")[0], alg.electronSelection, extraSelEl)
423  alg.muonSelection = self.extendObjectSelection(config, self.muons.split(".")[0], alg.muonSelection, extraSelMu)
424  alg.tauSelection = self.extendObjectSelection(config, self.taus.split(".")[0], alg.tauSelection, extraSelTau)
425  alg.minPtEl = self.check_float(items[4])
426  alg.minPtMu = self.check_float(items[5])
427  alg.minPtTau = self.check_float(items[6])
428  alg.sign = self.check_sign(items[7])
429  alg.count = self.check_int(items[8])
430  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
431  return
432 
433  def add_NJET_selector(self, text, config):
434  items = text.split()
435  if items[0] != "JET_N":
436  self.raise_misconfig(text, "JET_N")
437  if len(items) != 4 and len(items) != 5:
438  self.raise_misconfig(text, "number of arguments")
439  if not self.jets:
440  self.raise_missinginput("jets")
441  thisalg = f'{self.name}_NJET_{self.step}'
442  alg = config.createAlgorithm('CP::NObjectPtSelectorAlg', thisalg)
443  alg.particles, alg.objectSelection = config.readNameAndSelection(self.jets)
444  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
445  if len(items) == 4:
446  alg.minPt = self.check_float(items[1])
447  alg.sign = self.check_sign(items[2])
448  alg.count = self.check_int(items[3])
449  elif len(items) == 5:
450  extraSel = self.check_string(items[1])
451  alg.objectSelection = self.extendObjectSelection(config, self.jets.split(".")[0], alg.objectSelection, extraSel)
452  alg.minPt = self.check_float(items[2])
453  alg.sign = self.check_sign(items[3])
454  alg.count = self.check_int(items[4])
455  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
456  return
457 
458  def add_NBJET_selector(self, text, config):
459  items = text.split()
460  if items[0] != "JET_N_BTAG":
461  self.raise_misconfig(text, "JET_N_BTAG")
462  if len(items) != 3 and len(items) != 4 and len(items) != 5:
463  self.raise_misconfig(text, "number of arguments")
464  if not self.jets:
465  self.raise_missinginput("jets")
466  thisalg = f'{self.name}_NBJET_{self.step}'
467  alg = config.createAlgorithm('CP::NObjectPtSelectorAlg', thisalg)
468  particles, selection = config.readNameAndSelection(self.jets)
469  alg.particles = particles
470  alg.objectSelection = f'{selection}&&{self.btagDecoration},as_char' if selection else f'{self.btagDecoration},as_char'
471  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
472  if len(items) == 3:
473  alg.sign = self.check_sign(items[1])
474  alg.count = self.check_int(items[2])
475  elif len(items) == 4:
476  if ":" in text:
477  btagger, btagWP = self.check_btagging(items[1])
478  customBtag = f'ftag_select_{btagger}_{btagWP}'
479  alg.objectSelection = f'{selection}&&{customBtag},as_char' if selection else f'{customBtag},as_char'
480  else:
481  extraSel = self.check_string(items[1])
482  alg.objectSelection = self.extendObjectSelection(config, self.jets.split(".")[0], alg.objectSelection, extraSel)
483  alg.sign = self.check_sign(items[2])
484  alg.count = self.check_int(items[3])
485  elif len(items) == 5:
486  extraSel = self.check_string(items[1])
487  btagger, btagWP = self.check_btagging(items[2])
488  customBtag = f'ftag_select_{btagger}_{btagWP}'
489  alg.objectSelection = f'{selection}&&{customBtag},as_char' if selection else f'{customBtag},as_char'
490  alg.objectSelection = self.extendObjectSelection(config, self.jets.split(".")[0], alg.objectSelection, extraSel)
491  alg.sign = self.check_sign(items[3])
492  alg.count = self.check_int(items[4])
493  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
494  return
495 
496  def add_NPH_selector(self, text, config):
497  items = text.split()
498  if items[0] != "PH_N":
499  self.raise_misconfig(text, "PH_N")
500  if len(items) != 4 and len(items) != 5:
501  self.raise_misconfig(text, "number of arguments")
502  if not self.photons:
503  self.raise_missinginput("photons")
504  thisalg = f'{self.name}_NPH_{self.step}'
505  alg = config.createAlgorithm('CP::NObjectPtSelectorAlg', thisalg)
506  alg.particles, alg.objectSelection = config.readNameAndSelection(self.photons)
507  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
508  if len(items) == 4:
509  alg.minPt = self.check_float(items[1])
510  alg.sign = self.check_sign(items[2])
511  alg.count = self.check_int(items[3])
512  elif len(items) == 5:
513  extraSel = self.check_string(items[1])
514  alg.objectSelection = self.extendObjectSelection(config, self.photons.split(".")[0], alg.objectSelection, extraSel)
515  alg.minPt = self.check_float(items[2])
516  alg.sign = self.check_sign(items[3])
517  alg.count = self.check_int(items[4])
518  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
519  return
520 
521  def add_NTAU_selector(self, text, config):
522  items = text.split()
523  if items[0] != "TAU_N":
524  self.raise_misconfig(text, "TAU_N")
525  if len(items) != 4 and len(items) != 5:
526  self.raise_misconfig(text, "number of arguments")
527  if not self.taus:
528  self.raise_missinginput("taus")
529  thisalg = f'{self.name}_NTAU_{self.step}'
530  alg = config.createAlgorithm('CP::NObjectPtSelectorAlg', thisalg)
531  alg.particles, alg.objectSelection = config.readNameAndSelection(self.taus)
532  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
533  if len(items) == 4:
534  alg.minPt = self.check_float(items[1])
535  alg.sign = self.check_sign(items[2])
536  alg.count = self.check_int(items[3])
537  elif len(items) == 5:
538  extraSel = self.check_string(items[1])
539  alg.objectSelection = self.extendObjectSelection(config, self.taus.split(".")[0], alg.objectSelection, extraSel)
540  alg.minPt = self.check_float(items[2])
541  alg.sign = self.check_sign(items[3])
542  alg.count = self.check_int(items[4])
543  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
544  return
545 
546  def add_NLJET_selector(self, text, config):
547  items = text.split()
548  if items[0] != "LJET_N":
549  self.raise_misconfig(text, "LJET_N")
550  if len(items) != 4 and len(items) != 5:
551  self.raise_misconfig(text, "number of arguments")
552  thisalg = f'{self.name}_NLJET_{self.step}'
553  alg = config.createAlgorithm('CP::NObjectPtSelectorAlg', thisalg)
554  alg.particles, alg.objectSelection = config.readNameAndSelection(self.largeRjets)
555  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
556  if len(items) == 4:
557  alg.minPt = self.check_float(items[1])
558  alg.sign = self.check_sign(items[2])
559  alg.count = self.check_int(items[3])
560  elif len(items) == 5:
561  extraSel = self.check_string(items[1])
562  alg.objectSelection = self.extendObjectSelection(config, self.largeRjets.split(".")[0], alg.objectSelection, extraSel)
563  alg.minPt = self.check_float(items[2])
564  alg.sign = self.check_sign(items[3])
565  alg.count = self.check_int(items[4])
566  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
567  return
568 
569  def add_NLJETMASS_selector(self, text, config):
570  items = text.split()
571  if items[0] != "LJETMASS_N":
572  self.raise_misconfig(text, "LJETMASS_N")
573  if len(items) != 4 and len(items) != 5:
574  self.raise_misconfig(text, "number of arguments")
575  thisalg = f'{self.name}_NLJETMASS_{self.step}'
576  alg = config.createAlgorithm('CP::NObjectMassSelectorAlg', thisalg)
577  alg.particles, alg.objectSelection = config.readNameAndSelection(self.largeRjets)
578  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
579  if len(items) == 4:
580  alg.minMass = self.check_float(items[1])
581  alg.sign = self.check_sign(items[2])
582  alg.count = self.check_int(items[3])
583  elif len(items) == 5:
584  extraSel = self.check_string(items[1])
585  alg.objectSelection = self.extendObjectSelection(config, self.largeRjets.split(".")[0], alg.objectSelection, extraSel)
586  alg.minMass = self.check_float(items[2])
587  alg.sign = self.check_sign(items[3])
588  alg.count = self.check_int(items[4])
589  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
590  return
591 
592  def add_NLJETMASSWINDOW_selector(self, text, config):
593  items = text.split()
594  if items[0] != "LJETMASSWINDOW_N":
595  self.raise_misconfig(text, "LJETMASSWINDOW_N")
596  if len(items) != 5 and len(items) != 6 and len(items) != 7:
597  self.raise_misconfig(text, "number of arguments")
598  thisalg = f'{self.name}_NLJETMASSWINDOW_{self.step}'
599  alg = config.createAlgorithm('CP::NLargeRJetMassWindowSelectorAlg', thisalg)
600  alg.ljets, alg.ljetSelection = config.readNameAndSelection(self.largeRjets)
601  vetoMode = items[-1] == 'veto' or items[-1] == 'VETO'
602  if len(items) == 5 or (len(items) == 6 and vetoMode):
603  alg.lowMass = self.check_float(items[1])
604  alg.highMass = self.check_float(items[2])
605  alg.sign = self.check_sign(items[3])
606  alg.count = self.check_int(items[4])
607  alg.vetoMode = vetoMode
608  elif (len(items) == 6 and not vetoMode) or len(items) == 7:
609  extraSel = self.check_string(items[1])
610  alg.ljetSelection = self.extendObjectSelection(config, self.largeRjets.split(".")[0], alg.ljetSelection, extraSel)
611  alg.lowMass = self.check_float(items[2])
612  alg.highMass = self.check_float(items[3])
613  alg.sign = self.check_sign(items[4])
614  alg.count = self.check_int(items[5])
615  alg.vetoMode = vetoMode
616  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
617  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
618  return
619 
620  def add_NJETGHOST_selector(self, text, config):
621  items = text.split()
622  if items[0] != "JET_N_GHOST":
623  self.raise_misconfig(text, "JET_N_GHOST")
624  if len(items) != 4 and len(items) != 5:
625  self.raise_misconfig(text, "number of arguments")
626  thisalg = f'{self.name}_NJETGHOST_{self.step}'
627  alg = config.createAlgorithm('CP::JetNGhostSelectorAlg', thisalg)
628  alg.jets, alg.jetSelection = config.readNameAndSelection(self.jets)
629  ghosts = self.check_ghosts(items[1])
630  alg.ghost = ghosts[0]
631  if len(ghosts) > 1 :
632  alg.veto = ghosts[1]
633  if len(items) == 4:
634  alg.sign = self.check_sign(items[2])
635  alg.count = self.check_int(items[3])
636  elif len(items) == 5:
637  alg.minPt = self.check_float(items[2])
638  alg.sign = self.check_sign(items[3])
639  alg.count = self.check_int(items[4])
640  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
641  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
642  return
643 
644  def add_NLJETGHOST_selector(self, text, config):
645  items = text.split()
646  if items[0] != "LJET_N_GHOST":
647  self.raise_misconfig(text, "LJET_N_GHOST")
648  if len(items) != 4 and len(items) != 5:
649  self.raise_misconfig(text, "number of arguments")
650  thisalg = f'{self.name}_NLJETGHOST_{self.step}'
651  alg = config.createAlgorithm('CP::JetNGhostSelectorAlg', thisalg)
652  alg.jets, alg.jetSelection = config.readNameAndSelection(self.largeRjets)
653  ghosts = self.check_ghosts(items[1])
654  alg.ghost = ghosts[0]
655  if len(ghosts) > 1 :
656  alg.veto = ghosts[1]
657  if len(items) == 4:
658  alg.sign = self.check_sign(items[2])
659  alg.count = self.check_int(items[3])
660  elif len(items) == 5:
661  alg.minPt = self.check_float(items[2])
662  alg.sign = self.check_sign(items[3])
663  alg.count = self.check_int(items[4])
664  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
665  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
666  return
667 
668  def add_NOBJ_selector(self, text, config):
669  items = text.split()
670  if items[0] != "OBJ_N":
671  self.raise_misconfig(text, "OBJ_N")
672  if len(items) != 5:
673  self.raise_misconfig(text, "number of arguments")
674  thisalg = f'{self.name}_NOBJ_{self.step}'
675  alg = config.createAlgorithm('CP::NObjectPtSelectorAlg', thisalg)
676  alg.particles, alg.objectSelection = config.readNameAndSelection(self.check_string(items[1]))
677  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
678  alg.minPt = self.check_float(items[2])
679  alg.sign = self.check_sign(items[3])
680  alg.count = self.check_int(items[4])
681  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
682  return
683 
684  def add_MET_selector(self, text, config):
685  items = text.split()
686  if items[0] != "MET":
687  self.raise_misconfig(text, "MET")
688  if len(items) != 3:
689  self.raise_misconfig(text, "number of arguments")
690  if not self.met:
691  self.raise_missinginput("MET")
692  thisalg = f'{self.name}_MET_{self.step}'
693  alg = config.createAlgorithm('CP::MissingETSelectorAlg', thisalg)
694  alg.met = config.readName(self.met)
695  alg.metTerm = self.metTerm
696  alg.sign = self.check_sign(items[1])
697  alg.refMET = self.check_float(items[2])
698  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
699  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
700  return
701 
702  def add_MWT_selector(self, text, config):
703  items = text.split()
704  if items[0] != "MWT":
705  self.raise_misconfig(text, "MWT")
706  if len(items) != 3:
707  self.raise_misconfig(text, "number of arguments")
708  if not self.electrons and not self.muons:
709  self.raise_missinginput("electrons or muons")
710  thisalg = f'{self.name}_MWT_{self.step}'
711  alg = config.createAlgorithm('CP::TransverseMassSelectorAlg', thisalg)
712  alg.met = config.readName(self.met)
713  alg.metTerm = self.metTerm
714  alg.electrons, alg.electronSelection = config.readNameAndSelection(self.electrons)
715  alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
716  if "Truth" in self.electrons or "Truth" in self.muons:
717  alg.useDressedProperties = self.useDressedProperties
718  alg.sign = self.check_sign(items[1])
719  alg.refMWT = self.check_float(items[2])
720  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
721  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
722  return
723 
724  def add_METMWT_selector(self, text, config):
725  items = text.split()
726  if items[0] != "MET+MWT":
727  self.raise_misconfig(text, "MET+MWT")
728  if len(items) != 3:
729  self.raise_misconfig(text, "number of arguments")
730  if not self.met:
731  self.raise_missinginput("MET")
732  if not self.electrons and not self.muons:
733  self.raise_missinginput("electrons or muons")
734  thisalg = f'{self.name}_METMWT_{self.step}'
735  alg = config.createAlgorithm('CP::MissingETPlusTransverseMassSelectorAlg', thisalg)
736  alg.met = config.readName(self.met)
737  alg.metTerm = self.metTerm
738  alg.electrons, alg.electronSelection = config.readNameAndSelection(self.electrons)
739  alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
740  if "Truth" in self.electrons or "Truth" in self.muons:
741  alg.useDressedProperties = self.useDressedProperties
742  alg.sign = self.check_sign(items[1])
743  alg.refMETMWT = self.check_float(items[2])
744  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
745  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
746  return
747 
748  def add_MLL_selector(self, text, config):
749  items = text.split()
750  if items[0] != "MLL":
751  self.raise_misconfig(text, "MLL")
752  if len(items) != 3:
753  self.raise_misconfig(text, "number of arguments")
754  if not self.electrons and not self.muons:
755  self.raise_missinginput("electrons or muons")
756  thisalg = f'{self.name}_MLL_{self.step}'
757  alg = config.createAlgorithm('CP::DileptonInvariantMassSelectorAlg', thisalg)
758  if self.electrons:
759  alg.electrons, alg.electronSelection = config.readNameAndSelection(self.electrons)
760  if self.muons:
761  alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
762  if "Truth" in self.electrons or "Truth" in self.muons:
763  alg.useDressedProperties = self.useDressedProperties
764  alg.sign = self.check_sign(items[1])
765  alg.refMLL = self.check_float(items[2])
766  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
767  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
768  return
769 
770  def add_MLLWINDOW_selector(self, text, config):
771  items = text.split()
772  if items[0] != "MLLWINDOW":
773  self.raise_misconfig(text, "MLLWINDOW")
774  if len(items) != 3 and len(items) != 4:
775  self.raise_misconfig(text, "number of arguments")
776  if not self.electrons and not self.muons:
777  self.raise_missinginput("electrons or muons")
778  thisalg = f'{self.name}_MLLWINDOW_{self.step}'
779  alg = config.createAlgorithm('CP::DileptonInvariantMassWindowSelectorAlg', thisalg)
780  if self.electrons:
781  alg.electrons, alg.electronSelection = config.readNameAndSelection(self.electrons)
782  if self.muons:
783  alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
784  if "Truth" in self.electrons or "Truth" in self.muons:
785  alg.useDressedProperties = self.useDressedProperties
786  alg.lowMLL = self.check_float(items[1])
787  alg.highMLL = self.check_float(items[2])
788  alg.vetoMode = (len(items) == 4 and self.check_string(items[3]).lower() == "veto")
789  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
790  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
791  return
792 
793  def add_OS_selector(self, text, config):
794  items = text.split()
795  if not items or len(items) > 4:
796  self.raise_misconfig(text, "number of arguments")
797  if not self.electrons and not self.muons and not self.taus:
798  self.raise_missinginput("electrons or muons or taus")
799  thisalg = f'{self.name}_OS_{self.step}'
800  alg = config.createAlgorithm('CP::ChargeSelectorAlg', thisalg)
801  if self.electrons and (len(items) == 1 or "el" in items):
802  if "Particle" in self.electrons or "Truth" in self.electrons:
803  alg.truthElectrons, alg.truthElectronSelection = config.readNameAndSelection(self.electrons)
804  else:
805  alg.electrons, alg.electronSelection = config.readNameAndSelection(self.electrons)
806  if self.muons and (len(items) == 1 or "mu" in items):
807  if "Particle" in self.muons or "Truth" in self.muons:
808  alg.truthMuons, alg.truthMuonSelection = config.readNameAndSelection(self.muons)
809  else:
810  alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
811  if self.taus and (len(items) == 1 or "tau" in items):
812  if "Particle" in self.taus or "Truth" in self.taus:
813  alg.truthTaus, alg.truthTauSelection = config.readNameAndSelection(self.taus)
814  else:
815  alg.taus, alg.tauSelection = config.readNameAndSelection(self.taus)
816  alg.OS = True
817  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
818  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
819  return
820 
821  def add_SS_selector(self, text, config):
822  items = text.split()
823  if not items or len(items) > 4:
824  self.raise_misconfig(text, "number of arguments")
825  if not self.electrons and not self.muons and not self.taus:
826  self.raise_missinginput("electrons or muons or taus")
827  thisalg = f'{self.name}_SS_{self.step}'
828  alg = config.createAlgorithm('CP::ChargeSelectorAlg', thisalg)
829  if self.electrons and (len(items) == 1 or "el" in items):
830  if "Particle" in self.electrons or "Truth" in self.electrons:
831  alg.truthElectrons, alg.truthElectronSelection = config.readNameAndSelection(self.electrons)
832  else:
833  alg.electrons, alg.electronSelection = config.readNameAndSelection(self.electrons)
834  if self.muons and (len(items) == 1 or "mu" in items):
835  if "Particle" in self.muons or "Truth" in self.muons:
836  alg.truthMuons, alg.truthMuonSelection = config.readNameAndSelection(self.muons)
837  else:
838  alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
839  if self.taus and (len(items) == 1 or "tau" in items):
840  if "Particle" in self.taus or "Truth" in self.taus:
841  alg.truthTaus, alg.truthTauSelection = config.readNameAndSelection(self.taus)
842  else:
843  alg.taus, alg.tauSelection = config.readNameAndSelection(self.taus)
844  alg.OS = False
845  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
846  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
847  return
848 
849  def add_MLL_OSSF_selector(self, text, config):
850  items = text.split()
851  if items[0] != "MLL_OSSF":
852  self.raise_misconfig(text, "MLL_OSSF")
853  if len(items) != 3 and len(items) != 4:
854  self.raise_misconfig(text, "number of arguments")
855  if not self.electrons and not self.muons:
856  self.raise_missinginput("electrons or muons")
857  thisalg = f'{self.name}_MLL_OSSF_{self.step}'
858  alg = config.createAlgorithm('CP::DileptonOSSFInvariantMassWindowSelectorAlg', thisalg)
859  if self.electrons:
860  if "Particle" in self.electrons or "Truth" in self.electrons:
861  alg.truthElectrons, alg.truthElectronSelection = config.readNameAndSelection(self.electrons)
862  else:
863  alg.electrons, alg.electronSelection = config.readNameAndSelection(self.electrons)
864  if self.muons:
865  if "Particle" in self.muons or "Truth" in self.muons:
866  alg.truthMuons, alg.truthMuonSelection = config.readNameAndSelection(self.muons)
867  else:
868  alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
869  if "Truth" in self.electrons or "Truth" in self.muons:
870  alg.useDressedProperties = self.useDressedProperties
871  alg.lowMll = self.check_float(items[1])
872  alg.highMll = self.check_float(items[2])
873  alg.vetoMode = (len(items) == 4 and self.check_string(items[3]).lower() == "veto")
874  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
875  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
876  return
877 
878  def add_EVENTFLAG(self, text, config):
879  items = text.split()
880  if items[0] != "EVENTFLAG":
881  self.raise_misconfig(text, "EVENTFLAG")
882  if len(items) != 2:
883  self.raise_misconfig(text, "number of arguments")
884  existingDecoration = self.check_string(items[1])
885  self.setDecorationName(None, config, existingDecoration)
886  return
887 
888  def add_GLOBALTRIGMATCH(self, text, config):
889  items = text.split()
890  if items[0] != "GLOBALTRIGMATCH":
891  self.raise_misconfig(text, "GLOBALTRIGMATCH")
892  if len(items) != 1 and len(items) != 2 :
893  self.raise_misconfig(text, "number of arguments")
894  if len(items) == 1:
895  self.setDecorationName(None, config, "globalTriggerMatch_%SYS%,as_char")
896  else:
897  postfix = self.check_string(items[1])
898  self.setDecorationName(None, config, f"globalTriggerMatch{postfix}_%SYS%,as_char")
899  return
900 
901  def add_RUNNUMBER(self, text, config):
902  items = text.split()
903  if items[0] != "RUN_NUMBER":
904  self.raise_misconfig(text, "RUN_NUMBER")
905  if len(items) != 3:
906  self.raise_misconfig(text, "number of arguments")
907  thisalg = f'{self.name}_RUN_NUMBER_{self.step}'
908  alg = config.createAlgorithm('CP::RunNumberSelectorAlg', thisalg)
909  alg.sign = self.check_sign(items[1])
910  alg.runNumber = self.check_int(items[2])
911  alg.useRandomRunNumber = config.dataType() is not DataType.Data
912  alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
913  self.setDecorationName(alg, config, f'{thisalg}_%SYS%')
914  return
915 
916  def add_SAVE(self, text, config):
917  items = text.split()
918  if items[0] != "SAVE":
919  self.raise_misconfig(text, "SAVE")
920  if len(items) != 1:
921  self.raise_misconfig(text, "number of arguments")
922  thisalg = f'{self.name}_SAVE'
923  alg = config.createAlgorithm('CP::SaveFilterAlg', thisalg)
924  alg.FilterDescription = f'events passing < {self.name} >'
925  alg.eventDecisionOutputDecoration = f'ignore_{self.name}_%SYS%'
926  alg.selection = self.checkDecorationName(self.currentDecoration)
927  alg.noFilter = self.noFilter
928  alg.selectionName = f'pass_{self.name}_%SYS%,as_char' # this one is used as a selection
929  alg.decorationName = f'ntuplepass_{self.name}_%SYS%' # this one is saved to file
930  config.addOutputVar('EventInfo', f'ntuplepass_{self.name}_%SYS%', f'pass_{self.name}')
931  return
932 
934  name,
935  electrons=None, muons=None, jets=None,
936  largeRjets=None,
937  photons=None, taus=None, met=None, metTerm=None,
938  btagDecoration=None, preselection=None,
939  selectionCuts=None, noFilter=None,
940  debugMode=None, cutFlowHistograms=None):
941  """Create an event selection config block
942 
943  Keyword arguments:
944  name -- the name defining this selection
945  electrons -- the electron container and selection
946  muons -- the muon container and selection
947  jets -- the jet container and selection
948  largeRjets -- the large-R jet container and selection
949  photons -- the photon container and selection
950  taus -- the tau-jet container and selection
951  met -- the MET container
952  metTerm -- the MET term to use (e.g. 'Final', 'NonInt')
953  btagDecoration -- the b-tagging decoration to use when defining b-jets
954  preselection -- optional event-wise selection flag to start from
955  selectionCuts -- a string listing one selection cut per line
956  noFilter -- whether to disable the event filter
957  debugMode -- enables saving all intermediate decorations
958  cutFlowHistograms -- whether to toggle event cutflow histograms per systematic
959  """
960 
961  config = EventSelectionConfig()
962  config.setOptionValue ('name', name)
963  config.setOptionValue ('electrons', electrons)
964  config.setOptionValue ('muons', muons)
965  config.setOptionValue ('jets', jets)
966  config.setOptionValue ('largeRjets', largeRjets)
967  config.setOptionValue ('photons', photons)
968  config.setOptionValue ('taus', taus)
969  config.setOptionValue ('met', met)
970  config.setOptionValue ('metTerm', metTerm)
971  config.setOptionValue ('btagDecoration', btagDecoration)
972  config.setOptionValue ('preselection', preselection)
973  config.setOptionValue ('selectionCuts', selectionCuts)
974  config.setOptionValue ('noFilter', noFilter)
975  config.setOptionValue ('debugMode', debugMode)
976  seq.append(config)
977 
978  # add event cutflow algorithm
979  if cutFlowHistograms:
980  makeEventCutFlowConfig(seq, 'EventInfo', selectionName='', postfix=name,
981  customSelections=name)
982 
984  electrons=None, muons=None, jets=None,
985  largeRjets=None,
986  photons=None, taus=None, met=None, metTerm=None,
987  btagDecoration=None, preselection=None,
988  selectionCutsDict=None, noFilter=None,
989  debugMode=None, cutFlowHistograms=None):
990  """Create multiple event selection config blocks
991 
992  Keyword arguments:
993  electrons -- the electron container and selection
994  muons -- the muon container and selection
995  jets -- the jet container and selection
996  largeRjets -- the large-R jet container and selection
997  photons -- the photon container and selection
998  taus -- the tau-jet container and selection
999  met -- the MET container
1000  metTerm -- the MET term to use (e.g. 'Final', 'NonInt')
1001  btagDecoration -- the b-tagging decoration to use when defining b-jets
1002  preselection -- optional event-wise selection flag to start from
1003  selectionCutsDict -- a dictionary with key the name of the selection and value a string listing one selection cut per line
1004  noFilter -- whether to disable the event filter
1005  debugMode -- enables saving all intermediate decorations
1006  cutFlowHistograms -- whether to toggle event cutflow histograms per region and per systematic
1007  """
1008 
1009  # handle the case where a user is only providing one selection
1010  if len(list(selectionCutsDict.keys())) == 1:
1011  name, selectionCuts = list(selectionCutsDict.items())[0]
1012  makeEventSelectionConfig(seq, name, electrons, muons, jets, largeRjets, photons, taus, met, metTerm, btagDecoration, preselection, selectionCuts, noFilter=noFilter, debugMode=debugMode, cutFlowHistograms=cutFlowHistograms)
1013  return
1014 
1015  # first, we generate all the individual event selections
1016  # !!! it's important to pass noFilter=True, to avoid applying the individual filters in series
1017  for name, selectionCuts in selectionCutsDict.items():
1018  makeEventSelectionConfig(seq, name, electrons, muons, jets, largeRjets, photons, taus, met, metTerm, btagDecoration, preselection, selectionCuts, noFilter=True, debugMode=debugMode, cutFlowHistograms=cutFlowHistograms)
1019 
1020  # now we are ready to collect all the filters and apply their logical OR
1021  # !!! subregions (name starts with "SUB") are not used in the final filtering
1022  config = EventSelectionMergerConfig()
1023  config.setOptionValue ('selections', [f'pass_{name}_%SYS%' for name in selectionCutsDict.keys() if not name.startswith("SUB")])
1024  config.setOptionValue ('noFilter', noFilter)
1025  seq.append(config)
python.EventSelectionConfig.EventSelectionConfig.add_MWT_selector
def add_MWT_selector(self, text, config)
Definition: EventSelectionConfig.py:702
python.EventSelectionConfig.EventSelectionConfig.add_NJETGHOST_selector
def add_NJETGHOST_selector(self, text, config)
Definition: EventSelectionConfig.py:620
python.EventSelectionConfig.EventSelectionConfig.add_MLLWINDOW_selector
def add_MLLWINDOW_selector(self, text, config)
Definition: EventSelectionConfig.py:770
python.EventSelectionConfig.EventSelectionConfig.check_float
def check_float(self, test, requirePositive=True)
Definition: EventSelectionConfig.py:188
python.EventSelectionConfig.EventSelectionConfig.check_string
def check_string(self, test)
Definition: EventSelectionConfig.py:211
python.EventSelectionConfig.EventSelectionConfig
Definition: EventSelectionConfig.py:38
python.EventSelectionConfig.EventSelectionConfig.add_SS_selector
def add_SS_selector(self, text, config)
Definition: EventSelectionConfig.py:821
python.EventSelectionConfig.EventSelectionConfig.add_NMU_selector
def add_NMU_selector(self, text, config)
Definition: EventSelectionConfig.py:326
python.EventSelectionConfig.EventSelectionConfig.setDecorationName
def setDecorationName(self, algorithm, config, decoration)
Definition: EventSelectionConfig.py:254
python.AsgAnalysisConfig.makeEventCutFlowConfig
def makeEventCutFlowConfig(seq, containerName, *postfix=None, selectionName, customSelections=None)
Definition: AsgAnalysisConfig.py:805
python.EventSelectionConfig.EventSelectionConfig.extendObjectSelection
def extendObjectSelection(self, config, container, oldSelection, newSelection)
Definition: EventSelectionConfig.py:276
python.EventSelectionConfig.EventSelectionConfig.add_SAVE
def add_SAVE(self, text, config)
Definition: EventSelectionConfig.py:916
python.EventSelectionConfig.EventSelectionConfig.add_MET_selector
def add_MET_selector(self, text, config)
Definition: EventSelectionConfig.py:684
python.EventSelectionConfig.EventSelectionConfig.add_GLOBALTRIGMATCH
def add_GLOBALTRIGMATCH(self, text, config)
Definition: EventSelectionConfig.py:888
python.EventSelectionConfig.EventSelectionConfig.interpret
def interpret(self, text, cfg)
Definition: EventSelectionConfig.py:118
python.EventSelectionConfig.EventSelectionConfig.currentDecoration
currentDecoration
Definition: EventSelectionConfig.py:96
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
python.EventSelectionConfig.EventSelectionMergerConfig
Definition: EventSelectionConfig.py:8
python.EventSelectionConfig.EventSelectionConfig.add_NTAU_selector
def add_NTAU_selector(self, text, config)
Definition: EventSelectionConfig.py:521
python.EventSelectionConfig.EventSelectionMergerConfig.__init__
def __init__(self)
Definition: EventSelectionConfig.py:11
python.EventSelectionConfig.EventSelectionConfig.checkDecorationName
def checkDecorationName(self, decoration)
Definition: EventSelectionConfig.py:269
python.EventSelectionConfig.EventSelectionConfig.getCutflow
def getCutflow(self)
Definition: EventSelectionConfig.py:251
python.EventSelectionConfig.EventSelectionMergerConfig.makeAlgs
def makeAlgs(self, config)
Definition: EventSelectionConfig.py:25
python.EventSelectionConfig.EventSelectionConfig.add_EVENTFLAG
def add_EVENTFLAG(self, text, config)
Definition: EventSelectionConfig.py:878
python.EventSelectionConfig.EventSelectionConfig.add_RUNNUMBER
def add_RUNNUMBER(self, text, config)
Definition: EventSelectionConfig.py:901
python.EventSelectionConfig.EventSelectionConfig.check_int
def check_int(self, test, requirePositive=True)
Definition: EventSelectionConfig.py:198
python.EventSelectionConfig.makeMultipleEventSelectionConfigs
def makeMultipleEventSelectionConfigs(seq, electrons=None, muons=None, jets=None, largeRjets=None, photons=None, taus=None, met=None, metTerm=None, btagDecoration=None, preselection=None, selectionCutsDict=None, noFilter=None, debugMode=None, cutFlowHistograms=None)
Definition: EventSelectionConfig.py:983
python.EventSelectionConfig.EventSelectionConfig.add_OS_selector
def add_OS_selector(self, text, config)
Definition: EventSelectionConfig.py:793
python.EventSelectionConfig.EventSelectionConfig.__init__
def __init__(self)
Definition: EventSelectionConfig.py:41
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
python.EventSelectionConfig.EventSelectionConfig.raise_misconfig
def raise_misconfig(self, text, keyword)
Definition: EventSelectionConfig.py:182
python.EventSelectionConfig.EventSelectionConfig.add_SUMNLEPTONS_selector
def add_SUMNLEPTONS_selector(self, text, config)
Definition: EventSelectionConfig.py:390
python.EventSelectionConfig.EventSelectionConfig.add_NLJETMASS_selector
def add_NLJETMASS_selector(self, text, config)
Definition: EventSelectionConfig.py:569
python.EventSelectionConfig.EventSelectionConfig.instanceName
def instanceName(self)
Definition: EventSelectionConfig.py:99
python.EventSelectionConfig.EventSelectionConfig.add_IMPORT
def add_IMPORT(self, text, config)
Definition: EventSelectionConfig.py:282
python.EventSelectionConfig.EventSelectionConfig.add_NLJET_selector
def add_NLJET_selector(self, text, config)
Definition: EventSelectionConfig.py:546
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:26
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
python.EventSelectionConfig.EventSelectionConfig.step
step
Definition: EventSelectionConfig.py:95
python.EventSelectionConfig.EventSelectionConfig.makeAlgs
def makeAlgs(self, config)
Definition: EventSelectionConfig.py:103
python.EventSelectionConfig.EventSelectionConfig.check_btagging
def check_btagging(self, test)
Definition: EventSelectionConfig.py:230
python.EventSelectionConfig.EventSelectionConfig.add_METMWT_selector
def add_METMWT_selector(self, text, config)
Definition: EventSelectionConfig.py:724
python.EventSelectionConfig.EventSelectionMergerConfig.instanceName
def instanceName(self)
Definition: EventSelectionConfig.py:21
python.EventSelectionConfig.EventSelectionConfig.raise_missinginput
def raise_missinginput(self, collection)
Definition: EventSelectionConfig.py:185
python.EventSelectionConfig.EventSelectionConfig.add_NOBJ_selector
def add_NOBJ_selector(self, text, config)
Definition: EventSelectionConfig.py:668
python.EventSelectionConfig.EventSelectionConfig.add_NPH_selector
def add_NPH_selector(self, text, config)
Definition: EventSelectionConfig.py:496
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
python.EventSelectionConfig.EventSelectionConfig.add_NBJET_selector
def add_NBJET_selector(self, text, config)
Definition: EventSelectionConfig.py:458
python.EventSelectionConfig.EventSelectionConfig.add_NEL_selector
def add_NEL_selector(self, text, config)
Definition: EventSelectionConfig.py:299
python.EventSelectionConfig.EventSelectionConfig.cutflow
cutflow
Definition: EventSelectionConfig.py:97
python.EventSelectionConfig.EventSelectionConfig.add_SUMNELNMU_selector
def add_SUMNELNMU_selector(self, text, config)
Definition: EventSelectionConfig.py:353
python.EventSelectionConfig.EventSelectionConfig.check_sign
def check_sign(self, test)
Definition: EventSelectionConfig.py:217
python.EventSelectionConfig.EventSelectionConfig.add_NLJETMASSWINDOW_selector
def add_NLJETMASSWINDOW_selector(self, text, config)
Definition: EventSelectionConfig.py:592
python.EventSelectionConfig.EventSelectionConfig.check_ghosts
def check_ghosts(self, test)
Definition: EventSelectionConfig.py:237
python.EventSelectionConfig.EventSelectionConfig.add_MLL_OSSF_selector
def add_MLL_OSSF_selector(self, text, config)
Definition: EventSelectionConfig.py:849
Cut::all
@ all
Definition: SUSYToolsAlg.cxx:67
python.EventSelectionConfig.EventSelectionConfig.add_NLJETGHOST_selector
def add_NLJETGHOST_selector(self, text, config)
Definition: EventSelectionConfig.py:644
python.EventSelectionConfig.EventSelectionConfig.add_MLL_selector
def add_MLL_selector(self, text, config)
Definition: EventSelectionConfig.py:748
python.EventSelectionConfig.makeEventSelectionConfig
def makeEventSelectionConfig(seq, name, electrons=None, muons=None, jets=None, largeRjets=None, photons=None, taus=None, met=None, metTerm=None, btagDecoration=None, preselection=None, selectionCuts=None, noFilter=None, debugMode=None, cutFlowHistograms=None)
Definition: EventSelectionConfig.py:933
python.EventSelectionConfig.EventSelectionConfig.add_NJET_selector
def add_NJET_selector(self, text, config)
Definition: EventSelectionConfig.py:433
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
python.LArMinBiasAlgConfig.float
float
Definition: LArMinBiasAlgConfig.py:65