14 import modularAnalysis
as ma
17 from ROOT
import Belle2
21 _chargednames = [
'pi',
'K',
'p',
'e',
'mu']
22 _pidnames = [
'pionID',
'kaonID',
'protonID',
'electronID',
'muonID']
23 _stdnames = [
'all',
'loose',
'loosepid',
'good',
'higheff']
24 _effnames = [
'95eff',
'90eff',
'85eff']
27 _mostLikelyList =
'mostlikely'
30 def _stdChargedEffCuts(particletype, listtype):
32 Provides the PID cut corresponding to a given efficiency percentile
34 @param particletype type of charged particle (pi, K, p, e, mu)
35 @param listtype efficiency percentile for the list (95eff, 90eff, 85eff)
38 particleindex = _chargednames.index(particletype)
39 effindex = _effnames.index(listtype)
42 effcuts = [[0.001, 0.019, 0.098],
44 [0.000, 0.043, 0.251],
45 [0.093, 0.301, 0.709],
46 [0.187, 0.418, 0.909]]
48 return effcuts[particleindex][effindex]
53 Function to prepare one of several standardized types of charged particle lists:
54 - 'all' with no cuts on track
55 - 'good' high purity lists for data studies
56 - 'loosepid' loose selections for skimming, PID cut only
57 - 'loose' loose selections for skimming
58 - 'higheff' high efficiency list with loose global ID cut for data studies
59 - 'mostlikely' list with the highest PID likelihood
60 Also the following lists, which may or may not be available depending on the release
61 - '99eff' with 99% selection efficiency (calculated for 1<p<4 GeV) and good track (MC only)
62 - '95eff' with 95% selection efficiency (calculated for 1<p<4 GeV) and good track (MC only)
63 - '90eff' with 90% selection efficiency (calculated for 1<p<4 GeV) and good track (MC only)
64 - '85eff' with 85% selection efficiency (calculated for 1<p<4 GeV) and good track (MC only)
66 @param particletype type of charged particle to make a list of
67 @param listtype name of standard list
68 @param path modules are added to this path
72 trackQuality =
'thetaInCDCAcceptance and nCDCHits>20'
73 ipCut =
'dr < 0.5 and abs(dz) < 2'
74 goodTrack = trackQuality +
' and ' + ipCut
76 if particletype
not in _chargednames:
77 b2.B2ERROR(
"The requested list is not a standard charged particle. Use one of pi, K, e, mu, p.")
80 ma.fillParticleList(particletype +
'+:all',
'',
True, path=path)
81 elif listtype ==
'good':
83 particletype +
'+:good',
84 _pidnames[_chargednames.index(particletype)] +
' > 0.5 and ' + goodTrack,
87 elif listtype ==
'loose':
89 particletype +
'+:loose',
90 _pidnames[_chargednames.index(particletype)] +
' > 0.1 and ' + goodTrack,
93 elif listtype ==
'loosepid':
95 particletype +
'+:loosepid',
96 _pidnames[_chargednames.index(particletype)] +
' > 0.1',
99 elif listtype ==
'higheff':
101 particletype +
'+:higheff',
102 _pidnames[_chargednames.index(particletype)] +
' > 0.002 and ' + goodTrack,
105 elif listtype
not in _effnames:
106 b2.B2ERROR(
"The requested list is not defined. Please refer to the stdCharged documentation.")
108 pidcut = _stdChargedEffCuts(particletype, listtype)
109 if 0.0 < pidcut < 1.0:
114 _pidnames[_chargednames.index(particletype)] +
122 b2.B2ERROR(
'The requested standard particle list ' + particletype +
123 '+:' + listtype +
' is not available in this release.')
126 def stdPi(listtype=_defaultlist, path=None):
128 Function to prepare standard pion lists, refer to `stdCharged` for details
130 @param listtype name of standard list
131 @param path modules are added to this path
136 def stdK(listtype=_defaultlist, path=None):
138 Function to prepare standard kaon lists, refer to `stdCharged` for details
140 @param listtype name of standard list
141 @param path modules are added to this path
146 def stdPr(listtype=_defaultlist, path=None):
148 Function to prepare standard proton lists, refer to `stdCharged` for details
150 @param listtype name of standard list
151 @param path modules are added to this path
156 def stdLep(pdgId, listtype, method, classification, path=None):
158 Function to prepare one of several standardized types of lepton (:math:`e,\\mu`) lists:
160 * 'UniformEff60' 60% lepton efficiency list, uniform in a given multi-dimensional parametrisation.
161 * 'UniformEff70' 70% lepton efficiency list, uniform in a given multi-dimensional parametrisation.
162 * 'UniformEff80' 80% lepton efficiency list, uniform in a given multi-dimensional parametrisation.
163 * 'UniformEff90' 90% lepton efficiency list, uniform in a given multi-dimensional parametrisation.
164 * 'UniformEff95' 95% lepton efficiency list, uniform in a given multi-dimensional parametrisation.
167 The function will select particles according to the chosen ``listtype``, and decorate each candidate
168 with the nominal Data/MC :math:`\\ell` ID efficiency and :math:`\\pi,K` fake rate
169 correction factors and their stat, syst uncertainty, reading the info from the Conditions Database.
172 pdgId (int): the lepton pdg code.
173 listtype (str): name of standard list. Choose among the above values.
174 method (str): the PID method: 'likelihood' or 'bdt'.
175 classification (str): the type of classifier: 'binary' (one-vs-pion) or 'global' (one-vs-all).
176 path (basf2.Path): modules are added to this path.
179 std_lepton_list_names = (
187 available_methods = (
"likelihood",
"bdt")
188 available_classificators = (
"global",
"binary")
194 if listtype
not in std_lepton_list_names:
195 b2.B2ERROR(
"The requested lepton list is not defined. Please refer to the stdLep and stdCharged documentation.")
198 if pdgId
not in (Const.electron.getPDGCode(), Const.muon.getPDGCode()):
199 b2.B2ERROR(f
"{pdgId} is not that of a light charged lepton.")
202 if method
not in available_methods:
203 b2.B2ERROR(f
"method: {method}. Must be any of: {available_methods}.")
205 if classification
not in available_classificators:
206 b2.B2ERROR(f
"classification: {classification}. Must be any of: {available_classificators}.")
212 "global":
"electronID_noTOP" if pdgId == Const.electron.getPDGCode()
else "muonID",
214 "binary": f
"binaryPID_noTOP({pdgId}, {Const.pion.getPDGCode()})" if pdgId == Const.electron.getPDGCode() \
215 else f
"binaryPID({pdgId}, {Const.pion.getPDGCode()})"
218 "global": f
"pidChargedBDTScore({pdgId}, ALL)",
219 "binary": f
"pidPairChargedBDTScore({pdgId}, 211, ALL)"
224 plistname = f
"{pdg.to_name(pdgId)}:{listtype}"
225 ma.fillParticleList(plistname,
"", path=path)
228 pid_var = pid_variables[method][classification]
232 pid_var_stripped = re.sub(
r"[\W]+",
"_", pid_var).rstrip(
"_")
235 payload_eff = f
"ParticleReweighting:{pid_var_stripped}_eff_combination_{listtype}"
236 payload_misid_pi = f
"ParticleReweighting:{pid_var_stripped}_misid_pi_combination_{listtype}"
237 payload_misid_K = f
"ParticleReweighting:{pid_var_stripped}_misid_K_combination_{listtype}"
240 reweighter_eff = path.add_module(
"ParticleWeighting",
241 particleList=plistname,
242 tableName=payload_eff).set_name(f
"ParticleWeighting_eff_{plistname}")
243 reweighter_misid_pi = path.add_module(
"ParticleWeighting",
244 particleList=plistname,
245 tableName=payload_misid_pi).set_name(f
"ParticleWeighting_misid_pi_{plistname}")
246 reweighter_misid_K = path.add_module(
"ParticleWeighting",
247 particleList=plistname,
248 tableName=payload_misid_K).set_name(f
"ParticleWeighting_misid_K_{plistname}")
251 cut = f
"{pid_var} > extraInfo({payload_eff}_threshold)"
252 ma.applyCuts(plistname, cut, path=path)
255 def stdE(listtype=_defaultlist, method=None, classification=None, path=None):
256 """ Function to prepare one of several standardized types of electron lists.
257 See the documentation of `stdLep` for details.
259 It also accepts any of the legacy definitions
260 for the ``listtype`` parameter to fall back to the `stdCharged` behaviour:
272 if listtype
in _stdnames + _effnames:
276 stdLep(Const.electron.getPDGCode(), listtype, method, classification, path=path)
279 def stdMu(listtype=_defaultlist, method=None, classification=None, path=None):
280 """ Function to prepare one of several standardized types of muon lists.
281 See the documentation of `stdLep` for details.
283 It also accepts any of the legacy definitions
284 for the ``listtype`` parameter to fall back to the `stdCharged` behaviour:
296 if listtype
in _stdnames + _effnames:
300 stdLep(Const.muon.getPDGCode(), listtype, method, classification, path=path)
303 def stdMostLikely(pidPriors=None, suffix='', custom_cuts='', path=None):
305 Function to prepare most likely particle lists according to PID likelihood, refer to stdCharged for details
307 @param pidPriors list of 6 float numbers used to reweight PID likelihoods
308 @param suffix string added to the end of particle list names
309 @param custom_cuts custom selection cut string, if empty, standard track quality cuts will be applied
310 @param path modules are added to this path
316 if pidPriors
is not None:
317 args = str(pidPriors)[1:-1]
318 trackQuality =
'thetaInCDCAcceptance and nCDCHits>20'
319 if custom_cuts !=
'':
320 trackQuality = custom_cuts
321 for name
in _chargednames:
322 ma.fillParticleList(f
'{name}+:{_mostLikelyList}{suffix}',
323 f
'pidIsMostLikely({args}) > 0 and {trackQuality}',
True, path=path)
This class provides a set of constants for the framework.