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 1074 of file EventSelectionConfig.py.

1074 def _add_charge(self, text, config, *, osMode, tag):
1075 """Builder shared by OS and SS: same algorithm, opposite charge mode."""
1076 args = self.parseArgs(tag, text.split())
1077 self._require_inputs("electrons", "muons", "taus")
1078 thisalg = f'{self.selectionName}_{tag}_{self.step}'
1079 alg = config.createAlgorithm('CP::ChargeSelectorAlg', thisalg)
1080 allLeptons = not (args['el'] or args['mu'] or args['tau'])
1081 if self.electrons and (allLeptons or args['el']):
1082 self._route_lepton(alg, config, self.electrons,
1083 ('electrons', 'electronSelection'),
1084 ('truthElectrons', 'truthElectronSelection'))
1085 if self.muons and (allLeptons or args['mu']):
1086 self._route_lepton(alg, config, self.muons,
1087 ('muons', 'muonSelection'),
1088 ('truthMuons', 'truthMuonSelection'))
1089 if self.taus and (allLeptons or args['tau']):
1090 self._route_lepton(alg, config, self.taus,
1091 ('taus', 'tauSelection'),
1092 ('truthTaus', 'truthTauSelection'))
1093 alg.OS = osMode
1094 self._finish_selector(alg, config, thisalg)
1095

◆ _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 824 of file EventSelectionConfig.py.

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

◆ _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 568 of file EventSelectionConfig.py.

568 def _argCounts(cls, spec):
569 """Return the set of valid total token counts (leading keyword included)
570 allowed by a keyword specification, or None when the keyword takes free
571 text and no count check applies."""
572 if spec.get('freeText'):
573 return None
574 forms = spec.get('forms') or [spec.get('args', [])]
575 counts = set()
576 for form in forms:
577 min_args = sum(1 for arg in form if not arg.get('optional'))
578 max_args = len(form)
579 counts.update(n + 1 for n in range(min_args, max_args + 1))
580 return counts
581
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 625 of file EventSelectionConfig.py.

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

◆ _configure_leptons()

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

Definition at line 797 of file EventSelectionConfig.py.

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

◆ _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 1295 of file EventSelectionConfig.py.

1295 def _emit_save(self, config):
1296 """Create the SaveFilterAlg that turns the accumulated event selection
1297 into a named, persisted selection (and ntuple branch). Called once per
1298 block, automatically at the end of makeAlgs."""
1299 thisalg = f'{self.selectionName}_SAVE'
1300 alg = config.createAlgorithm('CP::SaveFilterAlg', thisalg)
1301 alg.FilterDescription = f'events passing < {self.selectionName} >'
1302 alg.eventDecisionOutputDecoration = f'ignore_{self.selectionName}_%SYS%'
1303 alg.selection = self.checkDecorationName(self.currentDecoration)
1304 alg.noFilter = True
1305 alg.selectionName = f'pass_{self.selectionName}_%SYS%,as_char' # this one is used as a selection
1306 alg.decorationName = f'ntuplepass_{self.selectionName}_%SYS%' # this one is saved to file
1307 config.addOutputVar('EventInfo', f'ntuplepass_{self.selectionName}_%SYS%', f'pass_{self.selectionName}')
1308
1309
1310@groupBlocks

◆ _expr_parse()

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

Definition at line 1172 of file EventSelectionConfig.py.

1172 def _expr_parse(self, tokens):
1173 return _ExprParser(self._EXPR_TOKEN_RE).parse(tokens)
1174
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 1169 of file EventSelectionConfig.py.

1169 def _expr_tokenize(self, text):
1170 return _ExprParser(self._EXPR_TOKEN_RE).tokenize(text)
1171
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 1175 of file EventSelectionConfig.py.

1175 def _expr_validate(self, variable, separator, operands):
1176 if variable not in self._EXPR_VARS:
1177 raise UnavailableFeatureError(
1178 f"[EventSelectionConfig] EXPR: variable '{variable}' is not available. "
1179 "Please request it from the EventSelectionAlgorithms developers.")
1180 var_spec = self._EXPR_VARS[variable]
1181 minN = var_spec.min_operands
1182 maxN = var_spec.max_operands
1183 sep = var_spec.separator
1184 metOk = var_spec.met_ok
1185 n = len(operands)
1186 if n < minN or (maxN is not None and n > maxN):
1187 expected = f"{minN}" if maxN == minN else (f"{minN}+" if maxN is None else f"{minN}-{maxN}")
1188 raise InconsistentSettingsError(
1189 f"[EventSelectionConfig] EXPR: '{variable}' takes {expected} operand(s), got {n}")
1190 if n > 1 and separator != sep:
1191 want = {",": "','", "+": "'+'"}.get(sep, str(sep))
1192 raise InconsistentSettingsError(
1193 f"[EventSelectionConfig] EXPR: '{variable}' operands must be separated by {want}")
1194 for coll, index in operands:
1195 if coll not in self._EXPR_COLL:
1196 raise UnavailableFeatureError(
1197 f"[EventSelectionConfig] EXPR: collection '{coll}' is not available. "
1198 "Please request it from the EventSelectionAlgorithms developers.")
1199 coll_spec = self._EXPR_COLL[coll]
1200 isMET = coll_spec.is_met
1201 if isMET:
1202 if not metOk:
1203 raise InconsistentSettingsError(
1204 f"[EventSelectionConfig] EXPR: 'met' is not valid for '{variable}'")
1205 if index is not None:
1206 raise InconsistentSettingsError(
1207 "[EventSelectionConfig] EXPR: 'met' cannot be indexed")
1208 if separator == "+":
1209 raise InconsistentSettingsError(
1210 "[EventSelectionConfig] EXPR: 'met' cannot be combined in a sum")
1211 elif index is None:
1212 raise InconsistentSettingsError(
1213 f"[EventSelectionConfig] EXPR: '{coll}' must be indexed, e.g. {coll}[0]")
1214
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 634 of file EventSelectionConfig.py.

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

◆ _finish_selector()

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

Definition at line 792 of file EventSelectionConfig.py.

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

◆ _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 dilepton invariant mass',
466 'args': [
467 {'name': 'sign', 'type': 'sign'},
468 {'name': 'refMLL', 'type': 'float'},
469 ],
470 },
471 'MLLWINDOW': {
472 'info': 'Require the dilepton invariant mass inside (or, with `veto`, '
473 'outside) a mass window',
474 'args': [
475 {'name': 'lowMLL', 'type': 'float'},
476 {'name': 'highMLL', 'type': 'float'},
477 {'name': 'veto', 'type': 'flag', 'optional': True},
478 ],
479 },
480 'MLL_OSSF': {
481 'info': 'Require the opposite-sign same-flavour dilepton invariant mass '
482 'inside (or, with `veto`, outside) a mass window',
483 'args': [
484 {'name': 'lowMll', 'type': 'float'},
485 {'name': 'highMll', 'type': 'float'},
486 {'name': 'veto', 'type': 'flag', 'optional': True},
487 ],
488 },
489 'OS': {
490 'info': 'Require an opposite-sign lepton pair; without any flag, all '
491 'available lepton flavours are considered',
492 'args': [
493 {'name': 'el', 'type': 'flag', 'optional': True},
494 {'name': 'mu', 'type': 'flag', 'optional': True},
495 {'name': 'tau', 'type': 'flag', 'optional': True},
496 ],
497 },
498 'SS': {
499 'info': 'Require a same-sign lepton pair; without any flag, all '
500 'available lepton flavours are considered',
501 'args': [
502 {'name': 'el', 'type': 'flag', 'optional': True},
503 {'name': 'mu', 'type': 'flag', 'optional': True},
504 {'name': 'tau', 'type': 'flag', 'optional': True},
505 ],
506 },
507 'IMPORT': {
508 'info': 'Import all the cuts of a previously defined event selection',
509 'args': [
510 {'name': 'region', 'type': 'region'},
511 ],
512 },
513 'EVENTFLAG': {
514 'info': 'Require an existing event-wise decoration to be true',
515 'args': [
516 {'name': 'decoration', 'type': 'str'},
517 ],
518 },
519 'GLOBALTRIGMATCH': {
520 'info': 'Require the global trigger matching decision, optionally for '
521 'a given trigger-configuration postfix',
522 'args': [
523 {'name': 'postfix', 'type': 'str', 'optional': True},
524 ],
525 },
526 'RUN_NUMBER': {
527 'info': 'Cut on the (random) run number',
528 'args': [
529 {'name': 'sign', 'type': 'sign'},
530 {'name': 'runNumber', 'type': 'int'},
531 ],
532 },
533 'EVENTVAR': {
534 'info': 'Cut on an existing EventInfo scalar variable, e.g. a DNN or '
535 'BDT discriminant',
536 'args': [
537 {'name': 'type', 'type': 'str', 'choices': sorted(cls._EVENTVAR_TYPES)},
538 {'name': 'name', 'type': 'str'},
539 {'name': 'sign', 'type': 'sign'},
540 {'name': 'value', 'type': 'float', 'signed': True},
541 ],
542 },
543 'EXPR': {
544 'info': 'Cut on a generic object-kinematic expression, e.g. '
545 '`dR(el[0],jet[0]) > 0.4`',
546 'freeText': True,
547 'grammar': {
548 'collections': sorted(cls._EXPR_COLL),
549 'variables': sorted(cls._EXPR_VARS),
550 },
551 },
552 'SAVE': {
553 'info': 'Deprecated and ignored: the event filter is now emitted '
554 'automatically at the end of every event selection',
555 'deprecated': True,
556 'args': [],
557 },
558 })
559 cls._KEYWORD_SPECS = specs
560 return cls._KEYWORD_SPECS
561

◆ _match_form()

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

Definition at line 649 of file EventSelectionConfig.py.

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

◆ _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 804 of file EventSelectionConfig.py.

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

◆ _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 787 of file EventSelectionConfig.py.

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

◆ _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 811 of file EventSelectionConfig.py.

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

◆ add_EVENTFLAG()

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

Definition at line 1112 of file EventSelectionConfig.py.

1112 def add_EVENTFLAG(self, text, config):
1113 args = self.parseArgs("EVENTFLAG", text.split())
1114 existingDecoration = self.check_string(args['decoration'])
1115 self.setDecorationName(None, config, existingDecoration)
1116

◆ add_EVENTVAR_selector()

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

Definition at line 1269 of file EventSelectionConfig.py.

1269 def add_EVENTVAR_selector(self, text, config):
1270 # EVENTVAR <type> <varname> <sign> <threshold>
1271 args = self.parseArgs("EVENTVAR", text.split())
1272 valueType = self.check_string(args['type'])
1273 if valueType not in self._EVENTVAR_TYPES:
1274 self.raise_misconfig(text, f"value type (one of {sorted(self._EVENTVAR_TYPES)})")
1275 varname = self.check_string(args['name'])
1276 thisalg = f'{self.selectionName}_EVENTVAR_{self.step}'
1277 alg = config.createAlgorithm('CP::EventScalarSelectorAlg', thisalg)
1278 # the variable name is given bare; the systematics suffix is appended here
1279 setattr(alg, self._EVENTVAR_TYPES[valueType], f'{varname}_%SYS%')
1280 alg.sign = self.check_sign(args['sign'])
1281 alg.refValue = self.check_float(args['value'], requirePositive=False) # discriminants may be negative
1282 self._finish_selector(alg, config, thisalg)
1283

◆ add_EXPR_selector()

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

Definition at line 1215 of file EventSelectionConfig.py.

1215 def add_EXPR_selector(self, text, config):
1216 body = text[len("EXPR"):].strip()
1217 if not body:
1218 self.raise_misconfig(text, "EXPR expression")
1219 variable, separator, operands, sign, refValue = self._expr_parse(self._expr_tokenize(body))
1220 self._expr_validate(variable, separator, operands)
1221
1222 thisalg = f'{self.selectionName}_EXPR_{self.step}'
1223 alg = config.createAlgorithm('CP::ObjectKinematicSelectorAlg', thisalg)
1224 alg.variable = variable
1225 alg.sign = sign
1226 alg.refValue = refValue
1227
1228 operandKinds, collections, selections, indices = [], [], [], []
1229 usesMET = False
1230 for coll, index in operands:
1231 coll_spec = self._EXPR_COLL[coll]
1232 opt = coll_spec.option
1233 applyBtag = coll_spec.apply_btag
1234 isMET = coll_spec.is_met
1235 container = getattr(self, opt)
1236 if not container:
1237 self.raise_missinginput(opt)
1238 if isMET:
1239 operandKinds.append("MET")
1240 usesMET = True
1241 continue
1242 operandKinds.append("PARTICLE")
1243 name, selection = config.readNameAndSelection(container)
1244 if applyBtag:
1245 if not self.btagDecoration:
1246 self.raise_missinginput("btagDecoration")
1247 selection = (f'{selection}&&{self.btagDecoration},as_char'
1248 if selection else f'{self.btagDecoration},as_char')
1249 collections.append(name)
1250 selections.append(selection)
1251 indices.append(index)
1252
1253 alg.operandKinds = operandKinds
1254 alg.collections = collections
1255 alg.selections = selections
1256 alg.indices = indices
1257 if usesMET:
1258 if not self.met:
1259 self.raise_missinginput("met")
1260 alg.met = config.readName(self.met)
1261 alg.metTerm = self.metTerm
1262 self._finish_selector(alg, config, thisalg)
1263

◆ add_GLOBALTRIGMATCH()

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

Definition at line 1117 of file EventSelectionConfig.py.

1117 def add_GLOBALTRIGMATCH(self, text, config):
1118 args = self.parseArgs("GLOBALTRIGMATCH", text.split())
1119 postfix = self.check_string(args['postfix'])
1120 self.setDecorationName(None, config, f"globalTriggerMatch{postfix}_%SYS%,as_char")
1121

◆ add_IMPORT()

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

Definition at line 847 of file EventSelectionConfig.py.

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

◆ add_MET_selector()

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

Definition at line 1003 of file EventSelectionConfig.py.

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

◆ add_METMWT_selector()

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

Definition at line 1028 of file EventSelectionConfig.py.

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

◆ add_MLL_OSSF_selector()

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

Definition at line 1096 of file EventSelectionConfig.py.

1096 def add_MLL_OSSF_selector(self, text, config):
1097 args = self.parseArgs("MLL_OSSF", text.split())
1098 self._require_inputs("electrons", "muons")
1099 thisalg = f'{self.selectionName}_MLL_OSSF_{self.step}'
1100 alg = config.createAlgorithm('CP::DileptonOSSFInvariantMassWindowSelectorAlg', thisalg)
1101 self._configure_leptons(alg, config, (
1102 (self.electrons, ('electrons', 'electronSelection'),
1103 ('truthElectrons', 'truthElectronSelection')),
1104 (self.muons, ('muons', 'muonSelection'),
1105 ('truthMuons', 'truthMuonSelection')),
1106 ))
1107 alg.lowMll = self.check_float(args['lowMll'])
1108 alg.highMll = self.check_float(args['highMll'])
1109 alg.vetoMode = args['veto']
1110 self._finish_selector(alg, config, thisalg)
1111

◆ add_MLL_selector()

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

Definition at line 1043 of file EventSelectionConfig.py.

1043 def add_MLL_selector(self, text, config):
1044 args = self.parseArgs("MLL", text.split())
1045 self._require_inputs("electrons", "muons")
1046 thisalg = f'{self.selectionName}_MLL_{self.step}'
1047 alg = config.createAlgorithm('CP::DileptonInvariantMassSelectorAlg', thisalg)
1048 self._configure_leptons(alg, config, (
1049 (self.electrons, ('electrons', 'electronSelection'),
1050 ('truthElectrons', 'truthElectronSelection')),
1051 (self.muons, ('muons', 'muonSelection'),
1052 ('truthMuons', 'truthMuonSelection')),
1053 ))
1054 alg.sign = self.check_sign(args['sign'])
1055 alg.refMLL = self.check_float(args['refMLL'])
1056 self._finish_selector(alg, config, thisalg)
1057

◆ add_MLLWINDOW_selector()

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

Definition at line 1058 of file EventSelectionConfig.py.

1058 def add_MLLWINDOW_selector(self, text, config):
1059 args = self.parseArgs("MLLWINDOW", text.split())
1060 self._require_inputs("electrons", "muons")
1061 thisalg = f'{self.selectionName}_MLLWINDOW_{self.step}'
1062 alg = config.createAlgorithm('CP::DileptonInvariantMassWindowSelectorAlg', thisalg)
1063 self._configure_leptons(alg, config, (
1064 (self.electrons, ('electrons', 'electronSelection'),
1065 ('truthElectrons', 'truthElectronSelection')),
1066 (self.muons, ('muons', 'muonSelection'),
1067 ('truthMuons', 'truthMuonSelection')),
1068 ))
1069 alg.lowMLL = self.check_float(args['lowMLL'])
1070 alg.highMLL = self.check_float(args['highMLL'])
1071 alg.vetoMode = args['veto']
1072 self._finish_selector(alg, config, thisalg)
1073

◆ add_MWT_selector()

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

Definition at line 1014 of file EventSelectionConfig.py.

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

◆ add_NBJET_selector()

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

Definition at line 859 of file EventSelectionConfig.py.

859 def add_NBJET_selector(self, text, config):
860 args = self.parseArgs("JET_N_BTAG", text.split())
861 self._require_inputs("jets")
862 thisalg = f'{self.selectionName}_NBJET_{self.step}'
863 alg = config.createAlgorithm('CP::NObjectPtSelectorAlg', thisalg)
864 particles, selection = config.readNameAndSelection(self.jets)
865 alg.particles = particles
866 alg.objectSelection = f'{selection}&&{self.btagDecoration},as_char' if selection else f'{self.btagDecoration},as_char'
867 if args['btag']:
868 btagger, btagWP = self.check_btagging(args['btag'])
869 customBtag = f'ftag_select_{btagger}_{btagWP}'
870 alg.objectSelection = f'{selection}&&{customBtag},as_char' if selection else f'{customBtag},as_char'
871 if args['sel']:
872 extraSel = self.check_string(args['sel'])
873 alg.objectSelection = self.extendObjectSelection(config, self.jets.split(".")[0], alg.objectSelection, extraSel)
874 alg.sign = self.check_sign(args['sign'])
875 alg.count = self.check_int(args['count'])
876 self._finish_selector(alg, config, thisalg)
877
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 963 of file EventSelectionConfig.py.

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

◆ add_NLJETGHOST_selector()

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

Definition at line 978 of file EventSelectionConfig.py.

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

◆ add_NLJETMASS_selector()

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

Definition at line 934 of file EventSelectionConfig.py.

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

◆ add_NLJETMASSWINDOW_selector()

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

Definition at line 948 of file EventSelectionConfig.py.

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

◆ add_NOBJ_selector()

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

Definition at line 993 of file EventSelectionConfig.py.

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

◆ add_RUNNUMBER()

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

Definition at line 1122 of file EventSelectionConfig.py.

1122 def add_RUNNUMBER(self, text, config):
1123 args = self.parseArgs("RUN_NUMBER", text.split())
1124 thisalg = f'{self.selectionName}_RUN_NUMBER_{self.step}'
1125 alg = config.createAlgorithm('CP::RunNumberSelectorAlg', thisalg)
1126 alg.sign = self.check_sign(args['sign'])
1127 alg.runNumber = self.check_int(args['runNumber'])
1128 alg.useRandomRunNumber = config.dataType() is not DataType.Data
1129 self._finish_selector(alg, config, thisalg)
1130

◆ add_SAVE()

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

Definition at line 1284 of file EventSelectionConfig.py.

1284 def add_SAVE(self, text, config):
1285 # SAVE is deprecated: the event filter is now emitted automatically at
1286 # the end of the block (see makeAlgs). The keyword is accepted only to
1287 # warn existing configs; it performs no operation itself.
1288 self.parseArgs("SAVE", text.split())
1289 warnings.warn(
1290 "[EventSelectionConfig] The 'SAVE' keyword is deprecated: the event "
1291 "filter is now created automatically at the end of each EventSelection "
1292 f"block. Please remove the 'SAVE' line from selection '{self.selectionName}'.",
1293 category=ConfigDeprecationWarning, stacklevel=2)
1294

◆ add_SUMNELNMU_selector()

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

Definition at line 878 of file EventSelectionConfig.py.

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

◆ add_SUMNLEPTONS_selector()

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

Definition at line 903 of file EventSelectionConfig.py.

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

◆ check_btagging()

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

Definition at line 728 of file EventSelectionConfig.py.

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

◆ check_float()

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

Definition at line 687 of file EventSelectionConfig.py.

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

◆ check_ghosts()

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

Definition at line 735 of file EventSelectionConfig.py.

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

◆ check_int()

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

Definition at line 697 of file EventSelectionConfig.py.

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

◆ check_sign()

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

Definition at line 715 of file EventSelectionConfig.py.

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

◆ check_string()

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

Definition at line 709 of file EventSelectionConfig.py.

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

◆ checkDecorationName()

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

Definition at line 770 of file EventSelectionConfig.py.

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

◆ extendObjectSelection()

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

Definition at line 777 of file EventSelectionConfig.py.

777 def extendObjectSelection(self, config, container, oldSelection, newSelection):
778 if oldSelection:
779 return oldSelection + "&&" + config.getFullSelection(container, newSelection)
780 else:
781 return config.getFullSelection(container, newSelection)
782

◆ getCutflow()

python.EventSelectionConfig.EventSelectionConfig.getCutflow ( self)

Definition at line 753 of file EventSelectionConfig.py.

753 def getCutflow(self):
754 return self.cutflow
755

◆ 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 604 of file EventSelectionConfig.py.

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

◆ keywordSpecs()

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

Definition at line 563 of file EventSelectionConfig.py.

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

◆ makeAlgs()

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

Definition at line 582 of file EventSelectionConfig.py.

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

◆ 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 673 of file EventSelectionConfig.py.

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

◆ raise_misconfig()

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

Definition at line 619 of file EventSelectionConfig.py.

619 def raise_misconfig(self, text, keyword):
620 raise ValueError (f"[EventSelectionConfig] Misconfiguration! Check {keyword} in: {text}")
621

◆ raise_missinginput()

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

Definition at line 622 of file EventSelectionConfig.py.

622 def raise_missinginput(self, collection):
623 raise ValueError (f"[EventSelectionConfig] Misconfiguration! Missing input collection for {collection}")
624

◆ setDecorationName()

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

Definition at line 756 of file EventSelectionConfig.py.

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

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 1267 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 1136 of file EventSelectionConfig.py.

◆ _EXPR_TOKEN_RE

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

Definition at line 1159 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 1148 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 1245 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 761 of file EventSelectionConfig.py.

◆ electrons

python.EventSelectionConfig.EventSelectionConfig.electrons

Definition at line 885 of file EventSelectionConfig.py.

◆ met

python.EventSelectionConfig.EventSelectionConfig.met

Definition at line 1258 of file EventSelectionConfig.py.

◆ muons

python.EventSelectionConfig.EventSelectionConfig.muons

Definition at line 885 of file EventSelectionConfig.py.

◆ selectionName

python.EventSelectionConfig.EventSelectionConfig.selectionName

Definition at line 602 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 1090 of file EventSelectionConfig.py.


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