10#include <analysis/variables/PIDVariables.h>
12#include <analysis/dataobjects/Particle.h>
13#include <analysis/utility/ReferenceFrame.h>
14#include <mdst/dataobjects/PIDLikelihood.h>
15#include <mdst/dataobjects/TrackFitResult.h>
18#include <framework/logging/Logger.h>
19#include <framework/utilities/Conversion.h>
20#include <framework/gearbox/Const.h>
24#include <analysis/dbobjects/PIDCalibrationWeight.h>
25#include <analysis/utility/PIDCalibrationWeightUtil.h>
26#include <analysis/utility/PIDNeuralNetwork.h>
28#include <boost/algorithm/string.hpp>
48 Const::ChargedStable hypothesisConversion(
const int hypothesis)
70 for (std::string val : arguments) {
73 else if (val ==
"svd") result += Const::SVD;
74 else if (val ==
"cdc") result += Const::CDC;
75 else if (val ==
"top") result += Const::TOP;
76 else if (val ==
"arich") result += Const::ARICH;
77 else if (val ==
"ecl") result += Const::ECL;
78 else if (val ==
"klm") result += Const::KLM;
79 else B2ERROR(
"Unknown detector component: " << val);
88 for (std::string val : arguments) {
91 else if (val ==
"ecl") result += Const::ECL;
92 else B2ERROR(
"Invalid detector component: " << val <<
" for charged BDT.");
103 double particleID(
const Particle* p)
105 int pdg = abs(p->getPDGCode());
107 else if (pdg ==
Const::muon.getPDGCode())
return muonID(p);
108 else if (pdg ==
Const::pion.getPDGCode())
return pionID(p);
109 else if (pdg ==
Const::kaon.getPDGCode())
return kaonID(p);
110 else if (pdg ==
Const::proton.getPDGCode())
return protonID(p);
115 bool isPIDAvailable(
const Particle* part)
117 const auto* pid = part->getPIDLikelihood();
118 if (not pid)
return false;
119 return pid->isAvailable();
125 auto func = [detectorSet](
const Particle * part) ->
bool {
126 const auto* pid = part->getPIDLikelihood();
127 if (not pid)
return false;
128 return pid->isAvailable(detectorSet);
135 if (arguments.size() < 2) {
136 B2ERROR(
"Need at least two arguments to pidLogLikelihoodValueExpert");
141 pdgCode = Belle2::convertString<int>(arguments[0]);
142 }
catch (std::invalid_argument& e) {
143 B2ERROR(
"First argument of pidLogLikelihoodValueExpert must be a PDG code");
146 std::vector<std::string> detectors(arguments.begin() + 1, arguments.end());
149 auto hypType = Const::ChargedStable(abs(pdgCode));
151 auto func = [hypType, detectorSet](
const Particle * part) ->
double {
152 const PIDLikelihood* pid = part->getPIDLikelihood();
158 return pid->getLogL(hypType, detectorSet);
164 Manager::FunctionPtr pidDeltaLogLikelihoodValueExpert(
const std::vector<std::string>& arguments)
166 if (arguments.size() < 3) {
167 B2ERROR(
"Need at least three arguments to pidDeltaLogLikelihoodValueExpert");
170 int pdgCodeHyp, pdgCodeTest;
172 pdgCodeHyp = Belle2::convertString<int>(arguments[0]);
173 }
catch (std::invalid_argument& e) {
174 B2ERROR(
"First argument of pidDeltaLogLikelihoodValueExpert must be a PDG code");
178 pdgCodeTest = Belle2::convertString<int>(arguments[1]);
179 }
catch (std::invalid_argument& e) {
180 B2ERROR(
"Second argument of pidDeltaLogLikelihoodValueExpert must be a PDG code");
184 std::vector<std::string> detectors(arguments.begin() + 2, arguments.end());
186 auto hypType = Const::ChargedStable(abs(pdgCodeHyp));
187 auto testType = Const::ChargedStable(abs(pdgCodeTest));
189 auto func = [hypType, testType, detectorSet](
const Particle * part) ->
double {
190 const PIDLikelihood* pid = part->getPIDLikelihood();
195 return pid->getDeltaLogL(hypType, testType, detectorSet);
203 if (arguments.size() < 3) {
204 B2ERROR(
"Need at least three arguments to pidPairProbabilityExpert");
207 int pdgCodeHyp = 0, pdgCodeTest = 0;
209 pdgCodeHyp = Belle2::convertString<int>(arguments[0]);
210 }
catch (std::invalid_argument& e) {
211 B2ERROR(
"First argument of pidPairProbabilityExpert must be PDG code");
215 pdgCodeTest = Belle2::convertString<int>(arguments[1]);
216 }
catch (std::invalid_argument& e) {
217 B2ERROR(
"Second argument of pidPairProbabilityExpert must be PDG code");
221 std::vector<std::string> detectors(arguments.begin() + 2, arguments.end());
224 auto hypType = Const::ChargedStable(abs(pdgCodeHyp));
225 auto testType = Const::ChargedStable(abs(pdgCodeTest));
226 auto func = [hypType, testType, detectorSet](
const Particle * part) ->
double {
227 const PIDLikelihood* pid = part->getPIDLikelihood();
232 return pid->getProbability(hypType, testType, detectorSet);
240 if (arguments.size() < 2) {
241 B2ERROR(
"Need at least two arguments for pidProbabilityExpert");
246 pdgCodeHyp = Belle2::convertString<int>(arguments[0]);
247 }
catch (std::invalid_argument& e) {
248 B2ERROR(
"First argument of pidProbabilityExpert must be PDG code");
252 std::vector<std::string> detectors(arguments.begin() + 1, arguments.end());
254 auto hypType = Const::ChargedStable(abs(pdgCodeHyp));
259 for (
double& i : frac) i = 1.0;
261 auto func = [hypType, frac, detectorSet](
const Particle * part) ->
double {
262 const PIDLikelihood* pid = part->getPIDLikelihood();
267 return pid->getProbability(hypType, frac, detectorSet);
275 if (arguments.size() < 2) {
276 B2ERROR(
"Need at least two arguments for pidLogarithmicProbabilityExpert");
281 pdgCodeHyp = Belle2::convertString<int>(arguments[0]);
282 }
catch (std::invalid_argument& e) {
283 B2ERROR(
"First argument of pidLogarithmicProbabilityExpert must be PDG code");
287 std::vector<std::string> detectors(arguments.begin() + 1, arguments.end());
289 auto hypType = Const::ChargedStable(abs(pdgCodeHyp));
294 for (
double& i : frac) i = 1.0;
296 auto func = [hypType, frac, detectorSet](
const Particle * part) ->
double {
297 const auto* pid = part->getPIDLikelihood();
300 return pid->getLogarithmicProbability(hypType, frac, detectorSet);
308 if (arguments.size() < 1) {
309 B2ERROR(
"Need at least one argument to pidMissingProbabilityExpert");
313 std::vector<std::string> detectors(arguments.begin(), arguments.end());
316 auto func = [detectorSet](
const Particle * part) ->
double {
317 const PIDLikelihood* pid = part->getPIDLikelihood();
319 if (not pid->areAllAvailable(detectorSet))
return 1;
325 Manager::FunctionPtr pidWeightedLogLikelihoodValueExpert(
const std::vector<std::string>& arguments)
327 if (arguments.size() < 3) {
328 B2ERROR(
"Need at least three arguments to pidWeightedLogLikelihoodValueExpert");
331 std::string matrixName = arguments[0];
335 pdgCode = Belle2::convertString<int>(arguments[1]);
336 }
catch (std::invalid_argument& e) {
337 B2ERROR(
"Second argument of pidWeightedLogLikelihoodValueExpert must be a PDG code");
340 std::vector<std::string> detectors(arguments.begin() + 2, arguments.end());
342 auto hypType = Const::ChargedStable(abs(pdgCode));
344 auto func = [hypType, detectorSet, matrixName](
const Particle * part) ->
double {
345 PIDCalibrationWeightUtil weightMatrix(matrixName);
346 const PIDLikelihood* pid = part->getPIDLikelihood();
353 auto mom = frame.getMomentum(part);
355 auto theta = mom.Theta();
360 if (detectorSet.contains(detector))
361 LogL += pid->getLogL(hypType, detector) * weightMatrix.getWeight(hypType.getPDGCode(), detector, p, theta);
371 if (arguments.size() < 3) {
372 B2ERROR(
"Need at least three arguments for pidWeightedProbabilityExpert");
375 std::string matrixName = arguments[0];
379 pdgCodeHyp = Belle2::convertString<int>(arguments[1]);
380 }
catch (std::invalid_argument& e) {
381 B2ERROR(
"Second argument of pidWeightedProbabilityExpert must be PDG code");
385 std::vector<std::string> detectors(arguments.begin() + 2, arguments.end());
387 auto hypType = Const::ChargedStable(abs(pdgCodeHyp));
389 auto func = [hypType, detectorSet, matrixName](
const Particle * part) ->
double {
390 PIDCalibrationWeightUtil weightMatrix(matrixName);
391 const PIDLikelihood* pid = part->getPIDLikelihood();
397 auto mom = frame.getMomentum(part);
399 auto theta = mom.Theta();
406 const int index_pdg = pdgIter.getIndex();
410 if (detectorSet.contains(detector))
411 LogL[index_pdg] += pid->getLogL(pdgIter, detector) * weightMatrix.getWeight(pdgIter.getPDGCode(), detector, p, theta);
414 if (!hasMax || (LogL[index_pdg] > LogL_max)) {
415 LogL_max = LogL[index_pdg];
421 for (
auto LogL_i : LogL)
422 norm += exp(LogL_i - LogL_max);
425 return exp(LogL[hypType.getIndex()] - LogL_max) / norm;
435 if (arguments.size() == 0) {
436 B2ERROR(
"Need pdg code for pidNeuralNetworkValueExpert");
439 if (arguments.size() > 2) {
440 B2ERROR(
"pidNeuralNetworkValueExpert expects at most two arguments, i.e. the pdg code and the pidNeuralNetworkName");
445 pdgCode = abs(Belle2::convertString<int>(arguments[0]));
446 }
catch (std::invalid_argument& e) {
447 B2ERROR(
"First argument of pidNeuralNetworkValueExpert must be a PDG code");
451 std::shared_ptr<PIDNeuralNetwork> neuralNetworkPtr;
452 if (arguments.size() == 2) {
453 std::string parameterSetName = arguments[1];
454 neuralNetworkPtr = std::make_shared<PIDNeuralNetwork>(parameterSetName);
456 neuralNetworkPtr = std::make_shared<PIDNeuralNetwork>();
459 neuralNetworkPtr->hasPdgCode(pdgCode,
true);
461 auto func = [neuralNetworkPtr, pdgCode](
const Particle * part) ->
double {
462 const auto& extraInfoName = neuralNetworkPtr->getExtraInfoName(pdgCode);
463 if (part->hasExtraInfo(extraInfoName))
464 return part->getExtraInfo(extraInfoName);
466 const PIDLikelihood* pid = part->getPIDLikelihood();
471 std::vector<float> inputsNN;
472 inputsNN.reserve(neuralNetworkPtr->getInputSize());
473 for (
const auto& inputName : neuralNetworkPtr->getInputBasf2Names())
476 const auto probabilities = neuralNetworkPtr->predict(inputsNN);
479 for (
const auto element : probabilities)
481 const auto [pdgCodeElement, probability] = element;
482 const_cast<Particle*
>(part)->addExtraInfo(neuralNetworkPtr->getExtraInfoName(pdgCodeElement), probability);
485 return probabilities.at(pdgCode);
492 Manager::FunctionPtr pidWeightedPairProbabilityExpert(
const std::vector<std::string>& arguments)
494 if (arguments.size() < 4) {
495 B2ERROR(
"Need at least four arguments to pidWeightedPairProbabilityExpert");
498 std::string matrixName = arguments[0];
500 int pdgCodeHyp = 0, pdgCodeTest = 0;
502 pdgCodeHyp = Belle2::convertString<int>(arguments[1]);
503 }
catch (std::invalid_argument& e) {
504 B2ERROR(
"Second argument of pidWeightedPairProbabilityExpert must be PDG code");
508 pdgCodeTest = Belle2::convertString<int>(arguments[2]);
509 }
catch (std::invalid_argument& e) {
510 B2ERROR(
"Third argument of pidWeightedPairProbabilityExpert must be PDG code");
514 std::vector<std::string> detectors(arguments.begin() + 3, arguments.end());
517 auto hypType = Const::ChargedStable(abs(pdgCodeHyp));
518 auto testType = Const::ChargedStable(abs(pdgCodeTest));
520 auto func = [hypType, testType, detectorSet, matrixName](
const Particle * part) ->
double {
521 PIDCalibrationWeightUtil weightMatrix(matrixName);
523 const PIDLikelihood* pid = part->getPIDLikelihood();
529 auto mom = frame.getMomentum(part);
531 auto theta = mom.Theta();
533 double LogL_hypType(0), LogL_testType(0);
536 if (detectorSet.contains(detector)) {
537 LogL_hypType += pid->getLogL(hypType, detector) * weightMatrix.getWeight(hypType.getPDGCode(), detector, p, theta);
538 LogL_testType += pid->getLogL(testType, detector) * weightMatrix.getWeight(testType.getPDGCode(), detector, p, theta);
542 double deltaLogL = LogL_testType - LogL_hypType;
546 double eLogL = exp(deltaLogL);
547 res = 1. / (1. + eLogL);
550 double eLogL = exp(-deltaLogL);
551 res = eLogL / (1.0 + eLogL);
554 if (std::isfinite(res))
562 double electronID(
const Particle* part)
565 pidProbabilityExpert({
"11",
"ALL"});
566 return std::get<double>(pidFunction(part));
569 double muonID(
const Particle* part)
572 pidProbabilityExpert({
"13",
"ALL"});
573 return std::get<double>(pidFunction(part));
576 double pionID(
const Particle* part)
579 pidProbabilityExpert({
"211",
"ALL"});
580 return std::get<double>(pidFunction(part));
583 double kaonID(
const Particle* part)
586 pidProbabilityExpert({
"321",
"ALL"});
587 return std::get<double>(pidFunction(part));
590 double protonID(
const Particle* part)
593 pidProbabilityExpert({
"2212",
"ALL"});
594 return std::get<double>(pidFunction(part));
597 double deuteronID(
const Particle* part)
600 pidProbabilityExpert({
"1000010020",
"ALL"});
601 return std::get<double>(pidFunction(part));
604 double binaryPID(
const Particle* part,
const std::vector<double>& arguments)
606 if (arguments.size() != 2) {
607 B2ERROR(
"The variable binaryPID needs exactly two arguments: the PDG codes of two hypotheses.");
610 int pdgCodeHyp = std::abs(
int(std::lround(arguments[0])));
611 int pdgCodeTest = std::abs(
int(std::lround(arguments[1])));
612 return std::get<double>(
Manager::Instance().getVariable(
"pidPairProbabilityExpert(" + std::to_string(
613 pdgCodeHyp) +
", " + std::to_string(
614 pdgCodeTest) +
", ALL)")->function(part));
617 double electronID_noSVD(
const Particle* part)
621 pidProbabilityExpert({
"11",
"CDC",
"TOP",
"ARICH",
"ECL",
"KLM"});
622 return std::get<double>(pidFunction(part));
625 double muonID_noSVD(
const Particle* part)
629 pidProbabilityExpert({
"13",
"CDC",
"TOP",
"ARICH",
"ECL",
"KLM"});
630 return std::get<double>(pidFunction(part));
633 double pionID_noSVD(
const Particle* part)
637 pidProbabilityExpert({
"211",
"CDC",
"TOP",
"ARICH",
"ECL",
"KLM"});
638 return std::get<double>(pidFunction(part));
641 double kaonID_noSVD(
const Particle* part)
645 pidProbabilityExpert({
"321",
"CDC",
"TOP",
"ARICH",
"ECL",
"KLM"});
646 return std::get<double>(pidFunction(part));
649 double protonID_noSVD(
const Particle* part)
653 pidProbabilityExpert({
"2212",
"CDC",
"TOP",
"ARICH",
"ECL",
"KLM"});
654 return std::get<double>(pidFunction(part));
657 double deuteronID_noSVD(
const Particle* part)
661 pidProbabilityExpert({
"1000010020",
"CDC",
"TOP",
"ARICH",
"ECL",
"KLM"});
662 return std::get<double>(pidFunction(part));
665 double binaryPID_noSVD(
const Particle* part,
const std::vector<double>& arguments)
668 if (arguments.size() != 2) {
669 B2ERROR(
"The variable binaryPID_noSVD needs exactly two arguments: the PDG codes of two hypotheses.");
672 int pdgCodeHyp = std::abs(
int(std::lround(arguments[0])));
673 int pdgCodeTest = std::abs(
int(std::lround(arguments[1])));
674 return std::get<double>(
Manager::Instance().getVariable(
"pidPairProbabilityExpert(" + std::to_string(
675 pdgCodeHyp) +
", " + std::to_string(
676 pdgCodeTest) +
", CDC, TOP, ARICH, ECL, KLM)")->function(part));
679 double electronID_noTOP(
const Particle* part)
683 pidProbabilityExpert({
"11",
"SVD",
"CDC",
"ARICH",
"ECL",
"KLM"});
684 return std::get<double>(pidFunction(part));
687 double binaryElectronID_noTOP(
const Particle* part,
const std::vector<double>& arguments)
690 if (arguments.size() != 1) {
691 B2ERROR(
"The variable binaryElectronID_noTOP needs exactly one argument: the PDG code of the test hypothesis.");
696 int pdgCodeTest = std::abs(
int(std::lround(arguments[0])));
698 const auto var =
"pidPairProbabilityExpert(" + std::to_string(pdgCodeHyp) +
", " +
699 std::to_string(pdgCodeTest) +
", SVD, CDC, ARICH, ECL, KLM)";
704 double electronID_noSVD_noTOP(
const Particle* part)
708 pidProbabilityExpert({
"11",
"CDC",
"ARICH",
"ECL",
"KLM"});
709 return std::get<double>(pidFunction(part));
712 double binaryElectronID_noSVD_noTOP(
const Particle* part,
const std::vector<double>& arguments)
715 if (arguments.size() != 1) {
716 B2ERROR(
"The variable binaryElectronID_noSVD_noTOP needs exactly one argument: the PDG code of the test hypothesis.");
721 int pdgCodeTest = std::abs(
int(std::lround(arguments[0])));
723 const auto var =
"pidPairProbabilityExpert(" + std::to_string(pdgCodeHyp) +
", " +
724 std::to_string(pdgCodeTest) +
", CDC, ARICH, ECL, KLM)";
730 double pionID_noARICHwoECL(
const Particle* part)
733 const ECLCluster* cluster = part->getECLCluster();
735 const PIDLikelihood* pid = part->getPIDLikelihood();
739 pidProbabilityExpert({
"211",
"SVD",
"CDC",
"TOP",
"ECL",
"KLM"});
740 return std::get<double>(pidFunction(part));
747 double kaonID_noARICHwoECL(
const Particle* part)
750 const ECLCluster* cluster = part->getECLCluster();
752 const PIDLikelihood* pid = part->getPIDLikelihood();
756 pidProbabilityExpert({
"321",
"SVD",
"CDC",
"TOP",
"ECL",
"KLM"});
757 return std::get<double>(pidFunction(part));
764 double binaryPID_noARICHwoECL(
const Particle* part,
const std::vector<double>& arguments)
767 if (arguments.size() != 2) {
768 B2ERROR(
"The variable binaryPID_noARICHwoECL needs exactly two arguments: the PDG codes of two hypotheses.");
771 int pdgCodeHyp = std::abs(
int(std::lround(arguments[0])));
772 int pdgCodeTest = std::abs(
int(std::lround(arguments[1])));
773 auto hypType = Const::ChargedStable(abs(pdgCodeHyp));
774 auto testType = Const::ChargedStable(abs(pdgCodeTest));
776 const ECLCluster* cluster = part->getECLCluster();
778 const PIDLikelihood* pid = part->getPIDLikelihood();
780 double lkhdiff = pid->getDeltaLogL(hypType, testType, Const::ARICH);
781 if ((lkhdiff > 0 && pdgCodeHyp > pdgCodeTest) || (lkhdiff < 0 && pdgCodeHyp < pdgCodeTest)) {
782 std::string varName =
"pidPairProbabilityExpert(" +
783 std::to_string(pdgCodeHyp) +
", " + std::to_string(pdgCodeTest) +
", SVD, CDC, TOP, ECL, KLM)";
784 return std::get<double>(
Manager::Instance().getVariable(varName)->function(part));
788 return binaryPID(part, arguments);
794 double antineutronID(
const Particle* particle)
796 if (particle->hasExtraInfo(
"nbarID")) {
797 return particle->getExtraInfo(
"nbarID");
800 B2WARNING(
"The extraInfo nbarID is not registered! \n"
801 "Please use function getNbarIDMVA in modularAnalysis.");
809 if (arguments.size() != 2) {
810 B2ERROR(
"Need exactly two arguments for pidChargedBDTScore: pdgCodeHyp, detector");
816 hypPdgId = Belle2::convertString<int>(arguments.at(0));
817 }
catch (std::invalid_argument& e) {
818 B2ERROR(
"First argument of pidChargedBDTScore must be an integer (PDG code).");
821 Const::ChargedStable hypType = Const::ChargedStable(hypPdgId);
823 std::vector<std::string> detectors(arguments.begin() + 1, arguments.end());
826 auto func = [hypType, detectorSet](
const Particle * part) ->
double {
827 auto name =
"pidChargedBDTScore_" + std::to_string(hypType.getPDGCode());
830 name +=
"_" + std::to_string(detector);
832 return (part->hasExtraInfo(name)) ? part->getExtraInfo(name) :
Const::doubleNaN;
839 if (arguments.size() != 3) {
840 B2ERROR(
"Need exactly three arguments for pidPairChargedBDTScore: pdgCodeHyp, pdgCodeTest, detector.");
844 int hypPdgId, testPdgId;
846 hypPdgId = Belle2::convertString<int>(arguments.at(0));
847 }
catch (std::invalid_argument& e) {
848 B2ERROR(
"First argument of pidPairChargedBDTScore must be an integer (PDG code).");
852 testPdgId = Belle2::convertString<int>(arguments.at(1));
853 }
catch (std::invalid_argument& e) {
854 B2ERROR(
"First argument of pidPairChargedBDTScore must be an integer (PDG code).");
857 Const::ChargedStable hypType = Const::ChargedStable(hypPdgId);
858 Const::ChargedStable testType = Const::ChargedStable(testPdgId);
860 std::vector<std::string> detectors(arguments.begin() + 2, arguments.end());
863 auto func = [hypType, testType, detectorSet](
const Particle * part) ->
double {
864 auto name =
"pidPairChargedBDTScore_" + std::to_string(hypType.getPDGCode()) +
"_VS_" + std::to_string(testType.getPDGCode());
867 name +=
"_" + std::to_string(detector);
869 return (part->hasExtraInfo(name)) ? part->getExtraInfo(name) :
Const::doubleNaN;
874 double mostLikelyPDG(
const Particle* part,
const std::vector<double>& arguments)
881 if (arguments.size() == 0) {
884 copy(arguments.begin(), arguments.end(), prob);
887 auto* pid = part->getPIDLikelihood();
889 return pid->getMostLikely(prob).getPDGCode();
892 bool isMostLikely(
const Particle* part,
const std::vector<double>& arguments)
898 return mostLikelyPDG(part, arguments) == abs(part->getPDGCode());
904 if (arguments.size() == 0) {
905 varName =
"pidWeightedProbabilityExpert(PIDCalibrationWeightMatrix, 11, ALL)";
906 }
else if (arguments.size() == 1) {
907 varName =
"pidWeightedProbabilityExpert(" + arguments[0] +
", 11, ALL)";
909 B2ERROR(
"Need zero or one argument for weightedElectronID");
914 auto func = [var](
const Particle * particle) ->
double {
915 return std::get<double>(var->function(particle));
923 if (arguments.size() == 0) {
924 varName =
"pidWeightedProbabilityExpert(PIDCalibrationWeightMatrix, 13, ALL)";
925 }
else if (arguments.size() == 1) {
926 varName =
"pidWeightedProbabilityExpert(" + arguments[0] +
", 13, ALL)";
928 B2ERROR(
"Need zero or one argument for weightedMuonID");
933 auto func = [var](
const Particle * particle) ->
double {
934 return std::get<double>(var->function(particle));
942 if (arguments.size() == 0) {
943 varName =
"pidWeightedProbabilityExpert(PIDCalibrationWeightMatrix, 211, ALL)";
944 }
else if (arguments.size() == 1) {
945 varName =
"pidWeightedProbabilityExpert(" + arguments[0] +
", 211, ALL)";
947 B2ERROR(
"Need zero or one argument for weightedPionID");
952 auto func = [var](
const Particle * particle) ->
double {
953 return std::get<double>(var->function(particle));
961 if (arguments.size() == 0) {
962 varName =
"pidWeightedProbabilityExpert(PIDCalibrationWeightMatrix, 321, ALL)";
963 }
else if (arguments.size() == 1) {
964 varName =
"pidWeightedProbabilityExpert(" + arguments[0] +
", 321, ALL)";
966 B2ERROR(
"Need zero or one argument for weightedKaonID");
971 auto func = [var](
const Particle * particle) ->
double {
972 return std::get<double>(var->function(particle));
980 if (arguments.size() == 0) {
981 varName =
"pidWeightedProbabilityExpert(PIDCalibrationWeightMatrix, 2212, ALL)";
982 }
else if (arguments.size() == 1) {
983 varName =
"pidWeightedProbabilityExpert(" + arguments[0] +
", 2212, ALL)";
985 B2ERROR(
"Need zero or one argument for weightedProtonID");
990 auto func = [var](
const Particle * particle) ->
double {
991 return std::get<double>(var->function(particle));
999 if (arguments.size() == 0) {
1000 varName =
"pidWeightedProbabilityExpert(PIDCalibrationWeightMatrix, 1000010020, ALL)";
1001 }
else if (arguments.size() == 1) {
1002 varName =
"pidWeightedProbabilityExpert(" + arguments[0] +
", 1000010020, ALL)";
1004 B2ERROR(
"Need zero or one argument for weightedDeuteronID");
1009 auto func = [var](
const Particle * particle) ->
double {
1010 return std::get<double>(var->function(particle));
1016 double pionIDNN(
const Particle* particle)
1018 if (particle->hasExtraInfo(
"pidNeuralNetworkValueExpert(211)"))
1019 return particle->getExtraInfo(
"pidNeuralNetworkValueExpert(211)");
1020 static auto func = pidNeuralNetworkValueExpert({
"211"});
1021 return std::get<double>(func(particle));
1024 double kaonIDNN(
const Particle* particle)
1026 if (particle->hasExtraInfo(
"pidNeuralNetworkValueExpert(321)"))
1027 return particle->getExtraInfo(
"pidNeuralNetworkValueExpert(321)");
1028 static auto func = pidNeuralNetworkValueExpert({
"321"});
1029 return std::get<double>(func(particle));
1032 double klmMuonIDDNN(
const Particle* part)
1034 const PIDLikelihood* pid = part->getPIDLikelihood();
1036 double klmMuonIDDNNvalue = pid->getPreOfficialLikelihood(
"klmMuonIDDNN");
1039 return klmMuonIDDNNvalue;
1046 double muIDBelle(
const Particle* particle)
1048 const PIDLikelihood* pid = particle->getPIDLikelihood();
1049 if (!pid)
return 0.5;
1051 if (pid->isAvailable(Const::KLM))
1052 return exp(pid->getLogL(
Const::muon, Const::KLM));
1057 double muIDBelleQuality(
const Particle* particle)
1059 const PIDLikelihood* pid = particle->getPIDLikelihood();
1062 return pid->isAvailable(Const::KLM);
1065 double atcPIDBelle(
const Particle* particle,
const std::vector<double>& sigAndBkgHyp)
1067 int sigHyp = int(std::lround(sigAndBkgHyp[0]));
1068 int bkgHyp = int(std::lround(sigAndBkgHyp[1]));
1070 const PIDLikelihood* pid = particle->getPIDLikelihood();
1071 if (!pid)
return 0.5;
1075 double acc_sig = exp(pid->getLogL(hypothesisConversion(sigHyp), set));
1076 double acc_bkg = exp(pid->getLogL(hypothesisConversion(bkgHyp), set));
1078 if (acc_sig + acc_bkg > 0.0)
1079 acc = acc_sig / (acc_sig + acc_bkg);
1083 double tof_sig = exp(pid->getLogL(hypothesisConversion(sigHyp), set));
1084 double tof_bkg = exp(pid->getLogL(hypothesisConversion(bkgHyp), set));
1086 double tof_all = tof_sig + tof_bkg;
1088 tof = tof_sig / tof_all;
1089 if (tof < 0.001) tof = 0.001;
1090 if (tof > 0.999) tof = 0.999;
1095 double cdc_sig = exp(pid->getLogL(hypothesisConversion(sigHyp), set));
1096 double cdc_bkg = exp(pid->getLogL(hypothesisConversion(bkgHyp), set));
1098 double cdc_all = cdc_sig + cdc_bkg;
1100 cdc = cdc_sig / cdc_all;
1101 if (cdc < 0.001) cdc = 0.001;
1102 if (cdc > 0.999) cdc = 0.999;
1106 double pid_sig = acc * tof * cdc;
1107 double pid_bkg = (1. - acc) * (1. - tof) * (1. - cdc);
1109 return pid_sig / (pid_sig + pid_bkg);
1113 double eIDBelle(
const Particle* part)
1115 const PIDLikelihood* pid = part->getPIDLikelihood();
1116 if (!pid)
return 0.5;
1124 VARIABLE_GROUP(
"PID");
1125 REGISTER_VARIABLE(
"particleID", particleID,
1126 "the particle identification probability under the particle's own hypothesis, using info from all available detectors");
1127 REGISTER_VARIABLE(
"isPIDAvailable", isPIDAvailable,
1128 "True if PID is available (for at least one of the PID detectors");
1129 REGISTER_METAVARIABLE(
"isPIDAvailableFrom(detectorList)", isPIDAvailableFrom,
1130 "True if PID is available for at least one of the detectors in the list)",
1131 Manager::VariableDataType::c_bool);
1132 REGISTER_VARIABLE(
"electronID", electronID,
1133 "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");
1134 REGISTER_VARIABLE(
"muonID", muonID,
1135 "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");
1136 REGISTER_VARIABLE(
"pionID", pionID,
1137 "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");
1138 REGISTER_VARIABLE(
"kaonID", kaonID,
1139 "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");
1140 REGISTER_VARIABLE(
"protonID", protonID,
1141 "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");
1142 REGISTER_VARIABLE(
"deuteronID", deuteronID,
1143 "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");
1144 REGISTER_METAVARIABLE(
"binaryPID(pdgCode1, pdgCode2)", binaryPID,
1145 "Returns the binary probability for the first provided mass hypothesis with respect to the second mass hypothesis using all detector components",
1146 Manager::VariableDataType::c_double);
1147 REGISTER_METAVARIABLE(
"pidChargedBDTScore(pdgCodeHyp, detector)", pidChargedBDTScore,
1148 "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.",
1149 Manager::VariableDataType::c_double);
1150 REGISTER_METAVARIABLE(
"pidPairChargedBDTScore(pdgCodeHyp, pdgCodeTest, detector)", pidPairChargedBDTScore,
1151 "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.",
1152 Manager::VariableDataType::c_double);
1153 REGISTER_VARIABLE(
"nbarID", antineutronID, R
"DOC(
1154Returns MVA classifier for antineutron PID.
1156- 1 signal(antineutron) like
1158- -1 invalid using this PID due to some ECL variables used unavailable
1160This PID is only for antineutron. Neutron is also considered as background.
1161The variables used are `clusterPulseShapeDiscriminationMVA`, `clusterE`, `clusterLAT`, `clusterE1E9`, `clusterE9E21`,
1162`clusterAbsZernikeMoment40`, `clusterAbsZernikeMoment51`, `clusterZernikeMVA`.)DOC");
1165 REGISTER_VARIABLE(
"electronID_noSVD", electronID_noSVD,
1166 "**(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*");
1167 REGISTER_VARIABLE(
"muonID_noSVD", muonID_noSVD,
1168 "**(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*");
1169 REGISTER_VARIABLE(
"pionID_noSVD", pionID_noSVD,
1170 "**(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*");
1171 REGISTER_VARIABLE(
"kaonID_noSVD", kaonID_noSVD,
1172 "**(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*");
1173 REGISTER_VARIABLE(
"protonID_noSVD", protonID_noSVD,
1174 "**(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*");
1175 REGISTER_VARIABLE(
"deuteronID_noSVD", deuteronID_noSVD,
1176 "**(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*");
1177 REGISTER_METAVARIABLE(
"binaryPID_noSVD(pdgCode1, pdgCode2)", binaryPID_noSVD,
1178 "Returns the binary probability for the first provided mass hypothesis with respect to the second mass hypothesis using all detector components, *excluding the SVD*.",
1179 Manager::VariableDataType::c_double);
1180 REGISTER_VARIABLE(
"electronID_noTOP", electronID_noTOP,
1181 "**(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*. *NB:* this variable must be used in place of `electronID` when analysing data (MC) processed (simulated) in *release 6*");
1182 REGISTER_METAVARIABLE(
"binaryElectronID_noTOP(pdgCodeTest)", binaryElectronID_noTOP,
1183 "**(SPECIAL (TEMP) variable)** Returns the binary probability for the electron mass hypothesis with respect to another mass hypothesis using all detector components, *excluding the TOP*. *NB:* this variable must be used in place of `binaryPID` (``pdgCode1=11``) when analysing data (MC) processed (simulated) in **release 6**",
1184 Manager::VariableDataType::c_double);
1185 REGISTER_VARIABLE(
"electronID_noSVD_noTOP", electronID_noSVD_noTOP,
1186 "**(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 and the TOP*. *NB:* this variable must be used in place of `electronID` when analysing data (MC) processed (simulated) in *release 5*");
1187 REGISTER_METAVARIABLE(
"binaryElectronID_noSVD_noTOP(pdgCodeTest)", binaryElectronID_noSVD_noTOP,
1188 "**(SPECIAL (TEMP) variable)** Returns the binary probability for the electron mass hypothesis with respect to another mass hypothesis using all detector components, *excluding the SVD and the TOP*. *NB:* this variable must be used in place of `binaryPID` (``pdgCode1=11``) when analysing data (MC) processed (simulated) in **release 5**",
1189 Manager::VariableDataType::c_double);
1190 REGISTER_VARIABLE(
"pionID_noARICHwoECL", pionID_noARICHwoECL,
1191 "**(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 but ARICH info excluded for tracks without associated ECL cluster");
1192 REGISTER_VARIABLE(
"kaonID_noARICHwoECL", kaonID_noARICHwoECL,
1193 "**(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 but ARICH info excluded for tracks without associated ECL cluster");
1194 REGISTER_METAVARIABLE(
"binaryPID_noARICHwoECL(pdgCode1, pdgCode2)", binaryPID_noARICHwoECL,
1195 "Returns the binary probability for the first provided mass hypothesis with respect to the second mass hypothesis using all detector components, but ARICH info excluded for tracks without associated ECL cluster",
1196 Manager::VariableDataType::c_double);
1199 REGISTER_METAVARIABLE(
"weightedElectronID(weightMatrixName)", weightedElectronID,
1201weighted electron identification probability defined as :math:`\frac{\mathcal{\tilde{L}}_e}{\sum_{i=e,\mu,\pi,K,p,d} \mathcal{\tilde{L}}_i}`,
1202where :math:`\mathcal{\tilde{L}}_i` is defined as :math:`\log\mathcal{\tilde{L}}_i = \sum_{j={\mathrm{SVD, CDC, TOP, ARICH, ECL, KLM}}} \mathcal{w}_{ij}\log\mathcal{L}_{ij}`.
1203The :math:`\mathcal{L}_{ij}` is the original likelihood and :math:`\mathcal{w}_{ij}` is the PID calibration weight of i-th particle type and j-th detector.
1204One can provide the name of the weight matrix as the argument.
1206 Manager::VariableDataType::c_double);
1207 REGISTER_METAVARIABLE("weightedMuonID(weightMatrixName)", weightedMuonID,
1209weighted muon identification probability defined as :math:`\frac{\mathcal{\tilde{L}}_\mu}{\sum_{i=e,\mu,\pi,K,p,d} \mathcal{\tilde{L}}_i}`,
1210where :math:`\mathcal{\tilde{L}}_i` is defined as :math:`\log\mathcal{\tilde{L}}_i = \sum_{j={\mathrm{SVD, CDC, TOP, ARICH, ECL, KLM}}} \mathcal{w}_{ij}\log\mathcal{L}_{ij}`.
1211The :math:`\mathcal{L}_{ij}` is the original likelihood and :math:`\mathcal{w}_{ij}` is the PID calibration weight of i-th particle type and j-th detector.
1212One can provide the name of the weight matrix as the argument.
1214 Manager::VariableDataType::c_double);
1215 REGISTER_METAVARIABLE("weightedPionID(weightMatrixName)", weightedPionID,
1217weighted pion identification probability defined as :math:`\frac{\mathcal{\tilde{L}}_\pi}{\sum_{i=e,\mu,\pi,K,p,d} \mathcal{\tilde{L}}_i}`,
1218where :math:`\mathcal{\tilde{L}}_i` is defined as :math:`\log\mathcal{\tilde{L}}_i = \sum_{j={\mathrm{SVD, CDC, TOP, ARICH, ECL, KLM}}} \mathcal{w}_{ij}\log\mathcal{L}_{ij}`.
1219The :math:`\mathcal{L}_{ij}` is the original likelihood and :math:`\mathcal{w}_{ij}` is the PID calibration weight of i-th particle type and j-th detector.
1220One can provide the name of the weight matrix as the argument.
1222 Manager::VariableDataType::c_double);
1223 REGISTER_METAVARIABLE("weightedKaonID(weightMatrixName)", weightedKaonID,
1225weighted kaon identification probability defined as :math:`\frac{\mathcal{\tilde{L}}_K}{\sum_{i=e,\mu,\pi,K,p,d} \mathcal{\tilde{L}}_i}`,
1226where :math:`\mathcal{\tilde{L}}_i` is defined as :math:`\log\mathcal{\tilde{L}}_i = \sum_{j={\mathrm{SVD, CDC, TOP, ARICH, ECL, KLM}}} \mathcal{w}_{ij}\log\mathcal{L}_{ij}`.
1227The :math:`\mathcal{L}_{ij}` is the original likelihood and :math:`\mathcal{w}_{ij}` is the PID calibration weight of i-th particle type and j-th detector.
1228One can provide the name of the weight matrix as the argument.
1230 Manager::VariableDataType::c_double);
1231 REGISTER_METAVARIABLE("weightedProtonID(weightMatrixName)", weightedProtonID,
1233weighted proton identification probability defined as :math:`\frac{\mathcal{\tilde{L}}_p}{\sum_{i=e,\mu,\pi,K,p,d} \mathcal{\tilde{L}}_i}`,
1234where :math:`\mathcal{\tilde{L}}_i` is defined as :math:`\log\mathcal{\tilde{L}}_i = \sum_{j={\mathrm{SVD, CDC, TOP, ARICH, ECL, KLM}}} \mathcal{w}_{ij}\log\mathcal{L}_{ij}`.
1235The :math:`\mathcal{L}_{ij}` is the original likelihood and :math:`\mathcal{w}_{ij}` is the PID calibration weight of i-th particle type and j-th detector.
1236One can provide the name of the weight matrix as the argument.
1238 Manager::VariableDataType::c_double);
1239 REGISTER_METAVARIABLE("weightedDeuteronID(weightMatrixName)", weightedDeuteronID,
1241weighted deuteron identification probability defined as :math:`\frac{\mathcal{\tilde{L}}_d}{\sum_{i=e,\mu,\pi,K,p,d} \mathcal{\tilde{L}}_i}`,
1242where :math:`\mathcal{\tilde{L}}_i` is defined as :math:`\log\mathcal{\tilde{L}}_i = \sum_{j={\mathrm{SVD, CDC, TOP, ARICH, ECL, KLM}}} \mathcal{w}_{ij}\log\mathcal{L}_{ij}`.
1243The :math:`\mathcal{L}_{ij}` is the original likelihood and :math:`\mathcal{w}_{ij}` is the PID calibration weight of i-th particle type and j-th detector.
1244One can provide the name of the weight matrix as the argument.
1246 Manager::VariableDataType::c_double);
1249 REGISTER_VARIABLE("pionIDNN", pionIDNN,
1251pion identification probability as calculated from the PID neural network.
1253 REGISTER_VARIABLE("kaonIDNN", kaonIDNN,
1255kaon identification probability as calculated from the PID neural network.
1260 VARIABLE_GROUP(
"PID_expert");
1261 REGISTER_METAVARIABLE(
"pidLogLikelihoodValueExpert(pdgCode, detectorList)", pidLogLikelihoodValueExpert,
1262 "returns the log likelihood value of for a specific mass hypothesis and set of detectors.", Manager::VariableDataType::c_double);
1263 REGISTER_METAVARIABLE(
"pidDeltaLogLikelihoodValueExpert(pdgCode1, pdgCode2, detectorList)", pidDeltaLogLikelihoodValueExpert,
1264 "returns LogL(hyp1) - LogL(hyp2) (aka DLL) for two mass hypotheses and a set of detectors.", Manager::VariableDataType::c_double);
1265 REGISTER_METAVARIABLE(
"pidPairProbabilityExpert(pdgCodeHyp, pdgCodeTest, detectorList)", pidPairProbabilityExpert,
1266 "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})`",
1267 Manager::VariableDataType::c_double);
1268 REGISTER_METAVARIABLE(
"pidProbabilityExpert(pdgCodeHyp, detectorList)", pidProbabilityExpert,
1269 "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})`. ",
1270 Manager::VariableDataType::c_double);
1271 REGISTER_METAVARIABLE(
"pidLogarithmicProbabilityExpert(pdgCodeHyp, detectorList)", pidLogarithmicProbabilityExpert,
1272 "logarithmic equivalent of pidProbability (p) defined as log(p/(1-p)), which gives a smooth peak-like distribution",
1273 Manager::VariableDataType::c_double);
1274 REGISTER_METAVARIABLE(
"pidMissingProbabilityExpert(detectorList)", pidMissingProbabilityExpert,
1275 "returns 1 if PID is missing for at least one of the detectors in the list, otherwise 0. ",
1276 Manager::VariableDataType::c_double);
1277 REGISTER_VARIABLE(
"pidMostLikelyPDG(ePrior=1/6, muPrior=1/6, piPrior=1/6, KPrior=1/6, pPrior=1/6, dPrior=1/6)", mostLikelyPDG,
1279Returns PDG code of the largest PID likelihood, or NaN if PID information is not available.
1280This function accepts either no arguments, or 6 floats as priors for the charged particle hypotheses
1281following the order shown in the metavariable's declaration. Flat priors are assumed as default.)DOC");
1282 REGISTER_VARIABLE("pidIsMostLikely(ePrior=1/6, muPrior=1/6, piPrior=1/6, KPrior=1/6, pPrior=1/6, dPrior=1/6)", isMostLikely, R
"DOC(
1283Returns True if the largest PID likelihood of a given particle corresponds to its particle hypothesis.
1284This function accepts either no arguments, or 6 floats as priors for the charged particle hypotheses
1285following the order shown in the metavariable's declaration. Flat priors are assumed as default.)DOC");
1287 REGISTER_METAVARIABLE("pidWeightedLogLikelihoodValueExpert(weightMatrixName, pdgCode, detectorList)",
1288 pidWeightedLogLikelihoodValueExpert,
1289 "returns the weighted log likelihood value of for a specific mass hypothesis and set of detectors, "
1290 ":math:`\\log\\mathcal{\\tilde{L}}_{hyp} = \\sum_{j\\in\\mathrm{detectorList}} \\mathcal{w}_{hyp,j}\\log\\mathcal{L}_{hyp,j}`. "
1291 "The :math:`\\mathcal{L}_{ij}` is the original likelihood and :math:`\\mathcal{w}_{ij}` is the PID calibration weight of i-th particle type and j-th detector.",
1292 Manager::VariableDataType::c_double);
1293 REGISTER_METAVARIABLE(
"pidWeightedPairProbabilityExpert(weightMatrixName, pdgCodeHyp, pdgCodeTest, detectorList)",
1294 pidWeightedPairProbabilityExpert,
1295 "Weighted pair (or binary) probability for the pdgCodeHyp mass hypothesis with respect to the pdgCodeTest one, using an arbitrary set of detectors, "
1296 ":math:`\\mathcal{\\tilde{L}}_{hyp}/(\\mathcal{\\tilde{L}}_{test}+\\mathcal{\\tilde{L}}_{hyp})` where :math:`\\mathcal{\\tilde{L}}_{i}` is defined as "
1297 ":math:`\\log\\mathcal{\\tilde{L}}_{i} = \\sum_{j\\in\\mathrm{detectorList}} \\mathcal{w}_{i,j}\\log\\mathcal{L}_{i,j}`. "
1298 "The :math:`\\mathcal{L}_{ij}` is the original likelihood and :math:`\\mathcal{w}_{ij}` is the PID calibration weight of i-th particle type and j-th detector.",
1299 Manager::VariableDataType::c_double);
1300 REGISTER_METAVARIABLE(
"pidWeightedProbabilityExpert(weightMatrixName, pdgCodeHyp, detectorList)",
1301 pidWeightedProbabilityExpert,
1302 "Weighted probability for the pdgCodeHyp mass hypothesis with respect to all the other ones, using an arbitrary set of detectors, "
1303 ":math:`\\mathcal{\\tilde{L}}_{hyp}/\\sum_{i=e,\\mu,\\pi,K,p,d} \\mathcal{\\tilde{L}}_i` where :math:`\\mathcal{\\tilde{L}}_{i}` is defined as "
1304 ":math:`\\log\\mathcal{\\tilde{L}}_{i} = \\sum_{j\\in\\mathrm{detectorList}} \\mathcal{w}_{i,j}\\log\\mathcal{L}_{i,j}`. "
1305 "The :math:`\\mathcal{L}_{ij}` is the original likelihood and :math:`\\mathcal{w}_{ij}` is the PID calibration weight of i-th particle type and j-th detector.",
1306 Manager::VariableDataType::c_double);
1307 REGISTER_METAVARIABLE(
"pidNeuralNetworkValueExpert(pdgCodeHyp, PIDNeuralNetworkName)",
1308 pidNeuralNetworkValueExpert,
1309 "Probability for the particle hypothesis pdgCodeHype calculated from a neural network, which uses high-level information as inputs, "
1310 "such as the likelihood from the 6 subdetectors for PID for all 6 hypotheses, "
1311 ":math:`\\mathcal{\\tilde{L}}_{hyp}^{det}`, or the track momentum and charge",
1312 Manager::VariableDataType::c_double);
1313 REGISTER_VARIABLE(
"klmMuonIDDNN", klmMuonIDDNN,
1314 "Muon probability calculated from Neural Network with KLM information (expert use only)");
1317 VARIABLE_GROUP(
"Belle PID variables");
1318 REGISTER_METAVARIABLE(
"atcPIDBelle(i,j)", atcPIDBelle, R
"DOC(
1319[Legacy] Returns Belle's PID atc variable: ``atc_pid(3,1,5,i,j).prob()``.
1320Parameters i,j are signal and background hypothesis: (0 = electron, 1 = muon, 2 = pion, 3 = kaon, 4 = proton)
1321Returns 0.5 in case there is no likelihood found and a factor of 0.5 will appear in the product if any of the subdetectors don't report a likelihood (Belle behaviour).
1323.. warning:: The behaviour is different from Belle II PID variables which typically return NaN in case of error.
1324 )DOC", Manager::VariableDataType::c_double);
1325 REGISTER_VARIABLE("muIDBelle", muIDBelle, R
"DOC(
1326[Legacy] Returns Belle's PID ``Muon_likelihood()`` variable.
1327Returns 0.5 in case there is no likelihood found and returns zero if the muon likelihood is not usable (Belle behaviour).
1329.. warning:: The behaviour is different from Belle II PID variables which typically return NaN in case of error.
1331 REGISTER_VARIABLE("muIDBelleQuality", muIDBelleQuality, R
"DOC(
1332[Legacy] Returns true if Belle's PID ``Muon_likelihood()`` is usable (reliable).
1333Returns zero/false if not usable or if there is no PID found.
1335 REGISTER_VARIABLE("eIDBelle", eIDBelle, R
"DOC(
1336[Legacy] Returns Belle's electron ID ``eid(3,-1,5).prob()`` variable.
1337Returns 0.5 in case there is no likelihood found (Belle behaviour).
1339.. warning:: The behaviour is different from Belle II PID variables which typically return NaN in case of error.
static const unsigned int c_SetSize
Number of elements (for use in array bounds etc.)
static DetectorSet set()
Accessor function for the set of valid detectors.
int getPDGCode() const
PDG code.
static DetectorSet set()
Accessor for the set of valid detector IDs.
static const ParticleType neutron
neutron particle
static const ChargedStable muon
muon particle
RestrictedDetectorSet< PIDDetectors > PIDDetectorSet
Typedef for set of PID detectors.
static const ParticleSet chargedStableSet
set of charged stable particles
EDetector
Enum for identifying the detector components (detector and subdetector).
static const ChargedStable pion
charged pion particle
static const ChargedStable proton
proton particle
static const double doubleNaN
quiet_NaN
static const ChargedStable kaon
charged kaon particle
static const ChargedStable electron
electron particle
static const ChargedStable deuteron
deuteron particle
static const ReferenceFrame & GetCurrent()
Get current rest frame.
std::function< VarVariant(const Particle *)> FunctionPtr
functions stored take a const Particle* and return VarVariant.
const Var * getVariable(std::string name)
Get the variable belonging to the given key.
static Manager & Instance()
get singleton instance.
Abstract base class for different kinds of events.
FunctionPtr function
Pointer to function.