10 #include <analysis/variables/PIDVariables.h>
12 #include <analysis/VariableManager/Manager.h>
14 #include <mdst/dataobjects/PIDLikelihood.h>
17 #include <framework/logging/Logger.h>
18 #include <framework/utilities/Conversion.h>
19 #include <framework/gearbox/Const.h>
21 #include <boost/algorithm/string.hpp>
43 Const::ChargedStable hypothesisConversion(
const int hypothesis)
47 return Const::electron;
62 Const::PIDDetectorSet parseDetectors(
const std::vector<std::string>& arguments)
64 Const::PIDDetectorSet result;
65 for (std::string val : arguments) {
67 if (val ==
"all")
return Const::PIDDetectors::set();
68 else if (val ==
"svd") result += Const::SVD;
69 else if (val ==
"cdc") result += Const::CDC;
70 else if (val ==
"top") result += Const::TOP;
71 else if (val ==
"arich") result += Const::ARICH;
72 else if (val ==
"ecl") result += Const::ECL;
73 else if (val ==
"klm") result += Const::KLM;
74 else B2ERROR(
"Unknown detector component: " << val);
80 Const::PIDDetectorSet parseDetectorsChargedBDT(
const std::vector<std::string>& arguments)
82 Const::PIDDetectorSet result;
83 for (std::string val : arguments) {
85 if (val ==
"all")
return Const::PIDDetectors::set();
86 else if (val ==
"ecl") result += Const::ECL;
87 else B2ERROR(
"Invalid detector component: " << val <<
" for charged BDT.");
98 double particleID(
const Particle* p)
100 int pdg = abs(p->getPDGCode());
101 if (pdg == Const::electron.getPDGCode())
return electronID(p);
102 else if (pdg == Const::muon.getPDGCode())
return muonID(p);
103 else if (pdg == Const::pion.getPDGCode())
return pionID(p);
104 else if (pdg == Const::kaon.getPDGCode())
return kaonID(p);
105 else if (pdg == Const::proton.getPDGCode())
return protonID(p);
106 else if (pdg == Const::deuteron.getPDGCode())
return deuteronID(p);
107 else return std::numeric_limits<float>::quiet_NaN();
110 Manager::FunctionPtr pidLogLikelihoodValueExpert(
const std::vector<std::string>& arguments)
112 if (arguments.size() < 2) {
113 B2ERROR(
"Need at least two arguments to pidLogLikelihoodValueExpert");
118 pdgCode = Belle2::convertString<int>(arguments[0]);
119 }
catch (std::invalid_argument& e) {
120 B2ERROR(
"First argument of pidLogLikelihoodValueExpert must be a PDG code");
123 std::vector<std::string> detectors(arguments.begin() + 1, arguments.end());
125 Const::PIDDetectorSet detectorSet = parseDetectors(detectors);
126 auto hypType = Const::ChargedStable(abs(pdgCode));
128 auto func = [hypType, detectorSet](
const Particle * part) ->
double {
129 const PIDLikelihood* pid = part->getPIDLikelihood();
131 return std::numeric_limits<float>::quiet_NaN();
133 if (pid->getLogL(hypType, detectorSet) == 0)
134 return std::numeric_limits<float>::quiet_NaN();
136 return pid->getLogL(hypType, detectorSet);
143 Manager::FunctionPtr pidDeltaLogLikelihoodValueExpert(
const std::vector<std::string>& arguments)
145 if (arguments.size() < 3) {
146 B2ERROR(
"Need at least three arguments to pidDeltaLogLikelihoodValueExpert");
149 int pdgCodeHyp, pdgCodeTest;
151 pdgCodeHyp = Belle2::convertString<int>(arguments[0]);
152 }
catch (std::invalid_argument& e) {
153 B2ERROR(
"First argument of pidDeltaLogLikelihoodValueExpert must be a PDG code");
157 pdgCodeTest = Belle2::convertString<int>(arguments[1]);
158 }
catch (std::invalid_argument& e) {
159 B2ERROR(
"Second argument of pidDeltaLogLikelihoodValueExpert must be a PDG code");
163 std::vector<std::string> detectors(arguments.begin() + 2, arguments.end());
164 Const::PIDDetectorSet detectorSet = parseDetectors(detectors);
165 auto hypType = Const::ChargedStable(abs(pdgCodeHyp));
166 auto testType = Const::ChargedStable(abs(pdgCodeTest));
168 auto func = [hypType, testType, detectorSet](
const Particle * part) ->
double {
169 const PIDLikelihood* pid = part->getPIDLikelihood();
170 if (!pid)
return std::numeric_limits<float>::quiet_NaN();
172 if (pid->getLogL(hypType, detectorSet) == 0)
173 return std::numeric_limits<float>::quiet_NaN();
175 return (pid->getLogL(hypType, detectorSet) - pid->getLogL(testType, detectorSet));
181 Manager::FunctionPtr pidPairProbabilityExpert(
const std::vector<std::string>& arguments)
183 if (arguments.size() < 3) {
184 B2ERROR(
"Need at least three arguments to pidPairProbabilityExpert");
187 int pdgCodeHyp = 0, pdgCodeTest = 0;
189 pdgCodeHyp = Belle2::convertString<int>(arguments[0]);
190 }
catch (std::invalid_argument& e) {
191 B2ERROR(
"First argument of pidPairProbabilityExpert must be PDG code");
195 pdgCodeTest = Belle2::convertString<int>(arguments[1]);
196 }
catch (std::invalid_argument& e) {
197 B2ERROR(
"Second argument of pidPairProbabilityExpert must be PDG code");
201 std::vector<std::string> detectors(arguments.begin() + 2, arguments.end());
203 Const::PIDDetectorSet detectorSet = parseDetectors(detectors);
204 auto hypType = Const::ChargedStable(abs(pdgCodeHyp));
205 auto testType = Const::ChargedStable(abs(pdgCodeTest));
206 auto func = [hypType, testType, detectorSet](
const Particle * part) ->
double {
207 const PIDLikelihood* pid = part->getPIDLikelihood();
208 if (!pid)
return std::numeric_limits<float>::quiet_NaN();
210 if (pid->getLogL(hypType, detectorSet) == 0)
211 return std::numeric_limits<float>::quiet_NaN();
213 return pid->getProbability(hypType, testType, detectorSet);
219 Manager::FunctionPtr pidProbabilityExpert(
const std::vector<std::string>& arguments)
221 if (arguments.size() < 2) {
222 B2ERROR(
"Need at least two arguments for pidProbabilityExpert");
227 pdgCodeHyp = Belle2::convertString<int>(arguments[0]);
228 }
catch (std::invalid_argument& e) {
229 B2ERROR(
"First argument of pidProbabilityExpert must be PDG code");
233 std::vector<std::string> detectors(arguments.begin() + 1, arguments.end());
234 Const::PIDDetectorSet detectorSet = parseDetectors(detectors);
235 auto hypType = Const::ChargedStable(abs(pdgCodeHyp));
238 const unsigned int n = Const::ChargedStable::c_SetSize;
240 for (
double& i : frac) i = 1.0;
242 auto func = [hypType, frac, detectorSet](
const Particle * part) ->
double {
243 const PIDLikelihood* pid = part->getPIDLikelihood();
244 if (!pid)
return std::numeric_limits<float>::quiet_NaN();
246 if (pid->getLogL(hypType, detectorSet) == 0)
247 return std::numeric_limits<float>::quiet_NaN();
249 return pid->getProbability(hypType, frac, detectorSet);
255 Manager::FunctionPtr pidMissingProbabilityExpert(
const std::vector<std::string>& arguments)
257 if (arguments.size() < 1) {
258 B2ERROR(
"Need at least one argument to pidMissingProbabilityExpert");
262 std::vector<std::string> detectors(arguments.begin(), arguments.end());
263 Const::PIDDetectorSet detectorSet = parseDetectors(detectors);
265 auto func = [detectorSet](
const Particle * part) ->
double {
266 const PIDLikelihood* pid = part->getPIDLikelihood();
267 if (!pid)
return std::numeric_limits<double>::quiet_NaN();
268 if (not pid->isAvailable(detectorSet))
275 double electronID(
const Particle* part)
277 return Manager::Instance().getVariable(
"pidProbabilityExpert(11, ALL)")->function(part);
280 double muonID(
const Particle* part)
282 return Manager::Instance().getVariable(
"pidProbabilityExpert(13, ALL)")->function(part);
285 double pionID(
const Particle* part)
287 return Manager::Instance().getVariable(
"pidProbabilityExpert(211, ALL)")->function(part);
290 double kaonID(
const Particle* part)
292 return Manager::Instance().getVariable(
"pidProbabilityExpert(321, ALL)")->function(part);
295 double protonID(
const Particle* part)
297 return Manager::Instance().getVariable(
"pidProbabilityExpert(2212, ALL)")->function(part);
300 double deuteronID(
const Particle* part)
302 return Manager::Instance().getVariable(
"pidProbabilityExpert(1000010020, ALL)")->function(part);
305 double binaryPID(
const Particle* part,
const std::vector<double>& arguments)
307 if (arguments.size() != 2) {
308 B2ERROR(
"The variable binaryPID needs exactly two arguments: the PDG codes of two hypotheses.");
309 return std::numeric_limits<float>::quiet_NaN();;
311 int pdgCodeHyp = std::abs(
int(std::lround(arguments[0])));
312 int pdgCodeTest = std::abs(
int(std::lround(arguments[1])));
313 return Manager::Instance().getVariable(
"pidPairProbabilityExpert(" + std::to_string(pdgCodeHyp) +
", " + std::to_string(
314 pdgCodeTest) +
", ALL)")->function(part);
317 double electronID_noSVD(
const Particle* part)
320 return Manager::Instance().getVariable(
"pidProbabilityExpert(11, CDC, TOP, ARICH, ECL, KLM)")->function(part);
323 double muonID_noSVD(
const Particle* part)
326 return Manager::Instance().getVariable(
"pidProbabilityExpert(13, CDC, TOP, ARICH, ECL, KLM)")->function(part);
329 double pionID_noSVD(
const Particle* part)
332 return Manager::Instance().getVariable(
"pidProbabilityExpert(211, CDC, TOP, ARICH, ECL, KLM)")->function(part);
335 double kaonID_noSVD(
const Particle* part)
338 return Manager::Instance().getVariable(
"pidProbabilityExpert(321, CDC, TOP, ARICH, ECL, KLM)")->function(part);
341 double protonID_noSVD(
const Particle* part)
344 return Manager::Instance().getVariable(
"pidProbabilityExpert(2212, CDC, TOP, ARICH, ECL, KLM)")->function(part);
347 double deuteronID_noSVD(
const Particle* part)
350 return Manager::Instance().getVariable(
"pidProbabilityExpert(1000010020, CDC, TOP, ARICH, ECL, KLM)")->function(part);
353 double binaryPID_noSVD(
const Particle* part,
const std::vector<double>& arguments)
356 if (arguments.size() != 2) {
357 B2ERROR(
"The variable binaryPID_noSVD needs exactly two arguments: the PDG codes of two hypotheses.");
358 return std::numeric_limits<float>::quiet_NaN();;
360 int pdgCodeHyp = std::abs(
int(std::lround(arguments[0])));
361 int pdgCodeTest = std::abs(
int(std::lround(arguments[1])));
362 return Manager::Instance().getVariable(
"pidPairProbabilityExpert(" + std::to_string(pdgCodeHyp) +
", " + std::to_string(
363 pdgCodeTest) +
", CDC, TOP, ARICH, ECL, KLM)")->function(part);
366 double electronID_noTOP(
const Particle* part)
369 return Manager::Instance().getVariable(
"pidProbabilityExpert(11, CDC, SVD, ARICH, ECL, KLM)")->function(part);
372 double antineutronID(
const Particle* particle)
374 if (particle->hasExtraInfo(
"nbarID")) {
375 return particle->getExtraInfo(
"nbarID");
377 if (particle->getPDGCode() == -Const::neutron.getPDGCode()) {
378 B2WARNING(
"The extraInfo nbarID is not registered! \n"
379 "Please use function getNbarIDMVA in modularAnalysis.");
381 return std::numeric_limits<float>::quiet_NaN();
385 Manager::FunctionPtr pidChargedBDTScore(
const std::vector<std::string>& arguments)
387 if (arguments.size() != 2) {
388 B2ERROR(
"Need exactly two arguments for pidChargedBDTScore: pdgCodeHyp, detector");
394 hypPdgId = Belle2::convertString<int>(arguments.at(0));
395 }
catch (std::invalid_argument& e) {
396 B2ERROR(
"First argument of pidChargedBDTScore must be an integer (PDG code).");
399 Const::ChargedStable hypType = Const::ChargedStable(hypPdgId);
401 std::vector<std::string> detectors(arguments.begin() + 1, arguments.end());
402 Const::PIDDetectorSet detectorSet = parseDetectorsChargedBDT(detectors);
404 auto func = [hypType, detectorSet](
const Particle * part) ->
double {
405 auto name =
"pidChargedBDTScore_" + std::to_string(hypType.getPDGCode());
406 for (
size_t iDet(0); iDet < detectorSet.size(); ++iDet)
408 auto det = detectorSet[iDet];
409 name +=
"_" + std::to_string(det);
411 return (part->hasExtraInfo(name)) ? part->getExtraInfo(name) : std::numeric_limits<float>::quiet_NaN();
416 Manager::FunctionPtr pidPairChargedBDTScore(
const std::vector<std::string>& arguments)
418 if (arguments.size() != 3) {
419 B2ERROR(
"Need exactly three arguments for pidPairChargedBDTScore: pdgCodeHyp, pdgCodeTest, detector.");
423 int hypPdgId, testPdgId;
425 hypPdgId = Belle2::convertString<int>(arguments.at(0));
426 }
catch (std::invalid_argument& e) {
427 B2ERROR(
"First argument of pidPairChargedBDTScore must be an integer (PDG code).");
431 testPdgId = Belle2::convertString<int>(arguments.at(1));
432 }
catch (std::invalid_argument& e) {
433 B2ERROR(
"First argument of pidPairChargedBDTScore must be an integer (PDG code).");
436 Const::ChargedStable hypType = Const::ChargedStable(hypPdgId);
437 Const::ChargedStable testType = Const::ChargedStable(testPdgId);
439 std::vector<std::string> detectors(arguments.begin() + 2, arguments.end());
440 Const::PIDDetectorSet detectorSet = parseDetectorsChargedBDT(detectors);
442 auto func = [hypType, testType, detectorSet](
const Particle * part) ->
double {
443 auto name =
"pidPairChargedBDTScore_" + std::to_string(hypType.getPDGCode()) +
"_VS_" + std::to_string(testType.getPDGCode());
444 for (
size_t iDet(0); iDet < detectorSet.size(); ++iDet)
446 auto det = detectorSet[iDet];
447 name +=
"_" + std::to_string(det);
449 return (part->hasExtraInfo(name)) ? part->getExtraInfo(name) : std::numeric_limits<float>::quiet_NaN();
454 Manager::FunctionPtr mostLikelyPDG(
const std::vector<std::string>& arguments)
456 if (arguments.size() != 0 and arguments.size() != Const::ChargedStable::c_SetSize) {
457 B2ERROR(
"Need zero or exactly " << Const::ChargedStable::c_SetSize <<
" arguments for pidMostLikelyPDG");
460 double prob[Const::ChargedStable::c_SetSize];
461 if (arguments.size() == 0) {
462 for (
unsigned int i = 0; i < Const::ChargedStable::c_SetSize; i++) prob[i] = 1. / Const::ChargedStable::c_SetSize;
464 if (arguments.size() == Const::ChargedStable::c_SetSize) {
467 for (std::string arg : arguments) {
468 prob[i++] = Belle2::convertString<float>(arg);
470 }
catch (std::invalid_argument& e) {
471 B2ERROR(
"All arguments of mostLikelyPDG must be a float number");
475 auto func = [prob](
const Particle * part) ->
double {
476 auto* pid = part->getPIDLikelihood();
477 if (!pid)
return std::numeric_limits<double>::quiet_NaN();
478 return pid->getMostLikely(prob).getPDGCode();
483 Manager::FunctionPtr isMostLikely(
const std::vector<std::string>& arguments)
485 if (arguments.size() != 0 and arguments.size() != 6) {
486 B2ERROR(
"Need zero or exactly " << Const::ChargedStable::c_SetSize <<
" arguments for pidIsMostLikely");
489 auto func = [arguments](
const Particle * part) ->
double {
490 return mostLikelyPDG(arguments)(part) == abs(part->getPDGCode());
499 double muIDBelle(
const Particle* particle)
501 const PIDLikelihood* pid = particle->getPIDLikelihood();
502 if (!pid)
return 0.5;
504 if (pid->isAvailable(Const::KLM))
505 return exp(pid->getLogL(Const::muon, Const::KLM));
510 double muIDBelleQuality(
const Particle* particle)
512 const PIDLikelihood* pid = particle->getPIDLikelihood();
515 return pid->isAvailable(Const::KLM);
518 double atcPIDBelle(
const Particle* particle,
const std::vector<double>& sigAndBkgHyp)
520 int sigHyp = int(std::lround(sigAndBkgHyp[0]));
521 int bkgHyp = int(std::lround(sigAndBkgHyp[1]));
523 const PIDLikelihood* pid = particle->getPIDLikelihood();
524 if (!pid)
return 0.5;
527 Const::PIDDetectorSet set = Const::ARICH;
528 double acc_sig = exp(pid->getLogL(hypothesisConversion(sigHyp), set));
529 double acc_bkg = exp(pid->getLogL(hypothesisConversion(bkgHyp), set));
531 if (acc_sig + acc_bkg > 0.0)
532 acc = acc_sig / (acc_sig + acc_bkg);
536 double tof_sig = exp(pid->getLogL(hypothesisConversion(sigHyp), set));
537 double tof_bkg = exp(pid->getLogL(hypothesisConversion(bkgHyp), set));
539 double tof_all = tof_sig + tof_bkg;
541 tof = tof_sig / tof_all;
542 if (tof < 0.001) tof = 0.001;
543 if (tof > 0.999) tof = 0.999;
548 double cdc_sig = exp(pid->getLogL(hypothesisConversion(sigHyp), set));
549 double cdc_bkg = exp(pid->getLogL(hypothesisConversion(bkgHyp), set));
551 double cdc_all = cdc_sig + cdc_bkg;
553 cdc = cdc_sig / cdc_all;
554 if (cdc < 0.001) cdc = 0.001;
555 if (cdc > 0.999) cdc = 0.999;
559 double pid_sig = acc * tof * cdc;
560 double pid_bkg = (1. - acc) * (1. - tof) * (1. - cdc);
562 return pid_sig / (pid_sig + pid_bkg);
566 double eIDBelle(
const Particle* part)
568 const PIDLikelihood* pid = part->getPIDLikelihood();
569 if (!pid)
return 0.5;
571 Const::PIDDetectorSet set = Const::ECL;
572 return pid->getProbability(Const::electron, Const::pion, set);
577 VARIABLE_GROUP(
"PID");
578 REGISTER_VARIABLE(
"particleID", particleID,
579 "the particle identification probability under the particle's own hypothesis, using info from all available detectors");
580 REGISTER_VARIABLE(
"electronID", electronID,
581 "electron identification probability defined as :math:`\\mathcal{L}_e/(\\mathcal{L}_e+\\mathcal{L}_\\mu+\\mathcal{L}_\\pi+\\mathcal{L}_K+\\mathcal{L}_p+\\mathcal{L}_d)`, using info from all available detectors");
582 REGISTER_VARIABLE(
"muonID", muonID,
583 "muon identification probability defined as :math:`\\mathcal{L}_\\mu/(\\mathcal{L}_e+\\mathcal{L}_\\mu+\\mathcal{L}_\\pi+\\mathcal{L}_K+\\mathcal{L}_p+\\mathcal{L}_d)`, using info from all available detectors");
584 REGISTER_VARIABLE(
"pionID", pionID,
585 "pion identification probability defined as :math:`\\mathcal{L}_\\pi/(\\mathcal{L}_e+\\mathcal{L}_\\mu+\\mathcal{L}_\\pi+\\mathcal{L}_K+\\mathcal{L}_p+\\mathcal{L}_d)`, using info from all available detectors");
586 REGISTER_VARIABLE(
"kaonID", kaonID,
587 "kaon identification probability defined as :math:`\\mathcal{L}_K/(\\mathcal{L}_e+\\mathcal{L}_\\mu+\\mathcal{L}_\\pi+\\mathcal{L}_K+\\mathcal{L}_p+\\mathcal{L}_d)`, using info from all available detectors");
588 REGISTER_VARIABLE(
"protonID", protonID,
589 "proton identification probability defined as :math:`\\mathcal{L}_p/(\\mathcal{L}_e+\\mathcal{L}_\\mu+\\mathcal{L}_\\pi+\\mathcal{L}_K+\\mathcal{L}_p+\\mathcal{L}_d)`, using info from all available detectors");
590 REGISTER_VARIABLE(
"deuteronID", deuteronID,
591 "deuteron identification probability defined as :math:`\\mathcal{L}_d/(\\mathcal{L}_e+\\mathcal{L}_\\mu+\\mathcal{L}_\\pi+\\mathcal{L}_K+\\mathcal{L}_p+\\mathcal{L}_d)`, using info from all available detectors");
592 REGISTER_VARIABLE(
"binaryPID(pdgCode1, pdgCode2)", binaryPID,
593 "Returns the binary probability for the first provided mass hypothesis with respect to the second mass hypothesis using all detector components");
594 REGISTER_VARIABLE(
"electronID_noSVD", electronID_noSVD,
595 "(SPECIAL (TEMP) variable) electron identification probability defined as :math:`\\mathcal{L}_e/(\\mathcal{L}_e+\\mathcal{L}_\\mu+\\mathcal{L}_\\pi+\\mathcal{L}_K+\\mathcal{L}_p+\\mathcal{L}_d)`, using info from all available detectors *excluding the SVD*");
596 REGISTER_VARIABLE(
"muonID_noSVD", muonID_noSVD,
597 "(SPECIAL (TEMP) variable) muon identification probability defined as :math:`\\mathcal{L}_\\mu/(\\mathcal{L}_e+\\mathcal{L}_\\mu+\\mathcal{L}_\\pi+\\mathcal{L}_K+\\mathcal{L}_p+\\mathcal{L}_d)`, using info from all available detectors *excluding the SVD*");
598 REGISTER_VARIABLE(
"pionID_noSVD", pionID_noSVD,
599 "(SPECIAL (TEMP) variable) pion identification probability defined as :math:`\\mathcal{L}_\\pi/(\\mathcal{L}_e+\\mathcal{L}_\\mu+\\mathcal{L}_\\pi+\\mathcal{L}_K+\\mathcal{L}_p+\\mathcal{L}_d)`, using info from all available detectors *excluding the SVD*");
600 REGISTER_VARIABLE(
"kaonID_noSVD", kaonID_noSVD,
601 "(SPECIAL (TEMP) variable) kaon identification probability defined as :math:`\\mathcal{L}_K/(\\mathcal{L}_e+\\mathcal{L}_\\mu+\\mathcal{L}_\\pi+\\mathcal{L}_K+\\mathcal{L}_p+\\mathcal{L}_d)`, using info from all available detectors *excluding the SVD*");
602 REGISTER_VARIABLE(
"protonID_noSVD", protonID_noSVD,
603 "(SPECIAL (TEMP) variable) proton identification probability defined as :math:`\\mathcal{L}_p/(\\mathcal{L}_e+\\mathcal{L}_\\mu+\\mathcal{L}_\\pi+\\mathcal{L}_K+\\mathcal{L}_p+\\mathcal{L}_d)`, using info from all available detectors *excluding the SVD*");
604 REGISTER_VARIABLE(
"deuteronID_noSVD", deuteronID_noSVD,
605 "(SPECIAL (TEMP) variable) deuteron identification probability defined as :math:`\\mathcal{L}_d/(\\mathcal{L}_e+\\mathcal{L}_\\mu+\\mathcal{L}_\\pi+\\mathcal{L}_K+\\mathcal{L}_p+\\mathcal{L}_d)`, using info from all available detectors *excluding the SVD*");
606 REGISTER_VARIABLE(
"binaryPID_noSVD(pdgCode1, pdgCode2)", binaryPID_noSVD,
607 "Returns the binary probability for the first provided mass hypothesis with respect to the second mass hypothesis using all detector components, *excluding the SVD*.");
608 REGISTER_VARIABLE(
"electronID_noTOP", electronID_noTOP,
609 "(SPECIAL (TEMP) variable) electron identification probability defined as :math:`\\mathcal{L}_e/(\\mathcal{L}_e+\\mathcal{L}_\\mu+\\mathcal{L}_\\pi+\\mathcal{L}_K+\\mathcal{L}_p+\\mathcal{L}_d)`, using info from all available detectors *excluding the TOP*");
610 REGISTER_VARIABLE(
"nbarID", antineutronID, R
"DOC(
611 Returns MVA classifier for antineutron PID.
613 - 1 signal(antineutron) like
615 - -1 invalid using this PID due to some ECL variables used unavailable
617 This PID is only for antineutron. Neutron is also considered as background.
618 The variables used are `clusterPulseShapeDiscriminationMVA`, `clusterE`, `clusterLAT`, `clusterE1E9`, `clusterE9E21`,
619 `clusterAbsZernikeMoment40`, `clusterAbsZernikeMoment51`, `clusterZernikeMVA`.)DOC");
622 VARIABLE_GROUP(
"PID_expert");
623 REGISTER_VARIABLE(
"pidLogLikelihoodValueExpert(pdgCode, detectorList)", pidLogLikelihoodValueExpert,
624 "returns the log likelihood value of for a specific mass hypothesis and set of detectors.");
625 REGISTER_VARIABLE(
"pidDeltaLogLikelihoodValueExpert(pdgCode1, pdgCode2, detectorList)", pidDeltaLogLikelihoodValueExpert,
626 "returns LogL(hyp1) - LogL(hyp2) (aka DLL) for two mass hypotheses and a set of detectors.");
627 REGISTER_VARIABLE(
"pidPairProbabilityExpert(pdgCodeHyp, pdgCodeTest, detectorList)", pidPairProbabilityExpert,
628 "Pair (or binary) probability for the pdgCodeHyp mass hypothesis respect to the pdgCodeTest one, using an arbitrary set of detectors. :math:`\\mathcal{L}_{hyp}/(\\mathcal{L}_{test}+\\mathcal{L}_{hyp}`");
629 REGISTER_VARIABLE(
"pidProbabilityExpert(pdgCodeHyp, detectorList)", pidProbabilityExpert,
630 "probability for the pdgCodeHyp mass hypothesis respect to all the other ones, using an arbitrary set of detectors :math:`\\mathcal{L}_{hyp}/(\\Sigma_{\\text{all~hyp}}\\mathcal{L}_{i}`. ");
631 REGISTER_VARIABLE(
"pidMissingProbabilityExpert(detectorList)", pidMissingProbabilityExpert,
632 "returns 1 if the PID probabiliy is missing for the provided detector list, otherwise 0. ");
633 REGISTER_VARIABLE(
"pidChargedBDTScore(pdgCodeHyp, detector)", pidChargedBDTScore,
634 "returns the charged Pid BDT score for a certain mass hypothesis with respect to all other charged stable particle hypotheses. The second argument specifies which BDT training to use: based on 'ALL' PID detectors (NB: 'SVD' is currently excluded), or 'ECL' only. The choice depends on the ChargedPidMVAMulticlassModule's configuration.");
635 REGISTER_VARIABLE(
"pidPairChargedBDTScore(pdgCodeHyp, pdgCodeTest, detector)", pidPairChargedBDTScore,
636 "returns the charged Pid BDT score for a certain mass hypothesis with respect to an alternative hypothesis. The second argument specifies which BDT training to use: based on 'ALL' PID detectors (NB: 'SVD' is currently excluded), or 'ECL' only. The choice depends on the ChargedPidMVAModule's configuration.");
637 REGISTER_VARIABLE(
"pidMostLikelyPDG", mostLikelyPDG,
638 "Returns PDG code of the largest PID likelihood, or NaN if PID information is not available.");
639 REGISTER_VARIABLE(
"pidIsMostLikely", isMostLikely,
640 "Returns 1 if the PID likelihood for the particle given its PID is the largest one");
643 VARIABLE_GROUP(
"PID_belle");
644 REGISTER_VARIABLE(
"atcPIDBelle(i,j)", atcPIDBelle,
645 "returns Belle's PID atc variable: ``atc_pid(3,1,5,i,j).prob()``.\n"
646 "Parameters i,j are signal and background hypothesis: (0 = electron, 1 = muon, 2 = pion, 3 = kaon, 4 = proton)");
647 REGISTER_VARIABLE(
"muIDBelle", muIDBelle,
648 "returns Belle's PID ``Muon_likelihood()`` variable.");
649 REGISTER_VARIABLE(
"muIDBelleQuality", muIDBelleQuality,
650 "returns true if Belle's PID ``Muon_likelihood()`` is usable (reliable).");
651 REGISTER_VARIABLE(
"eIDBelle", eIDBelle,
652 "returns Belle's electron ID ``eid(3,-1,5).prob()`` variable.");
Abstract base class for different kinds of events.