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);
117 if (arguments.size() < 2) {
118 B2ERROR(
"Need at least two arguments to pidLogLikelihoodValueExpert");
123 pdgCode = Belle2::convertString<int>(arguments[0]);
124 }
catch (std::invalid_argument& e) {
125 B2ERROR(
"First argument of pidLogLikelihoodValueExpert must be a PDG code");
128 std::vector<std::string> detectors(arguments.begin() + 1, arguments.end());
131 auto hypType = Const::ChargedStable(abs(pdgCode));
133 auto func = [hypType, detectorSet](
const Particle * part) ->
double {
134 const PIDLikelihood* pid = part->getPIDLikelihood();
138 if (pid->getLogL(hypType, detectorSet) == 0)
141 return pid->getLogL(hypType, detectorSet);
148 Manager::FunctionPtr pidDeltaLogLikelihoodValueExpert(
const std::vector<std::string>& arguments)
150 if (arguments.size() < 3) {
151 B2ERROR(
"Need at least three arguments to pidDeltaLogLikelihoodValueExpert");
154 int pdgCodeHyp, pdgCodeTest;
156 pdgCodeHyp = Belle2::convertString<int>(arguments[0]);
157 }
catch (std::invalid_argument& e) {
158 B2ERROR(
"First argument of pidDeltaLogLikelihoodValueExpert must be a PDG code");
162 pdgCodeTest = Belle2::convertString<int>(arguments[1]);
163 }
catch (std::invalid_argument& e) {
164 B2ERROR(
"Second argument of pidDeltaLogLikelihoodValueExpert must be a PDG code");
168 std::vector<std::string> detectors(arguments.begin() + 2, arguments.end());
170 auto hypType = Const::ChargedStable(abs(pdgCodeHyp));
171 auto testType = Const::ChargedStable(abs(pdgCodeTest));
173 auto func = [hypType, testType, detectorSet](
const Particle * part) ->
double {
174 const PIDLikelihood* pid = part->getPIDLikelihood();
177 if (pid->getLogL(hypType, detectorSet) == 0)
180 return (pid->getLogL(hypType, detectorSet) - pid->getLogL(testType, detectorSet));
188 if (arguments.size() < 3) {
189 B2ERROR(
"Need at least three arguments to pidPairProbabilityExpert");
192 int pdgCodeHyp = 0, pdgCodeTest = 0;
194 pdgCodeHyp = Belle2::convertString<int>(arguments[0]);
195 }
catch (std::invalid_argument& e) {
196 B2ERROR(
"First argument of pidPairProbabilityExpert must be PDG code");
200 pdgCodeTest = Belle2::convertString<int>(arguments[1]);
201 }
catch (std::invalid_argument& e) {
202 B2ERROR(
"Second argument of pidPairProbabilityExpert must be PDG code");
206 std::vector<std::string> detectors(arguments.begin() + 2, arguments.end());
209 auto hypType = Const::ChargedStable(abs(pdgCodeHyp));
210 auto testType = Const::ChargedStable(abs(pdgCodeTest));
211 auto func = [hypType, testType, detectorSet](
const Particle * part) ->
double {
212 const PIDLikelihood* pid = part->getPIDLikelihood();
215 if (pid->getLogL(hypType, detectorSet) == 0)
218 return pid->getProbability(hypType, testType, detectorSet);
226 if (arguments.size() < 2) {
227 B2ERROR(
"Need at least two arguments for pidProbabilityExpert");
232 pdgCodeHyp = Belle2::convertString<int>(arguments[0]);
233 }
catch (std::invalid_argument& e) {
234 B2ERROR(
"First argument of pidProbabilityExpert must be PDG code");
238 std::vector<std::string> detectors(arguments.begin() + 1, arguments.end());
240 auto hypType = Const::ChargedStable(abs(pdgCodeHyp));
245 for (
double& i : frac) i = 1.0;
247 auto func = [hypType, frac, detectorSet](
const Particle * part) ->
double {
248 const PIDLikelihood* pid = part->getPIDLikelihood();
251 if (pid->getLogL(hypType, detectorSet) == 0)
254 return pid->getProbability(hypType, frac, detectorSet);
262 if (arguments.size() < 1) {
263 B2ERROR(
"Need at least one argument to pidMissingProbabilityExpert");
267 std::vector<std::string> detectors(arguments.begin(), arguments.end());
270 auto func = [detectorSet](
const Particle * part) ->
double {
271 const PIDLikelihood* pid = part->getPIDLikelihood();
273 if (not pid->isAvailable(detectorSet))
280 Manager::FunctionPtr pidWeightedLogLikelihoodValueExpert(
const std::vector<std::string>& arguments)
282 if (arguments.size() < 3) {
283 B2ERROR(
"Need at least three arguments to pidWeightedLogLikelihoodValueExpert");
286 std::string matrixName = arguments[0];
290 pdgCode = Belle2::convertString<int>(arguments[1]);
291 }
catch (std::invalid_argument& e) {
292 B2ERROR(
"Second argument of pidWeightedLogLikelihoodValueExpert must be a PDG code");
295 std::vector<std::string> detectors(arguments.begin() + 2, arguments.end());
297 auto hypType = Const::ChargedStable(abs(pdgCode));
299 auto func = [hypType, detectorSet, matrixName](
const Particle * part) ->
double {
300 PIDCalibrationWeightUtil weightMatrix(matrixName);
301 const PIDLikelihood* pid = part->getPIDLikelihood();
305 if (pid->getLogL(hypType, detectorSet) == 0)
309 auto mom = frame.getMomentum(part);
311 auto theta = mom.Theta();
316 if (detectorSet.contains(detector))
317 LogL += pid->getLogL(hypType, detector) * weightMatrix.getWeight(hypType.getPDGCode(), detector, p, theta);
327 if (arguments.size() < 3) {
328 B2ERROR(
"Need at least three arguments for pidWeightedProbabilityExpert");
331 std::string matrixName = arguments[0];
335 pdgCodeHyp = Belle2::convertString<int>(arguments[1]);
336 }
catch (std::invalid_argument& e) {
337 B2ERROR(
"Second argument of pidWeightedProbabilityExpert must be PDG code");
341 std::vector<std::string> detectors(arguments.begin() + 2, arguments.end());
343 auto hypType = Const::ChargedStable(abs(pdgCodeHyp));
345 auto func = [hypType, detectorSet, matrixName](
const Particle * part) ->
double {
346 PIDCalibrationWeightUtil weightMatrix(matrixName);
347 const PIDLikelihood* pid = part->getPIDLikelihood();
350 if (pid->getLogL(hypType, detectorSet) == 0)
354 auto mom = frame.getMomentum(part);
356 auto theta = mom.Theta();
363 const int index_pdg = pdgIter.getIndex();
367 if (detectorSet.contains(detector))
368 LogL[index_pdg] += pid->getLogL(pdgIter, detector) * weightMatrix.getWeight(pdgIter.getPDGCode(), detector, p, theta);
371 if (!hasMax || (LogL[index_pdg] > LogL_max)) {
372 LogL_max = LogL[index_pdg];
378 for (
auto LogL_i : LogL)
379 norm += exp(LogL_i - LogL_max);
382 return exp(LogL[hypType.getIndex()] - LogL_max) / norm;
392 if (arguments.size() == 0) {
393 B2ERROR(
"Need pdg code for pidNeuralNetworkValueExpert");
396 if (arguments.size() > 2) {
397 B2ERROR(
"pidNeuralNetworkValueExpert expects at most two arguments, i.e. the pdg code and the pidNeuralNetworkName");
402 pdgCode = abs(Belle2::convertString<int>(arguments[0]));
403 }
catch (std::invalid_argument& e) {
404 B2ERROR(
"First argument of pidNeuralNetworkValueExpert must be a PDG code");
408 std::shared_ptr<PIDNeuralNetwork> neuralNetworkPtr;
409 if (arguments.size() == 2) {
410 std::string parameterSetName = arguments[1];
411 neuralNetworkPtr = std::make_shared<PIDNeuralNetwork>(parameterSetName);
413 neuralNetworkPtr = std::make_shared<PIDNeuralNetwork>();
416 neuralNetworkPtr->hasPdgCode(pdgCode,
true);
418 auto func = [neuralNetworkPtr, pdgCode](
const Particle * part) ->
double {
419 const auto& extraInfoName = neuralNetworkPtr->getExtraInfoName(pdgCode);
420 if (part->hasExtraInfo(extraInfoName))
421 return part->getExtraInfo(extraInfoName);
423 const PIDLikelihood* pid = part->getPIDLikelihood();
428 auto hypType = Const::ChargedStable(pdgCode);
429 if (pid->getLogL(hypType) == 0)
434 std::vector<float> inputsNN;
435 inputsNN.reserve(neuralNetworkPtr->getInputSize());
436 for (
const auto& inputName : neuralNetworkPtr->getInputBasf2Names())
439 const auto probabilities = neuralNetworkPtr->predict(inputsNN);
442 for (
const auto element : probabilities)
444 const auto [pdgCodeElement, probability] = element;
445 const_cast<Particle*
>(part)->addExtraInfo(neuralNetworkPtr->getExtraInfoName(pdgCodeElement), probability);
448 return probabilities.at(pdgCode);
455 Manager::FunctionPtr pidWeightedPairProbabilityExpert(
const std::vector<std::string>& arguments)
457 if (arguments.size() < 4) {
458 B2ERROR(
"Need at least four arguments to pidWeightedPairProbabilityExpert");
461 std::string matrixName = arguments[0];
463 int pdgCodeHyp = 0, pdgCodeTest = 0;
465 pdgCodeHyp = Belle2::convertString<int>(arguments[1]);
466 }
catch (std::invalid_argument& e) {
467 B2ERROR(
"Second argument of pidWeightedPairProbabilityExpert must be PDG code");
471 pdgCodeTest = Belle2::convertString<int>(arguments[2]);
472 }
catch (std::invalid_argument& e) {
473 B2ERROR(
"Third argument of pidWeightedPairProbabilityExpert must be PDG code");
477 std::vector<std::string> detectors(arguments.begin() + 3, arguments.end());
480 auto hypType = Const::ChargedStable(abs(pdgCodeHyp));
481 auto testType = Const::ChargedStable(abs(pdgCodeTest));
483 auto func = [hypType, testType, detectorSet, matrixName](
const Particle * part) ->
double {
484 PIDCalibrationWeightUtil weightMatrix(matrixName);
486 const PIDLikelihood* pid = part->getPIDLikelihood();
489 if (pid->getLogL(hypType, detectorSet) == 0)
493 auto mom = frame.getMomentum(part);
495 auto theta = mom.Theta();
497 double LogL_hypType(0), LogL_testType(0);
500 if (detectorSet.contains(detector)) {
501 LogL_hypType += pid->getLogL(hypType, detector) * weightMatrix.getWeight(hypType.getPDGCode(), detector, p, theta);
502 LogL_testType += pid->getLogL(testType, detector) * weightMatrix.getWeight(testType.getPDGCode(), detector, p, theta);
506 double deltaLogL = LogL_testType - LogL_hypType;
510 double eLogL = exp(deltaLogL);
511 res = 1. / (1. + eLogL);
514 double eLogL = exp(-deltaLogL);
515 res = eLogL / (1.0 + eLogL);
518 if (std::isfinite(res))
526 double electronID(
const Particle* part)
529 pidProbabilityExpert({
"11",
"ALL"});
530 return std::get<double>(pidFunction(part));
533 double muonID(
const Particle* part)
536 pidProbabilityExpert({
"13",
"ALL"});
537 return std::get<double>(pidFunction(part));
540 double pionID(
const Particle* part)
543 pidProbabilityExpert({
"211",
"ALL"});
544 return std::get<double>(pidFunction(part));
547 double kaonID(
const Particle* part)
550 pidProbabilityExpert({
"321",
"ALL"});
551 return std::get<double>(pidFunction(part));
554 double protonID(
const Particle* part)
557 pidProbabilityExpert({
"2212",
"ALL"});
558 return std::get<double>(pidFunction(part));
561 double deuteronID(
const Particle* part)
564 pidProbabilityExpert({
"1000010020",
"ALL"});
565 return std::get<double>(pidFunction(part));
568 double binaryPID(
const Particle* part,
const std::vector<double>& arguments)
570 if (arguments.size() != 2) {
571 B2ERROR(
"The variable binaryPID needs exactly two arguments: the PDG codes of two hypotheses.");
574 int pdgCodeHyp = std::abs(
int(std::lround(arguments[0])));
575 int pdgCodeTest = std::abs(
int(std::lround(arguments[1])));
576 return std::get<double>(
Manager::Instance().getVariable(
"pidPairProbabilityExpert(" + std::to_string(
577 pdgCodeHyp) +
", " + std::to_string(
578 pdgCodeTest) +
", ALL)")->function(part));
581 double electronID_noSVD(
const Particle* part)
585 pidProbabilityExpert({
"11",
"CDC",
"TOP",
"ARICH",
"ECL",
"KLM"});
586 return std::get<double>(pidFunction(part));
589 double muonID_noSVD(
const Particle* part)
593 pidProbabilityExpert({
"13",
"CDC",
"TOP",
"ARICH",
"ECL",
"KLM"});
594 return std::get<double>(pidFunction(part));
597 double pionID_noSVD(
const Particle* part)
601 pidProbabilityExpert({
"211",
"CDC",
"TOP",
"ARICH",
"ECL",
"KLM"});
602 return std::get<double>(pidFunction(part));
605 double kaonID_noSVD(
const Particle* part)
609 pidProbabilityExpert({
"321",
"CDC",
"TOP",
"ARICH",
"ECL",
"KLM"});
610 return std::get<double>(pidFunction(part));
613 double protonID_noSVD(
const Particle* part)
617 pidProbabilityExpert({
"2212",
"CDC",
"TOP",
"ARICH",
"ECL",
"KLM"});
618 return std::get<double>(pidFunction(part));
621 double deuteronID_noSVD(
const Particle* part)
625 pidProbabilityExpert({
"1000010020",
"CDC",
"TOP",
"ARICH",
"ECL",
"KLM"});
626 return std::get<double>(pidFunction(part));
629 double binaryPID_noSVD(
const Particle* part,
const std::vector<double>& arguments)
632 if (arguments.size() != 2) {
633 B2ERROR(
"The variable binaryPID_noSVD needs exactly two arguments: the PDG codes of two hypotheses.");
636 int pdgCodeHyp = std::abs(
int(std::lround(arguments[0])));
637 int pdgCodeTest = std::abs(
int(std::lround(arguments[1])));
638 return std::get<double>(
Manager::Instance().getVariable(
"pidPairProbabilityExpert(" + std::to_string(
639 pdgCodeHyp) +
", " + std::to_string(
640 pdgCodeTest) +
", CDC, TOP, ARICH, ECL, KLM)")->function(part));
643 double electronID_noTOP(
const Particle* part)
647 pidProbabilityExpert({
"11",
"SVD",
"CDC",
"ARICH",
"ECL",
"KLM"});
648 return std::get<double>(pidFunction(part));
651 double binaryElectronID_noTOP(
const Particle* part,
const std::vector<double>& arguments)
654 if (arguments.size() != 1) {
655 B2ERROR(
"The variable binaryElectronID_noTOP needs exactly one argument: the PDG code of the test hypothesis.");
660 int pdgCodeTest = std::abs(
int(std::lround(arguments[0])));
662 const auto var =
"pidPairProbabilityExpert(" + std::to_string(pdgCodeHyp) +
", " +
663 std::to_string(pdgCodeTest) +
", SVD, CDC, ARICH, ECL, KLM)";
668 double electronID_noSVD_noTOP(
const Particle* part)
672 pidProbabilityExpert({
"11",
"CDC",
"ARICH",
"ECL",
"KLM"});
673 return std::get<double>(pidFunction(part));
676 double binaryElectronID_noSVD_noTOP(
const Particle* part,
const std::vector<double>& arguments)
679 if (arguments.size() != 1) {
680 B2ERROR(
"The variable binaryElectronID_noSVD_noTOP needs exactly one argument: the PDG code of the test hypothesis.");
685 int pdgCodeTest = std::abs(
int(std::lround(arguments[0])));
687 const auto var =
"pidPairProbabilityExpert(" + std::to_string(pdgCodeHyp) +
", " +
688 std::to_string(pdgCodeTest) +
", CDC, ARICH, ECL, KLM)";
694 double pionID_noARICHwoECL(
const Particle* part)
697 const ECLCluster* cluster = part->getECLCluster();
699 const PIDLikelihood* pid = part->getPIDLikelihood();
703 pidProbabilityExpert({
"211",
"SVD",
"CDC",
"TOP",
"ECL",
"KLM"});
704 return std::get<double>(pidFunction(part));
711 double kaonID_noARICHwoECL(
const Particle* part)
714 const ECLCluster* cluster = part->getECLCluster();
716 const PIDLikelihood* pid = part->getPIDLikelihood();
720 pidProbabilityExpert({
"321",
"SVD",
"CDC",
"TOP",
"ECL",
"KLM"});
721 return std::get<double>(pidFunction(part));
728 double binaryPID_noARICHwoECL(
const Particle* part,
const std::vector<double>& arguments)
731 if (arguments.size() != 2) {
732 B2ERROR(
"The variable binaryPID_noARICHwoECL needs exactly two arguments: the PDG codes of two hypotheses.");
735 int pdgCodeHyp = std::abs(
int(std::lround(arguments[0])));
736 int pdgCodeTest = std::abs(
int(std::lround(arguments[1])));
737 auto hypType = Const::ChargedStable(abs(pdgCodeHyp));
738 auto testType = Const::ChargedStable(abs(pdgCodeTest));
740 const ECLCluster* cluster = part->getECLCluster();
742 const PIDLikelihood* pid = part->getPIDLikelihood();
744 double lkhdiff = pid->getLogL(hypType, Const::ARICH) - pid->getLogL(testType, Const::ARICH);
745 if ((lkhdiff > 0 && pdgCodeHyp > pdgCodeTest) || (lkhdiff < 0 && pdgCodeHyp < pdgCodeTest)) {
746 return std::get<double>(
Manager::Instance().getVariable(
"pidPairProbabilityExpert(" + std::to_string(
747 pdgCodeHyp) +
", " + std::to_string(
748 pdgCodeTest) +
", SVD, CDC, TOP, ECL, KLM)")->function(part));
752 return binaryPID(part, arguments);
758 double antineutronID(
const Particle* particle)
760 if (particle->hasExtraInfo(
"nbarID")) {
761 return particle->getExtraInfo(
"nbarID");
764 B2WARNING(
"The extraInfo nbarID is not registered! \n"
765 "Please use function getNbarIDMVA in modularAnalysis.");
773 if (arguments.size() != 2) {
774 B2ERROR(
"Need exactly two arguments for pidChargedBDTScore: pdgCodeHyp, detector");
780 hypPdgId = Belle2::convertString<int>(arguments.at(0));
781 }
catch (std::invalid_argument& e) {
782 B2ERROR(
"First argument of pidChargedBDTScore must be an integer (PDG code).");
785 Const::ChargedStable hypType = Const::ChargedStable(hypPdgId);
787 std::vector<std::string> detectors(arguments.begin() + 1, arguments.end());
790 auto func = [hypType, detectorSet](
const Particle * part) ->
double {
791 auto name =
"pidChargedBDTScore_" + std::to_string(hypType.getPDGCode());
794 name +=
"_" + std::to_string(detector);
796 return (part->hasExtraInfo(name)) ? part->getExtraInfo(name) :
Const::doubleNaN;
803 if (arguments.size() != 3) {
804 B2ERROR(
"Need exactly three arguments for pidPairChargedBDTScore: pdgCodeHyp, pdgCodeTest, detector.");
808 int hypPdgId, testPdgId;
810 hypPdgId = Belle2::convertString<int>(arguments.at(0));
811 }
catch (std::invalid_argument& e) {
812 B2ERROR(
"First argument of pidPairChargedBDTScore must be an integer (PDG code).");
816 testPdgId = Belle2::convertString<int>(arguments.at(1));
817 }
catch (std::invalid_argument& e) {
818 B2ERROR(
"First argument of pidPairChargedBDTScore must be an integer (PDG code).");
821 Const::ChargedStable hypType = Const::ChargedStable(hypPdgId);
822 Const::ChargedStable testType = Const::ChargedStable(testPdgId);
824 std::vector<std::string> detectors(arguments.begin() + 2, arguments.end());
827 auto func = [hypType, testType, detectorSet](
const Particle * part) ->
double {
828 auto name =
"pidPairChargedBDTScore_" + std::to_string(hypType.getPDGCode()) +
"_VS_" + std::to_string(testType.getPDGCode());
831 name +=
"_" + std::to_string(detector);
833 return (part->hasExtraInfo(name)) ? part->getExtraInfo(name) :
Const::doubleNaN;
838 double mostLikelyPDG(
const Particle* part,
const std::vector<double>& arguments)
845 if (arguments.size() == 0) {
848 copy(arguments.begin(), arguments.end(), prob);
851 auto* pid = part->getPIDLikelihood();
853 return pid->getMostLikely(prob).getPDGCode();
856 bool isMostLikely(
const Particle* part,
const std::vector<double>& arguments)
862 return mostLikelyPDG(part, arguments) == abs(part->getPDGCode());
868 if (arguments.size() == 0) {
869 varName =
"pidWeightedProbabilityExpert(PIDCalibrationWeightMatrix, 11, ALL)";
870 }
else if (arguments.size() == 1) {
871 varName =
"pidWeightedProbabilityExpert(" + arguments[0] +
", 11, ALL)";
873 B2ERROR(
"Need zero or one argument for weightedElectronID");
878 auto func = [var](
const Particle * particle) ->
double {
879 return std::get<double>(var->function(particle));
887 if (arguments.size() == 0) {
888 varName =
"pidWeightedProbabilityExpert(PIDCalibrationWeightMatrix, 13, ALL)";
889 }
else if (arguments.size() == 1) {
890 varName =
"pidWeightedProbabilityExpert(" + arguments[0] +
", 13, ALL)";
892 B2ERROR(
"Need zero or one argument for weightedMuonID");
897 auto func = [var](
const Particle * particle) ->
double {
898 return std::get<double>(var->function(particle));
906 if (arguments.size() == 0) {
907 varName =
"pidWeightedProbabilityExpert(PIDCalibrationWeightMatrix, 211, ALL)";
908 }
else if (arguments.size() == 1) {
909 varName =
"pidWeightedProbabilityExpert(" + arguments[0] +
", 211, ALL)";
911 B2ERROR(
"Need zero or one argument for weightedPionID");
916 auto func = [var](
const Particle * particle) ->
double {
917 return std::get<double>(var->function(particle));
925 if (arguments.size() == 0) {
926 varName =
"pidWeightedProbabilityExpert(PIDCalibrationWeightMatrix, 321, ALL)";
927 }
else if (arguments.size() == 1) {
928 varName =
"pidWeightedProbabilityExpert(" + arguments[0] +
", 321, ALL)";
930 B2ERROR(
"Need zero or one argument for weightedKaonID");
935 auto func = [var](
const Particle * particle) ->
double {
936 return std::get<double>(var->function(particle));
944 if (arguments.size() == 0) {
945 varName =
"pidWeightedProbabilityExpert(PIDCalibrationWeightMatrix, 2212, ALL)";
946 }
else if (arguments.size() == 1) {
947 varName =
"pidWeightedProbabilityExpert(" + arguments[0] +
", 2212, ALL)";
949 B2ERROR(
"Need zero or one argument for weightedProtonID");
954 auto func = [var](
const Particle * particle) ->
double {
955 return std::get<double>(var->function(particle));
963 if (arguments.size() == 0) {
964 varName =
"pidWeightedProbabilityExpert(PIDCalibrationWeightMatrix, 1000010020, ALL)";
965 }
else if (arguments.size() == 1) {
966 varName =
"pidWeightedProbabilityExpert(" + arguments[0] +
", 1000010020, ALL)";
968 B2ERROR(
"Need zero or one argument for weightedDeuteronID");
973 auto func = [var](
const Particle * particle) ->
double {
974 return std::get<double>(var->function(particle));
980 double pionIDNN(
const Particle* particle)
982 if (particle->hasExtraInfo(
"pidNeuralNetworkValueExpert(211)"))
983 return particle->getExtraInfo(
"pidNeuralNetworkValueExpert(211)");
984 static auto func = pidNeuralNetworkValueExpert({
"211"});
985 return std::get<double>(func(particle));
988 double kaonIDNN(
const Particle* particle)
990 if (particle->hasExtraInfo(
"pidNeuralNetworkValueExpert(321)"))
991 return particle->getExtraInfo(
"pidNeuralNetworkValueExpert(321)");
992 static auto func = pidNeuralNetworkValueExpert({
"321"});
993 return std::get<double>(func(particle));
1001 double muIDBelle(
const Particle* particle)
1003 const PIDLikelihood* pid = particle->getPIDLikelihood();
1004 if (!pid)
return 0.5;
1006 if (pid->isAvailable(Const::KLM))
1007 return exp(pid->getLogL(
Const::muon, Const::KLM));
1012 double muIDBelleQuality(
const Particle* particle)
1014 const PIDLikelihood* pid = particle->getPIDLikelihood();
1017 return pid->isAvailable(Const::KLM);
1020 double atcPIDBelle(
const Particle* particle,
const std::vector<double>& sigAndBkgHyp)
1022 int sigHyp = int(std::lround(sigAndBkgHyp[0]));
1023 int bkgHyp = int(std::lround(sigAndBkgHyp[1]));
1025 const PIDLikelihood* pid = particle->getPIDLikelihood();
1026 if (!pid)
return 0.5;
1030 double acc_sig = exp(pid->getLogL(hypothesisConversion(sigHyp), set));
1031 double acc_bkg = exp(pid->getLogL(hypothesisConversion(bkgHyp), set));
1033 if (acc_sig + acc_bkg > 0.0)
1034 acc = acc_sig / (acc_sig + acc_bkg);
1038 double tof_sig = exp(pid->getLogL(hypothesisConversion(sigHyp), set));
1039 double tof_bkg = exp(pid->getLogL(hypothesisConversion(bkgHyp), set));
1041 double tof_all = tof_sig + tof_bkg;
1043 tof = tof_sig / tof_all;
1044 if (tof < 0.001) tof = 0.001;
1045 if (tof > 0.999) tof = 0.999;
1050 double cdc_sig = exp(pid->getLogL(hypothesisConversion(sigHyp), set));
1051 double cdc_bkg = exp(pid->getLogL(hypothesisConversion(bkgHyp), set));
1053 double cdc_all = cdc_sig + cdc_bkg;
1055 cdc = cdc_sig / cdc_all;
1056 if (cdc < 0.001) cdc = 0.001;
1057 if (cdc > 0.999) cdc = 0.999;
1061 double pid_sig = acc * tof * cdc;
1062 double pid_bkg = (1. - acc) * (1. - tof) * (1. - cdc);
1064 return pid_sig / (pid_sig + pid_bkg);
1068 double eIDBelle(
const Particle* part)
1070 const PIDLikelihood* pid = part->getPIDLikelihood();
1071 if (!pid)
return 0.5;
1079 VARIABLE_GROUP(
"PID");
1080 REGISTER_VARIABLE(
"particleID", particleID,
1081 "the particle identification probability under the particle's own hypothesis, using info from all available detectors");
1082 REGISTER_VARIABLE(
"electronID", electronID,
1083 "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");
1084 REGISTER_VARIABLE(
"muonID", muonID,
1085 "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");
1086 REGISTER_VARIABLE(
"pionID", pionID,
1087 "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");
1088 REGISTER_VARIABLE(
"kaonID", kaonID,
1089 "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");
1090 REGISTER_VARIABLE(
"protonID", protonID,
1091 "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");
1092 REGISTER_VARIABLE(
"deuteronID", deuteronID,
1093 "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");
1094 REGISTER_METAVARIABLE(
"binaryPID(pdgCode1, pdgCode2)", binaryPID,
1095 "Returns the binary probability for the first provided mass hypothesis with respect to the second mass hypothesis using all detector components",
1096 Manager::VariableDataType::c_double);
1097 REGISTER_METAVARIABLE(
"pidChargedBDTScore(pdgCodeHyp, detector)", pidChargedBDTScore,
1098 "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.",
1099 Manager::VariableDataType::c_double);
1100 REGISTER_METAVARIABLE(
"pidPairChargedBDTScore(pdgCodeHyp, pdgCodeTest, detector)", pidPairChargedBDTScore,
1101 "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.",
1102 Manager::VariableDataType::c_double);
1103 REGISTER_VARIABLE(
"nbarID", antineutronID, R
"DOC(
1104Returns MVA classifier for antineutron PID.
1106- 1 signal(antineutron) like
1108- -1 invalid using this PID due to some ECL variables used unavailable
1110This PID is only for antineutron. Neutron is also considered as background.
1111The variables used are `clusterPulseShapeDiscriminationMVA`, `clusterE`, `clusterLAT`, `clusterE1E9`, `clusterE9E21`,
1112`clusterAbsZernikeMoment40`, `clusterAbsZernikeMoment51`, `clusterZernikeMVA`.)DOC");
1115 REGISTER_VARIABLE(
"electronID_noSVD", electronID_noSVD,
1116 "**(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*");
1117 REGISTER_VARIABLE(
"muonID_noSVD", muonID_noSVD,
1118 "**(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*");
1119 REGISTER_VARIABLE(
"pionID_noSVD", pionID_noSVD,
1120 "**(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*");
1121 REGISTER_VARIABLE(
"kaonID_noSVD", kaonID_noSVD,
1122 "**(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*");
1123 REGISTER_VARIABLE(
"protonID_noSVD", protonID_noSVD,
1124 "**(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*");
1125 REGISTER_VARIABLE(
"deuteronID_noSVD", deuteronID_noSVD,
1126 "**(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*");
1127 REGISTER_METAVARIABLE(
"binaryPID_noSVD(pdgCode1, pdgCode2)", binaryPID_noSVD,
1128 "Returns the binary probability for the first provided mass hypothesis with respect to the second mass hypothesis using all detector components, *excluding the SVD*.",
1129 Manager::VariableDataType::c_double);
1130 REGISTER_VARIABLE(
"electronID_noTOP", electronID_noTOP,
1131 "**(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*");
1132 REGISTER_METAVARIABLE(
"binaryElectronID_noTOP(pdgCodeTest)", binaryElectronID_noTOP,
1133 "**(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**",
1134 Manager::VariableDataType::c_double);
1135 REGISTER_VARIABLE(
"electronID_noSVD_noTOP", electronID_noSVD_noTOP,
1136 "**(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*");
1137 REGISTER_METAVARIABLE(
"binaryElectronID_noSVD_noTOP(pdgCodeTest)", binaryElectronID_noSVD_noTOP,
1138 "**(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**",
1139 Manager::VariableDataType::c_double);
1140 REGISTER_VARIABLE(
"pionID_noARICHwoECL", pionID_noARICHwoECL,
1141 "**(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");
1142 REGISTER_VARIABLE(
"kaonID_noARICHwoECL", kaonID_noARICHwoECL,
1143 "**(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");
1144 REGISTER_METAVARIABLE(
"binaryPID_noARICHwoECL(pdgCode1, pdgCode2)", binaryPID_noARICHwoECL,
1145 "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",
1146 Manager::VariableDataType::c_double);
1149 REGISTER_METAVARIABLE(
"weightedElectronID(weightMatrixName)", weightedElectronID,
1151weighted electron identification probability defined as :math:`\frac{\mathcal{\tilde{L}}_e}{\sum_{i=e,\mu,\pi,K,p,d} \mathcal{\tilde{L}}_i}`,
1152where :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}`.
1153The :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.
1154One can provide the name of the weight matrix as the argument.
1156 Manager::VariableDataType::c_double);
1157 REGISTER_METAVARIABLE("weightedMuonID(weightMatrixName)", weightedMuonID,
1159weighted muon identification probability defined as :math:`\frac{\mathcal{\tilde{L}}_\mu}{\sum_{i=e,\mu,\pi,K,p,d} \mathcal{\tilde{L}}_i}`,
1160where :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}`.
1161The :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.
1162One can provide the name of the weight matrix as the argument.
1164 Manager::VariableDataType::c_double);
1165 REGISTER_METAVARIABLE("weightedPionID(weightMatrixName)", weightedPionID,
1167weighted pion identification probability defined as :math:`\frac{\mathcal{\tilde{L}}_\pi}{\sum_{i=e,\mu,\pi,K,p,d} \mathcal{\tilde{L}}_i}`,
1168where :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}`.
1169The :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.
1170One can provide the name of the weight matrix as the argument.
1172 Manager::VariableDataType::c_double);
1173 REGISTER_METAVARIABLE("weightedKaonID(weightMatrixName)", weightedKaonID,
1175weighted kaon identification probability defined as :math:`\frac{\mathcal{\tilde{L}}_K}{\sum_{i=e,\mu,\pi,K,p,d} \mathcal{\tilde{L}}_i}`,
1176where :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}`.
1177The :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.
1178One can provide the name of the weight matrix as the argument.
1180 Manager::VariableDataType::c_double);
1181 REGISTER_METAVARIABLE("weightedProtonID(weightMatrixName)", weightedProtonID,
1183weighted proton identification probability defined as :math:`\frac{\mathcal{\tilde{L}}_p}{\sum_{i=e,\mu,\pi,K,p,d} \mathcal{\tilde{L}}_i}`,
1184where :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}`.
1185The :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.
1186One can provide the name of the weight matrix as the argument.
1188 Manager::VariableDataType::c_double);
1189 REGISTER_METAVARIABLE("weightedDeuteronID(weightMatrixName)", weightedDeuteronID,
1191weighted deuteron identification probability defined as :math:`\frac{\mathcal{\tilde{L}}_d}{\sum_{i=e,\mu,\pi,K,p,d} \mathcal{\tilde{L}}_i}`,
1192where :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}`.
1193The :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.
1194One can provide the name of the weight matrix as the argument.
1196 Manager::VariableDataType::c_double);
1199 REGISTER_VARIABLE("pionIDNN", pionIDNN,
1201pion identification probability as calculated from the PID neural network.
1203 REGISTER_VARIABLE("kaonIDNN", kaonIDNN,
1205kaon identification probability as calculated from the PID neural network.
1210 VARIABLE_GROUP(
"PID_expert");
1211 REGISTER_METAVARIABLE(
"pidLogLikelihoodValueExpert(pdgCode, detectorList)", pidLogLikelihoodValueExpert,
1212 "returns the log likelihood value of for a specific mass hypothesis and set of detectors.", Manager::VariableDataType::c_double);
1213 REGISTER_METAVARIABLE(
"pidDeltaLogLikelihoodValueExpert(pdgCode1, pdgCode2, detectorList)", pidDeltaLogLikelihoodValueExpert,
1214 "returns LogL(hyp1) - LogL(hyp2) (aka DLL) for two mass hypotheses and a set of detectors.", Manager::VariableDataType::c_double);
1215 REGISTER_METAVARIABLE(
"pidPairProbabilityExpert(pdgCodeHyp, pdgCodeTest, detectorList)", pidPairProbabilityExpert,
1216 "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})`",
1217 Manager::VariableDataType::c_double);
1218 REGISTER_METAVARIABLE(
"pidProbabilityExpert(pdgCodeHyp, detectorList)", pidProbabilityExpert,
1219 "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})`. ",
1220 Manager::VariableDataType::c_double);
1221 REGISTER_METAVARIABLE(
"pidMissingProbabilityExpert(detectorList)", pidMissingProbabilityExpert,
1222 "returns 1 if the PID probabiliy is missing for the provided detector list, otherwise 0. ", Manager::VariableDataType::c_double);
1223 REGISTER_VARIABLE(
"pidMostLikelyPDG(ePrior=1/6, muPrior=1/6, piPrior=1/6, KPrior=1/6, pPrior=1/6, dPrior=1/6)", mostLikelyPDG,
1225Returns PDG code of the largest PID likelihood, or NaN if PID information is not available.
1226This function accepts either no arguments, or 6 floats as priors for the charged particle hypotheses
1227following the order shown in the metavariable's declaration. Flat priors are assumed as default.)DOC");
1228 REGISTER_VARIABLE("pidIsMostLikely(ePrior=1/6, muPrior=1/6, piPrior=1/6, KPrior=1/6, pPrior=1/6, dPrior=1/6)", isMostLikely, R
"DOC(
1229Returns True if the largest PID likelihood of a given particle corresponds to its particle hypothesis.
1230This function accepts either no arguments, or 6 floats as priors for the charged particle hypotheses
1231following the order shown in the metavariable's declaration. Flat priors are assumed as default.)DOC");
1233 REGISTER_METAVARIABLE("pidWeightedLogLikelihoodValueExpert(weightMatrixName, pdgCode, detectorList)",
1234 pidWeightedLogLikelihoodValueExpert,
1235 "returns the weighted log likelihood value of for a specific mass hypothesis and set of detectors, "
1236 ":math:`\\log\\mathcal{\\tilde{L}}_{hyp} = \\sum_{j\\in\\mathrm{detectorList}} \\mathcal{w}_{hyp,j}\\log\\mathcal{L}_{hyp,j}`. "
1237 "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.",
1238 Manager::VariableDataType::c_double);
1239 REGISTER_METAVARIABLE(
"pidWeightedPairProbabilityExpert(weightMatrixName, pdgCodeHyp, pdgCodeTest, detectorList)",
1240 pidWeightedPairProbabilityExpert,
1241 "Weighted pair (or binary) probability for the pdgCodeHyp mass hypothesis with respect to the pdgCodeTest one, using an arbitrary set of detectors, "
1242 ":math:`\\mathcal{\\tilde{L}}_{hyp}/(\\mathcal{\\tilde{L}}_{test}+\\mathcal{\\tilde{L}}_{hyp})` where :math:`\\mathcal{\\tilde{L}}_{i}` is defined as "
1243 ":math:`\\log\\mathcal{\\tilde{L}}_{i} = \\sum_{j\\in\\mathrm{detectorList}} \\mathcal{w}_{i,j}\\log\\mathcal{L}_{i,j}`. "
1244 "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.",
1245 Manager::VariableDataType::c_double);
1246 REGISTER_METAVARIABLE(
"pidWeightedProbabilityExpert(weightMatrixName, pdgCodeHyp, detectorList)",
1247 pidWeightedProbabilityExpert,
1248 "Weighted probability for the pdgCodeHyp mass hypothesis with respect to all the other ones, using an arbitrary set of detectors, "
1249 ":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 "
1250 ":math:`\\log\\mathcal{\\tilde{L}}_{i} = \\sum_{j\\in\\mathrm{detectorList}} \\mathcal{w}_{i,j}\\log\\mathcal{L}_{i,j}`. "
1251 "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.",
1252 Manager::VariableDataType::c_double);
1253 REGISTER_METAVARIABLE(
"pidNeuralNetworkValueExpert(pdgCodeHyp, PIDNeuralNetworkName)",
1254 pidNeuralNetworkValueExpert,
1255 "Probability for the particle hypothesis pdgCodeHype calculated from a neural network, which uses high-level information as inputs, "
1256 "such as the likelihood from the 6 subdetectors for PID for all 6 hypotheses, "
1257 ":math:`\\mathcal{\\tilde{L}}_{hyp}^{det}`, or the track momentum and charge",
1258 Manager::VariableDataType::c_double);
1261 VARIABLE_GROUP(
"Belle PID variables");
1262 REGISTER_METAVARIABLE(
"atcPIDBelle(i,j)", atcPIDBelle, R
"DOC(
1263[Legacy] Returns Belle's PID atc variable: ``atc_pid(3,1,5,i,j).prob()``.
1264Parameters i,j are signal and background hypothesis: (0 = electron, 1 = muon, 2 = pion, 3 = kaon, 4 = proton)
1265Returns 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).
1267.. warning:: The behaviour is different from Belle II PID variables which typically return NaN in case of error.
1268 )DOC", Manager::VariableDataType::c_double);
1269 REGISTER_VARIABLE("muIDBelle", muIDBelle, R
"DOC(
1270[Legacy] Returns Belle's PID ``Muon_likelihood()`` variable.
1271Returns 0.5 in case there is no likelihood found and returns zero if the muon likelihood is not usable (Belle behaviour).
1273.. warning:: The behaviour is different from Belle II PID variables which typically return NaN in case of error.
1275 REGISTER_VARIABLE("muIDBelleQuality", muIDBelleQuality, R
"DOC(
1276[Legacy] Returns true if Belle's PID ``Muon_likelihood()`` is usable (reliable).
1277Returns zero/false if not usable or if there is no PID found.
1279 REGISTER_VARIABLE("eIDBelle", eIDBelle, R
"DOC(
1280[Legacy] Returns Belle's electron ID ``eid(3,-1,5).prob()`` variable.
1281Returns 0.5 in case there is no likelihood found (Belle behaviour).
1283.. 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.