ATLAS Offline Software
Loading...
Searching...
No Matches
python.EventSelectionConfig.EventSelectionConfig Class Reference
Inheritance diagram for python.EventSelectionConfig.EventSelectionConfig:
Collaboration diagram for python.EventSelectionConfig.EventSelectionConfig:

Public Member Functions

 __init__ (self)
 instanceName (self)
dict keywordSpecs (cls)
 makeAlgs (self, config)
 interpret (self, text, cfg)
 raise_misconfig (self, text, keyword)
 raise_missinginput (self, collection)
 parseArgs (self, keyword, items)
 check_float (self, test, requirePositive=True)
 check_int (self, test, requirePositive=True)
 check_string (self, test)
 check_sign (self, test)
 check_btagging (self, test)
 check_ghosts (self, test)
 getCutflow (self)
 setDecorationName (self, algorithm, config, decoration)
 checkDecorationName (self, decoration)
 extendObjectSelection (self, config, container, oldSelection, newSelection)
 add_IMPORT (self, text, config)
 add_NBJET_selector (self, text, config)
 add_SUMNELNMU_selector (self, text, config)
 add_SUMNLEPTONS_selector (self, text, config)
 add_NLJETMASS_selector (self, text, config)
 add_NLJETMASSWINDOW_selector (self, text, config)
 add_NJETGHOST_selector (self, text, config)
 add_NLJETGHOST_selector (self, text, config)
 add_NOBJ_selector (self, text, config)
 add_MET_selector (self, text, config)
 add_MWT_selector (self, text, config)
 add_METMWT_selector (self, text, config)
 add_MLL_selector (self, text, config)
 add_MLLWINDOW_selector (self, text, config)
 add_MLL_OSSF_selector (self, text, config)
 add_EVENTFLAG (self, text, config)
 add_GLOBALTRIGMATCH (self, text, config)
 add_RUNNUMBER (self, text, config)
 add_EXPR_selector (self, text, config)
 add_EVENTVAR_selector (self, text, config)
 add_SAVE (self, text, config)

Public Attributes

int step = 0
str currentDecoration = ''
list cutflow = []
 selectionName
 debugMode
 electrons
 muons
 taus
 btagDecoration
 met

Protected Member Functions

 _build_dispatch (self)
dict _keywordSpecs (cls)
 _argCounts (cls, spec)
 _check_args (self, items, keyword)
 _extract_flags (self, form, tokens)
 _match_form (self, form, tokens)
 _require_inputs (self, *names, message=None)
 _finish_selector (self, alg, config, name)
 _configure_leptons (self, alg, config, leptons)
 _maybe_dressed (self, alg, *specs)
 _route_lepton (self, alg, config, spec, reco, truth)
 _add_nobject (self, text, config, *, attr, tag)
 _add_charge (self, text, config, *, osMode, tag)
 _expr_tokenize (self, text)
 _expr_parse (self, tokens)
 _expr_validate (self, variable, separator, operands)
 _emit_save (self, config)

Protected Attributes

 _dispatch = self._build_dispatch()

Static Protected Attributes

dict _NOBJECT
 _KEYWORD_SPECS = None
dict _EXPR_COLL
dict _EXPR_VARS
 _EXPR_TOKEN_RE = re.compile(, re.VERBOSE)
dict _EVENTVAR_TYPES = {"float": "floatVariable", "int": "intVariable", "double": "doubleVariable"}

Detailed Description

ConfigBlock for interpreting text-based event selections

Definition at line 164 of file EventSelectionConfig.py.

Constructor & Destructor Documentation

◆ __init__()

python.EventSelectionConfig.EventSelectionConfig.__init__ ( self)

Definition at line 179 of file EventSelectionConfig.py.

179 def __init__(self):
180 super(EventSelectionConfig, self).__init__()
181 self.setBlockName('EventSelection')
182 self.addOption('selectionName', '', type=str,
183 noneAction='error',
184 info="the name of the event selection, used to uniquely identify "
185 "the `EventSelectionConfig` block.",
186 meta={'role':'region'})
187 self.addOption('electrons', "", type=str,
188 info="the input electron container, with a possible selection, in "
189 "the format `container` or `container.selection`.",
190 meta={'role':'containerRef'})
191 self.addOption('muons', "", type=str,
192 info="the input muon container, with a possible selection, in the "
193 "format `container` or `container.selection`.",
194 meta={'role':'containerRef'})
195 self.addOption('jets', "", type=str,
196 info="the input jet container, with a possible selection, in the "
197 "format `container` or `container.selection`.",
198 meta={'role':'containerRef'})
199 self.addOption('largeRjets', "", type=str,
200 info="the large-R jet container, with a possible selection, in "
201 "the format `container` or `container.selection`.",
202 meta={'role':'containerRef'})
203 self.addOption('photons', "", type=str,
204 info="the input photon container, with a possible selection, in "
205 "the format `container` or `container.selection`.",
206 meta={'role':'containerRef'})
207 self.addOption('taus', "", type=str,
208 info="the input tau-jet container, with a possible selection, in "
209 "the format `container` or `container.selection`.",
210 meta={'role':'containerRef'})
211 self.addOption('met', "", type=str,
212 info="the input MET container.",
213 meta={'role':'containerRef'})
214 self.addOption('metTerm', "Final", type=str,
215 info="the MET term to use when computing MET-based quantities.")
216 self.addOption('btagDecoration', "", type=str,
217 info="the b-tagging decoration to use when defining b-jets.")
218 self.addOption('preselection', "", type=str,
219 info="the event-wise selection flag to start this event selection "
220 "from.",
221 meta={'role':'region'})
222 self.addOption('selectionCuts', "", type=str,
223 noneAction='error',
224 info="a single string listing one selection cut per line. "
225 "See [available keywords](https://topcptoolkit.docs.cern.ch/latest/settings/eventselection/#available-keywords).")
226 self.addOption('debugMode', False, type=bool,
227 info="whether to create an output branch for every single line "
228 "of the selection cuts. Setting it to `False` only saves the"
229 " final decision.")
230 self.addOption('useDressedProperties', True, type=bool,
231 info="whether to use dressed truth electron and truth muon "
232 "kinematics rather than simple 4-vector kinematics.")
233 self.step = 0
234 self.currentDecoration = ''
235 self.cutflow = []
236 self._dispatch = self._build_dispatch()
237

Member Function Documentation

◆ _add_charge()

python.EventSelectionConfig.EventSelectionConfig._add_charge ( self,
text,
config,
* ,
osMode,
tag )
protected
Builder shared by OS and SS: same algorithm, opposite charge mode.

Definition at line 1089 of file EventSelectionConfig.py.

1089 def _add_charge(self, text, config, *, osMode, tag):
1090 """Builder shared by OS and SS: same algorithm, opposite charge mode."""
1091 args = self.parseArgs(tag, text.split())
1092 self._require_inputs("electrons", "muons", "taus")
1093 thisalg = f'{self.selectionName}_{tag}_{self.step}'
1094 alg = config.createAlgorithm('CP::ChargeSelectorAlg', thisalg)
1095 allLeptons = not (args['el'] or args['mu'] or args['tau'])
1096 if self.electrons and (allLeptons or args['el']):
1097 self._route_lepton(alg, config, self.electrons,
1098 ('electrons', 'electronSelection'),
1099 ('truthElectrons', 'truthElectronSelection'))
1100 if self.muons and (allLeptons or args['mu']):
1101 self._route_lepton(alg, config, self.muons,
1102 ('muons', 'muonSelection'),
1103 ('truthMuons', 'truthMuonSelection'))
1104 if self.taus and (allLeptons or args['tau']):
1105 self._route_lepton(alg, config, self.taus,
1106 ('taus', 'tauSelection'),
1107 ('truthTaus', 'truthTauSelection'))
1108 alg.OS = osMode
1109 self._finish_selector(alg, config, thisalg)
1110

◆ _add_nobject()

python.EventSelectionConfig.EventSelectionConfig._add_nobject ( self,
text,
config,
* ,
attr,
tag )
protected
Generic builder for the N-object pT selectors (EL_N, MU_N, JET_N,
PH_N, TAU_N, LJET_N): identical except for the source container, which
is always required since the cut acts on it.

Definition at line 827 of file EventSelectionConfig.py.

827 def _add_nobject(self, text, config, *, attr, tag):
828 """Generic builder for the N-object pT selectors (EL_N, MU_N, JET_N,
829 PH_N, TAU_N, LJET_N): identical except for the source container, which
830 is always required since the cut acts on it."""
831 items = text.split()
832 spec = getattr(self, attr)
833 self._require_inputs(attr)
834 # the keyword is not known to this generic builder: read it back
835 args = self.parseArgs(items[0], items)
836 thisalg = f'{self.selectionName}_{tag}_{self.step}'
837 alg = config.createAlgorithm('CP::NObjectPtSelectorAlg', thisalg)
838 alg.particles, alg.objectSelection = config.readNameAndSelection(spec)
839 if attr in ("electrons", "muons"):
840 self._maybe_dressed(alg, spec)
841 if args['sel']:
842 alg.objectSelection = self.extendObjectSelection(
843 config, spec.split(".")[0], alg.objectSelection,
844 self.check_string(args['sel']))
845 alg.minPt = self.check_float(args['ptmin'])
846 alg.sign = self.check_sign(args['sign'])
847 alg.count = self.check_int(args['count'])
848 self._finish_selector(alg, config, thisalg)
849

◆ _argCounts()

python.EventSelectionConfig.EventSelectionConfig._argCounts ( cls,
spec )
protected
Return the set of valid total token counts (leading keyword included)
allowed by a keyword specification, or None when the keyword takes free
text and no count check applies.

Definition at line 571 of file EventSelectionConfig.py.

571 def _argCounts(cls, spec):
572 """Return the set of valid total token counts (leading keyword included)
573 allowed by a keyword specification, or None when the keyword takes free
574 text and no count check applies."""
575 if spec.get('freeText'):
576 return None
577 forms = spec.get('forms') or [spec.get('args', [])]
578 counts = set()
579 for form in forms:
580 min_args = sum(1 for arg in form if not arg.get('optional'))
581 max_args = len(form)
582 counts.update(n + 1 for n in range(min_args, max_args + 1))
583 return counts
584
STL class.

◆ _build_dispatch()

python.EventSelectionConfig.EventSelectionConfig._build_dispatch ( self)
protected
Map each keyword to its handler. Dispatch is an exact lookup on the
first token, which removes the ordering fragility of token-membership.

Definition at line 242 of file EventSelectionConfig.py.

242 def _build_dispatch(self):
243 """Map each keyword to its handler. Dispatch is an exact lookup on the
244 first token, which removes the ordering fragility of token-membership."""
245 d = {
246 "JET_N_BTAG": self.add_NBJET_selector,
247 "JET_N_GHOST": self.add_NJETGHOST_selector,
248 "LJET_N_GHOST": self.add_NLJETGHOST_selector,
249 "LJETMASS_N": self.add_NLJETMASS_selector,
250 "LJETMASSWINDOW_N": self.add_NLJETMASSWINDOW_selector,
251 "OBJ_N": self.add_NOBJ_selector,
252 "SUM_EL_N_MU_N": self.add_SUMNELNMU_selector,
253 "SUM_EL_N_MU_N_TAU_N": self.add_SUMNLEPTONS_selector,
254 "MET": self.add_MET_selector,
255 "MWT": self.add_MWT_selector,
256 "MET+MWT": self.add_METMWT_selector,
257 "MLL": self.add_MLL_selector,
258 "MLLWINDOW": self.add_MLLWINDOW_selector,
259 "MLL_OSSF": self.add_MLL_OSSF_selector,
260 "OS": partial(self._add_charge, osMode=True, tag="OS"),
261 "SS": partial(self._add_charge, osMode=False, tag="SS"),
262 "SAVE": self.add_SAVE,
263 "IMPORT": self.add_IMPORT,
264 "EVENTFLAG": self.add_EVENTFLAG,
265 "GLOBALTRIGMATCH": self.add_GLOBALTRIGMATCH,
266 "RUN_NUMBER": self.add_RUNNUMBER,
267 "EXPR": self.add_EXPR_selector,
268 "EVENTVAR": self.add_EVENTVAR_selector,
269 }
270 for kw, (attr, tag, _noun) in self._NOBJECT.items():
271 d[kw] = partial(self._add_nobject, attr=attr, tag=tag)
272 return d
273

◆ _check_args()

python.EventSelectionConfig.EventSelectionConfig._check_args ( self,
items,
keyword )
protected
Validate the leading keyword and the number of arguments, the latter
derived from the keyword specification table.

Definition at line 628 of file EventSelectionConfig.py.

628 def _check_args(self, items, keyword):
629 """Validate the leading keyword and the number of arguments, the latter
630 derived from the keyword specification table."""
631 if items[0] != keyword:
632 self.raise_misconfig(' '.join(items), keyword)
633 validCounts = self._argCounts(self._keywordSpecs()[keyword])
634 if validCounts is not None and len(items) not in validCounts:
635 self.raise_misconfig(' '.join(items), "number of arguments")
636

◆ _configure_leptons()

python.EventSelectionConfig.EventSelectionConfig._configure_leptons ( self,
alg,
config,
leptons )
protected
Configure reco/truth lepton handles from explicit metadata.

Definition at line 800 of file EventSelectionConfig.py.

800 def _configure_leptons(self, alg, config, leptons):
801 """Configure reco/truth lepton handles from explicit metadata."""
802 for spec, reco, truth in leptons:
803 if spec:
804 self._route_lepton(alg, config, spec, reco, truth)
805 self._maybe_dressed(alg, *(spec for spec, _reco, _truth in leptons))
806

◆ _emit_save()

python.EventSelectionConfig.EventSelectionConfig._emit_save ( self,
config )
protected
Create the SaveFilterAlg that turns the accumulated event selection
into a named, persisted selection (and ntuple branch). Called once per
block, automatically at the end of makeAlgs.

Definition at line 1316 of file EventSelectionConfig.py.

1316 def _emit_save(self, config):
1317 """Create the SaveFilterAlg that turns the accumulated event selection
1318 into a named, persisted selection (and ntuple branch). Called once per
1319 block, automatically at the end of makeAlgs."""
1320 thisalg = f'{self.selectionName}_SAVE'
1321 alg = config.createAlgorithm('CP::SaveFilterAlg', thisalg)
1322 alg.FilterDescription = f'events passing < {self.selectionName} >'
1323 alg.eventDecisionOutputDecoration = f'ignore_{self.selectionName}_%SYS%'
1324 alg.selection = self.checkDecorationName(self.currentDecoration)
1325 alg.noFilter = True
1326 alg.selectionName = f'pass_{self.selectionName}_%SYS%,as_char' # this one is used as a selection
1327 alg.decorationName = f'ntuplepass_{self.selectionName}_%SYS%' # this one is saved to file
1328 config.addOutputVar('EventInfo', f'ntuplepass_{self.selectionName}_%SYS%', f'pass_{self.selectionName}')
1329
1330
1331@groupBlocks

◆ _expr_parse()

python.EventSelectionConfig.EventSelectionConfig._expr_parse ( self,
tokens )
protected

Definition at line 1193 of file EventSelectionConfig.py.

1193 def _expr_parse(self, tokens):
1194 return _ExprParser(self._EXPR_TOKEN_RE).parse(tokens)
1195
std::map< std::string, std::string, std::less<> > parse(const std::string &list)

◆ _expr_tokenize()

python.EventSelectionConfig.EventSelectionConfig._expr_tokenize ( self,
text )
protected

Definition at line 1190 of file EventSelectionConfig.py.

1190 def _expr_tokenize(self, text):
1191 return _ExprParser(self._EXPR_TOKEN_RE).tokenize(text)
1192
std::vector< std::string > tokenize(std::string_view the_str, std::string_view delimiters)
Splits the string into smaller substrings.

◆ _expr_validate()

python.EventSelectionConfig.EventSelectionConfig._expr_validate ( self,
variable,
separator,
operands )
protected

Definition at line 1196 of file EventSelectionConfig.py.

1196 def _expr_validate(self, variable, separator, operands):
1197 if variable not in self._EXPR_VARS:
1198 raise UnavailableFeatureError(
1199 f"[EventSelectionConfig] EXPR: variable '{variable}' is not available. "
1200 "Please request it from the EventSelectionAlgorithms developers.")
1201 var_spec = self._EXPR_VARS[variable]
1202 minN = var_spec.min_operands
1203 maxN = var_spec.max_operands
1204 sep = var_spec.separator
1205 metOk = var_spec.met_ok
1206 n = len(operands)
1207 if n < minN or (maxN is not None and n > maxN):
1208 expected = f"{minN}" if maxN == minN else (f"{minN}+" if maxN is None else f"{minN}-{maxN}")
1209 raise InconsistentSettingsError(
1210 f"[EventSelectionConfig] EXPR: '{variable}' takes {expected} operand(s), got {n}")
1211 if n > 1 and separator != sep:
1212 want = {",": "','", "+": "'+'"}.get(sep, str(sep))
1213 raise InconsistentSettingsError(
1214 f"[EventSelectionConfig] EXPR: '{variable}' operands must be separated by {want}")
1215 for coll, index in operands:
1216 if coll not in self._EXPR_COLL:
1217 raise UnavailableFeatureError(
1218 f"[EventSelectionConfig] EXPR: collection '{coll}' is not available. "
1219 "Please request it from the EventSelectionAlgorithms developers.")
1220 coll_spec = self._EXPR_COLL[coll]
1221 isMET = coll_spec.is_met
1222 if isMET:
1223 if not metOk:
1224 raise InconsistentSettingsError(
1225 f"[EventSelectionConfig] EXPR: 'met' is not valid for '{variable}'")
1226 if index is not None:
1227 raise InconsistentSettingsError(
1228 "[EventSelectionConfig] EXPR: 'met' cannot be indexed")
1229 if separator == "+":
1230 raise InconsistentSettingsError(
1231 "[EventSelectionConfig] EXPR: 'met' cannot be combined in a sum")
1232 elif index is None:
1233 raise InconsistentSettingsError(
1234 f"[EventSelectionConfig] EXPR: '{coll}' must be indexed, e.g. {coll}[0]")
1235
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:132

◆ _extract_flags()

python.EventSelectionConfig.EventSelectionConfig._extract_flags ( self,
form,
tokens )
protected
Remove flag tokens from `tokens` and return their boolean values.

Definition at line 637 of file EventSelectionConfig.py.

637 def _extract_flags(self, form, tokens):
638 """Remove flag tokens from `tokens` and return their boolean values."""
639 tokens = list(tokens)
640 values = {}
641 for arg in form:
642 if arg.get('type') != 'flag':
643 continue
644 values[arg['name']] = False
645 for i, token in enumerate(tokens):
646 if token.lower() == arg['name'].lower():
647 del tokens[i]
648 values[arg['name']] = True
649 break
650 return tokens, values
651

◆ _finish_selector()

python.EventSelectionConfig.EventSelectionConfig._finish_selector ( self,
alg,
config,
name )
protected
Apply the common event-preselection and output decoration.

Definition at line 795 of file EventSelectionConfig.py.

795 def _finish_selector(self, alg, config, name):
796 """Apply the common event-preselection and output decoration."""
797 alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
798 self.setDecorationName(alg, config, f'{name}_%SYS%')
799

◆ _keywordSpecs()

dict python.EventSelectionConfig.EventSelectionConfig._keywordSpecs ( cls)
protected
Machine-readable description of every `selectionCuts` keyword.

Spec fields:
  * `info` (str, required): one-line description of the keyword.
  * `args` (list): argument descriptors, in token order.
  * `forms` (list of arg-lists): used instead of `args` for keywords
    offering several fixed shapes that are not "required + optionals".
  * `freeText` (True): everything after the keyword is a single
    expression (EXPR only).
  * `grammar` (dict): the vocabulary of that expression (EXPR only).
  * `deprecated` (True): the keyword is deprecated (SAVE only).

Argument descriptor fields:
  * `name` (str), `type` (str), and optionally `optional` (True),
    `choices` (list), `pattern` (regex str), `signed` (True).
  * `type` is one of 'str', 'float', 'int', 'sign', 'region', 'flag',
    'container', where:
      - 'sign'      is one of `<` `>` `==` `>=` `<=`
      - 'region'    is the `selectionName` of another EventSelection
      - 'flag'      is a literal token, present or absent; the literal
                    is the arg's `name`, matched case-insensitively
      - 'container' is a container reference, in the format `Name` or
                    `Name.selection`
  * `signed` (True) marks a float that may be negative; every other
    float goes through `check_float(requirePositive=True)`.

Filling rule (implemented by `parseArgs`):
  1. `flag` arguments are lifted out of the token list first, by
     case-insensitive match against the arg name.
  2. Of what remains, required arguments are matched first; optional
     ones are filled left-to-right with the surplus tokens, skipping an
     optional whose `pattern` the candidate token does not match.
  3. With `forms`, the first form whose token count and patterns fit
     wins.

Definition at line 279 of file EventSelectionConfig.py.

279 def _keywordSpecs(cls) -> dict:
280 """Machine-readable description of every `selectionCuts` keyword.
281
282 Spec fields:
283 * `info` (str, required): one-line description of the keyword.
284 * `args` (list): argument descriptors, in token order.
285 * `forms` (list of arg-lists): used instead of `args` for keywords
286 offering several fixed shapes that are not "required + optionals".
287 * `freeText` (True): everything after the keyword is a single
288 expression (EXPR only).
289 * `grammar` (dict): the vocabulary of that expression (EXPR only).
290 * `deprecated` (True): the keyword is deprecated (SAVE only).
291
292 Argument descriptor fields:
293 * `name` (str), `type` (str), and optionally `optional` (True),
294 `choices` (list), `pattern` (regex str), `signed` (True).
295 * `type` is one of 'str', 'float', 'int', 'sign', 'region', 'flag',
296 'container', where:
297 - 'sign' is one of `<` `>` `==` `>=` `<=`
298 - 'region' is the `selectionName` of another EventSelection
299 - 'flag' is a literal token, present or absent; the literal
300 is the arg's `name`, matched case-insensitively
301 - 'container' is a container reference, in the format `Name` or
302 `Name.selection`
303 * `signed` (True) marks a float that may be negative; every other
304 float goes through `check_float(requirePositive=True)`.
305
306 Filling rule (implemented by `parseArgs`):
307 1. `flag` arguments are lifted out of the token list first, by
308 case-insensitive match against the arg name.
309 2. Of what remains, required arguments are matched first; optional
310 ones are filled left-to-right with the surplus tokens, skipping an
311 optional whose `pattern` the candidate token does not match.
312 3. With `forms`, the first form whose token count and patterns fit
313 wins.
314 """
315 if cls._KEYWORD_SPECS is not None:
316 return cls._KEYWORD_SPECS
317
318 specs = {}
319 for kw, (_attr, _tag, noun) in cls._NOBJECT.items():
320 specs[kw] = {
321 'info': f'Count {noun} above a pT threshold',
322 'args': [
323 {'name': 'sel', 'type': 'str', 'optional': True},
324 {'name': 'ptmin', 'type': 'float'},
325 {'name': 'sign', 'type': 'sign'},
326 {'name': 'count', 'type': 'int'},
327 ],
328 }
329 specs.update({
330 'JET_N_BTAG': {
331 'info': 'Count b-tagged jets above the default b-tagging working '
332 'point, or above a custom one given as `tagger:WP`',
333 'args': [
334 {'name': 'sel', 'type': 'str', 'optional': True, 'pattern': '^[^:]+$'},
335 {'name': 'btag', 'type': 'str', 'optional': True, 'pattern': '^[^:]+:[^:]+$'},
336 {'name': 'sign', 'type': 'sign'},
337 {'name': 'count', 'type': 'int'},
338 ],
339 },
340 'JET_N_GHOST': {
341 'info': 'Count jets ghost-associated to a given particle, e.g. `B`, '
342 'or `B!C` to also veto a second ghost association',
343 'args': [
344 {'name': 'ghost', 'type': 'str', 'pattern': '^[A-Za-z]+(![A-Za-z]+)?$'},
345 {'name': 'ptmin', 'type': 'float', 'optional': True},
346 {'name': 'sign', 'type': 'sign'},
347 {'name': 'count', 'type': 'int'},
348 ],
349 },
350 'LJET_N_GHOST': {
351 'info': 'Count large-R jets ghost-associated to a given particle, e.g. '
352 '`B`, or `B!C` to also veto a second ghost association',
353 'args': [
354 {'name': 'ghost', 'type': 'str', 'pattern': '^[A-Za-z]+(![A-Za-z]+)?$'},
355 {'name': 'ptmin', 'type': 'float', 'optional': True},
356 {'name': 'sign', 'type': 'sign'},
357 {'name': 'count', 'type': 'int'},
358 ],
359 },
360 'LJETMASS_N': {
361 'info': 'Count large-R jets above a mass threshold',
362 'args': [
363 {'name': 'sel', 'type': 'str', 'optional': True},
364 {'name': 'minMass', 'type': 'float'},
365 {'name': 'sign', 'type': 'sign'},
366 {'name': 'count', 'type': 'int'},
367 ],
368 },
369 'LJETMASSWINDOW_N': {
370 'info': 'Count large-R jets inside (or, with `veto`, outside) a mass window',
371 'args': [
372 {'name': 'sel', 'type': 'str', 'optional': True},
373 {'name': 'lowMass', 'type': 'float'},
374 {'name': 'highMass', 'type': 'float'},
375 {'name': 'sign', 'type': 'sign'},
376 {'name': 'count', 'type': 'int'},
377 {'name': 'veto', 'type': 'flag', 'optional': True},
378 ],
379 },
380 'OBJ_N': {
381 'info': 'Count objects of an arbitrary container above a pT threshold',
382 'args': [
383 {'name': 'container', 'type': 'container'},
384 {'name': 'ptmin', 'type': 'float'},
385 {'name': 'sign', 'type': 'sign'},
386 {'name': 'count', 'type': 'int'},
387 ],
388 },
389 'SUM_EL_N_MU_N': {
390 'info': 'Count electrons and muons together, above a common or '
391 'per-flavour pT threshold',
392 'forms': [
393 [
394 {'name': 'ptmin', 'type': 'float'},
395 {'name': 'sign', 'type': 'sign'},
396 {'name': 'count', 'type': 'int'},
397 ],
398 [
399 {'name': 'ptEl', 'type': 'float'},
400 {'name': 'ptMu', 'type': 'float'},
401 {'name': 'sign', 'type': 'sign'},
402 {'name': 'count', 'type': 'int'},
403 ],
404 [
405 {'name': 'selEl', 'type': 'str'},
406 {'name': 'selMu', 'type': 'str'},
407 {'name': 'ptEl', 'type': 'float'},
408 {'name': 'ptMu', 'type': 'float'},
409 {'name': 'sign', 'type': 'sign'},
410 {'name': 'count', 'type': 'int'},
411 ],
412 ],
413 },
414 'SUM_EL_N_MU_N_TAU_N': {
415 'info': 'Count electrons, muons and tau-jets together, above a common '
416 'or per-flavour pT threshold',
417 'forms': [
418 [
419 {'name': 'ptmin', 'type': 'float'},
420 {'name': 'sign', 'type': 'sign'},
421 {'name': 'count', 'type': 'int'},
422 ],
423 [
424 {'name': 'ptEl', 'type': 'float'},
425 {'name': 'ptMu', 'type': 'float'},
426 {'name': 'ptTau', 'type': 'float'},
427 {'name': 'sign', 'type': 'sign'},
428 {'name': 'count', 'type': 'int'},
429 ],
430 [
431 {'name': 'selEl', 'type': 'str'},
432 {'name': 'selMu', 'type': 'str'},
433 {'name': 'selTau', 'type': 'str'},
434 {'name': 'ptEl', 'type': 'float'},
435 {'name': 'ptMu', 'type': 'float'},
436 {'name': 'ptTau', 'type': 'float'},
437 {'name': 'sign', 'type': 'sign'},
438 {'name': 'count', 'type': 'int'},
439 ],
440 ],
441 },
442 'MET': {
443 'info': 'Cut on the missing transverse energy',
444 'args': [
445 {'name': 'sign', 'type': 'sign'},
446 {'name': 'refMET', 'type': 'float'},
447 ],
448 },
449 'MWT': {
450 'info': 'Cut on the transverse mass of the leading lepton and MET',
451 'args': [
452 {'name': 'sign', 'type': 'sign'},
453 {'name': 'refMWT', 'type': 'float'},
454 ],
455 },
456 'MET+MWT': {
457 'info': 'Cut on the sum of the missing transverse energy and the '
458 'transverse mass',
459 'args': [
460 {'name': 'sign', 'type': 'sign'},
461 {'name': 'refMETMWT', 'type': 'float'},
462 ],
463 },
464 'MLL': {
465 'info': 'Cut on the light dilepton invariant mass (optionally including taus with `include_taus`)',
466 'args': [
467 {'name': 'sign', 'type': 'sign'},
468 {'name': 'refMLL', 'type': 'float'},
469 {'name': 'include_taus', 'type': 'flag', 'optional': True},
470 ],
471 },
472 'MLLWINDOW': {
473 'info': 'Require the light dilepton invariant mass inside (or, with `veto`, '
474 'outside) a mass window (optionally including taus with `include_taus`)',
475 'args': [
476 {'name': 'lowMLL', 'type': 'float'},
477 {'name': 'highMLL', 'type': 'float'},
478 {'name': 'veto', 'type': 'flag', 'optional': True},
479 {'name': 'include_taus', 'type': 'flag', 'optional': True},
480 ],
481 },
482 'MLL_OSSF': {
483 'info': 'Require the opposite-sign same-flavour light dilepton invariant mass '
484 'inside (or, with `veto`, outside) a mass window (optionally including taus with `include_taus`)',
485 'args': [
486 {'name': 'lowMll', 'type': 'float'},
487 {'name': 'highMll', 'type': 'float'},
488 {'name': 'veto', 'type': 'flag', 'optional': True},
489 {'name': 'include_taus', 'type': 'flag', 'optional': True},
490 ],
491 },
492 'OS': {
493 'info': 'Require an opposite-sign lepton pair; without any flag, all '
494 'available lepton flavours are considered',
495 'args': [
496 {'name': 'el', 'type': 'flag', 'optional': True},
497 {'name': 'mu', 'type': 'flag', 'optional': True},
498 {'name': 'tau', 'type': 'flag', 'optional': True},
499 ],
500 },
501 'SS': {
502 'info': 'Require a same-sign lepton pair; without any flag, all '
503 'available lepton flavours are considered',
504 'args': [
505 {'name': 'el', 'type': 'flag', 'optional': True},
506 {'name': 'mu', 'type': 'flag', 'optional': True},
507 {'name': 'tau', 'type': 'flag', 'optional': True},
508 ],
509 },
510 'IMPORT': {
511 'info': 'Import all the cuts of a previously defined event selection',
512 'args': [
513 {'name': 'region', 'type': 'region'},
514 ],
515 },
516 'EVENTFLAG': {
517 'info': 'Require an existing event-wise decoration to be true',
518 'args': [
519 {'name': 'decoration', 'type': 'str'},
520 ],
521 },
522 'GLOBALTRIGMATCH': {
523 'info': 'Require the global trigger matching decision, optionally for '
524 'a given trigger-configuration postfix',
525 'args': [
526 {'name': 'postfix', 'type': 'str', 'optional': True},
527 ],
528 },
529 'RUN_NUMBER': {
530 'info': 'Cut on the (random) run number',
531 'args': [
532 {'name': 'sign', 'type': 'sign'},
533 {'name': 'runNumber', 'type': 'int'},
534 ],
535 },
536 'EVENTVAR': {
537 'info': 'Cut on an existing EventInfo scalar variable, e.g. a DNN or '
538 'BDT discriminant',
539 'args': [
540 {'name': 'type', 'type': 'str', 'choices': sorted(cls._EVENTVAR_TYPES)},
541 {'name': 'name', 'type': 'str'},
542 {'name': 'sign', 'type': 'sign'},
543 {'name': 'value', 'type': 'float', 'signed': True},
544 ],
545 },
546 'EXPR': {
547 'info': 'Cut on a generic object-kinematic expression, e.g. '
548 '`dR(el[0],jet[0]) > 0.4`',
549 'freeText': True,
550 'grammar': {
551 'collections': sorted(cls._EXPR_COLL),
552 'variables': sorted(cls._EXPR_VARS),
553 },
554 },
555 'SAVE': {
556 'info': 'Deprecated and ignored: the event filter is now emitted '
557 'automatically at the end of every event selection',
558 'deprecated': True,
559 'args': [],
560 },
561 })
562 cls._KEYWORD_SPECS = specs
563 return cls._KEYWORD_SPECS
564

◆ _match_form()

python.EventSelectionConfig.EventSelectionConfig._match_form ( self,
form,
tokens )
protected
Match one keyword argument form, returning values or None.

Definition at line 652 of file EventSelectionConfig.py.

652 def _match_form(self, form, tokens):
653 """Match one keyword argument form, returning values or None."""
654 tokens, values = self._extract_flags(form, tokens)
655 positional = [arg for arg in form if arg.get('type') != 'flag']
656 nRequired = sum(1 for arg in positional if not arg.get('optional'))
657 if len(tokens) < nRequired or len(tokens) > len(positional):
658 return None
659
660 budget = len(tokens) - nRequired
661 cursor = 0
662 for arg in positional:
663 if not arg.get('optional'):
664 values[arg['name']] = tokens[cursor]
665 cursor += 1
666 continue
667 pattern = arg.get('pattern')
668 if budget > 0 and (pattern is None or re.fullmatch(pattern, tokens[cursor])):
669 values[arg['name']] = tokens[cursor]
670 cursor += 1
671 budget -= 1
672 else:
673 values[arg['name']] = ''
674 return values if cursor == len(tokens) else None
675

◆ _maybe_dressed()

python.EventSelectionConfig.EventSelectionConfig._maybe_dressed ( self,
alg,
* specs )
protected
Enable dressed kinematics when any of the given electron/muon
containers is a truth container. Dressed kinematics only exist for
truth electrons and muons, so only those specs should be passed here.

Definition at line 807 of file EventSelectionConfig.py.

807 def _maybe_dressed(self, alg, *specs):
808 """Enable dressed kinematics when any of the given electron/muon
809 containers is a truth container. Dressed kinematics only exist for
810 truth electrons and muons, so only those specs should be passed here."""
811 if any(spec and ("Particle" in spec or "Truth" in spec) for spec in specs):
812 alg.useDressedProperties = self.useDressedProperties
813

◆ _require_inputs()

python.EventSelectionConfig.EventSelectionConfig._require_inputs ( self,
* names,
message = None )
protected
Require at least one of the named input options to be configured.

Definition at line 790 of file EventSelectionConfig.py.

790 def _require_inputs(self, *names, message=None):
791 """Require at least one of the named input options to be configured."""
792 if not any(getattr(self, name) for name in names):
793 self.raise_missinginput(message or " or ".join(names))
794

◆ _route_lepton()

python.EventSelectionConfig.EventSelectionConfig._route_lepton ( self,
alg,
config,
spec,
reco,
truth )
protected
Assign (name, selection) to the reco or truth handles of `alg`
depending on whether `spec` points to a truth container.
`reco`/`truth` are (nameAttr, selectionAttr) pairs.

Definition at line 814 of file EventSelectionConfig.py.

814 def _route_lepton(self, alg, config, spec, reco, truth):
815 """Assign (name, selection) to the reco or truth handles of `alg`
816 depending on whether `spec` points to a truth container.
817 `reco`/`truth` are (nameAttr, selectionAttr) pairs."""
818 name, sel = config.readNameAndSelection(spec)
819 nameAttr, selAttr = truth if ("Particle" in spec or "Truth" in spec) else reco
820 setattr(alg, nameAttr, name)
821 setattr(alg, selAttr, sel)
822

◆ add_EVENTFLAG()

python.EventSelectionConfig.EventSelectionConfig.add_EVENTFLAG ( self,
text,
config )

Definition at line 1133 of file EventSelectionConfig.py.

1133 def add_EVENTFLAG(self, text, config):
1134 args = self.parseArgs("EVENTFLAG", text.split())
1135 existingDecoration = self.check_string(args['decoration'])
1136 self.setDecorationName(None, config, existingDecoration)
1137

◆ add_EVENTVAR_selector()

python.EventSelectionConfig.EventSelectionConfig.add_EVENTVAR_selector ( self,
text,
config )

Definition at line 1290 of file EventSelectionConfig.py.

1290 def add_EVENTVAR_selector(self, text, config):
1291 # EVENTVAR <type> <varname> <sign> <threshold>
1292 args = self.parseArgs("EVENTVAR", text.split())
1293 valueType = self.check_string(args['type'])
1294 if valueType not in self._EVENTVAR_TYPES:
1295 self.raise_misconfig(text, f"value type (one of {sorted(self._EVENTVAR_TYPES)})")
1296 varname = self.check_string(args['name'])
1297 thisalg = f'{self.selectionName}_EVENTVAR_{self.step}'
1298 alg = config.createAlgorithm('CP::EventScalarSelectorAlg', thisalg)
1299 # the variable name is given bare; the systematics suffix is appended here
1300 setattr(alg, self._EVENTVAR_TYPES[valueType], f'{varname}_%SYS%')
1301 alg.sign = self.check_sign(args['sign'])
1302 alg.refValue = self.check_float(args['value'], requirePositive=False) # discriminants may be negative
1303 self._finish_selector(alg, config, thisalg)
1304

◆ add_EXPR_selector()

python.EventSelectionConfig.EventSelectionConfig.add_EXPR_selector ( self,
text,
config )

Definition at line 1236 of file EventSelectionConfig.py.

1236 def add_EXPR_selector(self, text, config):
1237 body = text[len("EXPR"):].strip()
1238 if not body:
1239 self.raise_misconfig(text, "EXPR expression")
1240 variable, separator, operands, sign, refValue = self._expr_parse(self._expr_tokenize(body))
1241 self._expr_validate(variable, separator, operands)
1242
1243 thisalg = f'{self.selectionName}_EXPR_{self.step}'
1244 alg = config.createAlgorithm('CP::ObjectKinematicSelectorAlg', thisalg)
1245 alg.variable = variable
1246 alg.sign = sign
1247 alg.refValue = refValue
1248
1249 operandKinds, collections, selections, indices = [], [], [], []
1250 usesMET = False
1251 for coll, index in operands:
1252 coll_spec = self._EXPR_COLL[coll]
1253 opt = coll_spec.option
1254 applyBtag = coll_spec.apply_btag
1255 isMET = coll_spec.is_met
1256 container = getattr(self, opt)
1257 if not container:
1258 self.raise_missinginput(opt)
1259 if isMET:
1260 operandKinds.append("MET")
1261 usesMET = True
1262 continue
1263 operandKinds.append("PARTICLE")
1264 name, selection = config.readNameAndSelection(container)
1265 if applyBtag:
1266 if not self.btagDecoration:
1267 self.raise_missinginput("btagDecoration")
1268 selection = (f'{selection}&&{self.btagDecoration},as_char'
1269 if selection else f'{self.btagDecoration},as_char')
1270 collections.append(name)
1271 selections.append(selection)
1272 indices.append(index)
1273
1274 alg.operandKinds = operandKinds
1275 alg.collections = collections
1276 alg.selections = selections
1277 alg.indices = indices
1278 if usesMET:
1279 if not self.met:
1280 self.raise_missinginput("met")
1281 alg.met = config.readName(self.met)
1282 alg.metTerm = self.metTerm
1283 self._finish_selector(alg, config, thisalg)
1284

◆ add_GLOBALTRIGMATCH()

python.EventSelectionConfig.EventSelectionConfig.add_GLOBALTRIGMATCH ( self,
text,
config )

Definition at line 1138 of file EventSelectionConfig.py.

1138 def add_GLOBALTRIGMATCH(self, text, config):
1139 args = self.parseArgs("GLOBALTRIGMATCH", text.split())
1140 postfix = self.check_string(args['postfix'])
1141 self.setDecorationName(None, config, f"globalTriggerMatch{postfix}_%SYS%,as_char")
1142

◆ add_IMPORT()

python.EventSelectionConfig.EventSelectionConfig.add_IMPORT ( self,
text,
config )

Definition at line 850 of file EventSelectionConfig.py.

850 def add_IMPORT(self, text, config):
851 # this is used to import a previous selection
852 args = self.parseArgs("IMPORT", text.split())
853 region = self.check_string(args['region'])
854 if not self.currentDecoration:
855 self.currentDecoration = f'pass_{region}_%SYS%,as_char'
856 else:
857 self.currentDecoration = f'{self.currentDecoration},as_char&&pass_{region}_%SYS%'
858 # for the cutflow, we need to retrieve all the cuts corresponding to this IMPORT
859 imported_cuts = [cut for cut in config.getSelectionCutFlow('EventInfo', '') if cut.startswith(region)]
860 self.cutflow += imported_cuts
861

◆ add_MET_selector()

python.EventSelectionConfig.EventSelectionConfig.add_MET_selector ( self,
text,
config )

Definition at line 1006 of file EventSelectionConfig.py.

1006 def add_MET_selector(self, text, config):
1007 args = self.parseArgs("MET", text.split())
1008 self._require_inputs("met", message="MET")
1009 thisalg = f'{self.selectionName}_MET_{self.step}'
1010 alg = config.createAlgorithm('CP::MissingETSelectorAlg', thisalg)
1011 alg.met = config.readName(self.met)
1012 alg.metTerm = self.metTerm
1013 alg.sign = self.check_sign(args['sign'])
1014 alg.refMET = self.check_float(args['refMET'])
1015 self._finish_selector(alg, config, thisalg)
1016

◆ add_METMWT_selector()

python.EventSelectionConfig.EventSelectionConfig.add_METMWT_selector ( self,
text,
config )

Definition at line 1031 of file EventSelectionConfig.py.

1031 def add_METMWT_selector(self, text, config):
1032 args = self.parseArgs("MET+MWT", text.split())
1033 self._require_inputs("met", message="MET")
1034 self._require_inputs("electrons", "muons")
1035 thisalg = f'{self.selectionName}_METMWT_{self.step}'
1036 alg = config.createAlgorithm('CP::MissingETPlusTransverseMassSelectorAlg', thisalg)
1037 alg.met = config.readName(self.met)
1038 alg.metTerm = self.metTerm
1039 alg.electrons, alg.electronSelection = config.readNameAndSelection(self.electrons)
1040 alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
1041 self._maybe_dressed(alg, self.electrons, self.muons)
1042 alg.sign = self.check_sign(args['sign'])
1043 alg.refMETMWT = self.check_float(args['refMETMWT'])
1044 self._finish_selector(alg, config, thisalg)
1045

◆ add_MLL_OSSF_selector()

python.EventSelectionConfig.EventSelectionConfig.add_MLL_OSSF_selector ( self,
text,
config )

Definition at line 1111 of file EventSelectionConfig.py.

1111 def add_MLL_OSSF_selector(self, text, config):
1112 args = self.parseArgs("MLL_OSSF", text.split())
1113 self._require_inputs("electrons", "muons")
1114 thisalg = f'{self.selectionName}_MLL_OSSF_{self.step}'
1115 alg = config.createAlgorithm('CP::DileptonOSSFInvariantMassWindowSelectorAlg', thisalg)
1116 self._configure_leptons(alg, config, (
1117 (self.electrons, ('electrons', 'electronSelection'),
1118 ('truthElectrons', 'truthElectronSelection')),
1119 (self.muons, ('muons', 'muonSelection'),
1120 ('truthMuons', 'truthMuonSelection')),
1121 ))
1122 if args['include_taus']:
1123 self._require_inputs("taus")
1124 self._configure_leptons(alg, config, (
1125 (self.taus, ('taus', 'tauSelection'),
1126 ('truthTaus', 'truthTauSelection')),
1127 ))
1128 alg.lowMll = self.check_float(args['lowMll'])
1129 alg.highMll = self.check_float(args['highMll'])
1130 alg.vetoMode = args['veto']
1131 self._finish_selector(alg, config, thisalg)
1132

◆ add_MLL_selector()

python.EventSelectionConfig.EventSelectionConfig.add_MLL_selector ( self,
text,
config )

Definition at line 1046 of file EventSelectionConfig.py.

1046 def add_MLL_selector(self, text, config):
1047 args = self.parseArgs("MLL", text.split())
1048 self._require_inputs("electrons", "muons")
1049 thisalg = f'{self.selectionName}_MLL_{self.step}'
1050 alg = config.createAlgorithm('CP::DileptonInvariantMassSelectorAlg', thisalg)
1051 self._configure_leptons(alg, config, (
1052 (self.electrons, ('electrons', 'electronSelection'),
1053 ('truthElectrons', 'truthElectronSelection')),
1054 (self.muons, ('muons', 'muonSelection'),
1055 ('truthMuons', 'truthMuonSelection')),
1056 ))
1057 if args['include_taus']:
1058 self._require_inputs("taus")
1059 self._configure_leptons(alg, config, (
1060 (self.taus, ('taus', 'tauSelection'),
1061 ('truthTaus', 'truthTauSelection')),
1062 ))
1063 alg.sign = self.check_sign(args['sign'])
1064 alg.refMLL = self.check_float(args['refMLL'])
1065 self._finish_selector(alg, config, thisalg)
1066

◆ add_MLLWINDOW_selector()

python.EventSelectionConfig.EventSelectionConfig.add_MLLWINDOW_selector ( self,
text,
config )

Definition at line 1067 of file EventSelectionConfig.py.

1067 def add_MLLWINDOW_selector(self, text, config):
1068 args = self.parseArgs("MLLWINDOW", text.split())
1069 self._require_inputs("electrons", "muons")
1070 thisalg = f'{self.selectionName}_MLLWINDOW_{self.step}'
1071 alg = config.createAlgorithm('CP::DileptonInvariantMassWindowSelectorAlg', thisalg)
1072 self._configure_leptons(alg, config, (
1073 (self.electrons, ('electrons', 'electronSelection'),
1074 ('truthElectrons', 'truthElectronSelection')),
1075 (self.muons, ('muons', 'muonSelection'),
1076 ('truthMuons', 'truthMuonSelection')),
1077 ))
1078 if args['include_taus']:
1079 self._require_inputs("taus")
1080 self._configure_leptons(alg, config, (
1081 (self.taus, ('taus', 'tauSelection'),
1082 ('truthTaus', 'truthTauSelection')),
1083 ))
1084 alg.lowMLL = self.check_float(args['lowMLL'])
1085 alg.highMLL = self.check_float(args['highMLL'])
1086 alg.vetoMode = args['veto']
1087 self._finish_selector(alg, config, thisalg)
1088

◆ add_MWT_selector()

python.EventSelectionConfig.EventSelectionConfig.add_MWT_selector ( self,
text,
config )

Definition at line 1017 of file EventSelectionConfig.py.

1017 def add_MWT_selector(self, text, config):
1018 args = self.parseArgs("MWT", text.split())
1019 self._require_inputs("electrons", "muons")
1020 thisalg = f'{self.selectionName}_MWT_{self.step}'
1021 alg = config.createAlgorithm('CP::TransverseMassSelectorAlg', thisalg)
1022 alg.met = config.readName(self.met)
1023 alg.metTerm = self.metTerm
1024 alg.electrons, alg.electronSelection = config.readNameAndSelection(self.electrons)
1025 alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
1026 self._maybe_dressed(alg, self.electrons, self.muons)
1027 alg.sign = self.check_sign(args['sign'])
1028 alg.refMWT = self.check_float(args['refMWT'])
1029 self._finish_selector(alg, config, thisalg)
1030

◆ add_NBJET_selector()

python.EventSelectionConfig.EventSelectionConfig.add_NBJET_selector ( self,
text,
config )

Definition at line 862 of file EventSelectionConfig.py.

862 def add_NBJET_selector(self, text, config):
863 args = self.parseArgs("JET_N_BTAG", text.split())
864 self._require_inputs("jets")
865 thisalg = f'{self.selectionName}_NBJET_{self.step}'
866 alg = config.createAlgorithm('CP::NObjectPtSelectorAlg', thisalg)
867 particles, selection = config.readNameAndSelection(self.jets)
868 alg.particles = particles
869 alg.objectSelection = f'{selection}&&{self.btagDecoration},as_char' if selection else f'{self.btagDecoration},as_char'
870 if args['btag']:
871 btagger, btagWP = self.check_btagging(args['btag'])
872 customBtag = f'ftag_select_{btagger}_{btagWP}'
873 alg.objectSelection = f'{selection}&&{customBtag},as_char' if selection else f'{customBtag},as_char'
874 if args['sel']:
875 extraSel = self.check_string(args['sel'])
876 alg.objectSelection = self.extendObjectSelection(config, self.jets.split(".")[0], alg.objectSelection, extraSel)
877 alg.sign = self.check_sign(args['sign'])
878 alg.count = self.check_int(args['count'])
879 self._finish_selector(alg, config, thisalg)
880
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:179

◆ add_NJETGHOST_selector()

python.EventSelectionConfig.EventSelectionConfig.add_NJETGHOST_selector ( self,
text,
config )

Definition at line 966 of file EventSelectionConfig.py.

966 def add_NJETGHOST_selector(self, text, config):
967 args = self.parseArgs("JET_N_GHOST", text.split())
968 thisalg = f'{self.selectionName}_NJETGHOST_{self.step}'
969 alg = config.createAlgorithm('CP::JetNGhostSelectorAlg', thisalg)
970 alg.jets, alg.jetSelection = config.readNameAndSelection(self.jets)
971 ghosts = self.check_ghosts(args['ghost'])
972 alg.ghost = ghosts[0]
973 if len(ghosts) > 1 :
974 alg.veto = ghosts[1]
975 if args['ptmin']:
976 alg.minPt = self.check_float(args['ptmin'])
977 alg.sign = self.check_sign(args['sign'])
978 alg.count = self.check_int(args['count'])
979 self._finish_selector(alg, config, thisalg)
980

◆ add_NLJETGHOST_selector()

python.EventSelectionConfig.EventSelectionConfig.add_NLJETGHOST_selector ( self,
text,
config )

Definition at line 981 of file EventSelectionConfig.py.

981 def add_NLJETGHOST_selector(self, text, config):
982 args = self.parseArgs("LJET_N_GHOST", text.split())
983 thisalg = f'{self.selectionName}_NLJETGHOST_{self.step}'
984 alg = config.createAlgorithm('CP::JetNGhostSelectorAlg', thisalg)
985 alg.jets, alg.jetSelection = config.readNameAndSelection(self.largeRjets)
986 ghosts = self.check_ghosts(args['ghost'])
987 alg.ghost = ghosts[0]
988 if len(ghosts) > 1 :
989 alg.veto = ghosts[1]
990 if args['ptmin']:
991 alg.minPt = self.check_float(args['ptmin'])
992 alg.sign = self.check_sign(args['sign'])
993 alg.count = self.check_int(args['count'])
994 self._finish_selector(alg, config, thisalg)
995

◆ add_NLJETMASS_selector()

python.EventSelectionConfig.EventSelectionConfig.add_NLJETMASS_selector ( self,
text,
config )

Definition at line 937 of file EventSelectionConfig.py.

937 def add_NLJETMASS_selector(self, text, config):
938 args = self.parseArgs("LJETMASS_N", text.split())
939 thisalg = f'{self.selectionName}_NLJETMASS_{self.step}'
940 alg = config.createAlgorithm('CP::NObjectMassSelectorAlg', thisalg)
941 alg.particles, alg.objectSelection = config.readNameAndSelection(self.largeRjets)
942 if args['sel']:
943 alg.objectSelection = self.extendObjectSelection(
944 config, self.largeRjets.split(".")[0], alg.objectSelection,
945 self.check_string(args['sel']))
946 alg.minMass = self.check_float(args['minMass'])
947 alg.sign = self.check_sign(args['sign'])
948 alg.count = self.check_int(args['count'])
949 self._finish_selector(alg, config, thisalg)
950

◆ add_NLJETMASSWINDOW_selector()

python.EventSelectionConfig.EventSelectionConfig.add_NLJETMASSWINDOW_selector ( self,
text,
config )

Definition at line 951 of file EventSelectionConfig.py.

951 def add_NLJETMASSWINDOW_selector(self, text, config):
952 args = self.parseArgs("LJETMASSWINDOW_N", text.split())
953 thisalg = f'{self.selectionName}_NLJETMASSWINDOW_{self.step}'
954 alg = config.createAlgorithm('CP::NLargeRJetMassWindowSelectorAlg', thisalg)
955 alg.ljets, alg.ljetSelection = config.readNameAndSelection(self.largeRjets)
956 if args['sel']:
957 extraSel = self.check_string(args['sel'])
958 alg.ljetSelection = self.extendObjectSelection(config, self.largeRjets.split(".")[0], alg.ljetSelection, extraSel)
959 alg.lowMass = self.check_float(args['lowMass'])
960 alg.highMass = self.check_float(args['highMass'])
961 alg.sign = self.check_sign(args['sign'])
962 alg.count = self.check_int(args['count'])
963 alg.vetoMode = args['veto']
964 self._finish_selector(alg, config, thisalg)
965

◆ add_NOBJ_selector()

python.EventSelectionConfig.EventSelectionConfig.add_NOBJ_selector ( self,
text,
config )

Definition at line 996 of file EventSelectionConfig.py.

996 def add_NOBJ_selector(self, text, config):
997 args = self.parseArgs("OBJ_N", text.split())
998 thisalg = f'{self.selectionName}_NOBJ_{self.step}'
999 alg = config.createAlgorithm('CP::NObjectPtSelectorAlg', thisalg)
1000 alg.particles, alg.objectSelection = config.readNameAndSelection(self.check_string(args['container']))
1001 alg.minPt = self.check_float(args['ptmin'])
1002 alg.sign = self.check_sign(args['sign'])
1003 alg.count = self.check_int(args['count'])
1004 self._finish_selector(alg, config, thisalg)
1005

◆ add_RUNNUMBER()

python.EventSelectionConfig.EventSelectionConfig.add_RUNNUMBER ( self,
text,
config )

Definition at line 1143 of file EventSelectionConfig.py.

1143 def add_RUNNUMBER(self, text, config):
1144 args = self.parseArgs("RUN_NUMBER", text.split())
1145 thisalg = f'{self.selectionName}_RUN_NUMBER_{self.step}'
1146 alg = config.createAlgorithm('CP::RunNumberSelectorAlg', thisalg)
1147 alg.sign = self.check_sign(args['sign'])
1148 alg.runNumber = self.check_int(args['runNumber'])
1149 alg.useRandomRunNumber = config.dataType() is not DataType.Data
1150 self._finish_selector(alg, config, thisalg)
1151

◆ add_SAVE()

python.EventSelectionConfig.EventSelectionConfig.add_SAVE ( self,
text,
config )

Definition at line 1305 of file EventSelectionConfig.py.

1305 def add_SAVE(self, text, config):
1306 # SAVE is deprecated: the event filter is now emitted automatically at
1307 # the end of the block (see makeAlgs). The keyword is accepted only to
1308 # warn existing configs; it performs no operation itself.
1309 self.parseArgs("SAVE", text.split())
1310 warnings.warn(
1311 "[EventSelectionConfig] The 'SAVE' keyword is deprecated: the event "
1312 "filter is now created automatically at the end of each EventSelection "
1313 f"block. Please remove the 'SAVE' line from selection '{self.selectionName}'.",
1314 category=ConfigDeprecationWarning, stacklevel=2)
1315

◆ add_SUMNELNMU_selector()

python.EventSelectionConfig.EventSelectionConfig.add_SUMNELNMU_selector ( self,
text,
config )

Definition at line 881 of file EventSelectionConfig.py.

881 def add_SUMNELNMU_selector(self, text, config):
882 args = self.parseArgs("SUM_EL_N_MU_N", text.split())
883 self._require_inputs("electrons", "muons")
884 thisalg = f'{self.selectionName}_SUMNELNMU_{self.step}'
885 alg = config.createAlgorithm('CP::SumNLeptonPtSelectorAlg', thisalg)
886 alg.electrons, alg.electronSelection = config.readNameAndSelection(self.electrons)
887 alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
888 self._maybe_dressed(alg, self.electrons, self.muons)
889 if args.get('ptmin') is not None:
890 # a single threshold, applied to every flavour
891 alg.minPtEl = self.check_float(args['ptmin'])
892 alg.minPtMu = self.check_float(args['ptmin'])
893 else:
894 if args.get('selEl'):
895 extraSelEl = self.check_string(args['selEl'])
896 alg.electronSelection = self.extendObjectSelection(config, self.electrons.split(".")[0], alg.electronSelection, extraSelEl)
897 if args.get('selMu'):
898 extraSelMu = self.check_string(args['selMu'])
899 alg.muonSelection = self.extendObjectSelection(config, self.muons.split(".")[0], alg.muonSelection, extraSelMu)
900 alg.minPtEl = self.check_float(args['ptEl'])
901 alg.minPtMu = self.check_float(args['ptMu'])
902 alg.sign = self.check_sign(args['sign'])
903 alg.count = self.check_int(args['count'])
904 self._finish_selector(alg, config, thisalg)
905

◆ add_SUMNLEPTONS_selector()

python.EventSelectionConfig.EventSelectionConfig.add_SUMNLEPTONS_selector ( self,
text,
config )

Definition at line 906 of file EventSelectionConfig.py.

906 def add_SUMNLEPTONS_selector(self, text, config):
907 args = self.parseArgs("SUM_EL_N_MU_N_TAU_N", text.split())
908 self._require_inputs("electrons", "muons", "taus", message="electrons, muons or taus")
909 thisalg = f'{self.selectionName}_SUMNLEPTONS_{self.step}'
910 alg = config.createAlgorithm('CP::SumNLeptonPtSelectorAlg', thisalg)
911 alg.electrons, alg.electronSelection = config.readNameAndSelection(self.electrons)
912 alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
913 alg.taus, alg.tauSelection = config.readNameAndSelection(self.taus)
914 self._maybe_dressed(alg, self.electrons, self.muons)
915 if args.get('ptmin') is not None:
916 # a single threshold, applied to every flavour
917 alg.minPtEl = self.check_float(args['ptmin'])
918 alg.minPtMu = self.check_float(args['ptmin'])
919 alg.minPtTau = self.check_float(args['ptmin'])
920 else:
921 if args.get('selEl'):
922 extraSelEl = self.check_string(args['selEl'])
923 alg.electronSelection = self.extendObjectSelection(config, self.electrons.split(".")[0], alg.electronSelection, extraSelEl)
924 if args.get('selMu'):
925 extraSelMu = self.check_string(args['selMu'])
926 alg.muonSelection = self.extendObjectSelection(config, self.muons.split(".")[0], alg.muonSelection, extraSelMu)
927 if args.get('selTau'):
928 extraSelTau = self.check_string(args['selTau'])
929 alg.tauSelection = self.extendObjectSelection(config, self.taus.split(".")[0], alg.tauSelection, extraSelTau)
930 alg.minPtEl = self.check_float(args['ptEl'])
931 alg.minPtMu = self.check_float(args['ptMu'])
932 alg.minPtTau = self.check_float(args['ptTau'])
933 alg.sign = self.check_sign(args['sign'])
934 alg.count = self.check_int(args['count'])
935 self._finish_selector(alg, config, thisalg)
936

◆ check_btagging()

python.EventSelectionConfig.EventSelectionConfig.check_btagging ( self,
test )

Definition at line 731 of file EventSelectionConfig.py.

731 def check_btagging(self, test):
732 test = test.split(":")
733 if len(test) != 2:
734 raise ValueError (f"[EventSelectionConfig] Misconfiguration! {test} should be provided as 'btagger:btagWP'")
735 else:
736 return test
737

◆ check_float()

python.EventSelectionConfig.EventSelectionConfig.check_float ( self,
test,
requirePositive = True )

Definition at line 690 of file EventSelectionConfig.py.

690 def check_float(self, test, requirePositive=True):
691 try:
692 value = float(test)
693 if not requirePositive or value >= 0:
694 return value
695 else:
696 raise ValueError (f"[EventSelectionConfig] Misconfiguration! Float {test} is not positive!")
697 except ValueError:
698 raise ValueError (f"[EventSelectionConfig] Misconfiguration! {test} should be a float, not {type(test)}!")
699

◆ check_ghosts()

python.EventSelectionConfig.EventSelectionConfig.check_ghosts ( self,
test )

Definition at line 738 of file EventSelectionConfig.py.

738 def check_ghosts(self, test):
739 test = self.check_string(test)
740 values = test.split("!")
741 ghost_map = {
742 "B": "GhostBHadronsFinalCount",
743 "C": "GhostCHadronsFinalCount",
744 "T": "GhostTQuarksFinalCount",
745 "W": "GhostWBosonsCount",
746 "Z": "GhostZBosonsCount",
747 "H": "GhostHBosonsCount",
748 "TAU": "GhostTausFinalCount"
749 }
750 return [ghost_map.get(value.upper(), value) for value in values]
751

◆ check_int()

python.EventSelectionConfig.EventSelectionConfig.check_int ( self,
test,
requirePositive = True )

Definition at line 700 of file EventSelectionConfig.py.

700 def check_int(self, test, requirePositive=True):
701 try:
702 numeric = float(test)
703 value = int(numeric)
704 except (TypeError, ValueError):
705 raise ValueError (f"[EventSelectionConfig] Misconfiguration! {test} should be an int, not {type(test)}")
706 if value != numeric:
707 raise ValueError (f"[EventSelectionConfig] Misconfiguration! {test} should be an int, not a float!")
708 if requirePositive and value < 0:
709 raise ValueError (f"[EventSelectionConfig] Misconfiguration! Int {test} is not positive!")
710 return value
711

◆ check_sign()

python.EventSelectionConfig.EventSelectionConfig.check_sign ( self,
test )

Definition at line 718 of file EventSelectionConfig.py.

718 def check_sign(self, test):
719 mapping = {
720 "<" : "LT",
721 ">" : "GT",
722 "==": "EQ",
723 ">=": "GE",
724 "<=": "LE"
725 }
726 try:
727 return mapping[test]
728 except KeyError:
729 raise KeyError (f"[EventSelectionConfig] Misconfiguration! {test} should be one of {list(mapping.keys())}")
730

◆ check_string()

python.EventSelectionConfig.EventSelectionConfig.check_string ( self,
test )

Definition at line 712 of file EventSelectionConfig.py.

712 def check_string(self, test):
713 if not isinstance(test, str):
714 raise ValueError (f"[EventSelectionConfig] Misconfiguration! {test} should be a string, not a number!")
715 else:
716 return test
717

◆ checkDecorationName()

python.EventSelectionConfig.EventSelectionConfig.checkDecorationName ( self,
decoration )

Definition at line 773 of file EventSelectionConfig.py.

773 def checkDecorationName(self, decoration):
774 if decoration == '':
775 return decoration
776 decoration = decoration.split("&&")
777 decoration = [sub + ',as_char' if ',as_char' not in sub else sub for sub in decoration]
778 return '&&'.join(decoration)
779

◆ extendObjectSelection()

python.EventSelectionConfig.EventSelectionConfig.extendObjectSelection ( self,
config,
container,
oldSelection,
newSelection )

Definition at line 780 of file EventSelectionConfig.py.

780 def extendObjectSelection(self, config, container, oldSelection, newSelection):
781 if oldSelection:
782 return oldSelection + "&&" + config.getFullSelection(container, newSelection)
783 else:
784 return config.getFullSelection(container, newSelection)
785

◆ getCutflow()

python.EventSelectionConfig.EventSelectionConfig.getCutflow ( self)

Definition at line 756 of file EventSelectionConfig.py.

756 def getCutflow(self):
757 return self.cutflow
758

◆ instanceName()

python.EventSelectionConfig.EventSelectionConfig.instanceName ( self)
Return the instance name for this block

Definition at line 238 of file EventSelectionConfig.py.

238 def instanceName (self) :
239 """Return the instance name for this block"""
240 return self.selectionName
241

◆ interpret()

python.EventSelectionConfig.EventSelectionConfig.interpret ( self,
text,
cfg )

Definition at line 607 of file EventSelectionConfig.py.

607 def interpret(self, text, cfg):
608 text = text.strip()
609 if not text or text.startswith("#"):
610 return
611 self.step += 1
612 keyword = text.split()[0]
613 handler = self._dispatch.get(keyword)
614 if handler is None:
615 raise ValueError (f"[EventSelectionConfig] The following selection cut is not recognised! --> {text}")
616 handler(text, cfg)
617
void handler(int sig)
signal handler
Definition rmain.cxx:100

◆ keywordSpecs()

dict python.EventSelectionConfig.EventSelectionConfig.keywordSpecs ( cls)
Return an independent copy of the keyword specification table.

Definition at line 566 of file EventSelectionConfig.py.

566 def keywordSpecs(cls) -> dict:
567 """Return an independent copy of the keyword specification table."""
568 return deepcopy(cls._keywordSpecs())
569

◆ makeAlgs()

python.EventSelectionConfig.EventSelectionConfig.makeAlgs ( self,
config )

Definition at line 585 of file EventSelectionConfig.py.

585 def makeAlgs(self, config):
586 existing = config.getContainerMeta('EventInfo', 'eventSelectionNames', defaultValue=[])
587 config.setContainerMeta('EventInfo', 'eventSelectionNames',
588 existing + [f'pass_{self.selectionName}_%SYS%'], allowOverwrite=True)
589
590 # need to re-initialize here to deal with multiple passes
591 self.step = 0
592 # initialize the pre-selection
593 self.currentDecoration = self.preselection
594 # re-initialize the cutflow
595 self.cutflow = []
596 # read the selection cuts
597 if self.selectionCuts is None:
598 raise ValueError ("[EventSelectionConfig] You must provide the 'selectionCuts' option to 'EventSelectionConfig': "
599 "a single string where each line represents a different selection cut to apply in order.")
600 for line in self.selectionCuts.split("\n"):
601 self.interpret(line, config)
602 # the event filter is always created automatically at the end of the
603 # block; an explicit SAVE line only triggers a deprecation warning
604 self._emit_save(config)
605 config.addEventCutFlow(self.selectionName, self.getCutflow())
606

◆ parseArgs()

python.EventSelectionConfig.EventSelectionConfig.parseArgs ( self,
keyword,
items )
Turn the already-split token list `items` (leading keyword included)
into a dict of argument name -> value, driven by `keywordSpecs`, which
is authoritative for the argument grammar.

Definition at line 676 of file EventSelectionConfig.py.

676 def parseArgs(self, keyword, items):
677 """Turn the already-split token list `items` (leading keyword included)
678 into a dict of argument name -> value, driven by `keywordSpecs`, which
679 is authoritative for the argument grammar."""
680 self._check_args(items, keyword)
681 spec = self._keywordSpecs()[keyword]
682 if spec.get('freeText'):
683 return {'text': ' '.join(items[1:])}
684 for form in (spec.get('forms') or [spec.get('args', [])]):
685 values = self._match_form(form, items[1:])
686 if values is not None:
687 return values
688 self.raise_misconfig(' '.join(items), "number of arguments")
689

◆ raise_misconfig()

python.EventSelectionConfig.EventSelectionConfig.raise_misconfig ( self,
text,
keyword )

Definition at line 622 of file EventSelectionConfig.py.

622 def raise_misconfig(self, text, keyword):
623 raise ValueError (f"[EventSelectionConfig] Misconfiguration! Check {keyword} in: {text}")
624

◆ raise_missinginput()

python.EventSelectionConfig.EventSelectionConfig.raise_missinginput ( self,
collection )

Definition at line 625 of file EventSelectionConfig.py.

625 def raise_missinginput(self, collection):
626 raise ValueError (f"[EventSelectionConfig] Misconfiguration! Missing input collection for {collection}")
627

◆ setDecorationName()

python.EventSelectionConfig.EventSelectionConfig.setDecorationName ( self,
algorithm,
config,
decoration )

Definition at line 759 of file EventSelectionConfig.py.

759 def setDecorationName(self, algorithm, config, decoration):
760 self.cutflow.append( decoration )
761 if algorithm is not None:
762 algorithm.decorationName = f'{decoration},as_char'
763 self.currentDecoration = decoration
764 if self.debugMode:
765 config.addOutputVar('EventInfo', decoration, decoration.split("_%SYS%")[0])
766 else:
767 if self.currentDecoration:
768 self.currentDecoration += '&&' + decoration
769 else:
770 self.currentDecoration = decoration
771 config.addSelection('EventInfo', '', decoration)
772

Member Data Documentation

◆ _dispatch

python.EventSelectionConfig.EventSelectionConfig._dispatch = self._build_dispatch()
protected

Definition at line 236 of file EventSelectionConfig.py.

◆ _EVENTVAR_TYPES

python.EventSelectionConfig.EventSelectionConfig._EVENTVAR_TYPES = {"float": "floatVariable", "int": "intVariable", "double": "doubleVariable"}
staticprotected

Definition at line 1288 of file EventSelectionConfig.py.

◆ _EXPR_COLL

python.EventSelectionConfig.EventSelectionConfig._EXPR_COLL
staticprotected
Initial value:
= {
"jet": _ExprCollection("jets"),
"bjet": _ExprCollection("jets", apply_btag=True),
"el": _ExprCollection("electrons"),
"mu": _ExprCollection("muons"),
"tau": _ExprCollection("taus"),
"ph": _ExprCollection("photons"),
"ljet": _ExprCollection("largeRjets"),
"met": _ExprCollection("met", is_met=True),
}

Definition at line 1157 of file EventSelectionConfig.py.

◆ _EXPR_TOKEN_RE

python.EventSelectionConfig.EventSelectionConfig._EXPR_TOKEN_RE = re.compile(, re.VERBOSE)
staticprotected

Definition at line 1180 of file EventSelectionConfig.py.

◆ _EXPR_VARS

python.EventSelectionConfig.EventSelectionConfig._EXPR_VARS
staticprotected
Initial value:
= {
"dR": _ExprVariable(2, 2, ",", True, False),
"dEta": _ExprVariable(2, 2, ",", True, False),
"dPhi": _ExprVariable(2, 2, ",", False, True),
"m": _ExprVariable(1, None, "+", False, False),
"e": _ExprVariable(1, None, "+", False, False),
"pt": _ExprVariable(1, None, "+", False, True),
"eta": _ExprVariable(1, 1, None, True, False),
"phi": _ExprVariable(1, 1, None, False, True),
}

Definition at line 1169 of file EventSelectionConfig.py.

◆ _KEYWORD_SPECS

python.EventSelectionConfig.EventSelectionConfig._KEYWORD_SPECS = None
staticprotected

Definition at line 177 of file EventSelectionConfig.py.

◆ _NOBJECT

dict python.EventSelectionConfig.EventSelectionConfig._NOBJECT
staticprotected
Initial value:
= {
"EL_N": ("electrons", "NEL", "electrons"),
"MU_N": ("muons", "NMU", "muons"),
"JET_N": ("jets", "NJET", "jets"),
"PH_N": ("photons", "NPH", "photons"),
"TAU_N": ("taus", "NTAU", "tau-jets"),
"LJET_N": ("largeRjets", "NLJET", "large-R jets"),
}

Definition at line 169 of file EventSelectionConfig.py.

◆ btagDecoration

python.EventSelectionConfig.EventSelectionConfig.btagDecoration

Definition at line 1266 of file EventSelectionConfig.py.

◆ currentDecoration

str python.EventSelectionConfig.EventSelectionConfig.currentDecoration = ''

Definition at line 234 of file EventSelectionConfig.py.

◆ cutflow

list python.EventSelectionConfig.EventSelectionConfig.cutflow = []

Definition at line 235 of file EventSelectionConfig.py.

◆ debugMode

python.EventSelectionConfig.EventSelectionConfig.debugMode

Definition at line 764 of file EventSelectionConfig.py.

◆ electrons

python.EventSelectionConfig.EventSelectionConfig.electrons

Definition at line 888 of file EventSelectionConfig.py.

◆ met

python.EventSelectionConfig.EventSelectionConfig.met

Definition at line 1279 of file EventSelectionConfig.py.

◆ muons

python.EventSelectionConfig.EventSelectionConfig.muons

Definition at line 888 of file EventSelectionConfig.py.

◆ selectionName

python.EventSelectionConfig.EventSelectionConfig.selectionName

Definition at line 605 of file EventSelectionConfig.py.

◆ step

int python.EventSelectionConfig.EventSelectionConfig.step = 0

Definition at line 233 of file EventSelectionConfig.py.

◆ taus

python.EventSelectionConfig.EventSelectionConfig.taus

Definition at line 1060 of file EventSelectionConfig.py.


The documentation for this class was generated from the following file: