Belle II Software  light-2205-abys
stdCharged.py
1 #!/usr/bin/env python3
2 
3 
10 
11 import re
12 
13 import basf2 as b2
14 import modularAnalysis as ma
15 from variables import variables
16 import pdg
17 
18 from ROOT import Belle2
19 Const = Belle2.Const
20 _TrainingMode = Belle2.ChargedPidMVAWeights.ChargedPidMVATrainingMode
21 
22 
23 # define arrays to interpret cut matrix
24 _chargednames = ['pi', 'K', 'p', 'e', 'mu']
25 _pidnames = ['pionID', 'kaonID', 'protonID', 'electronID', 'muonID']
26 _stdnames = ['all', 'loose', 'loosepid', 'good', 'higheff']
27 _effnames = ['95eff', '90eff', '85eff']
28 # default particle list for stdPi() and similar functions
29 _defaultlist = 'good'
30 _mostLikelyList = 'mostlikely'
31 
32 
33 def _stdChargedEffCuts(particletype, listtype):
34  """
35  Provides the PID cut corresponding to a given efficiency percentile
36 
37  @param particletype type of charged particle (pi, K, p, e, mu)
38  @param listtype efficiency percentile for the list (95eff, 90eff, 85eff)
39  """
40 
41  particleindex = _chargednames.index(particletype)
42  effindex = _effnames.index(listtype)
43 
44  # efficiency cuts = [.95,.90,.85] efficiency; values outside (0,1) mean the cut does not exist and an error will be thrown
45  effcuts = [[0.001, 0.019, 0.098],
46  [5e-6, 0.027, 0.167],
47  [0.000, 0.043, 0.251],
48  [0.093, 0.301, 0.709],
49  [0.187, 0.418, 0.909]]
50  #
51  return effcuts[particleindex][effindex]
52 
53 
54 def stdCharged(particletype, listtype, path):
55  """
56  Function to prepare one of several standardized types of charged particle lists:
57  - 'all' with no cuts on track
58  - 'good' high purity lists for data studies
59  - 'loosepid' loose selections for skimming, PID cut only
60  - 'loose' loose selections for skimming
61  - 'higheff' high efficiency list with loose global ID cut for data studies
62  - 'mostlikely' list with the highest PID likelihood
63  Also the following lists, which may or may not be available depending on the release
64  - '99eff' with 99% selection efficiency (calculated for 1<p<4 GeV) and good track (MC only)
65  - '95eff' with 95% selection efficiency (calculated for 1<p<4 GeV) and good track (MC only)
66  - '90eff' with 90% selection efficiency (calculated for 1<p<4 GeV) and good track (MC only)
67  - '85eff' with 85% selection efficiency (calculated for 1<p<4 GeV) and good track (MC only)
68 
69  @param particletype type of charged particle to make a list of
70  @param listtype name of standard list
71  @param path modules are added to this path
72  """
73 
74  # basic quality cut strings
75  trackQuality = 'thetaInCDCAcceptance and nCDCHits>20'
76  ipCut = 'dr < 0.5 and abs(dz) < 2'
77  goodTrack = trackQuality + ' and ' + ipCut
78 
79  if particletype not in _chargednames:
80  b2.B2ERROR("The requested list is not a standard charged particle. Use one of pi, K, e, mu, p.")
81 
82  if listtype == 'all':
83  ma.fillParticleList(particletype + '+:all', '', True, path=path)
84  elif listtype == 'good':
85  ma.fillParticleList(
86  particletype + '+:good',
87  _pidnames[_chargednames.index(particletype)] + ' > 0.5 and ' + goodTrack,
88  True,
89  path=path)
90  elif listtype == 'loose':
91  ma.fillParticleList(
92  particletype + '+:loose',
93  _pidnames[_chargednames.index(particletype)] + ' > 0.1 and ' + goodTrack,
94  True,
95  path=path)
96  elif listtype == 'loosepid':
97  ma.fillParticleList(
98  particletype + '+:loosepid',
99  _pidnames[_chargednames.index(particletype)] + ' > 0.1',
100  True,
101  path=path)
102  elif listtype == 'higheff':
103  ma.fillParticleList(
104  particletype + '+:higheff',
105  _pidnames[_chargednames.index(particletype)] + ' > 0.002 and ' + goodTrack,
106  True,
107  path=path)
108  elif listtype not in _effnames:
109  b2.B2ERROR("The requested list is not defined. Please refer to the stdCharged documentation.")
110  else:
111  pidcut = _stdChargedEffCuts(particletype, listtype)
112  if 0.0 < pidcut < 1.0:
113  ma.fillParticleList(
114  particletype +
115  '+:' +
116  listtype,
117  _pidnames[_chargednames.index(particletype)] +
118  ' > ' +
119  str(pidcut) +
120  ' and ' +
121  goodTrack,
122  True,
123  path=path)
124  else:
125  b2.B2ERROR('The requested standard particle list ' + particletype +
126  '+:' + listtype + ' is not available in this release.')
127 
128 
129 def stdPi(listtype=_defaultlist, path=None):
130  """
131  Function to prepare standard pion lists, refer to `stdCharged` for details
132 
133  @param listtype name of standard list
134  @param path modules are added to this path
135  """
136  stdCharged('pi', listtype, path)
137 
138 
139 def stdK(listtype=_defaultlist, path=None):
140  """
141  Function to prepare standard kaon lists, refer to `stdCharged` for details
142 
143  @param listtype name of standard list
144  @param path modules are added to this path
145  """
146  stdCharged('K', listtype, path)
147 
148 
149 def stdPr(listtype=_defaultlist, path=None):
150  """
151  Function to prepare standard proton lists, refer to `stdCharged` for details
152 
153  @param listtype name of standard list
154  @param path modules are added to this path
155  """
156  stdCharged('p', listtype, path)
157 
158 
159 def stdLep(pdgId,
160  working_point,
161  method,
162  classification,
163  lid_weights_gt,
164  release=None,
165  channel_eff="combination",
166  channel_misid_pi="combination",
167  channel_misid_K="combination",
168  inputListName=None,
169  outputListLabel=None,
170  trainingModeMulticlass=_TrainingMode.c_Multiclass,
171  trainingModeBinary=_TrainingMode.c_Classification,
172  path=None):
173  """
174  Function to prepare one of several standardized types of lepton (:math:`e,\\mu`) lists, with the following working points:
175 
176  * 'FixedThresh05', PID cut of > 0.5 for each particle in the list.
177  * 'FixedThresh09', PID cut of > 0.9 for each particle in the list.
178  * 'FixedThresh095', PID cut of > 0.95 for each particle in the list.
179  * 'UniformEff60' 60% lepton efficiency list, uniform in a given multi-dimensional parametrisation.
180  * 'UniformEff70' 70% lepton efficiency list, uniform in a given multi-dimensional parametrisation.
181  * 'UniformEff80' 80% lepton efficiency list, uniform in a given multi-dimensional parametrisation.
182  * 'UniformEff90' 90% lepton efficiency list, uniform in a given multi-dimensional parametrisation.
183  * 'UniformEff95' 95% lepton efficiency list, uniform in a given multi-dimensional parametrisation.
184 
185  The function creates a ``ParticleList``, selecting particles according to the chosen ``working_point``,
186  and decorates each candidate in the list with the nominal Data/MC :math:`\\ell` ID efficiency and
187  :math:`\\pi,K` fake rate correction factors and their stat, syst uncertainty, reading the info
188  from the Conditions Database (CDB) according to the chosen input global tag (GT).
189 
190  .. note::
191  Particles will **not** be selected if they are outside the Data/MC *efficiency* corrections' phase space coverage
192  for the given working point.
193  In fact, the threshold value for the PID cut in such cases is set to NaN.
194 
195  .. warning::
196  At the moment, the only supported *binary* lepton identification is against the **pion** hypothesis.
197  This implies that, if binary classification is chosen, only :math:`\\pi` fake rate corrections will be added to the
198  resulting particle list.
199 
200  Parameters:
201  pdgId (int): the lepton pdg code.
202  working_point (str): name of the chosen working point that defines the content of the list. Choose among the above values.
203  method (str): the PID method: 'likelihood' or 'bdt'.
204  classification (str): the type of classifier: 'binary' (one-vs-pion) or 'global' (one-vs-all).
205  lid_weights_gt (str): the name identifier of the global tag with the recommended Data/MC correction weights.
206 
207  .. tip::
208  Please refer to the
209  `Lepton ID Confluence page <https://confluence.desy.de/display/BI/Lepton+ID+Performance>`_
210  for info about the recommended global tags.
211 
212  release (Optional[int]): the major release number of the data and MC campaigns considered.
213  If specified, it ensures the correct :math:`\\ell` ID variables are used.
214 
215  .. tip::
216  Please refer to the
217  `Lepton ID Confluence page <https://confluence.desy.de/display/BI/Lepton+ID+Performance>`_
218  for info about lepton identification variables and campaigns.
219 
220  channel_eff (Optional[str]): the channel used to derive the :math:`\\ell` ID efficiency corrections.
221  By default, 'combination' is set, meaning they are obtained by combining results
222  of several hadronic and low multiplicity channels, wherever they overlap.
223 
224  .. tip::
225  Please refer to the
226  `Lepton ID Confluence page <https://confluence.desy.de/display/BI/Lepton+ID+Performance>`_
227  for other possible choices (if any).
228 
229  channel_misid_pi (Optional[str]): the channel used to derive the :math:`\\pi` fake rate corrections.
230  channel_misid_K (Optional[str]): the channel used to derive the :math:`K` fake rate corrections.
231  inputListName (Optional[str]): the name of a pre-existing ``ParticleList`` object (defined as a full ``decayString``,
232  e.g. 'e-:my_input_electrons') of which the standard lepton list will be a subset.
233  For instance, users might want to apply a Bremsstrahlung correction to electrons first,
234  which modifies their 4-momentum, and only later define the subset passing the PID selection,
235  including the appropriate PID weights and uncertainties (which are :math:`p`-dependent).
236  By default, the standard lepton list is created from all ``Track`` objects in the event.
237 
238  .. warning::
239  Do **not** apply any PID selection on the input list, otherwise results could be biased.
240 
241  outputListLabel (Optional[str]): the name of the output lepton list label, i.e.,
242  the string that follows the particle identifier ('e-:', 'mu-:').
243  By default, it is assigned as:
244  ``'{method}_{classification}_{working_point}'``.
245 
246  trainingModeMulticlass (Optional[``Belle2.ChargedPidMVAWeights.ChargedPidMVATrainingMode``]): enum identifier
247  of the multi-class (global PID) training mode.
248  See `modularAnalysis.applyChargedPidMVA` docs for available options.
249  trainingModeBinary (Optional[``Belle2.ChargedPidMVAWeights.ChargedPidMVATrainingMode``]): enum identifier
250  of the classification (binary PID) training mode.
251  See `modularAnalysis.applyChargedPidMVA` docs for available options.
252  path (basf2.Path): modules are added to this path.
253 
254  Returns:
255  tuple(str, list(str)): the alias for the lepton ID variable, and the list of aliases for the weights.
256  """
257 
258  working_points = (
259  "FixedThresh05",
260  "FixedThresh09",
261  "FixedThresh095",
262  "UniformEff60",
263  "UniformEff70",
264  "UniformEff80",
265  "UniformEff90",
266  "UniformEff95",
267  )
268 
269  available_methods = ("likelihood", "bdt")
270  available_classificators = ("global", "binary")
271 
272  if working_point not in working_points:
273  b2.B2ERROR("The requested lepton list working point is not defined. \
274  Please refer to the stdLep and stdCharged documentation.")
275  return None
276 
277  if method not in available_methods:
278  b2.B2ERROR(f"method: {method}. Must be any of: {available_methods}.")
279  return None
280 
281  if classification not in available_classificators:
282  b2.B2ERROR(f"classification: {classification}. Must be any of: {available_classificators}.")
283  return None
284 
285  b2.B2INFO(f"Prepending GT with LID corrections: {lid_weights_gt}")
286  b2.conditions.prepend_globaltag(lid_weights_gt)
287 
288  # We stick to positive pdgId by convention.
289  # Anyway, the particle list will be filled for anti-particles too.
290  lepton = abs(pdgId)
291  lepton_name = pdg.to_name(lepton)
292  electron = Const.electron.getPDGCode()
293  muon = Const.muon.getPDGCode()
294  pion = Const.pion.getPDGCode()
295 
296  if lepton not in (electron, muon):
297  b2.B2ERROR(f"{pdgId} is not that of a light charged lepton.")
298  return None
299 
300  # Declare LID variables (as in the VariableManager), and aliases to match the naming scheme used in the payloads.
301  pid_variables = {
302  "likelihood": {
303  "global": {
304  "var": {
305  electron: "electronID",
306  muon: "muonID",
307  },
308  "alias": {
309  electron: "electronID",
310  muon: "muonID",
311  }
312  },
313  "binary": {
314  "var": {
315  electron: f"binaryPID({electron}, {pion})",
316  muon: f"binaryPID({muon}, {pion})",
317  },
318  "alias": {
319  electron: "binaryPID_e_pi",
320  muon: "binaryPID_mu_pi",
321  }
322  }
323  },
324  "bdt": {
325  "global": {
326  "var": {
327  lepton: f"pidChargedBDTScore({lepton}, ALL)",
328  },
329  "alias": {
330  lepton: re.sub(r"\W+", "", f"pidChargedBDTScore_{lepton_name}"),
331  }
332  },
333  "binary": {
334  "var": {
335  lepton: f"pidPairChargedBDTScore({lepton}, {pion}, ALL)",
336  },
337  "alias": {
338  lepton: re.sub(r"\W+", "", f"pidPairChargedBDTScore_{lepton_name}_pi"),
339  }
340  }
341  }
342  }
343 
344  # Depending on the release associated to the chosen LID recommendations GT,
345  # some variable names and aliases may need to be reset.
346  if int(release) == 5:
347  if lepton == electron:
348  b2.B2INFO("The likelihood-based electron ID in release 5 samples is defined w/o the SVD and the TOP")
349  pid_variables["likelihood"]["global"]["var"][electron] = "electronID_noSVD_noTOP"
350  pid_variables["likelihood"]["global"]["alias"][electron] = "electronID_noSVD_noTOP"
351  pid_variables["likelihood"]["binary"]["var"][electron] = f"binaryElectronID_noSVD_noTOP({pion})"
352  pid_variables["likelihood"]["binary"]["alias"][electron] = "binaryElectronID_noSVD_noTOP_pi"
353  else:
354  b2.B2INFO("The likelihood-based muon ID in release 5 samples is defined w/o the SVD")
355  pid_variables["likelihood"]["global"]["var"][muon] = "muonID_noSVD"
356  pid_variables["likelihood"]["global"]["alias"][muon] = "muonID_noSVD"
357  pid_variables["likelihood"]["binary"]["var"][muon] = f"binaryPID_noSVD({muon}, {pion})"
358  pid_variables["likelihood"]["binary"]["alias"][muon] = "binaryMuonID_noSVD_pi"
359  if int(release) == 6:
360  if lepton == electron:
361  b2.B2INFO("The likelihood-based electron ID in release 6 samples is defined w/o the TOP")
362  pid_variables["likelihood"]["global"]["var"][electron] = "electronID_noTOP"
363  pid_variables["likelihood"]["global"]["alias"][electron] = "electronID_noTOP"
364  pid_variables["likelihood"]["binary"]["var"][electron] = f"binaryElectronID_noTOP({pion})"
365  pid_variables["likelihood"]["binary"]["alias"][electron] = "binaryElectronID_noTOP_pi"
366 
367  # Create the aliases.
368  pid_var = pid_variables[method][classification]["var"][lepton]
369  pid_alias = pid_variables[method][classification]["alias"][lepton]
370  if pid_alias != pid_var:
371  variables.addAlias(pid_alias, pid_var)
372 
373  # Start creating the particle list, w/o any selection.
374  outputListName = f"{lepton_name}:{method}_{classification}_{working_point}"
375  if outputListLabel is not None:
376  outputListName = f"{lepton_name}:{outputListLabel}"
377 
378  if inputListName is None:
379  ma.fillParticleList(outputListName, "", path=path)
380  else:
381  b2.B2INFO(
382  f"The standard lepton list: '{outputListName}' will be created as a subset \
383  of the following ParticleList: '{inputListName}'")
384  ma.copyList(outputListName, inputListName, path=path)
385 
386  # Here we must run the BDT if requested.
387  if method == "bdt":
388  if classification == "global":
389  ma.applyChargedPidMVA(particleLists=[outputListName],
390  path=path,
391  trainingMode=trainingModeMulticlass)
392  elif classification == "binary":
393  ma.applyChargedPidMVA(particleLists=[outputListName],
394  path=path,
395  binaryHypoPDGCodes=(lepton, pion),
396  trainingMode=trainingModeBinary)
397 
398  # The names of the payloads w/ efficiency and mis-id corrections.
399  payload_eff = f"ParticleReweighting:{pid_alias}_eff_{channel_eff}_{working_point}"
400  payload_misid_pi = f"ParticleReweighting:{pid_alias}_misid_pi_{channel_misid_pi}_{working_point}"
401  payload_misid_K = f"ParticleReweighting:{pid_alias}_misid_K_{channel_misid_K}_{working_point}"
402 
403  # Configure weighting module(s).
404  path.add_module("ParticleWeighting",
405  particleList=outputListName,
406  tableName=payload_eff).set_name(f"ParticleWeighting_eff_{outputListName}")
407  path.add_module("ParticleWeighting",
408  particleList=outputListName,
409  tableName=payload_misid_pi).set_name(f"ParticleWeighting_misid_pi_{outputListName}")
410  if classification == "global":
411  path.add_module("ParticleWeighting",
412  particleList=outputListName,
413  tableName=payload_misid_K).set_name(f"ParticleWeighting_misid_K_{outputListName}")
414 
415  # Apply the PID selection cut, which is read from the efficiency payload.
416  # The '>=' handles extreme cases in which the variable and the threshold value are at a boundary of the PID variable range.
417  cut = f"[{pid_alias} >= extraInfo({payload_eff}_threshold)]"
418  ma.applyCuts(outputListName, cut, path=path)
419 
420  # Define convenience aliases for the nominal weight and up/dn variations.
421  weight_aliases_to_var = {
422  f"weight_{pid_alias}_eff_{working_point}": f"extraInfo({payload_eff}_data_MC_ratio)",
423  f"weight_{pid_alias}_misid_pi_{working_point}": f"extraInfo({payload_misid_pi}_data_MC_ratio)",
424  # These aliases are *absolute* variations.
425  f"weight_{pid_alias}_eff_{working_point}_stat_up": f"extraInfo({payload_eff}_data_MC_uncertainty_stat_up)",
426  f"weight_{pid_alias}_eff_{working_point}_stat_dn": f"extraInfo({payload_eff}_data_MC_uncertainty_stat_dn)",
427  f"weight_{pid_alias}_eff_{working_point}_sys_up": f"extraInfo({payload_eff}_data_MC_uncertainty_sys_up)",
428  f"weight_{pid_alias}_eff_{working_point}_sys_dn": f"extraInfo({payload_eff}_data_MC_uncertainty_sys_dn)",
429  f"weight_{pid_alias}_misid_pi_{working_point}_stat_up": f"extraInfo({payload_misid_pi}_data_MC_uncertainty_stat_up)",
430  f"weight_{pid_alias}_misid_pi_{working_point}_stat_dn": f"extraInfo({payload_misid_pi}_data_MC_uncertainty_stat_dn)",
431  f"weight_{pid_alias}_misid_pi_{working_point}_sys_up": f"extraInfo({payload_misid_pi}_data_MC_uncertainty_sys_up)",
432  f"weight_{pid_alias}_misid_pi_{working_point}_sys_dn": f"extraInfo({payload_misid_pi}_data_MC_uncertainty_sys_dn)",
433  # These aliases are *relative* variations, so they can be multiplied to the nominal
434  # to get the varied weight:
435  #
436  # w_rel_var_up = (1 + w_up/w_nominal)
437  # w_rel_var_dn = (1 - w_dn/w_nominal)
438  #
439  # w_var_up = w_nominal * w_rel_var_up
440  # w_var_dn = w_nominal * w_rel_var_dn
441  f"weight_{pid_alias}_eff_{working_point}_rel_stat_up":
442  f"formula(1+[extraInfo({payload_eff}_data_MC_uncertainty_stat_up)/extraInfo({payload_eff}_data_MC_ratio)])",
443  f"weight_{pid_alias}_eff_{working_point}_rel_stat_dn":
444  f"formula(1-[extraInfo({payload_eff}_data_MC_uncertainty_stat_dn)/extraInfo({payload_eff}_data_MC_ratio)])",
445  f"weight_{pid_alias}_eff_{working_point}_rel_sys_up":
446  f"formula(1+[extraInfo({payload_eff}_data_MC_uncertainty_sys_up)/extraInfo({payload_eff}_data_MC_ratio)])",
447  f"weight_{pid_alias}_eff_{working_point}_rel_sys_dn":
448  f"formula(1-[extraInfo({payload_eff}_data_MC_uncertainty_sys_dn)/extraInfo({payload_eff}_data_MC_ratio)])",
449  f"weight_{pid_alias}_misid_pi_{working_point}_rel_stat_up":
450  f"formula(1+[extraInfo({payload_misid_pi}_data_MC_uncertainty_stat_up)/extraInfo({payload_misid_pi}_data_MC_ratio)])",
451  f"weight_{pid_alias}_misid_pi_{working_point}_rel_stat_dn":
452  f"formula(1-[extraInfo({payload_misid_pi}_data_MC_uncertainty_stat_dn)/extraInfo({payload_misid_pi}_data_MC_ratio)])",
453  f"weight_{pid_alias}_misid_pi_{working_point}_rel_sys_up":
454  f"formula(1+[extraInfo({payload_misid_pi}_data_MC_uncertainty_sys_up)/extraInfo({payload_misid_pi}_data_MC_ratio)])",
455  f"weight_{pid_alias}_misid_pi_{working_point}_rel_sys_dn":
456  f"formula(1-[extraInfo({payload_misid_pi}_data_MC_uncertainty_sys_dn)/extraInfo({payload_misid_pi}_data_MC_ratio)])",
457  }
458  if classification == "global":
459  weight_aliases_to_var.update({
460  f"weight_{pid_alias}_misid_K_{working_point}": f"extraInfo({payload_misid_K}_data_MC_ratio)",
461  #
462  f"weight_{pid_alias}_misid_K_{working_point}_stat_up": f"extraInfo({payload_misid_K}_data_MC_uncertainty_stat_up)",
463  f"weight_{pid_alias}_misid_K_{working_point}_stat_dn": f"extraInfo({payload_misid_K}_data_MC_uncertainty_stat_dn)",
464  f"weight_{pid_alias}_misid_K_{working_point}_sys_up": f"extraInfo({payload_misid_K}_data_MC_uncertainty_sys_up)",
465  f"weight_{pid_alias}_misid_K_{working_point}_sys_dn": f"extraInfo({payload_misid_K}_data_MC_uncertainty_sys_dn)",
466  #
467  f"weight_{pid_alias}_misid_K_{working_point}_rel_stat_up":
468  f"formula(1+[extraInfo({payload_misid_K}_data_MC_uncertainty_stat_up)/extraInfo({payload_misid_K}_data_MC_ratio)])",
469  f"weight_{pid_alias}_misid_K_{working_point}_rel_stat_dn":
470  f"formula(1-[extraInfo({payload_misid_K}_data_MC_uncertainty_stat_dn)/extraInfo({payload_misid_K}_data_MC_ratio)])",
471  f"weight_{pid_alias}_misid_K_{working_point}_rel_sys_up":
472  f"formula(1+[extraInfo({payload_misid_K}_data_MC_uncertainty_sys_up)/extraInfo({payload_misid_K}_data_MC_ratio)])",
473  f"weight_{pid_alias}_misid_K_{working_point}_rel_sys_dn":
474  f"formula(1-[extraInfo({payload_misid_K}_data_MC_uncertainty_sys_dn)/extraInfo({payload_misid_K}_data_MC_ratio)])",
475  })
476 
477  for alias, var in weight_aliases_to_var.items():
478  variables.addAlias(alias, var)
479 
480  return pid_alias, list(weight_aliases_to_var.keys())
481 
482 
483 def stdE(listtype=_defaultlist,
484  method=None,
485  classification=None,
486  lid_weights_gt=None,
487  release=None,
488  channel_eff="combination",
489  channel_misid_pi="combination",
490  channel_misid_K="combination",
491  inputListName=None,
492  outputListLabel=None,
493  trainingModeMulticlass=_TrainingMode.c_Multiclass,
494  trainingModeBinary=_TrainingMode.c_Classification,
495  path=None):
496  """ Function to prepare one of several standardized types of electron lists.
497  See the documentation of `stdLep` for details.
498 
499  It also accepts any of the legacy definitions
500  for the ``listtype`` parameter (aka ``working_point`` in `stdLep`) to fall back to the `stdCharged` behaviour:
501 
502  * 'all'
503  * 'good'
504  * 'loosepid'
505  * 'loose'
506  * 'higheff'
507  * '95eff'
508  * '90eff'
509  * '85eff'
510 
511  Returns:
512  tuple(str, list(str)): the alias for the electron ID variable, and the list of aliases for the weights.
513  """
514 
515  if listtype in _stdnames + _effnames:
516  stdCharged("e", listtype, path)
517  return _pidnames[_chargednames.index("e")], None
518 
519  return stdLep(Const.electron.getPDGCode(), listtype, method, classification, lid_weights_gt,
520  release=release,
521  channel_eff=channel_eff,
522  channel_misid_pi=channel_misid_pi,
523  channel_misid_K=channel_misid_K,
524  inputListName=inputListName,
525  outputListLabel=outputListLabel,
526  trainingModeMulticlass=trainingModeMulticlass,
527  trainingModeBinary=trainingModeBinary,
528  path=path)
529 
530 
531 def stdMu(listtype=_defaultlist,
532  method=None,
533  classification=None,
534  lid_weights_gt=None,
535  release=None,
536  channel_eff="combination",
537  channel_misid_pi="combination",
538  channel_misid_K="combination",
539  inputListName=None,
540  outputListLabel=None,
541  trainingModeMulticlass=_TrainingMode.c_Multiclass,
542  trainingModeBinary=_TrainingMode.c_Classification,
543  path=None):
544  """ Function to prepare one of several standardized types of muon lists.
545  See the documentation of `stdLep` for details.
546 
547  It also accepts any of the legacy definitions
548  for the ``listtype`` parameter (aka ``working_point`` in `stdLep`) to fall back to the `stdCharged` behaviour:
549 
550  * 'all'
551  * 'good'
552  * 'loosepid'
553  * 'loose'
554  * 'higheff'
555  * '95eff'
556  * '90eff'
557  * '85eff'
558 
559  Returns:
560  tuple(str, list(str)): the alias for the muon ID variable, and the list of aliases for the weights.
561  """
562 
563  if listtype in _stdnames + _effnames:
564  stdCharged("mu", listtype, path)
565  return _pidnames[_chargednames.index("mu")], None
566 
567  return stdLep(Const.muon.getPDGCode(), listtype, method, classification, lid_weights_gt,
568  release=release,
569  channel_eff=channel_eff,
570  channel_misid_pi=channel_misid_pi,
571  channel_misid_K=channel_misid_K,
572  inputListName=inputListName,
573  outputListLabel=outputListLabel,
574  trainingModeMulticlass=trainingModeMulticlass,
575  trainingModeBinary=trainingModeBinary,
576  path=path)
577 
578 
579 def stdMostLikely(pidPriors=None, suffix='', custom_cuts='', path=None):
580  """
581  Function to prepare most likely particle lists according to PID likelihood, refer to stdCharged for details
582 
583  @param pidPriors list of 6 float numbers used to reweight PID likelihoods, for e, mu, pi, K, p and d
584  @param suffix string added to the end of particle list names
585  @param custom_cuts custom selection cut string, if empty, standard track quality cuts will be applied
586  @param path modules are added to this path
587  """
588  # Here we need basic track quality cuts to be applied,
589  # otherwise, we get a lot of badly reconstructed particles,
590  # which will end up filled as a random type
591  args = ''
592  if pidPriors is not None:
593  args = str(pidPriors)[1:-1] # remove brackets
594  trackQuality = 'thetaInCDCAcceptance and nCDCHits>20'
595  if custom_cuts != '':
596  trackQuality = custom_cuts
597  for name in _chargednames:
598  ma.fillParticleList(f'{name}+:{_mostLikelyList}{suffix}',
599  f'pidIsMostLikely({args}) > 0 and {trackQuality}', True, path=path)
This class provides a set of constants for the framework.
Definition: Const.h:34
def to_name(pdg)
Definition: pdg.py:86