Belle II Software  light-2212-foldex
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  * 'FixedThresh099', PID cut of > 0.99 for each particle in the list.
180  * 'UniformEff60' 60% lepton efficiency list, uniform in a given multi-dimensional parametrisation.
181  * 'UniformEff70' 70% lepton efficiency list, uniform in a given multi-dimensional parametrisation.
182  * 'UniformEff80' 80% lepton efficiency list, uniform in a given multi-dimensional parametrisation.
183  * 'UniformEff90' 90% lepton efficiency list, uniform in a given multi-dimensional parametrisation.
184  * 'UniformEff95' 95% lepton efficiency list, uniform in a given multi-dimensional parametrisation.
185  * 'UniformPiFR5EM1' 50% pion to lepton fake rate, uniform in a given multi-dimensional parametrisation.
186  * 'UniformPiFR1EM1' 10% pion to lepton fake rate, uniform in a given multi-dimensional parametrisation.
187  * 'UniformPiFR5EM2' 5% pion to lepton fake rate, uniform in a given multi-dimensional parametrisation.
188  * 'UniformPiFR1EM2' 1% pion to lepton fake rate, uniform in a given multi-dimensional parametrisation.
189  * 'UniformPiFR5EM3' 0.5% pion to lepton fake rate, uniform in a given multi-dimensional parametrisation.
190  * 'UniformPiFR1EM3' 0.1% pion to lepton fake rate, uniform in a given multi-dimensional parametrisation.
191 
192  The function creates a ``ParticleList``, selecting particles according to the chosen ``working_point``,
193  and decorates each candidate in the list with the nominal Data/MC :math:`\\ell` ID efficiency and
194  :math:`\\pi,K` fake rate correction factors and their stat, syst uncertainty, reading the info
195  from the Conditions Database (CDB) according to the chosen input global tag (GT).
196 
197  .. note::
198  Particles will **not** be selected if they are outside the Data/MC *efficiency* corrections' phase space coverage
199  for the given working point.
200  In fact, the threshold value for the PID cut in such cases is set to NaN.
201 
202  .. warning::
203  At the moment, the only supported *binary* lepton identification is against the **pion** hypothesis.
204  This implies that, if binary classification is chosen, only :math:`\\pi` fake rate corrections will be added to the
205  resulting particle list.
206 
207  Parameters:
208  pdgId (int): the lepton pdg code.
209  working_point (str): name of the chosen working point that defines the content of the list. Choose among the above values.
210  method (str): the PID method: 'likelihood' or 'bdt'.
211  classification (str): the type of classifier: 'binary' (one-vs-pion) or 'global' (one-vs-all).
212  lid_weights_gt (str): the name identifier of the global tag with the recommended Data/MC correction weights.
213 
214  .. tip::
215  Please refer to the
216  `Lepton ID Confluence page <https://confluence.desy.de/display/BI/Lepton+ID+Performance>`_
217  for info about the recommended global tags.
218 
219  release (Optional[int]): the major release number of the data and MC campaigns considered.
220  If specified, it ensures the correct :math:`\\ell` ID variables are used.
221 
222  .. tip::
223  Please refer to the
224  `Lepton ID Confluence page <https://confluence.desy.de/display/BI/Lepton+ID+Performance>`_
225  for info about lepton identification variables and campaigns.
226 
227  channel_eff (Optional[str]): the channel used to derive the :math:`\\ell` ID efficiency corrections.
228  By default, 'combination' is set, meaning they are obtained by combining results
229  of several hadronic and low multiplicity channels, wherever they overlap.
230 
231  .. tip::
232  Please refer to the
233  `Lepton ID Confluence page <https://confluence.desy.de/display/BI/Lepton+ID+Performance>`_
234  for other possible choices (if any).
235 
236  channel_misid_pi (Optional[str]): the channel used to derive the :math:`\\pi` fake rate corrections.
237  channel_misid_K (Optional[str]): the channel used to derive the :math:`K` fake rate corrections.
238  inputListName (Optional[str]): the name of a pre-existing ``ParticleList`` object (defined as a full ``decayString``,
239  e.g. 'e-:my_input_electrons') of which the standard lepton list will be a subset.
240  For instance, users might want to apply a Bremsstrahlung correction to electrons first,
241  which modifies their 4-momentum, and only later define the subset passing the PID selection,
242  including the appropriate PID weights and uncertainties (which are :math:`p`-dependent).
243  By default, the standard lepton list is created from all ``Track`` objects in the event.
244 
245  .. warning::
246  Do **not** apply any PID selection on the input list, otherwise results could be biased.
247 
248  outputListLabel (Optional[str]): the name of the output lepton list label, i.e.,
249  the string that follows the particle identifier ('e-:', 'mu-:').
250  By default, it is assigned as:
251  ``'{method}_{classification}_{working_point}'``.
252 
253  trainingModeMulticlass (Optional[``Belle2.ChargedPidMVAWeights.ChargedPidMVATrainingMode``]): enum identifier
254  of the multi-class (global PID) training mode.
255  See `modularAnalysis.applyChargedPidMVA` docs for available options.
256  trainingModeBinary (Optional[``Belle2.ChargedPidMVAWeights.ChargedPidMVATrainingMode``]): enum identifier
257  of the classification (binary PID) training mode.
258  See `modularAnalysis.applyChargedPidMVA` docs for available options.
259  path (basf2.Path): modules are added to this path.
260 
261  Returns:
262  tuple(str, list(str)): the alias for the lepton ID variable, and the list of aliases for the weights.
263  """
264 
265  working_points = (
266  "FixedThresh05",
267  "FixedThresh09",
268  "FixedThresh095",
269  "FixedThresh099",
270  "UniformEff60",
271  "UniformEff70",
272  "UniformEff80",
273  "UniformEff90",
274  "UniformEff95",
275  "UniformPiFR5EM1",
276  "UniformPiFR1EM1",
277  "UniformPiFR5EM2",
278  "UniformPiFR1EM2",
279  "UniformPiFR5EM3",
280  "UniformPiFR1EM3",
281  )
282 
283  available_methods = ("likelihood", "bdt")
284  available_classificators = ("global", "binary")
285 
286  if working_point not in working_points:
287  b2.B2ERROR(f"The requested lepton list working point: {working_point} is not defined. \
288  Please refer to the stdLep and stdCharged documentation.")
289  return None
290 
291  if method not in available_methods:
292  b2.B2ERROR(f"method: {method}. Must be any of: {available_methods}.")
293  return None
294 
295  if classification not in available_classificators:
296  b2.B2ERROR(f"classification: {classification}. Must be any of: {available_classificators}.")
297  return None
298 
299  b2.B2INFO(f"Prepending GT with LID corrections: {lid_weights_gt}")
300  b2.conditions.prepend_globaltag(lid_weights_gt)
301 
302  # We stick to positive pdgId by convention.
303  # Anyway, the particle list will be filled for anti-particles too.
304  lepton = abs(pdgId)
305  lepton_name = pdg.to_name(lepton)
306  electron = Const.electron.getPDGCode()
307  muon = Const.muon.getPDGCode()
308  pion = Const.pion.getPDGCode()
309 
310  if lepton not in (electron, muon):
311  b2.B2ERROR(f"{pdgId} is not that of a light charged lepton.")
312  return None
313 
314  # Declare LID variables (as in the VariableManager), and aliases to match the naming scheme used in the payloads.
315  pid_variables = {
316  "likelihood": {
317  "global": {
318  "var": {
319  electron: "electronID",
320  muon: "muonID",
321  },
322  "alias": {
323  electron: "electronID",
324  muon: "muonID",
325  }
326  },
327  "binary": {
328  "var": {
329  electron: f"binaryPID({electron}, {pion})",
330  muon: f"binaryPID({muon}, {pion})",
331  },
332  "alias": {
333  electron: "binaryPID_e_pi",
334  muon: "binaryPID_mu_pi",
335  }
336  }
337  },
338  "bdt": {
339  "global": {
340  "var": {
341  lepton: f"pidChargedBDTScore({lepton}, ALL)",
342  },
343  "alias": {
344  lepton: re.sub(r"\W+", "", f"pidChargedBDTScore_{lepton_name}"),
345  }
346  },
347  "binary": {
348  "var": {
349  lepton: f"pidPairChargedBDTScore({lepton}, {pion}, ALL)",
350  },
351  "alias": {
352  lepton: re.sub(r"\W+", "", f"pidPairChargedBDTScore_{lepton_name}_pi"),
353  }
354  }
355  }
356  }
357 
358  # Depending on the release associated to the chosen LID recommendations GT,
359  # some variable names and aliases may need to be reset.
360  if int(release) in [5, 6]:
361  if lepton == electron:
362  b2.B2INFO(f"The likelihood-based electron ID in release {release} samples is defined w/o the SVD and the TOP")
363  pid_variables["likelihood"]["global"]["var"][electron] = "electronID_noSVD_noTOP"
364  pid_variables["likelihood"]["global"]["alias"][electron] = "electronID_noSVD_noTOP"
365  pid_variables["likelihood"]["binary"]["var"][electron] = f"binaryElectronID_noSVD_noTOP({pion})"
366  pid_variables["likelihood"]["binary"]["alias"][electron] = "binaryElectronID_noSVD_noTOP_pi"
367  else:
368  b2.B2INFO(f"The likelihood-based muon ID in release {release} samples is defined w/o the SVD")
369  pid_variables["likelihood"]["global"]["var"][muon] = "muonID_noSVD"
370  pid_variables["likelihood"]["global"]["alias"][muon] = "muonID_noSVD"
371  pid_variables["likelihood"]["binary"]["var"][muon] = f"binaryPID_noSVD({muon}, {pion})"
372  pid_variables["likelihood"]["binary"]["alias"][muon] = "binaryMuonID_noSVD_pi"
373 
374  # Create the aliases.
375  pid_var = pid_variables[method][classification]["var"][lepton]
376  pid_alias = pid_variables[method][classification]["alias"][lepton]
377  if pid_alias != pid_var:
378  variables.addAlias(pid_alias, pid_var)
379 
380  # Start creating the particle list, w/o any selection.
381  outputListName = f"{lepton_name}:{method}_{classification}_{working_point}"
382  if outputListLabel is not None:
383  outputListName = f"{lepton_name}:{outputListLabel}"
384 
385  if inputListName is None:
386  ma.fillParticleList(outputListName, "", path=path)
387  else:
388  b2.B2INFO(
389  f"The standard lepton list: '{outputListName}' will be created as a subset \
390  of the following ParticleList: '{inputListName}'")
391  ma.copyList(outputListName, inputListName, path=path)
392 
393  # Here we must run the BDT if requested.
394  if method == "bdt":
395  if classification == "global":
396  ma.applyChargedPidMVA(particleLists=[outputListName],
397  path=path,
398  trainingMode=trainingModeMulticlass)
399  elif classification == "binary":
400  ma.applyChargedPidMVA(particleLists=[outputListName],
401  path=path,
402  binaryHypoPDGCodes=(lepton, pion),
403  trainingMode=trainingModeBinary)
404 
405  # The names of the payloads w/ efficiency and mis-id corrections.
406  payload_eff = f"ParticleReweighting:{pid_alias}_eff_{channel_eff}_{working_point}"
407  payload_misid_pi = f"ParticleReweighting:{pid_alias}_misid_pi_{channel_misid_pi}_{working_point}"
408  payload_misid_K = f"ParticleReweighting:{pid_alias}_misid_K_{channel_misid_K}_{working_point}"
409 
410  # Configure weighting module(s).
411  path.add_module("ParticleWeighting",
412  particleList=outputListName,
413  tableName=payload_eff).set_name(f"ParticleWeighting_eff_{outputListName}")
414  path.add_module("ParticleWeighting",
415  particleList=outputListName,
416  tableName=payload_misid_pi).set_name(f"ParticleWeighting_misid_pi_{outputListName}")
417  if classification == "global":
418  path.add_module("ParticleWeighting",
419  particleList=outputListName,
420  tableName=payload_misid_K).set_name(f"ParticleWeighting_misid_K_{outputListName}")
421 
422  # Apply the PID selection cut, which is read from the efficiency payload.
423  # The '>=' handles extreme cases in which the variable and the threshold value are at a boundary of the PID variable range.
424  cut = f"[{pid_alias} >= extraInfo({payload_eff}_threshold)]"
425  ma.applyCuts(outputListName, cut, path=path)
426 
427  # Define convenience aliases for the nominal weight and up/dn variations.
428  weight_aliases_to_var = {
429  f"weight_{pid_alias}_eff_{working_point}": f"extraInfo({payload_eff}_data_MC_ratio)",
430  f"weight_{pid_alias}_misid_pi_{working_point}": f"extraInfo({payload_misid_pi}_data_MC_ratio)",
431  # These aliases are *absolute* variations.
432  f"weight_{pid_alias}_eff_{working_point}_stat_up": f"extraInfo({payload_eff}_data_MC_uncertainty_stat_up)",
433  f"weight_{pid_alias}_eff_{working_point}_stat_dn": f"extraInfo({payload_eff}_data_MC_uncertainty_stat_dn)",
434  f"weight_{pid_alias}_eff_{working_point}_sys_up": f"extraInfo({payload_eff}_data_MC_uncertainty_sys_up)",
435  f"weight_{pid_alias}_eff_{working_point}_sys_dn": f"extraInfo({payload_eff}_data_MC_uncertainty_sys_dn)",
436  f"weight_{pid_alias}_misid_pi_{working_point}_stat_up": f"extraInfo({payload_misid_pi}_data_MC_uncertainty_stat_up)",
437  f"weight_{pid_alias}_misid_pi_{working_point}_stat_dn": f"extraInfo({payload_misid_pi}_data_MC_uncertainty_stat_dn)",
438  f"weight_{pid_alias}_misid_pi_{working_point}_sys_up": f"extraInfo({payload_misid_pi}_data_MC_uncertainty_sys_up)",
439  f"weight_{pid_alias}_misid_pi_{working_point}_sys_dn": f"extraInfo({payload_misid_pi}_data_MC_uncertainty_sys_dn)",
440  # These aliases are *relative* variations, so they can be multiplied to the nominal
441  # to get the varied weight:
442  #
443  # w_rel_var_up = (1 + w_up/w_nominal)
444  # w_rel_var_dn = (1 - w_dn/w_nominal)
445  #
446  # w_var_up = w_nominal * w_rel_var_up
447  # w_var_dn = w_nominal * w_rel_var_dn
448  f"weight_{pid_alias}_eff_{working_point}_rel_stat_up":
449  f"formula(1+[extraInfo({payload_eff}_data_MC_uncertainty_stat_up)/extraInfo({payload_eff}_data_MC_ratio)])",
450  f"weight_{pid_alias}_eff_{working_point}_rel_stat_dn":
451  f"formula(1-[extraInfo({payload_eff}_data_MC_uncertainty_stat_dn)/extraInfo({payload_eff}_data_MC_ratio)])",
452  f"weight_{pid_alias}_eff_{working_point}_rel_sys_up":
453  f"formula(1+[extraInfo({payload_eff}_data_MC_uncertainty_sys_up)/extraInfo({payload_eff}_data_MC_ratio)])",
454  f"weight_{pid_alias}_eff_{working_point}_rel_sys_dn":
455  f"formula(1-[extraInfo({payload_eff}_data_MC_uncertainty_sys_dn)/extraInfo({payload_eff}_data_MC_ratio)])",
456  f"weight_{pid_alias}_misid_pi_{working_point}_rel_stat_up":
457  f"formula(1+[extraInfo({payload_misid_pi}_data_MC_uncertainty_stat_up)/extraInfo({payload_misid_pi}_data_MC_ratio)])",
458  f"weight_{pid_alias}_misid_pi_{working_point}_rel_stat_dn":
459  f"formula(1-[extraInfo({payload_misid_pi}_data_MC_uncertainty_stat_dn)/extraInfo({payload_misid_pi}_data_MC_ratio)])",
460  f"weight_{pid_alias}_misid_pi_{working_point}_rel_sys_up":
461  f"formula(1+[extraInfo({payload_misid_pi}_data_MC_uncertainty_sys_up)/extraInfo({payload_misid_pi}_data_MC_ratio)])",
462  f"weight_{pid_alias}_misid_pi_{working_point}_rel_sys_dn":
463  f"formula(1-[extraInfo({payload_misid_pi}_data_MC_uncertainty_sys_dn)/extraInfo({payload_misid_pi}_data_MC_ratio)])",
464  }
465  if classification == "global":
466  weight_aliases_to_var.update({
467  f"weight_{pid_alias}_misid_K_{working_point}": f"extraInfo({payload_misid_K}_data_MC_ratio)",
468  #
469  f"weight_{pid_alias}_misid_K_{working_point}_stat_up": f"extraInfo({payload_misid_K}_data_MC_uncertainty_stat_up)",
470  f"weight_{pid_alias}_misid_K_{working_point}_stat_dn": f"extraInfo({payload_misid_K}_data_MC_uncertainty_stat_dn)",
471  f"weight_{pid_alias}_misid_K_{working_point}_sys_up": f"extraInfo({payload_misid_K}_data_MC_uncertainty_sys_up)",
472  f"weight_{pid_alias}_misid_K_{working_point}_sys_dn": f"extraInfo({payload_misid_K}_data_MC_uncertainty_sys_dn)",
473  #
474  f"weight_{pid_alias}_misid_K_{working_point}_rel_stat_up":
475  f"formula(1+[extraInfo({payload_misid_K}_data_MC_uncertainty_stat_up)/extraInfo({payload_misid_K}_data_MC_ratio)])",
476  f"weight_{pid_alias}_misid_K_{working_point}_rel_stat_dn":
477  f"formula(1-[extraInfo({payload_misid_K}_data_MC_uncertainty_stat_dn)/extraInfo({payload_misid_K}_data_MC_ratio)])",
478  f"weight_{pid_alias}_misid_K_{working_point}_rel_sys_up":
479  f"formula(1+[extraInfo({payload_misid_K}_data_MC_uncertainty_sys_up)/extraInfo({payload_misid_K}_data_MC_ratio)])",
480  f"weight_{pid_alias}_misid_K_{working_point}_rel_sys_dn":
481  f"formula(1-[extraInfo({payload_misid_K}_data_MC_uncertainty_sys_dn)/extraInfo({payload_misid_K}_data_MC_ratio)])",
482  })
483 
484  for alias, var in weight_aliases_to_var.items():
485  variables.addAlias(alias, var)
486 
487  return pid_alias, list(weight_aliases_to_var.keys())
488 
489 
490 def stdE(listtype=_defaultlist,
491  method=None,
492  classification=None,
493  lid_weights_gt=None,
494  release=None,
495  channel_eff="combination",
496  channel_misid_pi="combination",
497  channel_misid_K="combination",
498  inputListName=None,
499  outputListLabel=None,
500  trainingModeMulticlass=_TrainingMode.c_Multiclass,
501  trainingModeBinary=_TrainingMode.c_Classification,
502  path=None):
503  """ Function to prepare one of several standardized types of electron lists.
504  See the documentation of `stdLep` for details.
505 
506  It also accepts any of the legacy definitions
507  for the ``listtype`` parameter (aka ``working_point`` in `stdLep`) to fall back to the `stdCharged` behaviour:
508 
509  * 'all'
510  * 'good'
511  * 'loosepid'
512  * 'loose'
513  * 'higheff'
514  * '95eff'
515  * '90eff'
516  * '85eff'
517 
518  Returns:
519  tuple(str, list(str)): the alias for the electron ID variable, and the list of aliases for the weights.
520  """
521 
522  if listtype in _stdnames + _effnames:
523  stdCharged("e", listtype, path)
524  return _pidnames[_chargednames.index("e")], None
525 
526  return stdLep(Const.electron.getPDGCode(), listtype, method, classification, lid_weights_gt,
527  release=release,
528  channel_eff=channel_eff,
529  channel_misid_pi=channel_misid_pi,
530  channel_misid_K=channel_misid_K,
531  inputListName=inputListName,
532  outputListLabel=outputListLabel,
533  trainingModeMulticlass=trainingModeMulticlass,
534  trainingModeBinary=trainingModeBinary,
535  path=path)
536 
537 
538 def stdMu(listtype=_defaultlist,
539  method=None,
540  classification=None,
541  lid_weights_gt=None,
542  release=None,
543  channel_eff="combination",
544  channel_misid_pi="combination",
545  channel_misid_K="combination",
546  inputListName=None,
547  outputListLabel=None,
548  trainingModeMulticlass=_TrainingMode.c_Multiclass,
549  trainingModeBinary=_TrainingMode.c_Classification,
550  path=None):
551  """ Function to prepare one of several standardized types of muon lists.
552  See the documentation of `stdLep` for details.
553 
554  It also accepts any of the legacy definitions
555  for the ``listtype`` parameter (aka ``working_point`` in `stdLep`) to fall back to the `stdCharged` behaviour:
556 
557  * 'all'
558  * 'good'
559  * 'loosepid'
560  * 'loose'
561  * 'higheff'
562  * '95eff'
563  * '90eff'
564  * '85eff'
565 
566  Returns:
567  tuple(str, list(str)): the alias for the muon ID variable, and the list of aliases for the weights.
568  """
569 
570  if listtype in _stdnames + _effnames:
571  stdCharged("mu", listtype, path)
572  return _pidnames[_chargednames.index("mu")], None
573 
574  return stdLep(Const.muon.getPDGCode(), listtype, method, classification, lid_weights_gt,
575  release=release,
576  channel_eff=channel_eff,
577  channel_misid_pi=channel_misid_pi,
578  channel_misid_K=channel_misid_K,
579  inputListName=inputListName,
580  outputListLabel=outputListLabel,
581  trainingModeMulticlass=trainingModeMulticlass,
582  trainingModeBinary=trainingModeBinary,
583  path=path)
584 
585 
586 def stdMostLikely(pidPriors=None, suffix='', custom_cuts='', path=None):
587  """
588  Function to prepare most likely particle lists according to PID likelihood, refer to stdCharged for details
589 
590  @param pidPriors list of 6 float numbers used to reweight PID likelihoods, for e, mu, pi, K, p and d
591  @param suffix string added to the end of particle list names
592  @param custom_cuts custom selection cut string, if empty, standard track quality cuts will be applied
593  @param path modules are added to this path
594  """
595  # Here we need basic track quality cuts to be applied,
596  # otherwise, we get a lot of badly reconstructed particles,
597  # which will end up filled as a random type
598  args = ''
599  if pidPriors is not None:
600  args = str(pidPriors)[1:-1] # remove brackets
601  trackQuality = 'thetaInCDCAcceptance and nCDCHits>20'
602  if custom_cuts != '':
603  trackQuality = custom_cuts
604  for name in _chargednames:
605  ma.fillParticleList(f'{name}+:{_mostLikelyList}{suffix}',
606  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