10#include <analysis/variables/Variables.h>
13#include <analysis/VariableManager/Manager.h>
15#include <analysis/utility/PCmsLabTransform.h>
16#include <analysis/utility/ReferenceFrame.h>
17#include <analysis/utility/MCMatching.h>
18#include <analysis/ClusterUtility/ClusterUtils.h>
21#include <framework/datastore/StoreArray.h>
22#include <framework/datastore/StoreObjPtr.h>
25#include <analysis/dataobjects/Particle.h>
26#include <analysis/dataobjects/ParticleList.h>
27#include <framework/dataobjects/EventExtraInfo.h>
28#include <analysis/dataobjects/EventShapeContainer.h>
30#include <mdst/dataobjects/MCParticle.h>
31#include <mdst/dataobjects/Track.h>
32#include <mdst/dataobjects/ECLCluster.h>
34#include <mdst/dbobjects/BeamSpot.h>
37#include <framework/logging/Logger.h>
38#include <framework/geometry/B2Vector3.h>
39#include <framework/geometry/BFieldManager.h>
40#include <framework/gearbox/Const.h>
41#include <framework/utilities/Conversion.h>
43#include <Math/Vector4D.h>
48#include <boost/algorithm/string.hpp>
62 double particleP(
const Particle* part)
65 return frame.getMomentum(part).P();
68 double particleE(
const Particle* part)
71 return frame.getMomentum(part).E();
74 double particleClusterEUncertainty(
const Particle* part)
76 const ECLCluster* cluster = part->getECLCluster();
79 const auto EPhiThetaCov = clutls.GetCovarianceMatrix3x3FromCluster(cluster);
80 return sqrt(fabs(EPhiThetaCov[0][0]));
85 double particlePx(
const Particle* part)
88 return frame.getMomentum(part).Px();
91 double particlePy(
const Particle* part)
94 return frame.getMomentum(part).Py();
97 double particlePz(
const Particle* part)
100 return frame.getMomentum(part).Pz();
103 double particlePt(
const Particle* part)
106 return frame.getMomentum(part).Pt();
109 double covMatrixElement(
const Particle* part,
const std::vector<double>& element)
111 int elementI = int(std::lround(element[0]));
112 int elementJ = int(std::lround(element[1]));
114 if (elementI < 0 || elementI > 6) {
115 B2WARNING(
"Requested particle's momentumVertex covariance matrix element is out of boundaries [0 - 6]:" <<
LogVar(
"i", elementI));
118 if (elementJ < 0 || elementJ > 6) {
119 B2WARNING(
"Requested particle's momentumVertex covariance matrix element is out of boundaries [0 - 6]:" <<
LogVar(
"j", elementJ));
123 return part->getMomentumVertexErrorMatrix()(elementI, elementJ);
126 double particleEUncertainty(
const Particle* part)
130 double errorSquared = frame.getMomentumErrorMatrix(part)(3, 3);
132 if (errorSquared >= 0.0)
133 return sqrt(errorSquared);
138 double particlePErr(
const Particle* part)
140 TMatrixD jacobianRot(3, 3);
143 double cosPhi = cos(particlePhi(part));
144 double sinPhi = sin(particlePhi(part));
145 double cosTheta = particleCosTheta(part);
146 double sinTheta = sin(acos(cosTheta));
147 double p = particleP(part);
149 jacobianRot(0, 0) = sinTheta * cosPhi;
150 jacobianRot(0, 1) = sinTheta * sinPhi;
151 jacobianRot(1, 0) = cosTheta * cosPhi / p;
152 jacobianRot(1, 1) = cosTheta * sinPhi / p;
153 jacobianRot(0, 2) = cosTheta;
154 jacobianRot(2, 0) = -sinPhi / sinTheta / p;
155 jacobianRot(1, 2) = -sinTheta / p;
156 jacobianRot(2, 1) = cosPhi / sinTheta / p;
160 double errorSquared = frame.getMomentumErrorMatrix(part).GetSub(0, 2, 0, 2,
" ").Similarity(jacobianRot)(0, 0);
162 if (errorSquared >= 0.0)
163 return sqrt(errorSquared);
168 double particlePxErr(
const Particle* part)
172 double errorSquared = frame.getMomentumErrorMatrix(part)(0, 0);
174 if (errorSquared >= 0.0)
175 return sqrt(errorSquared);
180 double particlePyErr(
const Particle* part)
183 double errorSquared = frame.getMomentumErrorMatrix(part)(1, 1);
185 if (errorSquared >= 0.0)
186 return sqrt(errorSquared);
191 double particlePzErr(
const Particle* part)
194 double errorSquared = frame.getMomentumErrorMatrix(part)(2, 2);
196 if (errorSquared >= 0.0)
197 return sqrt(errorSquared);
202 double particlePtErr(
const Particle* part)
204 TMatrixD jacobianRot(3, 3);
207 double px = particlePx(part);
208 double py = particlePy(part);
209 double pt = particlePt(part);
211 jacobianRot(0, 0) = px / pt;
212 jacobianRot(0, 1) = py / pt;
213 jacobianRot(1, 0) = -py / (pt * pt);
214 jacobianRot(1, 1) = px / (pt * pt);
215 jacobianRot(2, 2) = 1;
218 double errorSquared = frame.getMomentumErrorMatrix(part).GetSub(0, 2, 0, 2,
" ").Similarity(jacobianRot)(0, 0);
220 if (errorSquared >= 0.0)
221 return sqrt(errorSquared);
226 double momentumDeviationChi2(
const Particle* part)
231 if (part->getPValue() < 0.0)
240 result += TMath::Power(part->getPx() - mcp->getMomentum().X(), 2.0) / part->getMomentumVertexErrorMatrix()(0, 0);
241 result += TMath::Power(part->getPy() - mcp->getMomentum().Y(), 2.0) / part->getMomentumVertexErrorMatrix()(1, 1);
242 result += TMath::Power(part->getPz() - mcp->getMomentum().Z(), 2.0) / part->getMomentumVertexErrorMatrix()(2, 2);
247 double particleTheta(
const Particle* part)
250 return frame.getMomentum(part).Theta();
253 double particleThetaErr(
const Particle* part)
255 TMatrixD jacobianRot(3, 3);
258 double cosPhi = cos(particlePhi(part));
259 double sinPhi = sin(particlePhi(part));
260 double cosTheta = particleCosTheta(part);
261 double sinTheta = sin(acos(cosTheta));
262 double p = particleP(part);
264 jacobianRot(0, 0) = sinTheta * cosPhi;
265 jacobianRot(0, 1) = sinTheta * sinPhi;
266 jacobianRot(1, 0) = cosTheta * cosPhi / p;
267 jacobianRot(1, 1) = cosTheta * sinPhi / p;
268 jacobianRot(0, 2) = cosTheta;
269 jacobianRot(2, 0) = -sinPhi / sinTheta / p;
270 jacobianRot(1, 2) = -sinTheta / p;
271 jacobianRot(2, 1) = cosPhi / sinTheta / p;
274 double errorSquared = frame.getMomentumErrorMatrix(part).GetSub(0, 2, 0, 2,
" ").Similarity(jacobianRot)(1, 1);
276 if (errorSquared >= 0.0)
277 return sqrt(errorSquared);
282 double particleCosTheta(
const Particle* part)
285 return cos(frame.getMomentum(part).Theta());
288 double particleCosThetaErr(
const Particle* part)
290 return fabs(particleThetaErr(part) * sin(particleTheta(part)));
293 double particlePhi(
const Particle* part)
296 return frame.getMomentum(part).Phi();
299 double particlePhiErr(
const Particle* part)
301 TMatrixD jacobianRot(3, 3);
304 double px = particlePx(part);
305 double py = particlePy(part);
306 double pt = particlePt(part);
308 jacobianRot(0, 0) = px / pt;
309 jacobianRot(0, 1) = py / pt;
310 jacobianRot(1, 0) = -py / (pt * pt);
311 jacobianRot(1, 1) = px / (pt * pt);
312 jacobianRot(2, 2) = 1;
315 double errorSquared = frame.getMomentumErrorMatrix(part).GetSub(0, 2, 0, 2,
" ").Similarity(jacobianRot)(1, 1);
317 if (errorSquared >= 0.0)
318 return sqrt(errorSquared);
323 double particleXp(
const Particle* part)
326 ROOT::Math::PxPyPzEVector p4 = part -> get4Vector();
327 ROOT::Math::PxPyPzEVector p4CMS = T.rotateLabToCms() * p4;
328 float s = T.getCMSEnergy();
329 float M = part->getMass();
330 return p4CMS.P() / TMath::Sqrt(s * s / 4 - M * M);
333 int particlePDGCode(
const Particle* part)
335 return part->getPDGCode();
338 double cosAngleBetweenMomentumAndVertexVectorInXYPlane(
const Particle* part)
340 static DBObjPtr<BeamSpot> beamSpotDB;
341 double px = part->getPx();
342 double py = part->getPy();
344 double xV = part->getX();
345 double yV = part->getY();
347 double xIP = (beamSpotDB->getIPPosition()).X();
348 double yIP = (beamSpotDB->getIPPosition()).Y();
353 double cosangle = (px * x + py * y) / (
sqrt(px * px + py * py) *
sqrt(x * x + y * y));
357 double cosAngleBetweenMomentumAndVertexVector(
const Particle* part)
359 static DBObjPtr<BeamSpot> beamSpotDB;
360 return cos((
B2Vector3D(part->getVertex()) - beamSpotDB->getIPPosition()).Angle(
B2Vector3D(part->getMomentum())));
363 double cosThetaBetweenParticleAndNominalB(
const Particle* part)
366 int particlePDG = abs(part->getPDGCode());
367 if (particlePDG != 511 and particlePDG != 521)
368 B2FATAL(
"The Variables cosThetaBetweenParticleAndNominalB is only meant to be used on B mesons!");
371 double e_Beam = T.getCMSEnergy() / 2.0;
372 double m_B = part->getPDGMass();
374 if (e_Beam * e_Beam - m_B * m_B < 0) {
375 e_Beam = 1.0579400E+1 / 2.0;
377 double p_B = std::sqrt(e_Beam * e_Beam - m_B * m_B);
379 ROOT::Math::PxPyPzEVector p = T.rotateLabToCms() * part->get4Vector();
384 double theta_BY = (2 * e_Beam * e_d - m_B * m_B - m_d * m_d)
389 double cosToThrustOfEvent(
const Particle* part)
391 StoreObjPtr<EventShapeContainer> evtShape;
393 B2WARNING(
"Cannot find thrust of event information, did you forget to load the event shape calculation?");
398 B2Vector3D particleMomentum = (T.rotateLabToCms() * part -> get4Vector()).Vect();
399 return std::cos(th.Angle(particleMomentum));
402 double ImpactXY(
const Particle* particle)
404 static DBObjPtr<BeamSpot> beamSpotDB;
406 ROOT::Math::XYZVector mom = particle->getMomentum();
408 ROOT::Math::XYZVector r = particle->getVertex() - ROOT::Math::XYZVector(beamSpotDB->getIPPosition());
413 double T = TMath::Sqrt(mom.Perp2() - 2.0 * curvature.Dot(r.Cross(mom)) + curvature.Mag2() * r.Perp2());
415 return TMath::Abs((-2 * r.Cross(mom).Z() + curvature.R() * r.Perp2()) / (T + mom.Rho()));
418 double ArmenterosLongitudinalMomentumAsymmetry(
const Particle* part)
421 int nDaughters = part -> getNDaughters();
423 B2FATAL(
"You are trying to use an Armenteros variable. The mother particle is required to have exactly two daughters");
425 const auto& daughters = part -> getDaughters();
426 B2Vector3D motherMomentum = frame.getMomentum(part).Vect();
427 B2Vector3D daughter1Momentum = frame.getMomentum(daughters[0]).Vect();
428 B2Vector3D daughter2Momentum = frame.getMomentum(daughters[1]).Vect();
430 int daughter1Charge = daughters[0] -> getCharge();
431 int daughter2Charge = daughters[1] -> getCharge();
432 double daughter1Ql = daughter1Momentum.Dot(motherMomentum) / motherMomentum.Mag();
433 double daughter2Ql = daughter2Momentum.Dot(motherMomentum) / motherMomentum.Mag();
436 if (daughter2Charge > daughter1Charge)
437 Arm_alpha = (daughter2Ql - daughter1Ql) / (daughter2Ql + daughter1Ql);
439 Arm_alpha = (daughter1Ql - daughter2Ql) / (daughter1Ql + daughter2Ql);
444 double ArmenterosDaughter1Qt(
const Particle* part)
447 int nDaughters = part -> getNDaughters();
449 B2FATAL(
"You are trying to use an Armenteros variable. The mother particle is required to have exactly two daughters.");
451 const auto& daughters = part -> getDaughters();
452 B2Vector3D motherMomentum = frame.getMomentum(part).Vect();
453 B2Vector3D daughter1Momentum = frame.getMomentum(daughters[0]).Vect();
454 double qt = daughter1Momentum.
Perp(motherMomentum);
459 double ArmenterosDaughter2Qt(
const Particle* part)
462 int nDaughters = part -> getNDaughters();
464 B2FATAL(
"You are trying to use an Armenteros variable. The mother particle is required to have exactly two daughters.");
466 const auto& daughters = part -> getDaughters();
467 B2Vector3D motherMomentum = frame.getMomentum(part).Vect();
468 B2Vector3D daughter2Momentum = frame.getMomentum(daughters[1]).Vect();
469 double qt = daughter2Momentum.
Perp(motherMomentum);
477 double particleMass(
const Particle* part)
479 return part->getMass();
482 double particleDMass(
const Particle* part)
484 return part->getMass() - part->getPDGMass();
487 double particleInvariantMassFromDaughters(
const Particle* part)
489 const std::vector<Particle*> daughters = part->getDaughters();
490 if (daughters.size() > 0) {
491 ROOT::Math::PxPyPzEVector sum;
492 for (
auto daughter : daughters)
493 sum += daughter->get4Vector();
497 return part->getMass();
501 double particleInvariantMassFromDaughtersDisplaced(
const Particle* part)
503 ROOT::Math::XYZVector vertex = part->getVertex();
504 if (part->getParticleSource() != Particle::EParticleSourceObject::c_V0
505 && vertex.Rho() < 0.5)
return particleInvariantMassFromDaughters(part);
507 const std::vector<Particle*> daughters = part->getDaughters();
508 if (daughters.size() == 0)
return particleInvariantMassFromDaughters(part);
511 ROOT::Math::PxPyPzMVector sum;
512 for (
auto daughter : daughters) {
513 const TrackFitResult* tfr = daughter->getTrackFitResult();
515 sum += daughter->get4Vector();
518 Helix helix = tfr->getHelix();
519 helix.passiveMoveBy(vertex);
520 double scalingFactor = daughter->getEffectiveMomentumScale();
521 double momX = scalingFactor * helix.getMomentumX(bField);
522 double momY = scalingFactor * helix.getMomentumY(bField);
523 double momZ = scalingFactor * helix.getMomentumZ(bField);
524 float mPDG = daughter->getPDGMass();
525 sum += ROOT::Math::PxPyPzMVector(momX, momY, momZ, mPDG);
530 double particleInvariantMassLambda(
const Particle* part)
532 const std::vector<Particle*> daughters = part->getDaughters();
533 if (daughters.size() == 2) {
534 ROOT::Math::PxPyPzEVector dt1;
535 ROOT::Math::PxPyPzEVector dt2;
536 ROOT::Math::PxPyPzEVector dtsum;
539 dt1 = daughters[0]->get4Vector();
540 dt2 = daughters[1]->get4Vector();
541 double E1 = hypot(mpi, dt1.P());
542 double E2 = hypot(mpr, dt2.P());
544 return sqrt((E1 + E2) * (E1 + E2) - dtsum.P() * dtsum.P());
547 return part->getMass();
551 double particleInvariantMassError(
const Particle* part)
553 float invMass = part->getMass();
554 TMatrixFSym covarianceMatrix = part->getMomentumErrorMatrix();
556 TVectorF jacobian(Particle::c_DimMomentum);
557 jacobian[0] = -1.0 * part->getPx() / invMass;
558 jacobian[1] = -1.0 * part->getPy() / invMass;
559 jacobian[2] = -1.0 * part->getPz() / invMass;
560 jacobian[3] = 1.0 * part->getEnergy() / invMass;
562 double result = jacobian * (covarianceMatrix * jacobian);
567 return TMath::Sqrt(result);
570 double particleInvariantMassSignificance(
const Particle* part)
572 return particleDMass(part) / particleInvariantMassError(part);
575 double particleMassSquared(
const Particle* part)
577 ROOT::Math::PxPyPzEVector p4 = part->get4Vector();
581 double b2bTheta(
const Particle* part)
584 ROOT::Math::PxPyPzEVector pcms = T.rotateLabToCms() * part->get4Vector();
585 ROOT::Math::PxPyPzEVector b2bcms(-pcms.Px(), -pcms.Py(), -pcms.Pz(), pcms.E());
586 ROOT::Math::PxPyPzEVector b2blab = T.rotateCmsToLab() * b2bcms;
587 return b2blab.Theta();
590 double b2bPhi(
const Particle* part)
593 ROOT::Math::PxPyPzEVector pcms = T.rotateLabToCms() * part->get4Vector();
594 ROOT::Math::PxPyPzEVector b2bcms(-pcms.Px(), -pcms.Py(), -pcms.Pz(), pcms.E());
595 ROOT::Math::PxPyPzEVector b2blab = T.rotateCmsToLab() * b2bcms;
599 double b2bClusterTheta(
const Particle* part)
602 const ECLCluster* cluster = part->getECLCluster();
608 ROOT::Math::PxPyPzEVector p4Cluster = clutls.Get4MomentumFromCluster(cluster, clusterHypothesis);
612 ROOT::Math::PxPyPzEVector pcms = T.rotateLabToCms() * p4Cluster;
613 ROOT::Math::PxPyPzEVector b2bcms(-pcms.Px(), -pcms.Py(), -pcms.Pz(), pcms.E());
614 ROOT::Math::PxPyPzEVector b2blab = T.rotateCmsToLab() * b2bcms;
615 return b2blab.Theta();
618 double b2bClusterPhi(
const Particle* part)
621 const ECLCluster* cluster = part->getECLCluster();
627 ROOT::Math::PxPyPzEVector p4Cluster = clutls.Get4MomentumFromCluster(cluster, clusterHypothesis);
631 ROOT::Math::PxPyPzEVector pcms = T.rotateLabToCms() * p4Cluster;
632 ROOT::Math::PxPyPzEVector b2bcms(-pcms.Px(), -pcms.Py(), -pcms.Pz(), pcms.E());
633 ROOT::Math::PxPyPzEVector b2blab = T.rotateCmsToLab() * b2bcms;
640 double particleQ(
const Particle* part)
642 float m = part->getMass();
643 for (
unsigned i = 0; i < part->getNDaughters(); i++) {
644 const Particle* child = part->getDaughter(i);
646 m -= child->getMass();
651 double particleDQ(
const Particle* part)
653 float m = part->getMass() - part->getPDGMass();
654 for (
unsigned i = 0; i < part->getNDaughters(); i++) {
655 const Particle* child = part->getDaughter(i);
657 m -= (child->getMass() - child->getPDGMass());
664 double particleMbc(
const Particle* part)
667 ROOT::Math::PxPyPzEVector vec = T.rotateLabToCms() * part->get4Vector();
668 double E = T.getCMSEnergy() / 2;
669 double m2 =
E *
E - vec.P2();
670 double mbc = m2 >= 0 ?
sqrt(m2) : Const::doubleNaN;
674 double particleDeltaE(
const Particle* part)
677 ROOT::Math::PxPyPzEVector vec = T.rotateLabToCms() * part->get4Vector();
678 return vec.E() - T.getCMSEnergy() / 2;
684 void printParticleInternal(
const Particle* p,
int depth)
687 for (
int i = 0; i < depth; i++) {
690 s << p->getPDGCode();
691 const MCParticle* mcp = p->getMCParticle();
694 s <<
" -> MC: " << mcp->getPDG() <<
", mcErrors: " << flags <<
" ("
696 s <<
", mc-index " << mcp->getIndex();
698 s <<
" (no MC match)";
700 s <<
", mdst-source " << p->getMdstSource();
702 for (
const auto* daughter : p->getDaughters()) {
703 printParticleInternal(daughter, depth + 1);
707 bool printParticle(
const Particle* p)
709 printParticleInternal(p, 0);
714 double particleMCMomentumTransfer2(
const Particle* part)
722 ROOT::Math::PxPyPzEVector pB = mcB->get4Vector();
724 std::vector<MCParticle*> mcDaug = mcB->getDaughters();
731 ROOT::Math::PxPyPzEVector pX;
733 for (
auto mcTemp : mcDaug) {
734 if (abs(mcTemp->getPDG()) <= 16)
737 pX += mcTemp->get4Vector();
740 ROOT::Math::PxPyPzEVector q = pB - pX;
746 double recoilPx(
const Particle* particle)
751 ROOT::Math::PxPyPzEVector pIN = T.getBeamFourMomentum();
755 return frame.getMomentum(pIN - particle->get4Vector()).Px();
758 double recoilPy(
const Particle* particle)
763 ROOT::Math::PxPyPzEVector pIN = T.getBeamFourMomentum();
767 return frame.getMomentum(pIN - particle->get4Vector()).Py();
770 double recoilPz(
const Particle* particle)
775 ROOT::Math::PxPyPzEVector pIN = T.getBeamFourMomentum();
779 return frame.getMomentum(pIN - particle->get4Vector()).Pz();
782 double recoilMomentum(
const Particle* particle)
787 ROOT::Math::PxPyPzEVector pIN = T.getBeamFourMomentum();
791 return frame.getMomentum(pIN - particle->get4Vector()).P();
794 double recoilMomentumTheta(
const Particle* particle)
799 ROOT::Math::PxPyPzEVector pIN = T.getBeamFourMomentum();
803 return frame.getMomentum(pIN - particle->get4Vector()).Theta();
806 double recoilMomentumPhi(
const Particle* particle)
811 ROOT::Math::PxPyPzEVector pIN = T.getBeamFourMomentum();
815 return frame.getMomentum(pIN - particle->get4Vector()).Phi();
818 double recoilEnergy(
const Particle* particle)
823 ROOT::Math::PxPyPzEVector pIN = T.getBeamFourMomentum();
827 return frame.getMomentum(pIN - particle->get4Vector()).E();
830 double recoilMass(
const Particle* particle)
835 ROOT::Math::PxPyPzEVector pIN = T.getBeamFourMomentum();
839 return frame.getMomentum(pIN - particle->get4Vector()).M();
842 double recoilMassSquared(
const Particle* particle)
847 ROOT::Math::PxPyPzEVector pIN = T.getBeamFourMomentum();
851 return frame.getMomentum(pIN - particle->get4Vector()).M2();
854 double m2RecoilSignalSide(
const Particle* part)
857 double beamEnergy = T.getCMSEnergy() / 2.;
859 ROOT::Math::PxPyPzEVector tagVec = T.rotateLabToCms() * part->getDaughter(0)->get4Vector();
860 ROOT::Math::PxPyPzEVector sigVec = T.rotateLabToCms() * part->getDaughter(1)->get4Vector();
861 tagVec.SetE(-beamEnergy);
862 return (-tagVec - sigVec).M2();
865 double recoilMCDecayType(
const Particle* particle)
867 auto* mcp = particle->getMCParticle();
872 MCParticle* mcMother = mcp->getMother();
877 std::vector<MCParticle*> daughters = mcMother->getDaughters();
879 if (daughters.size() != 2)
882 MCParticle* recoilMC =
nullptr;
883 if (daughters[0]->getArrayIndex() == mcp->getArrayIndex())
884 recoilMC = daughters[1];
886 recoilMC = daughters[0];
892 checkMCParticleDecay(recoilMC, decayType,
false);
895 checkMCParticleDecay(recoilMC, decayType,
true);
900 void checkMCParticleDecay(MCParticle* mcp,
int& decayType,
bool recursive)
902 int nHadronicParticles = 0;
903 int nPrimaryParticleDaughters = 0;
904 std::vector<MCParticle*> daughters = mcp->getDaughters();
907 for (
auto& daughter : daughters) {
911 nPrimaryParticleDaughters++;
913 nHadronicParticles++;
916 if (nPrimaryParticleDaughters > 1) {
917 for (
auto& daughter : daughters) {
921 if (abs(daughter->getPDG()) == 12 or abs(daughter->getPDG()) == 14 or abs(daughter->getPDG()) == 16) {
923 if (nHadronicParticles == 0) {
937 checkMCParticleDecay(daughter, decayType, recursive);
942 int nRemainingTracksInEvent(
const Particle* particle)
945 StoreArray<Track> tracks;
946 int event_tracks = tracks.getEntries();
949 const auto& daughters = particle->getFinalStateDaughters();
950 for (
const auto& daughter : daughters) {
951 int pdg = abs(daughter->getPDGCode());
956 return event_tracks - par_tracks;
959 bool False(
const Particle*)
964 bool True(
const Particle*)
969 double infinity(
const Particle*)
971 double inf = std::numeric_limits<double>::infinity();
975 double random(
const Particle*)
977 return gRandom->Uniform(0, 1);
980 double eventRandom(
const Particle*)
982 std::string key =
"__eventRandom";
983 StoreObjPtr<EventExtraInfo> eventExtraInfo;
984 if (not eventExtraInfo.isValid())
985 eventExtraInfo.create();
986 if (eventExtraInfo->hasExtraInfo(key)) {
987 return eventExtraInfo->getExtraInfo(key);
989 double value = gRandom->Uniform(0, 1);
990 eventExtraInfo->addExtraInfo(key, value);
997 if (arguments.size() != 3 && arguments.size() != 4) {
998 B2ERROR(
"Wrong number of arguments (3 or 4 required) for meta variable minET2ETDist");
1001 bool useHighestProbMassForExt(
true);
1002 if (arguments.size() == 4) {
1004 useHighestProbMassForExt =
static_cast<bool>(Belle2::convertString<int>(arguments[3]));
1005 }
catch (std::invalid_argument& e) {
1006 B2ERROR(
"Fourth (optional) argument of minET2ETDist must be an integer flag.");
1011 std::string detName = arguments[0];
1012 std::string detLayer = arguments[1];
1013 std::string referenceListName = arguments[2];
1014 std::string extraSuffix = (useHighestProbMassForExt) ?
"__useHighestProbMassForExt" :
"";
1016 std::string extraInfo =
"distToClosestTrkAt" + detName + detLayer +
"_VS_" + referenceListName + extraSuffix;
1018 auto func = [ = ](
const Particle * part) ->
double {
1019 auto dist = (part->hasExtraInfo(extraInfo)) ? part->getExtraInfo(extraInfo) :
Const::doubleNaN;
1030 if (arguments.size() != 4) {
1031 B2ERROR(
"Wrong number of arguments (4 required) for meta variable minET2ETDistVar");
1035 std::string detName = arguments[0];
1036 std::string detLayer = arguments[1];
1037 std::string referenceListName = arguments[2];
1038 std::string variableName = arguments[3];
1040 std::string extraInfo =
"idxOfClosestPartAt" + detName + detLayer +
"In_" + referenceListName;
1042 auto func = [ = ](
const Particle * part) ->
double {
1044 StoreObjPtr<ParticleList> refPartList(referenceListName);
1045 if (!refPartList.isValid())
1047 B2FATAL(
"Invalid Listname " << referenceListName <<
" given to minET2ETDistVar!");
1050 if (!part->hasExtraInfo(extraInfo))
1056 auto refPart = refPartList->getParticleWithMdstSource(part->getExtraInfo(extraInfo));
1058 return std::get<double>(var->function(refPart));
1068 if (arguments.size() < 3) {
1069 B2ERROR(
"Wrong number of arguments (at least 3 required) for meta variable minET2ETIsoScore");
1073 std::string referenceListName = arguments[0];
1074 bool useHighestProbMassForExt;
1076 useHighestProbMassForExt =
static_cast<bool>(Belle2::convertString<int>(arguments[1]));
1077 }
catch (std::invalid_argument& e) {
1078 B2ERROR(
"Second argument must be an integer flag.");
1081 std::string extraSuffix = (useHighestProbMassForExt) ?
"__useHighestProbMassForExt" :
"";
1083 std::vector<std::string> detectorNames(arguments.begin() + 2, arguments.end());
1085 std::string detNamesConcat(
"");
1086 for (
auto& detName : detectorNames) {
1087 boost::to_upper(detName);
1088 detNamesConcat +=
"_" + detName;
1091 std::string extraInfo =
"trkIsoScore" + detNamesConcat +
"_VS_" + referenceListName + extraSuffix;
1093 auto func = [ = ](
const Particle * part) ->
double {
1095 StoreObjPtr<ParticleList> refPartList(referenceListName);
1096 if (!refPartList.isValid())
1098 B2FATAL(
"Invalid Listname " << referenceListName <<
" given to minET2ETIsoScore!");
1101 if (!part->hasExtraInfo(extraInfo))
1105 auto scoreDet = part->getExtraInfo(extraInfo);
1106 if (std::isnan(scoreDet))
1119 Manager::FunctionPtr particleExtTrkIsoScoreVarAsWeightedAvg(
const std::vector<std::string>& arguments)
1122 if (arguments.size() < 3) {
1123 B2ERROR(
"Wrong number of arguments (at least 3 required) for meta variable minET2ETIsoScoreAsWeightedAvg");
1127 std::string referenceListName = arguments[0];
1128 bool useHighestProbMassForExt;
1130 useHighestProbMassForExt =
static_cast<bool>(Belle2::convertString<int>(arguments[1]));
1131 }
catch (std::invalid_argument& e) {
1132 B2ERROR(
"Second argument must be an integer flag.");
1135 std::string extraSuffix = (useHighestProbMassForExt) ?
"__useHighestProbMassForExt" :
"";
1137 std::vector<std::string> detectorNames(arguments.begin() + 2, arguments.end());
1139 std::string detNamesConcat(
"");
1140 for (
auto& detName : detectorNames) {
1141 boost::to_upper(detName);
1142 detNamesConcat +=
"_" + detName;
1145 std::string extraInfo =
"trkIsoScoreAsWeightedAvg" + detNamesConcat +
"_VS_" + referenceListName + extraSuffix;
1147 auto func = [ = ](
const Particle * part) ->
double {
1149 StoreObjPtr<ParticleList> refPartList(referenceListName);
1150 if (!refPartList.isValid())
1152 B2FATAL(
"Invalid Listname " << referenceListName <<
" given to minET2ETIsoScoreAsWeightedAvg!");
1155 if (!part->hasExtraInfo(extraInfo))
1159 auto scoreDet = part->getExtraInfo(extraInfo);
1160 if (std::isnan(scoreDet))
1172 VARIABLE_GROUP(
"Kinematics");
1173 REGISTER_VARIABLE(
"p", particleP,
"momentum magnitude\n\n",
"GeV/c");
1174 REGISTER_VARIABLE(
"E", particleE,
"energy\n\n",
"GeV");
1176 REGISTER_VARIABLE(
"E_uncertainty", particleEUncertainty, R
"DOC(
1177 energy uncertainty (:math:`\sqrt{\sigma^2}`)
1180 REGISTER_VARIABLE(
"ECLClusterE_uncertainty", particleClusterEUncertainty,
1181 "energy uncertainty as given by the underlying ECL cluster\n\n",
"GeV");
1182 REGISTER_VARIABLE(
"px", particlePx,
"momentum component x\n\n",
"GeV/c");
1183 REGISTER_VARIABLE(
"py", particlePy,
"momentum component y\n\n",
"GeV/c");
1184 REGISTER_VARIABLE(
"pz", particlePz,
"momentum component z\n\n",
"GeV/c");
1185 REGISTER_VARIABLE(
"pt", particlePt,
"transverse momentum\n\n",
"GeV/c");
1186 REGISTER_VARIABLE(
"xp", particleXp,
1187 "scaled momentum: the momentum of the particle in the CMS as a fraction of its maximum available momentum in the collision");
1188 REGISTER_VARIABLE(
"pErr", particlePErr,
"error of momentum magnitude\n\n",
"GeV/c");
1189 REGISTER_VARIABLE(
"pxErr", particlePxErr,
"error of momentum component x\n\n",
"GeV/c");
1190 REGISTER_VARIABLE(
"pyErr", particlePyErr,
"error of momentum component y\n\n",
"GeV/c");
1191 REGISTER_VARIABLE(
"pzErr", particlePzErr,
"error of momentum component z\n\n",
"GeV/c");
1192 REGISTER_VARIABLE(
"ptErr", particlePtErr,
"error of transverse momentum\n\n",
"GeV/c");
1193 REGISTER_VARIABLE(
"momVertCovM(i,j)", covMatrixElement,
1194 "returns the (i,j)-th element of the MomentumVertex Covariance Matrix (7x7).\n"
1195 "Order of elements in the covariance matrix is: px, py, pz, E, x, y, z.\n\n",
"GeV/c, GeV/c, GeV/c, GeV, cm, cm, cm");
1196 REGISTER_VARIABLE(
"momDevChi2", momentumDeviationChi2, R
"DOC(
1197momentum deviation :math:`\chi^2` value calculated as :math:`\chi^2 = \sum_i (p_i - mc(p_i))^2/\sigma(p_i)^2`,
1198where :math:`\sum` runs over i = px, py, pz and :math:`mc(p_i)` is the mc truth value and :math:`\sigma(p_i)` is the estimated error of i-th component of momentum vector
1200 REGISTER_VARIABLE("theta", particleTheta,
"polar angle\n\n",
"rad");
1201 REGISTER_VARIABLE(
"thetaErr", particleThetaErr,
"error of polar angle\n\n",
"rad");
1202 REGISTER_VARIABLE(
"cosTheta", particleCosTheta,
"momentum cosine of polar angle");
1203 REGISTER_VARIABLE(
"cosThetaErr", particleCosThetaErr,
"error of momentum cosine of polar angle");
1204 REGISTER_VARIABLE(
"phi", particlePhi,
"momentum azimuthal angle\n\n",
"rad");
1205 REGISTER_VARIABLE(
"phiErr", particlePhiErr,
"error of momentum azimuthal angle\n\n",
"rad");
1206 REGISTER_VARIABLE(
"PDG", particlePDGCode,
"PDG code");
1207 REGISTER_VARIABLE(
"cosAngleBetweenMomentumAndVertexVectorInXYPlane",
1208 cosAngleBetweenMomentumAndVertexVectorInXYPlane,
1209 "cosine of the angle between momentum and vertex vector (vector connecting ip and fitted vertex) of this particle in xy-plane");
1210 REGISTER_VARIABLE(
"cosAngleBetweenMomentumAndVertexVector",
1211 cosAngleBetweenMomentumAndVertexVector,
1212 "cosine of the angle between momentum and vertex vector (vector connecting ip and fitted vertex) of this particle");
1213 REGISTER_VARIABLE(
"cosThetaBetweenParticleAndNominalB",
1214 cosThetaBetweenParticleAndNominalB,
1215 "cosine of the angle in CMS between momentum the particle and a nominal B particle. It is somewhere between -1 and 1 if only a massless particle like a neutrino is missing in the reconstruction.");
1216 REGISTER_VARIABLE(
"cosToThrustOfEvent", cosToThrustOfEvent,
1217 "Returns the cosine of the angle between the particle and the thrust axis of the event, as calculate by the EventShapeCalculator module. buildEventShape() must be run before calling this variable");
1219 REGISTER_VARIABLE(
"ImpactXY" , ImpactXY ,
"The impact parameter of the given particle in the xy plane\n\n",
"cm");
1221 REGISTER_VARIABLE(
"M", particleMass, R
"DOC(
1224Note that this is context-dependent variable and can take different values depending on the situation. This should be the "best"
1225value possible with the information provided.
1227- If this particle is track- or cluster- based, then this is the value of the mass hypothesis.
1228- If this particle is an MC particle then this is the mass of that particle.
1229- If this particle is composite, then *initially* this takes the value of the invariant mass of the daughters.
1230- If this particle is composite and a *mass or vertex fit* has been performed then this may be updated by the fit.
1232* You will see a difference between this mass and the :b2:var:`InvM`.
1234)DOC", "GeV/:math:`\\text{c}^2`");
1235 REGISTER_VARIABLE(
"dM", particleDMass,
"mass minus nominal mass\n\n",
"GeV/:math:`\\text{c}^2`");
1236 REGISTER_VARIABLE(
"Q", particleQ,
"energy released in decay\n\n",
"GeV");
1237 REGISTER_VARIABLE(
"dQ", particleDQ,
":b2:var:`Q` minus nominal energy released in decay\n\n",
"GeV");
1238 REGISTER_VARIABLE(
"Mbc", particleMbc,
"beam constrained mass\n\n",
"GeV/:math:`\\text{c}^2`");
1239 REGISTER_VARIABLE(
"deltaE", particleDeltaE,
"difference between :b2:var:`E` and half the center of mass energy\n\n",
"GeV");
1240 REGISTER_VARIABLE(
"M2", particleMassSquared,
"The particle's mass squared.\n\n",
":math:`[\\text{GeV}/\\text{c}^2]^2`");
1242 REGISTER_VARIABLE(
"InvM", particleInvariantMassFromDaughtersDisplaced,
1243 "invariant mass (determined from particle's daughter 4-momentum vectors). If this particle is V0 or decays at rho > 5 mm, its daughter 4-momentum vectors at fitted vertex are taken.\n"
1244 "If this particle has no daughters, defaults to :b2:var:`M`.\n\n",
"GeV/:math:`\\text{c}^2`");
1245 REGISTER_VARIABLE(
"InvMLambda", particleInvariantMassLambda,
1246 "Invariant mass (determined from particle's daughter 4-momentum vectors), assuming the first daughter is a pion and the second daughter is a proton.\n"
1247 "If the particle has not 2 daughters, it returns just the mass value.\n\n",
"GeV/:math:`\\text{c}^2`");
1249 REGISTER_VARIABLE(
"ErrM", particleInvariantMassError,
1250 "uncertainty of invariant mass\n\n",
"GeV/:math:`\\text{c}^2`");
1251 REGISTER_VARIABLE(
"SigM", particleInvariantMassSignificance,
1252 "signed deviation of particle's invariant mass from its nominal mass in units of the uncertainty on the invariant mass (:b2:var:`dM`/:b2:var:`ErrM`)");
1254 REGISTER_VARIABLE(
"pxRecoil", recoilPx,
1255 "component x of 3-momentum recoiling against given Particle\n\n",
"GeV/c");
1256 REGISTER_VARIABLE(
"pyRecoil", recoilPy,
1257 "component y of 3-momentum recoiling against given Particle\n\n",
"GeV/c");
1258 REGISTER_VARIABLE(
"pzRecoil", recoilPz,
1259 "component z of 3-momentum recoiling against given Particle\n\n",
"GeV/c");
1261 REGISTER_VARIABLE(
"pRecoil", recoilMomentum,
1262 "magnitude of 3 - momentum recoiling against given Particle\n\n",
"GeV/c");
1263 REGISTER_VARIABLE(
"pRecoilTheta", recoilMomentumTheta,
1264 "Polar angle of a particle's missing momentum\n\n",
"rad");
1265 REGISTER_VARIABLE(
"pRecoilPhi", recoilMomentumPhi,
1266 "Azimuthal angle of a particle's missing momentum\n\n",
"rad");
1267 REGISTER_VARIABLE(
"eRecoil", recoilEnergy,
1268 "energy recoiling against given Particle\n\n",
"GeV");
1269 REGISTER_VARIABLE(
"mRecoil", recoilMass,
1270 "Invariant mass of the system recoiling against given Particle\n\n",
"GeV/:math:`\\text{c}^2`");
1271 REGISTER_VARIABLE(
"m2Recoil", recoilMassSquared,
1272 "invariant mass squared of the system recoiling against given Particle\n\n",
":math:`[\\text{GeV}/\\text{c}^2]^2`");
1273 REGISTER_VARIABLE(
"m2RecoilSignalSide", m2RecoilSignalSide, R
"DOC(
1274 Squared recoil mass of the signal side which is calculated in the CMS frame under the assumption that the
1275 signal and tag side are produced back to back and the tag side energy equals the beam energy. The variable
1276 must be applied to the Upsilon and the tag side must be the first, the signal side the second daughter
1278 )DOC", ":math:`[\\text{GeV}/\\text{c}^2]^2`");
1280 REGISTER_VARIABLE(
"b2bTheta", b2bTheta,
1281 "Polar angle in the lab system that is back-to-back to the particle in the CMS. Useful for low multiplicity studies.\n\n",
"rad");
1282 REGISTER_VARIABLE(
"b2bPhi", b2bPhi,
1283 "Azimuthal angle in the lab system that is back-to-back to the particle in the CMS. Useful for low multiplicity studies.\n\n",
1285 REGISTER_VARIABLE(
"b2bClusterTheta", b2bClusterTheta,
1286 "Polar angle in the lab system that is back-to-back to the particle's associated ECLCluster in the CMS. Returns NAN if no cluster is found. Useful for low multiplicity studies.\n\n",
1288 REGISTER_VARIABLE(
"b2bClusterPhi", b2bClusterPhi,
1289 "Azimuthal angle in the lab system that is back-to-back to the particle's associated ECLCluster in the CMS. Returns NAN if no cluster is found. Useful for low multiplicity studies.\n\n",
1291 REGISTER_VARIABLE(
"ArmenterosLongitudinalMomentumAsymmetry", ArmenterosLongitudinalMomentumAsymmetry,
1292 "Longitudinal momentum asymmetry of V0's daughters.\n"
1293 "The mother (V0) is required to have exactly two daughters");
1294 REGISTER_VARIABLE(
"ArmenterosDaughter1Qt", ArmenterosDaughter1Qt, R
"DOC(
1295 Transverse momentum of the first daughter with respect to the V0 mother.
1296 The mother is required to have exactly two daughters
1299 REGISTER_VARIABLE(
"ArmenterosDaughter2Qt", ArmenterosDaughter2Qt, R
"DOC(
1300 Transverse momentum of the second daughter with respect to the V0 mother.
1301 The mother is required to have exactly two daughters
1305 VARIABLE_GROUP(
"Miscellaneous");
1306 REGISTER_VARIABLE(
"nRemainingTracksInEvent", nRemainingTracksInEvent,
1307 "Number of tracks in the event - Number of tracks( = charged FSPs) of particle.");
1308 REGISTER_VARIABLE(
"decayTypeRecoil", recoilMCDecayType,
1309 "type of the particle decay(no related mcparticle = -1, hadronic = 0, direct leptonic = 1, direct semileptonic = 2,"
1310 "lower level leptonic = 3.");
1312 REGISTER_VARIABLE(
"printParticle", printParticle,
1313 "For debugging, print Particle and daughter PDG codes, plus MC match. Returns 0.");
1314 REGISTER_VARIABLE(
"mcMomTransfer2", particleMCMomentumTransfer2,
1315 "Return the true momentum transfer to lepton pair in a B(semi -) leptonic B meson decay.\n\n",
"GeV/c");
1316 REGISTER_VARIABLE(
"False", False,
1317 "returns always 0, used for testing and debugging.");
1318 REGISTER_VARIABLE(
"True", True,
1319 "returns always 1, used for testing and debugging.");
1320 REGISTER_VARIABLE(
"infinity", infinity,
1321 "returns std::numeric_limits<double>::infinity()");
1322 REGISTER_VARIABLE(
"random", random,
1323 "return a random number between 0 and 1 for each candidate. Can be used, e.g. for picking a random"
1324 "candidate in the best candidate selection.");
1325 REGISTER_VARIABLE(
"eventRandom", eventRandom,
1326 "[Eventbased] Returns a random number between 0 and 1 for this event. Can be used, e.g. for applying an event prescale.");
1327 REGISTER_METAVARIABLE(
"minET2ETDist(detName, detLayer, referenceListName, useHighestProbMassForExt=1)", particleDistToClosestExtTrk,
1328 R
"DOC(Returns the distance :math:`d_{\mathrm{i}}` in [cm] between the particle and the nearest particle in the reference list at the given detector :math:`i`-th layer surface.
1329The definition is based on the track helices extrapolation.
1331* The first argument is the name of the detector to consider.
1332* The second argument is the detector layer on whose surface we search for the nearest neighbour.
1333* The third argument is the reference particle list name used to search for the nearest neighbour.
1334* The fourth (optional) argument is an integer ("boolean") flag: if 1 (the default, if nothing is set), it is assumed the extrapolation was done with the most probable mass hypothesis for the track fit;
1335 if 0, it is assumed the mass hypothesis matching the particle lists' PDG was used.
1338 This variable requires to run the ``TrackIsoCalculator`` module first.
1339 Note that the choice of input parameters of this metafunction must correspond to the settings used to configure the module!
1341 Manager::VariableDataType::c_double);
1343 REGISTER_METAVARIABLE("minET2ETDistVar(detName, detLayer, referenceListName, variableName)", particleDistToClosestExtTrkVar,
1344 R
"DOC(Returns the value of the variable for the nearest neighbour to this particle as taken from the reference list at the given detector :math:`i`-th layer surface
1345, according to the distance definition of `minET2ETDist`.
1347* The first argument is the name of the detector to consider.
1348* The second argument is the detector layer on whose surface we search for the nearest neighbour.
1349* The third argument is the reference particle list name used to search for the nearest neighbour.
1350* The fourth argument is a variable name, e.g. `nCDCHits`.
1353 This variable requires to run the ``TrackIsoCalculator`` module first.
1354 Note that the choice of input parameters of this metafunction must correspond to the settings used to configure the module!
1356 Manager::VariableDataType::c_double);
1358 REGISTER_METAVARIABLE("minET2ETIsoScore(referenceListName, useHighestProbMassForExt, detectorList)", particleExtTrkIsoScoreVar,
1359 R
"DOC(Returns a particle's isolation score :math:`s` defined as:
1366 s &= \sum_{\mathrm{det}} 1 - \left(-w_{\mathrm{det}} \cdot \frac{\sum_{i}^{N_{\mathrm{det}}^{\mathrm{layers}}} H(i)}{N_{\mathrm{det}}^{\mathrm{layers}}}\right), \\
1370 0 & d_{\mathrm{i}} > D_{\mathrm{det}}^{\mathrm{thresh}} \\
1371 1 & d_{\mathrm{i}} <= D_{\mathrm{det}}^{\mathrm{thresh}}, \\
1376where :math:`d_{\mathrm{i}}` is the distance to the closest neighbour at the :math:`i`-th layer of the given detector (c.f., `minET2ETDist`), :math:`N_{\mathrm{det}}^{\mathrm{layers}}` is the
1377number of layers of the detector, :math:`D_{\mathrm{det}}^{\mathrm{thresh}}` is a threshold length related to the detector's granularity defined in the ``TrackIsoCalculator`` module,
1378and :math:`w_{\mathrm{det}}` are (negative) weights associated to the detector's impact on PID for this particle type, read from a CDB payload.
1380The score is normalised in [0, 1], where values closer to 1 indicates a well-isolated particle.
1382* The first argument is the reference particle list name used to search for the nearest neighbour.
1383* The second argument is an integer ("boolean") flag: if 1, it is assumed the extrapolation was done with the most probable mass hypothesis for the track fit;
1384 if 0, it is assumed the mass hypothesis matching the particle lists' PDG was used.
1385* The remaining arguments are a comma-separated list of detector names, which must correspond to the one given to the `TrackIsoCalculator` module.
1388 The PID detector weights :math:`w_{\mathrm{det}}` are non-trivial only if ``excludePIDDetWeights=false`` in the ``TrackIsoCalculator`` module configuration.
1389 Otherwise :math:`w_{\mathrm{det}} = -1`.
1392 This variable requires to run the `TrackIsoCalculator` module first.
1393 Note that the choice of input parameters of this metafunction must correspond to the settings used to configure the module!
1396 Manager::VariableDataType::c_double);
1398 REGISTER_METAVARIABLE("minET2ETIsoScoreAsWeightedAvg(referenceListName, useHighestProbMassForExt, detectorList)", particleExtTrkIsoScoreVarAsWeightedAvg,
1399 R
"DOC(Returns a particle's isolation score :math:`s` based on the weighted average:
1403 s = 1 - \frac{\sum_{\mathrm{det}} \sum_{i}^{N_{\mathrm{det}}^{\mathrm{layers}}} w_{\mathrm{det}} \cdot \frac{D_{\mathrm{det}}^{\mathrm{thresh}}}{d_{\mathrm{i}}} }{ \sum_{\mathrm{det}} w_{\mathrm{det}}},
1405where :math:`d_{\mathrm{i}}` is the distance to the closest neighbour at the :math:`i`-th layer of the given detector (c.f., `minET2ETDist`), :math:`N_{\mathrm{det}}^{\mathrm{layers}}` is the
1406number of layers of the detector, :math:`D_{\mathrm{det}}^{\mathrm{thresh}}` is a threshold length related to the detector's granularity defined in the ``TrackIsoCalculator`` module,
1407and :math:`w_{\mathrm{det}}` are (negative) weights associated to the detector's impact on PID for this particle type, read from a CDB payload.
1409The score is normalised in [0, 1], where values closer to 1 indicates a well-isolated particle.
1411* The first argument is the reference particle list name used to search for the nearest neighbour.
1412* The second argument is an integer ("boolean") flag: if 1, it is assumed the extrapolation was done with the most probable mass hypothesis for the track fit;
1413 if 0, it is assumed the mass hypothesis matching the particle lists' PDG was used.
1414* The remaining arguments are a comma-separated list of detector names, which must correspond to the one given to the `TrackIsoCalculator` module.
1417 The PID detector weights :math:`w_{\mathrm{det}}` are non-trivial only if ``excludePIDDetWeights=false`` in the ``TrackIsoCalculator`` module configuration.
1418 Otherwise :math:`\lvert w_{\mathrm{det}} \rvert = 1`.
1421 This variable requires to run the `TrackIsoCalculator` module first.
1422 Note that the choice of input parameters of this metafunction must correspond to the settings used to configure the module!
1425 Manager::VariableDataType::c_double);
DataType Perp() const
The transverse component (R in cylindrical coordinate system).
static BFieldManager & getInstance()
Return the instance of the magnetic field manager.
static ROOT::Math::XYZVector getFieldInTesla(const ROOT::Math::XYZVector &pos)
return the magnetic field at a given position in Tesla.
int getPDGCode() const
PDG code.
static const ChargedStable muon
muon particle
static const ChargedStable pion
charged pion particle
static const double pionMass
charged pion mass
static const double speedOfLight
[cm/ns]
static const ChargedStable proton
proton particle
static const double protonMass
proton mass
static const double doubleNaN
quiet_NaN
static const ChargedStable kaon
charged kaon particle
static const ParticleType photon
photon particle
static const ChargedStable electron
electron particle
EHypothesisBit
The hypothesis bits for this ECLCluster (Connected region (CR) is split using this hypothesis.
@ c_PrimaryParticle
bit 0: Particle is primary particle.
const MCParticle * getMCParticle() const
Returns the pointer to the MCParticle object that was used to create this Particle (ParticleType == c...
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.
Class to store variables with their name which were sent to the logging service.
B2Vector3< double > B2Vector3D
typedef for common usage with double
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.
static std::string explainFlags(unsigned int flags)
Return string with all human-readable flags, e.g.
static int getMCErrors(const Belle2::Particle *particle, const Belle2::MCParticle *mcParticle=nullptr)
Returns quality indicator of the match as a bit pattern where the individual bits indicate the the ty...