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 self.addOption('electrons', "", type=str,
187 info="the input electron container, with a possible selection, in "
188 "the format `container` or `container.selection`.")
189 self.addOption('muons', "", type=str,
190 info="the input muon container, with a possible selection, in the "
191 "format `container` or `container.selection`.")
192 self.addOption('jets', "", type=str,
193 info="the input jet container, with a possible selection, in the "
194 "format `container` or `container.selection`.")
195 self.addOption('largeRjets', "", type=str,
196 info="the large-R jet container, with a possible selection, in "
197 "the format `container` or `container.selection`.")
198 self.addOption('photons', "", type=str,
199 info="the input photon container, with a possible selection, in "
200 "the format `container` or `container.selection`.")
201 self.addOption('taus', "", type=str,
202 info="the input tau-jet container, with a possible selection, in "
203 "the format `container` or `container.selection`.")
204 self.addOption('met', "", type=str,
205 info="the input MET container.")
206 self.addOption('metTerm', "Final", type=str,
207 info="the MET term to use when computing MET-based quantities.")
208 self.addOption('btagDecoration', "", type=str,
209 info="the b-tagging decoration to use when defining b-jets.")
210 self.addOption('preselection', "", type=str,
211 info="the event-wise selection flag to start this event selection "
212 "from.")
213 self.addOption('selectionCuts', "", type=str,
214 noneAction='error',
215 info="a single string listing one selection cut per line. "
216 "See [available keywords](https://topcptoolkit.docs.cern.ch/latest/settings/eventselection/#available-keywords).")
217 self.addOption('debugMode', False, type=bool,
218 info="whether to create an output branch for every single line "
219 "of the selection cuts. Setting it to `False` only saves the"
220 " final decision.")
221 self.addOption('useDressedProperties', True, type=bool,
222 info="whether to use dressed truth electron and truth muon "
223 "kinematics rather than simple 4-vector kinematics.")
224 self.step = 0
225 self.currentDecoration = ''
226 self.cutflow = []
227 self._dispatch = self._build_dispatch()
228

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

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

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

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

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

559 def _argCounts(cls, spec):
560 """Return the set of valid total token counts (leading keyword included)
561 allowed by a keyword specification, or None when the keyword takes free
562 text and no count check applies."""
563 if spec.get('freeText'):
564 return None
565 forms = spec.get('forms') or [spec.get('args', [])]
566 counts = set()
567 for form in forms:
568 min_args = sum(1 for arg in form if not arg.get('optional'))
569 max_args = len(form)
570 counts.update(n + 1 for n in range(min_args, max_args + 1))
571 return counts
572
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 233 of file EventSelectionConfig.py.

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

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

616 def _check_args(self, items, keyword):
617 """Validate the leading keyword and the number of arguments, the latter
618 derived from the keyword specification table."""
619 if items[0] != keyword:
620 self.raise_misconfig(' '.join(items), keyword)
621 validCounts = self._argCounts(self._keywordSpecs()[keyword])
622 if validCounts is not None and len(items) not in validCounts:
623 self.raise_misconfig(' '.join(items), "number of arguments")
624

◆ _configure_leptons()

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

Definition at line 788 of file EventSelectionConfig.py.

788 def _configure_leptons(self, alg, config, leptons):
789 """Configure reco/truth lepton handles from explicit metadata."""
790 for spec, reco, truth in leptons:
791 if spec:
792 self._route_lepton(alg, config, spec, reco, truth)
793 self._maybe_dressed(alg, *(spec for spec, _reco, _truth in leptons))
794

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

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

◆ _expr_parse()

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

Definition at line 1163 of file EventSelectionConfig.py.

1163 def _expr_parse(self, tokens):
1164 return _ExprParser(self._EXPR_TOKEN_RE).parse(tokens)
1165
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 1160 of file EventSelectionConfig.py.

1160 def _expr_tokenize(self, text):
1161 return _ExprParser(self._EXPR_TOKEN_RE).tokenize(text)
1162
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 1166 of file EventSelectionConfig.py.

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

625 def _extract_flags(self, form, tokens):
626 """Remove flag tokens from `tokens` and return their boolean values."""
627 tokens = list(tokens)
628 values = {}
629 for arg in form:
630 if arg.get('type') != 'flag':
631 continue
632 values[arg['name']] = False
633 for i, token in enumerate(tokens):
634 if token.lower() == arg['name'].lower():
635 del tokens[i]
636 values[arg['name']] = True
637 break
638 return tokens, values
639

◆ _finish_selector()

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

Definition at line 783 of file EventSelectionConfig.py.

783 def _finish_selector(self, alg, config, name):
784 """Apply the common event-preselection and output decoration."""
785 alg.eventPreselection = self.checkDecorationName(self.currentDecoration)
786 self.setDecorationName(alg, config, f'{name}_%SYS%')
787

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

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

◆ _match_form()

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

Definition at line 640 of file EventSelectionConfig.py.

640 def _match_form(self, form, tokens):
641 """Match one keyword argument form, returning values or None."""
642 tokens, values = self._extract_flags(form, tokens)
643 positional = [arg for arg in form if arg.get('type') != 'flag']
644 nRequired = sum(1 for arg in positional if not arg.get('optional'))
645 if len(tokens) < nRequired or len(tokens) > len(positional):
646 return None
647
648 budget = len(tokens) - nRequired
649 cursor = 0
650 for arg in positional:
651 if not arg.get('optional'):
652 values[arg['name']] = tokens[cursor]
653 cursor += 1
654 continue
655 pattern = arg.get('pattern')
656 if budget > 0 and (pattern is None or re.fullmatch(pattern, tokens[cursor])):
657 values[arg['name']] = tokens[cursor]
658 cursor += 1
659 budget -= 1
660 else:
661 values[arg['name']] = ''
662 return values if cursor == len(tokens) else None
663

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

795 def _maybe_dressed(self, alg, *specs):
796 """Enable dressed kinematics when any of the given electron/muon
797 containers is a truth container. Dressed kinematics only exist for
798 truth electrons and muons, so only those specs should be passed here."""
799 if any(spec and ("Particle" in spec or "Truth" in spec) for spec in specs):
800 alg.useDressedProperties = self.useDressedProperties
801

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

778 def _require_inputs(self, *names, message=None):
779 """Require at least one of the named input options to be configured."""
780 if not any(getattr(self, name) for name in names):
781 self.raise_missinginput(message or " or ".join(names))
782

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

802 def _route_lepton(self, alg, config, spec, reco, truth):
803 """Assign (name, selection) to the reco or truth handles of `alg`
804 depending on whether `spec` points to a truth container.
805 `reco`/`truth` are (nameAttr, selectionAttr) pairs."""
806 name, sel = config.readNameAndSelection(spec)
807 nameAttr, selAttr = truth if ("Particle" in spec or "Truth" in spec) else reco
808 setattr(alg, nameAttr, name)
809 setattr(alg, selAttr, sel)
810

◆ add_EVENTFLAG()

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

Definition at line 1103 of file EventSelectionConfig.py.

1103 def add_EVENTFLAG(self, text, config):
1104 args = self.parseArgs("EVENTFLAG", text.split())
1105 existingDecoration = self.check_string(args['decoration'])
1106 self.setDecorationName(None, config, existingDecoration)
1107

◆ add_EVENTVAR_selector()

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

Definition at line 1260 of file EventSelectionConfig.py.

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

◆ add_EXPR_selector()

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

Definition at line 1206 of file EventSelectionConfig.py.

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

◆ add_GLOBALTRIGMATCH()

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

Definition at line 1108 of file EventSelectionConfig.py.

1108 def add_GLOBALTRIGMATCH(self, text, config):
1109 args = self.parseArgs("GLOBALTRIGMATCH", text.split())
1110 postfix = self.check_string(args['postfix'])
1111 self.setDecorationName(None, config, f"globalTriggerMatch{postfix}_%SYS%,as_char")
1112

◆ add_IMPORT()

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

Definition at line 838 of file EventSelectionConfig.py.

838 def add_IMPORT(self, text, config):
839 # this is used to import a previous selection
840 args = self.parseArgs("IMPORT", text.split())
841 region = self.check_string(args['region'])
842 if not self.currentDecoration:
843 self.currentDecoration = f'pass_{region}_%SYS%,as_char'
844 else:
845 self.currentDecoration = f'{self.currentDecoration},as_char&&pass_{region}_%SYS%'
846 # for the cutflow, we need to retrieve all the cuts corresponding to this IMPORT
847 imported_cuts = [cut for cut in config.getSelectionCutFlow('EventInfo', '') if cut.startswith(region)]
848 self.cutflow += imported_cuts
849

◆ add_MET_selector()

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

Definition at line 994 of file EventSelectionConfig.py.

994 def add_MET_selector(self, text, config):
995 args = self.parseArgs("MET", text.split())
996 self._require_inputs("met", message="MET")
997 thisalg = f'{self.selectionName}_MET_{self.step}'
998 alg = config.createAlgorithm('CP::MissingETSelectorAlg', thisalg)
999 alg.met = config.readName(self.met)
1000 alg.metTerm = self.metTerm
1001 alg.sign = self.check_sign(args['sign'])
1002 alg.refMET = self.check_float(args['refMET'])
1003 self._finish_selector(alg, config, thisalg)
1004

◆ add_METMWT_selector()

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

Definition at line 1019 of file EventSelectionConfig.py.

1019 def add_METMWT_selector(self, text, config):
1020 args = self.parseArgs("MET+MWT", text.split())
1021 self._require_inputs("met", message="MET")
1022 self._require_inputs("electrons", "muons")
1023 thisalg = f'{self.selectionName}_METMWT_{self.step}'
1024 alg = config.createAlgorithm('CP::MissingETPlusTransverseMassSelectorAlg', thisalg)
1025 alg.met = config.readName(self.met)
1026 alg.metTerm = self.metTerm
1027 alg.electrons, alg.electronSelection = config.readNameAndSelection(self.electrons)
1028 alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
1029 self._maybe_dressed(alg, self.electrons, self.muons)
1030 alg.sign = self.check_sign(args['sign'])
1031 alg.refMETMWT = self.check_float(args['refMETMWT'])
1032 self._finish_selector(alg, config, thisalg)
1033

◆ add_MLL_OSSF_selector()

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

Definition at line 1087 of file EventSelectionConfig.py.

1087 def add_MLL_OSSF_selector(self, text, config):
1088 args = self.parseArgs("MLL_OSSF", text.split())
1089 self._require_inputs("electrons", "muons")
1090 thisalg = f'{self.selectionName}_MLL_OSSF_{self.step}'
1091 alg = config.createAlgorithm('CP::DileptonOSSFInvariantMassWindowSelectorAlg', thisalg)
1092 self._configure_leptons(alg, config, (
1093 (self.electrons, ('electrons', 'electronSelection'),
1094 ('truthElectrons', 'truthElectronSelection')),
1095 (self.muons, ('muons', 'muonSelection'),
1096 ('truthMuons', 'truthMuonSelection')),
1097 ))
1098 alg.lowMll = self.check_float(args['lowMll'])
1099 alg.highMll = self.check_float(args['highMll'])
1100 alg.vetoMode = args['veto']
1101 self._finish_selector(alg, config, thisalg)
1102

◆ add_MLL_selector()

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

Definition at line 1034 of file EventSelectionConfig.py.

1034 def add_MLL_selector(self, text, config):
1035 args = self.parseArgs("MLL", text.split())
1036 self._require_inputs("electrons", "muons")
1037 thisalg = f'{self.selectionName}_MLL_{self.step}'
1038 alg = config.createAlgorithm('CP::DileptonInvariantMassSelectorAlg', thisalg)
1039 self._configure_leptons(alg, config, (
1040 (self.electrons, ('electrons', 'electronSelection'),
1041 ('truthElectrons', 'truthElectronSelection')),
1042 (self.muons, ('muons', 'muonSelection'),
1043 ('truthMuons', 'truthMuonSelection')),
1044 ))
1045 alg.sign = self.check_sign(args['sign'])
1046 alg.refMLL = self.check_float(args['refMLL'])
1047 self._finish_selector(alg, config, thisalg)
1048

◆ add_MLLWINDOW_selector()

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

Definition at line 1049 of file EventSelectionConfig.py.

1049 def add_MLLWINDOW_selector(self, text, config):
1050 args = self.parseArgs("MLLWINDOW", text.split())
1051 self._require_inputs("electrons", "muons")
1052 thisalg = f'{self.selectionName}_MLLWINDOW_{self.step}'
1053 alg = config.createAlgorithm('CP::DileptonInvariantMassWindowSelectorAlg', thisalg)
1054 self._configure_leptons(alg, config, (
1055 (self.electrons, ('electrons', 'electronSelection'),
1056 ('truthElectrons', 'truthElectronSelection')),
1057 (self.muons, ('muons', 'muonSelection'),
1058 ('truthMuons', 'truthMuonSelection')),
1059 ))
1060 alg.lowMLL = self.check_float(args['lowMLL'])
1061 alg.highMLL = self.check_float(args['highMLL'])
1062 alg.vetoMode = args['veto']
1063 self._finish_selector(alg, config, thisalg)
1064

◆ add_MWT_selector()

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

Definition at line 1005 of file EventSelectionConfig.py.

1005 def add_MWT_selector(self, text, config):
1006 args = self.parseArgs("MWT", text.split())
1007 self._require_inputs("electrons", "muons")
1008 thisalg = f'{self.selectionName}_MWT_{self.step}'
1009 alg = config.createAlgorithm('CP::TransverseMassSelectorAlg', thisalg)
1010 alg.met = config.readName(self.met)
1011 alg.metTerm = self.metTerm
1012 alg.electrons, alg.electronSelection = config.readNameAndSelection(self.electrons)
1013 alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
1014 self._maybe_dressed(alg, self.electrons, self.muons)
1015 alg.sign = self.check_sign(args['sign'])
1016 alg.refMWT = self.check_float(args['refMWT'])
1017 self._finish_selector(alg, config, thisalg)
1018

◆ add_NBJET_selector()

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

Definition at line 850 of file EventSelectionConfig.py.

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

954 def add_NJETGHOST_selector(self, text, config):
955 args = self.parseArgs("JET_N_GHOST", text.split())
956 thisalg = f'{self.selectionName}_NJETGHOST_{self.step}'
957 alg = config.createAlgorithm('CP::JetNGhostSelectorAlg', thisalg)
958 alg.jets, alg.jetSelection = config.readNameAndSelection(self.jets)
959 ghosts = self.check_ghosts(args['ghost'])
960 alg.ghost = ghosts[0]
961 if len(ghosts) > 1 :
962 alg.veto = ghosts[1]
963 if args['ptmin']:
964 alg.minPt = self.check_float(args['ptmin'])
965 alg.sign = self.check_sign(args['sign'])
966 alg.count = self.check_int(args['count'])
967 self._finish_selector(alg, config, thisalg)
968

◆ add_NLJETGHOST_selector()

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

Definition at line 969 of file EventSelectionConfig.py.

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

◆ add_NLJETMASS_selector()

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

Definition at line 925 of file EventSelectionConfig.py.

925 def add_NLJETMASS_selector(self, text, config):
926 args = self.parseArgs("LJETMASS_N", text.split())
927 thisalg = f'{self.selectionName}_NLJETMASS_{self.step}'
928 alg = config.createAlgorithm('CP::NObjectMassSelectorAlg', thisalg)
929 alg.particles, alg.objectSelection = config.readNameAndSelection(self.largeRjets)
930 if args['sel']:
931 alg.objectSelection = self.extendObjectSelection(
932 config, self.largeRjets.split(".")[0], alg.objectSelection,
933 self.check_string(args['sel']))
934 alg.minMass = self.check_float(args['minMass'])
935 alg.sign = self.check_sign(args['sign'])
936 alg.count = self.check_int(args['count'])
937 self._finish_selector(alg, config, thisalg)
938

◆ add_NLJETMASSWINDOW_selector()

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

Definition at line 939 of file EventSelectionConfig.py.

939 def add_NLJETMASSWINDOW_selector(self, text, config):
940 args = self.parseArgs("LJETMASSWINDOW_N", text.split())
941 thisalg = f'{self.selectionName}_NLJETMASSWINDOW_{self.step}'
942 alg = config.createAlgorithm('CP::NLargeRJetMassWindowSelectorAlg', thisalg)
943 alg.ljets, alg.ljetSelection = config.readNameAndSelection(self.largeRjets)
944 if args['sel']:
945 extraSel = self.check_string(args['sel'])
946 alg.ljetSelection = self.extendObjectSelection(config, self.largeRjets.split(".")[0], alg.ljetSelection, extraSel)
947 alg.lowMass = self.check_float(args['lowMass'])
948 alg.highMass = self.check_float(args['highMass'])
949 alg.sign = self.check_sign(args['sign'])
950 alg.count = self.check_int(args['count'])
951 alg.vetoMode = args['veto']
952 self._finish_selector(alg, config, thisalg)
953

◆ add_NOBJ_selector()

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

Definition at line 984 of file EventSelectionConfig.py.

984 def add_NOBJ_selector(self, text, config):
985 args = self.parseArgs("OBJ_N", text.split())
986 thisalg = f'{self.selectionName}_NOBJ_{self.step}'
987 alg = config.createAlgorithm('CP::NObjectPtSelectorAlg', thisalg)
988 alg.particles, alg.objectSelection = config.readNameAndSelection(self.check_string(args['container']))
989 alg.minPt = self.check_float(args['ptmin'])
990 alg.sign = self.check_sign(args['sign'])
991 alg.count = self.check_int(args['count'])
992 self._finish_selector(alg, config, thisalg)
993

◆ add_RUNNUMBER()

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

Definition at line 1113 of file EventSelectionConfig.py.

1113 def add_RUNNUMBER(self, text, config):
1114 args = self.parseArgs("RUN_NUMBER", text.split())
1115 thisalg = f'{self.selectionName}_RUN_NUMBER_{self.step}'
1116 alg = config.createAlgorithm('CP::RunNumberSelectorAlg', thisalg)
1117 alg.sign = self.check_sign(args['sign'])
1118 alg.runNumber = self.check_int(args['runNumber'])
1119 alg.useRandomRunNumber = config.dataType() is not DataType.Data
1120 self._finish_selector(alg, config, thisalg)
1121

◆ add_SAVE()

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

Definition at line 1275 of file EventSelectionConfig.py.

1275 def add_SAVE(self, text, config):
1276 # SAVE is deprecated: the event filter is now emitted automatically at
1277 # the end of the block (see makeAlgs). The keyword is accepted only to
1278 # warn existing configs; it performs no operation itself.
1279 self.parseArgs("SAVE", text.split())
1280 warnings.warn(
1281 "[EventSelectionConfig] The 'SAVE' keyword is deprecated: the event "
1282 "filter is now created automatically at the end of each EventSelection "
1283 f"block. Please remove the 'SAVE' line from selection '{self.selectionName}'.",
1284 category=ConfigDeprecationWarning, stacklevel=2)
1285

◆ add_SUMNELNMU_selector()

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

Definition at line 869 of file EventSelectionConfig.py.

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

◆ add_SUMNLEPTONS_selector()

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

Definition at line 894 of file EventSelectionConfig.py.

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

◆ check_btagging()

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

Definition at line 719 of file EventSelectionConfig.py.

719 def check_btagging(self, test):
720 test = test.split(":")
721 if len(test) != 2:
722 raise ValueError (f"[EventSelectionConfig] Misconfiguration! {test} should be provided as 'btagger:btagWP'")
723 else:
724 return test
725

◆ check_float()

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

Definition at line 678 of file EventSelectionConfig.py.

678 def check_float(self, test, requirePositive=True):
679 try:
680 value = float(test)
681 if not requirePositive or value >= 0:
682 return value
683 else:
684 raise ValueError (f"[EventSelectionConfig] Misconfiguration! Float {test} is not positive!")
685 except ValueError:
686 raise ValueError (f"[EventSelectionConfig] Misconfiguration! {test} should be a float, not {type(test)}!")
687

◆ check_ghosts()

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

Definition at line 726 of file EventSelectionConfig.py.

726 def check_ghosts(self, test):
727 test = self.check_string(test)
728 values = test.split("!")
729 ghost_map = {
730 "B": "GhostBHadronsFinalCount",
731 "C": "GhostCHadronsFinalCount",
732 "T": "GhostTQuarksFinalCount",
733 "W": "GhostWBosonsCount",
734 "Z": "GhostZBosonsCount",
735 "H": "GhostHBosonsCount",
736 "TAU": "GhostTausFinalCount"
737 }
738 return [ghost_map.get(value.upper(), value) for value in values]
739

◆ check_int()

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

Definition at line 688 of file EventSelectionConfig.py.

688 def check_int(self, test, requirePositive=True):
689 try:
690 numeric = float(test)
691 value = int(numeric)
692 except (TypeError, ValueError):
693 raise ValueError (f"[EventSelectionConfig] Misconfiguration! {test} should be an int, not {type(test)}")
694 if value != numeric:
695 raise ValueError (f"[EventSelectionConfig] Misconfiguration! {test} should be an int, not a float!")
696 if requirePositive and value < 0:
697 raise ValueError (f"[EventSelectionConfig] Misconfiguration! Int {test} is not positive!")
698 return value
699

◆ check_sign()

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

Definition at line 706 of file EventSelectionConfig.py.

706 def check_sign(self, test):
707 mapping = {
708 "<" : "LT",
709 ">" : "GT",
710 "==": "EQ",
711 ">=": "GE",
712 "<=": "LE"
713 }
714 try:
715 return mapping[test]
716 except KeyError:
717 raise KeyError (f"[EventSelectionConfig] Misconfiguration! {test} should be one of {list(mapping.keys())}")
718

◆ check_string()

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

Definition at line 700 of file EventSelectionConfig.py.

700 def check_string(self, test):
701 if not isinstance(test, str):
702 raise ValueError (f"[EventSelectionConfig] Misconfiguration! {test} should be a string, not a number!")
703 else:
704 return test
705

◆ checkDecorationName()

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

Definition at line 761 of file EventSelectionConfig.py.

761 def checkDecorationName(self, decoration):
762 if decoration == '':
763 return decoration
764 decoration = decoration.split("&&")
765 decoration = [sub + ',as_char' if ',as_char' not in sub else sub for sub in decoration]
766 return '&&'.join(decoration)
767

◆ extendObjectSelection()

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

Definition at line 768 of file EventSelectionConfig.py.

768 def extendObjectSelection(self, config, container, oldSelection, newSelection):
769 if oldSelection:
770 return oldSelection + "&&" + config.getFullSelection(container, newSelection)
771 else:
772 return config.getFullSelection(container, newSelection)
773

◆ getCutflow()

python.EventSelectionConfig.EventSelectionConfig.getCutflow ( self)

Definition at line 744 of file EventSelectionConfig.py.

744 def getCutflow(self):
745 return self.cutflow
746

◆ instanceName()

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

Definition at line 229 of file EventSelectionConfig.py.

229 def instanceName (self) :
230 """Return the instance name for this block"""
231 return self.selectionName
232

◆ interpret()

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

Definition at line 595 of file EventSelectionConfig.py.

595 def interpret(self, text, cfg):
596 text = text.strip()
597 if not text or text.startswith("#"):
598 return
599 self.step += 1
600 keyword = text.split()[0]
601 handler = self._dispatch.get(keyword)
602 if handler is None:
603 raise ValueError (f"[EventSelectionConfig] The following selection cut is not recognised! --> {text}")
604 handler(text, cfg)
605
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 554 of file EventSelectionConfig.py.

554 def keywordSpecs(cls) -> dict:
555 """Return an independent copy of the keyword specification table."""
556 return deepcopy(cls._keywordSpecs())
557

◆ makeAlgs()

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

Definition at line 573 of file EventSelectionConfig.py.

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

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

664 def parseArgs(self, keyword, items):
665 """Turn the already-split token list `items` (leading keyword included)
666 into a dict of argument name -> value, driven by `keywordSpecs`, which
667 is authoritative for the argument grammar."""
668 self._check_args(items, keyword)
669 spec = self._keywordSpecs()[keyword]
670 if spec.get('freeText'):
671 return {'text': ' '.join(items[1:])}
672 for form in (spec.get('forms') or [spec.get('args', [])]):
673 values = self._match_form(form, items[1:])
674 if values is not None:
675 return values
676 self.raise_misconfig(' '.join(items), "number of arguments")
677

◆ raise_misconfig()

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

Definition at line 610 of file EventSelectionConfig.py.

610 def raise_misconfig(self, text, keyword):
611 raise ValueError (f"[EventSelectionConfig] Misconfiguration! Check {keyword} in: {text}")
612

◆ raise_missinginput()

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

Definition at line 613 of file EventSelectionConfig.py.

613 def raise_missinginput(self, collection):
614 raise ValueError (f"[EventSelectionConfig] Misconfiguration! Missing input collection for {collection}")
615

◆ setDecorationName()

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

Definition at line 747 of file EventSelectionConfig.py.

747 def setDecorationName(self, algorithm, config, decoration):
748 self.cutflow.append( decoration )
749 if algorithm is not None:
750 algorithm.decorationName = f'{decoration},as_char'
751 self.currentDecoration = decoration
752 if self.debugMode:
753 config.addOutputVar('EventInfo', decoration, decoration.split("_%SYS%")[0])
754 else:
755 if self.currentDecoration:
756 self.currentDecoration += '&&' + decoration
757 else:
758 self.currentDecoration = decoration
759 config.addSelection('EventInfo', '', decoration)
760

Member Data Documentation

◆ _dispatch

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

Definition at line 227 of file EventSelectionConfig.py.

◆ _EVENTVAR_TYPES

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

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

◆ _EXPR_TOKEN_RE

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

Definition at line 1150 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 1139 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 1236 of file EventSelectionConfig.py.

◆ currentDecoration

str python.EventSelectionConfig.EventSelectionConfig.currentDecoration = ''

Definition at line 225 of file EventSelectionConfig.py.

◆ cutflow

list python.EventSelectionConfig.EventSelectionConfig.cutflow = []

Definition at line 226 of file EventSelectionConfig.py.

◆ debugMode

python.EventSelectionConfig.EventSelectionConfig.debugMode

Definition at line 752 of file EventSelectionConfig.py.

◆ electrons

python.EventSelectionConfig.EventSelectionConfig.electrons

Definition at line 876 of file EventSelectionConfig.py.

◆ met

python.EventSelectionConfig.EventSelectionConfig.met

Definition at line 1249 of file EventSelectionConfig.py.

◆ muons

python.EventSelectionConfig.EventSelectionConfig.muons

Definition at line 876 of file EventSelectionConfig.py.

◆ selectionName

python.EventSelectionConfig.EventSelectionConfig.selectionName

Definition at line 593 of file EventSelectionConfig.py.

◆ step

int python.EventSelectionConfig.EventSelectionConfig.step = 0

Definition at line 224 of file EventSelectionConfig.py.

◆ taus

python.EventSelectionConfig.EventSelectionConfig.taus

Definition at line 1081 of file EventSelectionConfig.py.


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