10 #include <analysis/variables/FlightInfoVariables.h>
13 #include <analysis/VariableManager/Manager.h>
15 #include <framework/database/DBObjPtr.h>
16 #include <framework/logging/Logger.h>
18 #include <analysis/dataobjects/Particle.h>
19 #include <mdst/dataobjects/MCParticle.h>
20 #include <mdst/dbobjects/BeamSpot.h>
22 #include <TMatrixFSym.h>
24 #include <boost/algorithm/string.hpp>
35 bool hasRAVEBeamConstrainedProductionVertex(
const Particle* particle)
37 bool hasRAVEProdVertex =
true;
38 std::vector<std::string> directions = {
"x",
"y",
"z"};
39 for (
auto ielement : directions) {
40 std::string prodVertPositionElement = boost::str(boost::format(
"prodVert%s") % boost::to_upper_copy(ielement));
41 hasRAVEProdVertex &= particle -> hasExtraInfo(prodVertPositionElement);
42 for (
auto jelement : directions) {
43 std::string prodVertCovarianceElement = boost::str(boost::format(
"prodVertS%s%s") % ielement % jelement);
44 hasRAVEProdVertex &= particle -> hasExtraInfo(prodVertCovarianceElement);
47 return hasRAVEProdVertex;
51 inline double getFlightInfoBtw(
const Particle* particle,
const Particle* daughter,
double& outErr,
const std::string& mode,
52 const bool motherToGranddaughter =
false)
54 if (!particle || !daughter) {
55 outErr = std::numeric_limits<float>::quiet_NaN();
56 return std::numeric_limits<float>::quiet_NaN();
59 if (!(particle->getParticleSource() == Particle::EParticleSourceObject::c_Composite) ||
60 !(daughter->getParticleSource() == Particle::EParticleSourceObject::c_Composite)) {
62 if (!(particle->getParticleSource() == Particle::EParticleSourceObject::c_V0) ||
63 !(daughter->getParticleSource() == Particle::EParticleSourceObject::c_V0)) {
64 B2WARNING(
"Attempting to calculate flight " << mode <<
" for neither composite particle nor V0");
65 outErr = std::numeric_limits<float>::quiet_NaN();
66 return std::numeric_limits<float>::quiet_NaN();
69 if (!(mode ==
"distance") && !(mode ==
"time")) {
70 B2WARNING(
"FlightInfo helper function called with mode '" << mode
71 <<
"'. Only 'distance' and 'time' are available.");
72 outErr = std::numeric_limits<float>::quiet_NaN();
73 return std::numeric_limits<float>::quiet_NaN();
78 if (!motherToGranddaughter) {
79 if (mode ==
"distance" &&
80 daughter->hasExtraInfo(
"decayLength") &&
81 daughter->hasExtraInfo(
"decayLengthErr")) {
82 outErr = daughter -> getExtraInfo(
"decayLengthErr");
83 return daughter -> getExtraInfo(
"decayLength");
86 daughter->hasExtraInfo(
"lifeTime") &&
87 daughter->hasExtraInfo(
"lifeTimeErr")) {
88 outErr = daughter -> getExtraInfo(
"lifeTimeErr");
89 return daughter -> getExtraInfo(
"lifeTime");
94 double mumvtxX = particle->getX();
95 double mumvtxY = particle->getY();
96 double mumvtxZ = particle->getZ();
97 if (particle == daughter) {
98 if (hasRAVEBeamConstrainedProductionVertex(particle)) {
99 mumvtxX = particle->getExtraInfo(
"prodVertX");
100 mumvtxY = particle->getExtraInfo(
"prodVertY");
101 mumvtxZ = particle->getExtraInfo(
"prodVertZ");
104 static DBObjPtr<BeamSpot> beamSpotDB;
105 mumvtxX = (beamSpotDB->getIPPosition()).X();
106 mumvtxY = (beamSpotDB->getIPPosition()).Y();
107 mumvtxZ = (beamSpotDB->getIPPosition()).Z();
111 double vtxX = daughter->getX();
112 double vtxY = daughter->getY();
113 double vtxZ = daughter->getZ();
115 double p = daughter->getP();
116 double pX = daughter->getPx();
117 double pY = daughter->getPy();
118 double pZ = daughter->getPz();
125 double lX = vtxX - mumvtxX;
126 double lY = vtxY - mumvtxY;
127 double lZ = vtxZ - mumvtxZ;
130 double fD = lX * nX + lY * nY + lZ * nZ;
136 TMatrixFSym dauCov = daughter->getMomentumVertexErrorMatrix();
137 TMatrixFSym mumCov = particle->getVertexErrorMatrix();
138 if (particle == daughter) {
139 if (hasRAVEBeamConstrainedProductionVertex(particle)) {
140 std::vector<std::string> directions = {
"x",
"y",
"z"};
141 for (
unsigned int i = 0; i < directions.size(); i++) {
142 for (
unsigned int j = 0; j < directions.size(); j++) {
143 mumCov[i][j] = particle->getExtraInfo(boost::str(boost::format(
"prodVertS%s%s") % directions[i] % directions[j]));
147 static DBObjPtr<BeamSpot> beamSpotDB;
148 mumCov = beamSpotDB->getCovVertex();
155 for (
int i = 0; i < 10; i++)
156 for (
int j = 0; j < 10; j++)
158 Cov[i][j] = dauCov[i][j];
159 else if (i > 6 && j > 6)
160 Cov[i][j] = mumCov[i - 7][j - 7];
164 if (mode ==
"distance") {
165 TMatrixF deriv(10, 1);
166 deriv[0][0] = (lX - nX * fD) / p;
167 deriv[1][0] = (lY - nY * fD) / p;
168 deriv[2][0] = (lZ - nZ * fD) / p;
179 tmp.Mult(Cov, deriv);
181 TMatrixF result(1, 1);
182 result.Mult(deriv.T(), tmp);
184 outErr = sqrt(result[0][0]);
187 if (mode ==
"time") {
188 TMatrixF deriv(10, 1);
202 tmp.Mult(Cov, deriv);
204 TMatrixF result(1, 1);
205 result.Mult(deriv.T(), tmp);
206 outErr = sqrt(result[0][0]);
209 outErr = std::numeric_limits<float>::quiet_NaN();
210 return std::numeric_limits<float>::quiet_NaN();
214 inline double getMCFlightInfoBtw(
const MCParticle* mcparticle,
const std::string& mode)
217 if (mcparticle ==
nullptr)
218 return std::numeric_limits<float>::quiet_NaN();
221 if (mode ==
"distance") {
222 ROOT::Math::XYZVector deltaVtx = mcparticle->getDecayVertex() - mcparticle->getProductionVertex();
223 double distance = deltaVtx.R();
225 B2WARNING(
"Negative true flight distance, it's forbidden -> something went wrong.");
230 if (mode ==
"time") {
231 double lifetime = mcparticle->getLifetime();
232 double mass = mcparticle->getMass();
233 double time = std::numeric_limits<float>::quiet_NaN();
235 B2WARNING(
"you are asking for the proper time of a massless particle which is not allowed, returning -99.");
237 double energy = mcparticle->getEnergy();
238 time = lifetime / energy * mass;
242 B2WARNING(
"Negative true proper time, it's forbidden -> something went wrong.");
247 B2WARNING(
"MCFlightInfo helper function called with mode '" << mode
248 <<
"'. Only 'distance' and 'time' are available.");
249 return std::numeric_limits<float>::quiet_NaN();
253 double flightDistance(
const Particle* part)
255 double flightDistanceError = std::numeric_limits<float>::quiet_NaN();
256 return getFlightInfoBtw(part, part, flightDistanceError,
"distance");
259 double flightTime(
const Particle* part)
261 double flightTimeError = std::numeric_limits<float>::quiet_NaN();
262 return getFlightInfoBtw(part, part, flightTimeError,
"time");
265 double flightDistanceErr(
const Particle* part)
267 double flightDistanceError = std::numeric_limits<float>::quiet_NaN();
268 getFlightInfoBtw(part, part, flightDistanceError,
"distance");
269 return flightDistanceError;
272 double flightTimeErr(
const Particle* part)
274 double flightTimeError = std::numeric_limits<float>::quiet_NaN();
275 getFlightInfoBtw(part, part, flightTimeError,
"time");
276 return flightTimeError;
279 inline double getVertexDistance(
const Particle* particle,
const Particle* daughter,
double& vertexDistanceErr,
280 bool prodVertIsIP =
false)
282 if (!particle || !daughter) {
283 vertexDistanceErr = std::numeric_limits<float>::quiet_NaN();
284 return std::numeric_limits<float>::quiet_NaN();
288 double prodVtxX = particle->getX();
289 double prodVtxY = particle->getY();
290 double prodVtxZ = particle->getZ();
291 if (particle == daughter || prodVertIsIP) {
292 if (particle->hasExtraInfo(
"prodVertX")) prodVtxX = particle->getExtraInfo(
"prodVertX");
293 if (particle->hasExtraInfo(
"prodVertY")) prodVtxY = particle->getExtraInfo(
"prodVertY");
294 if (particle->hasExtraInfo(
"prodVertZ")) prodVtxZ = particle->getExtraInfo(
"prodVertZ");
298 double vtxX = daughter->getX();
299 double vtxY = daughter->getY();
300 double vtxZ = daughter->getZ();
303 double lX = vtxX - prodVtxX;
304 double lY = vtxY - prodVtxY;
305 double lZ = vtxZ - prodVtxZ;
308 double lD = sqrt(lX * lX + lY * lY + lZ * lZ);
311 TMatrixFSym decCov = daughter->getVertexErrorMatrix();
312 TMatrixFSym prodCov = particle->getVertexErrorMatrix();
313 if (particle == daughter || prodVertIsIP) {
314 if (particle->hasExtraInfo(
"prodVertSxx")) prodCov[0][0] = particle->getExtraInfo(
"prodVertSxx");
315 if (particle->hasExtraInfo(
"prodVertSxy")) prodCov[0][1] = particle->getExtraInfo(
"prodVertSxy");
316 if (particle->hasExtraInfo(
"prodVertSxz")) prodCov[0][2] = particle->getExtraInfo(
"prodVertSxz");
317 if (particle->hasExtraInfo(
"prodVertSyx")) prodCov[1][0] = particle->getExtraInfo(
"prodVertSyx");
318 if (particle->hasExtraInfo(
"prodVertSyy")) prodCov[1][1] = particle->getExtraInfo(
"prodVertSyy");
319 if (particle->hasExtraInfo(
"prodVertSyz")) prodCov[1][2] = particle->getExtraInfo(
"prodVertSyz");
320 if (particle->hasExtraInfo(
"prodVertSzx")) prodCov[2][0] = particle->getExtraInfo(
"prodVertSzx");
321 if (particle->hasExtraInfo(
"prodVertSzy")) prodCov[2][1] = particle->getExtraInfo(
"prodVertSzy");
322 if (particle->hasExtraInfo(
"prodVertSzz")) prodCov[2][2] = particle->getExtraInfo(
"prodVertSzz");
329 for (
int i = 0; i < 6; i++)
330 for (
int j = 0; j < 6; j++)
332 Cov[i][j] = prodCov[i][j];
333 else if (i > 2 && j > 2)
334 Cov[i][j] = decCov[i - 3][j - 3];
338 TMatrixF deriv(6, 1);
339 deriv[0][0] = - lX / lD;
340 deriv[1][0] = - lY / lD;
341 deriv[2][0] = - lZ / lD;
342 deriv[3][0] = lX / lD;
343 deriv[4][0] = lY / lD;
344 deriv[5][0] = lZ / lD;
348 tmp.Mult(Cov, deriv);
350 TMatrixF result(1, 1);
351 result.Mult(deriv.T(), tmp);
353 vertexDistanceErr = sqrt(result[0][0]);
357 double vertexDistance(
const Particle* part)
359 double vertexDistanceError = std::numeric_limits<float>::quiet_NaN();
360 if (!part->hasExtraInfo(
"prodVertX") || !part->hasExtraInfo(
"prodVertY") || !part->hasExtraInfo(
"prodVertZ")) {
361 return std::numeric_limits<float>::quiet_NaN();
363 return getVertexDistance(part, part, vertexDistanceError);
366 double vertexDistanceErr(
const Particle* part)
368 double vertexDistanceError = std::numeric_limits<float>::quiet_NaN();
369 if (!part->hasExtraInfo(
"prodVertX") || !part->hasExtraInfo(
"prodVertY") || !part->hasExtraInfo(
"prodVertZ")) {
370 return std::numeric_limits<float>::quiet_NaN();
372 getVertexDistance(part, part, vertexDistanceError);
373 return vertexDistanceError;
376 double vertexDistanceSignificance(
const Particle* part)
378 double vertexDistanceError = std::numeric_limits<float>::quiet_NaN();
379 if (!part->hasExtraInfo(
"prodVertX") || !part->hasExtraInfo(
"prodVertY") || !part->hasExtraInfo(
"prodVertZ")) {
380 return std::numeric_limits<float>::quiet_NaN();
382 return getVertexDistance(part, part, vertexDistanceError) / vertexDistanceError;
385 double flightTimeOfDaughter(
const Particle* particle,
const std::vector<double>& daughters)
388 return std::numeric_limits<float>::quiet_NaN();
390 long daughterNumber = -1;
391 if (daughters.size() > 0) {
392 daughterNumber = std::lround(daughters[0]);
394 B2ERROR(
"At least one integer, the index of the daughter, must be provided to flightTimeOfDaughter!");
395 return std::numeric_limits<float>::quiet_NaN();
397 int nDaughters =
static_cast<int>(particle->getNDaughters());
398 if (daughterNumber >= nDaughters) {
399 B2ERROR(
"The daughter index provided to flightTimeOfDaughter is larger than the number of daughters of this particle!");
400 return std::numeric_limits<float>::quiet_NaN();
403 long grandDaughterNumber = -1;
404 if (daughters.size() == 2) {
405 grandDaughterNumber = std::lround(daughters[1]);
408 const Particle* daughter = particle->getDaughter(daughterNumber);
409 double flightTimeError;
410 if (grandDaughterNumber > -1) {
411 if (grandDaughterNumber < (
int)daughter->getNDaughters()) {
412 return getFlightInfoBtw(particle, daughter->getDaughter(grandDaughterNumber), flightTimeError,
"time",
true);
414 B2ERROR(
"The granddaughter index provided to flightTimeOfDaughter is too large!");
415 return std::numeric_limits<float>::quiet_NaN();
418 return getFlightInfoBtw(particle, daughter, flightTimeError,
"time");
423 double flightTimeOfDaughterErr(
const Particle* particle,
const std::vector<double>& daughters)
426 return std::numeric_limits<float>::quiet_NaN();
428 long daughterNumber = -1;
429 if (daughters.size() > 0) {
430 daughterNumber = std::lround(daughters[0]);
432 B2ERROR(
"At least one integer, the index of the daughter, must be provided to flightTimeOfDaughterErr!");
433 return std::numeric_limits<float>::quiet_NaN();
435 int nDaughters =
static_cast<int>(particle->getNDaughters());
436 if (daughterNumber >= nDaughters) {
437 B2ERROR(
"The daughter index provided to flightTimeOfDaughterErr is larger than the number of daughters of this particle!");
438 return std::numeric_limits<float>::quiet_NaN();
441 long grandDaughterNumber = -1;
442 if (daughters.size() == 2) {
443 grandDaughterNumber = std::lround(daughters[1]);
446 const Particle* daughter = particle->getDaughter(daughterNumber);
447 double flightTimeError = std::numeric_limits<float>::quiet_NaN();;
448 if (grandDaughterNumber > -1) {
449 if (grandDaughterNumber < (
int)daughter->getNDaughters()) {
450 getFlightInfoBtw(particle, daughter->getDaughter(grandDaughterNumber), flightTimeError,
"time",
true);
452 B2ERROR(
"The granddaughter index provided to flightTimeOfDaughterErr is too large!");
455 getFlightInfoBtw(particle, daughter, flightTimeError,
"time");
457 return flightTimeError;
460 double flightDistanceOfDaughter(
const Particle* particle,
const std::vector<double>& daughters)
463 return std::numeric_limits<float>::quiet_NaN();
465 long daughterNumber = -1;
466 if (daughters.size() > 0) {
467 daughterNumber = std::lround(daughters[0]);
469 B2ERROR(
"At least one integer, the index of the daughter, must be provided to flightDistanceOfDaughter!");
470 return std::numeric_limits<float>::quiet_NaN();
472 int nDaughters =
static_cast<int>(particle->getNDaughters());
473 if (daughterNumber >= nDaughters) {
474 B2ERROR(
"The daughter index provided to flightDistanceOfDaughter is larger than the number of daughters of this particle!");
475 return std::numeric_limits<float>::quiet_NaN();
478 long grandDaughterNumber = -1;
479 if (daughters.size() == 2) {
480 grandDaughterNumber = std::lround(daughters[1]);
483 const Particle* daughter = particle->getDaughter(daughterNumber);
484 double flightDistanceError;
485 if (grandDaughterNumber > -1) {
486 if (grandDaughterNumber < (
int)daughter->getNDaughters()) {
487 return getFlightInfoBtw(particle, daughter->getDaughter(grandDaughterNumber), flightDistanceError,
"distance",
true);
489 B2ERROR(
"The granddaughter index provided to flightDistanceOfDaughter is too large!");
490 return std::numeric_limits<float>::quiet_NaN();
493 return getFlightInfoBtw(particle, daughter, flightDistanceError,
"distance");
498 double flightDistanceOfDaughterErr(
const Particle* particle,
const std::vector<double>& daughters)
501 return std::numeric_limits<float>::quiet_NaN();
503 long daughterNumber = -1;
504 if (daughters.size() > 0) {
505 daughterNumber = std::lround(daughters[0]);
507 B2ERROR(
"At least one integer, the index of the daughter, must be provided to flightDistanceOfDaughterErr!");
508 return std::numeric_limits<float>::quiet_NaN();
510 int nDaughters =
static_cast<int>(particle->getNDaughters());
511 if (daughterNumber >= nDaughters) {
512 B2ERROR(
"The daughter index provided to flightDistanceOfDaughterErr is larger than the number of daughters of this particle!");
513 return std::numeric_limits<float>::quiet_NaN();
516 long grandDaughterNumber = -1;
517 if (daughters.size() == 2) {
518 grandDaughterNumber = std::lround(daughters[1]);
521 const Particle* daughter = particle->getDaughter(daughterNumber);
522 double flightDistanceError = std::numeric_limits<float>::quiet_NaN();
523 if (grandDaughterNumber > -1) {
524 if (grandDaughterNumber < (
int)daughter->getNDaughters()) {
525 getFlightInfoBtw(particle, daughter->getDaughter(grandDaughterNumber), flightDistanceError,
"distance",
true);
527 B2ERROR(
"The granddaughter index provided to flightDistanceOfDaughterErr is too large!");
530 getFlightInfoBtw(particle, daughter, flightDistanceError,
"distance");
532 return flightDistanceError;
536 double vertexDistanceOfDaughter(
const Particle* particle,
const std::vector<double>& arguments)
539 return std::numeric_limits<float>::quiet_NaN();
540 long daughterNumber = -1;
541 if (arguments.size() > 0) {
542 daughterNumber = std::lround(arguments[0]);
544 B2ERROR(
"At least one integer, the index of the daughter, must be provided to vertexDistanceOfDaughter!");
545 return std::numeric_limits<float>::quiet_NaN();
547 int nDaughters =
static_cast<int>(particle->getNDaughters());
548 if (daughterNumber >= nDaughters) {
549 B2ERROR(
"The daughter index provided to vertexDistanceOfDaughter is larger than the number of daughters of this particle!");
550 return std::numeric_limits<float>::quiet_NaN();
553 bool prodVertIsIP =
true;
554 if (arguments.size() == 2) {
555 prodVertIsIP =
false;
558 const Particle* daughter = particle->getDaughter(daughterNumber);
559 double vertexDistanceError;
560 return getVertexDistance(particle, daughter, vertexDistanceError, prodVertIsIP);
564 double vertexDistanceOfDaughterErr(
const Particle* particle,
const std::vector<double>& arguments)
567 return std::numeric_limits<float>::quiet_NaN();
568 long daughterNumber = -1;
569 if (arguments.size() > 0) {
570 daughterNumber = std::lround(arguments[0]);
572 B2ERROR(
"At least one integer, the index of the daughter, must be provided to vertexDistanceOfDaughterErr!");
573 return std::numeric_limits<float>::quiet_NaN();
575 int nDaughters =
static_cast<int>(particle->getNDaughters());
576 if (daughterNumber >= nDaughters) {
577 B2ERROR(
"The daughter index provided to vertexDistanceOfDaughterErr is larger than the number of daughters of this particle!");
578 return std::numeric_limits<float>::quiet_NaN();
581 bool prodVertIsIP =
true;
582 if (arguments.size() == 2) {
583 prodVertIsIP =
false;
586 const Particle* daughter = particle->getDaughter(daughterNumber);
587 double vertexDistanceError;
588 getVertexDistance(particle, daughter, vertexDistanceError, prodVertIsIP);
589 return vertexDistanceError;
593 double vertexDistanceOfDaughterSignificance(
const Particle* particle,
const std::vector<double>& arguments)
596 return std::numeric_limits<float>::quiet_NaN();
597 long daughterNumber = -1;
598 if (arguments.size() > 0) {
599 daughterNumber = std::lround(arguments[0]);
601 B2ERROR(
"At least one integer, the index of the daughter, must be provided to vertexDistanceOfDaughterSignificance!");
602 return std::numeric_limits<float>::quiet_NaN();
604 int nDaughters =
static_cast<int>(particle->getNDaughters());
605 if (daughterNumber >= nDaughters) {
606 B2ERROR(
"The daughter index provided to vertexDistanceOfDaughterSignificance is larger than the number of daughters of this particle!");
607 return std::numeric_limits<float>::quiet_NaN();
610 bool prodVertIsIP =
true;
611 if (arguments.size() == 2) {
612 prodVertIsIP =
false;
615 const Particle* daughter = particle->getDaughter(daughterNumber);
616 double vertexDistanceError;
617 return getVertexDistance(particle, daughter, vertexDistanceError, prodVertIsIP) / vertexDistanceError;
622 double mcFlightDistance(
const Particle* particle)
624 if (particle ==
nullptr)
625 return std::numeric_limits<float>::quiet_NaN();
629 if (mcparticle ==
nullptr)
630 return std::numeric_limits<float>::quiet_NaN();
632 return getMCFlightInfoBtw(mcparticle,
"distance");
635 double mcFlightTime(
const Particle* particle)
637 if (particle ==
nullptr)
638 return std::numeric_limits<float>::quiet_NaN();
642 if (mcparticle ==
nullptr)
643 return std::numeric_limits<float>::quiet_NaN();
646 return getMCFlightInfoBtw(mcparticle,
"time");
649 double mcFlightDistanceOfDaughter(
const Particle* particle,
const std::vector<double>& daughters)
652 return std::numeric_limits<float>::quiet_NaN();
654 long daughterNumber = -1;
655 if (daughters.size() > 0) {
656 daughterNumber = std::lround(daughters[0]);
658 B2ERROR(
"At least one integer, the index of the daughter, must be provided to mcFlightDistanceOfDaughter!");
659 return std::numeric_limits<float>::quiet_NaN();
661 int nDaughters =
static_cast<int>(particle->getNDaughters());
662 if (daughterNumber >= nDaughters) {
663 B2ERROR(
"The daughter index provided to mcFlightDistanceOfDaughter is larger than the number of daughters of this particle!");
664 return std::numeric_limits<float>::quiet_NaN();
667 long grandDaughterNumber = -1;
668 if (daughters.size() == 2) {
669 grandDaughterNumber = std::lround(daughters[1]);
672 const Particle* daughterReco = particle->getDaughter(daughterNumber);
674 const MCParticle* daughter = daughterReco->getMCParticle();
676 double flightDistanceMC;
677 if (grandDaughterNumber > -1 && grandDaughterNumber < (
int)daughterReco->getNDaughters()) {
680 flightDistanceMC = getMCFlightInfoBtw(gdaughter,
"distance");
683 flightDistanceMC = getMCFlightInfoBtw(daughter,
"distance");
685 return flightDistanceMC;
688 double mcFlightTimeOfDaughter(
const Particle* particle,
const std::vector<double>& daughters)
691 return std::numeric_limits<float>::quiet_NaN();
693 long daughterNumber = -1;
694 if (daughters.size() > 0) {
695 daughterNumber = std::lround(daughters[0]);
697 B2ERROR(
"At least one integer, the index of the daughter, must be provided to mcFlightTimeOfDaughter!");
698 return std::numeric_limits<float>::quiet_NaN();
700 int nDaughters =
static_cast<int>(particle->getNDaughters());
701 if (daughterNumber >= nDaughters) {
702 B2ERROR(
"The daughter index provided to mcFlightTimeOfDaughter is larger than the number of daughters of this particle!");
703 return std::numeric_limits<float>::quiet_NaN();
706 long grandDaughterNumber = -1;
707 if (daughters.size() == 2) {
708 grandDaughterNumber = std::lround(daughters[1]);
711 const Particle* daughterReco = particle->getDaughter(daughterNumber);
713 const MCParticle* daughter = daughterReco->getMCParticle();
716 if (grandDaughterNumber > -1 && grandDaughterNumber < (
int)daughterReco->getNDaughters()) {
719 flightTimeMC = getMCFlightInfoBtw(gdaughter,
"time");
721 flightTimeMC = getMCFlightInfoBtw(daughter,
"time");
727 VARIABLE_GROUP(
"Flight Information");
728 REGISTER_VARIABLE(
"flightTime", flightTime,
729 "Returns the flight time of particle. If a treeFit has been performed the flight time calculated by TreeFitter is returned. Otherwise if a beam constrained rave fit has been performed the production vertex set by rave and the decay vertex are used to calculate the flight time. If neither fit has been performed the i.p. is taken to be the production vertex.",
731 REGISTER_VARIABLE(
"flightDistance", flightDistance,
732 "Returns the flight distance of particle. If a treeFit has been performed the flight distance calculated by TreeFitter is returned. Otherwise if a beam constrained rave fit has been performed the production vertex set by rave and the decay vertex are used to calculate the flight distance. If neither fit has been performed the i.p. is taken to be the production vertex.",
734 REGISTER_VARIABLE(
"flightTimeErr", flightTimeErr,
735 "Returns the flight time error of particle. If a treeFit has been performed the flight time error calculated by TreeFitter is returned. Otherwise if a beam constrained rave fit has been performed the production vertex set by rave and the decay vertex are used to calculate the flight time error. If neither fit has been performed the i.p. is taken to be the production vertex.",
737 REGISTER_VARIABLE(
"flightDistanceErr", flightDistanceErr,
738 "Returns the flight distance error of particle. If a treeFit has been performed the flight distance error calculated by TreeFitter is returned. Otherwise if a beam constrained rave fit has been performed the production vertex set by rave and the decay vertex are used to calculate the flight distance error. If neither fit has been performed the i.p. is taken to be the production vertex.",
741 REGISTER_VARIABLE(
"flightTimeOfDaughter(daughterN, gdaughterN = -1)", flightTimeOfDaughter,
742 "Returns the flight time between mother and daughter particle with daughterN index. If a treeFit has been performed the value calculated by treeFitter is returned. Otherwise the value is calculated using the decay vertices of the mother and daughter particle. If a second index granddaughterM is given the value is calculated between the mother and the Mth grandaughter (Mth daughter of Nth daughter).",
744 REGISTER_VARIABLE(
"flightTimeOfDaughterErr(daughterN, gdaughterN = -1)", flightTimeOfDaughterErr,
745 "Returns the flight time error between mother and daughter particle with daughterN index. If a treeFit has been performed the value calculated by treeFitter is returned. Otherwise the value is calculated using the decay vertices of the mother and daughter particle. If a second index granddaughterM is given the value is calculated between the mother and the Mth grandaughter (Mth daughter of Nth daughter).",
747 REGISTER_VARIABLE(
"flightDistanceOfDaughter(daughterN, gdaughterN = -1)", flightDistanceOfDaughter,
748 "Returns the flight distance between mother and daughter particle with daughterN index. If a treeFit has been performed the value calculated by treeFitter is returned. Otherwise the value is calculated using the decay vertices of the mother and daughter particle. If a second index granddaughterM is given the value is calculated between the mother and the Mth grandaughter (Mth daughter of Nth daughter).",
750 REGISTER_VARIABLE(
"flightDistanceOfDaughterErr(daughterN, gdaughterN = -1)", flightDistanceOfDaughterErr,
751 "Returns the flight distance error between mother and daughter particle with daughterN index. If a treeFit has been performed the value calculated by treeFitter is returned. Otherwise the value is calculated using the decay vertices of the mother and daughter particle. If a second index granddaughterM is given the value is calculated between the mother and the Mth grandaughter (Mth daughter of Nth daughter).",
754 REGISTER_VARIABLE(
"mcFlightDistance", mcFlightDistance,
755 "Returns the MC flight distance of the particle",
"cm");
756 REGISTER_VARIABLE(
"mcFlightTime", mcFlightTime,
757 "Returns the MC flight time of the particle",
"ns");
758 REGISTER_VARIABLE(
"mcFlightDistanceOfDaughter(daughterN, gdaughterN = -1)", mcFlightDistanceOfDaughter,
759 "Returns the MC flight distance between mother and daughter particle using generated info",
"cm");
760 REGISTER_VARIABLE(
"mcFlightTimeOfDaughter(daughterN, gdaughterN = -1)", mcFlightTimeOfDaughter,
761 "Returns the MC flight time between mother and daughter particle using generated info",
"ns");
763 REGISTER_VARIABLE(
"vertexDistance", vertexDistance,
764 "Returns the distance between the production and decay vertex of a particle. Returns NaN if particle has no production or decay vertex.",
766 REGISTER_VARIABLE(
"vertexDistanceErr", vertexDistanceErr,
767 "Returns the uncertainty on the distance between the production and decay vertex of a particle. Returns NaN if particle has no production or decay vertex.",
769 REGISTER_VARIABLE(
"vertexDistanceSignificance", vertexDistanceSignificance,
770 "Returns the distance between the production and decay vertex of a particle in units of the uncertainty on this value, i.e. the significance of the vertex separation.");
771 REGISTER_VARIABLE(
"vertexDistanceOfDaughter(daughterN[, option])", vertexDistanceOfDaughter,
772 "If any integer is provided as second argument it returns the distance between the decay vertices of the particle and of its daughter with index daughterN.\n"
773 "Otherwise, it is assumed that the particle has a production vertex (typically the IP) which is used to calculate the distance to the daughter's decay vertex.\n"
774 "Returns NaN in case anything goes wrong.",
"cm");
775 REGISTER_VARIABLE(
"vertexDistanceOfDaughterErr(daughterN[, option])", vertexDistanceOfDaughterErr,
776 "If any integer is provided as second argument it returns the uncertainty on the distance between the decay vertices of the particle and of its daughter with index daughterN.\n"
777 "Otherwise, it is assumed that the particle has a production vertex (typically the IP) with a corresponding covariance matrix to calculate the uncertainty on the distance to the daughter's decay vertex.\n"
778 "Returns NaN in case anything goes wrong.",
"cm");
779 REGISTER_VARIABLE(
"vertexDistanceOfDaughterSignificance(daughterN[, option)", vertexDistanceOfDaughterSignificance,
780 "If any integer is provided as second argument it returns the distance between the decay vertices of the particle and of its daughter with index daughterN in units of the uncertainty on this value.\n"
781 "Otherwise, it is assumed that the particle has a production vertex (typically the IP) with a corresponding covariance matrix and the significance of the separation to this vertex is calculated.");
static const double speedOfLight
[cm/ns]
const MCParticle * getMCParticle() const
Returns the pointer to the MCParticle object that was used to create this Particle (ParticleType == c...
const Particle * getDaughter(unsigned i) const
Returns a pointer to the i-th daughter particle.
Abstract base class for different kinds of events.