9 #include <analysis/variables/FlightInfoVariables.h>
10 #include <framework/logging/Logger.h>
11 #include <analysis/VariableManager/Manager.h>
12 #include <framework/database/DBObjPtr.h>
13 #include <mdst/dbobjects/BeamSpot.h>
14 #include <framework/utilities/Conversion.h>
15 #include <boost/algorithm/string.hpp>
16 #include <mdst/dataobjects/MCParticle.h>
18 #include <TMatrixFSym.h>
30 bool hasRAVEBeamConstrainedProductionVertex(
const Particle* particle)
32 bool hasRAVEProdVertex =
true;
33 std::vector<std::string> directions = {
"x",
"y",
"z"};
34 for (
auto ielement : directions) {
35 std::string prodVertPositionElement = boost::str(boost::format(
"prodVert%s") % boost::to_upper_copy(ielement));
36 hasRAVEProdVertex &= particle -> hasExtraInfo(prodVertPositionElement);
37 for (
auto jelement : directions) {
38 std::string prodVertCovarianceElement = boost::str(boost::format(
"prodVertS%s%s") % ielement % jelement);
39 hasRAVEProdVertex &= particle -> hasExtraInfo(prodVertCovarianceElement);
42 return hasRAVEProdVertex;
46 inline double getFlightInfoBtw(
const Particle* particle,
const Particle* daughter,
double& outErr,
const std::string& mode,
47 const bool motherToGranddaughter =
false)
49 if (!particle || !daughter) {
50 outErr = std::numeric_limits<float>::quiet_NaN();
51 return std::numeric_limits<float>::quiet_NaN();
54 if (!(particle->getParticleSource() == Particle::EParticleSourceObject::c_Composite) ||
55 !(daughter->getParticleSource() == Particle::EParticleSourceObject::c_Composite)) {
57 if (!(particle->getParticleSource() == Particle::EParticleSourceObject::c_V0) ||
58 !(daughter->getParticleSource() == Particle::EParticleSourceObject::c_V0)) {
59 B2WARNING(
"Attempting to calculate flight " << mode <<
" for neither composite particle nor V0");
60 outErr = std::numeric_limits<float>::quiet_NaN();
61 return std::numeric_limits<float>::quiet_NaN();
64 if (!(mode ==
"distance") && !(mode ==
"time")) {
65 B2WARNING(
"FlightInfo helper function called with mode '" << mode
66 <<
"'. Only 'distance' and 'time' are available.");
67 outErr = std::numeric_limits<float>::quiet_NaN();
68 return std::numeric_limits<float>::quiet_NaN();
73 if (!motherToGranddaughter) {
74 if (mode ==
"distance" &&
75 daughter->hasExtraInfo(
"decayLength") &&
76 daughter->hasExtraInfo(
"decayLengthErr")) {
77 outErr = daughter -> getExtraInfo(
"decayLengthErr");
78 return daughter -> getExtraInfo(
"decayLength");
81 daughter->hasExtraInfo(
"lifeTime") &&
82 daughter->hasExtraInfo(
"lifeTimeErr")) {
83 outErr = daughter -> getExtraInfo(
"lifeTimeErr");
84 return daughter -> getExtraInfo(
"lifeTime");
89 double mumvtxX = particle->getX();
90 double mumvtxY = particle->getY();
91 double mumvtxZ = particle->getZ();
92 if (particle == daughter) {
93 if (hasRAVEBeamConstrainedProductionVertex(particle)) {
94 mumvtxX = particle->getExtraInfo(
"prodVertX");
95 mumvtxY = particle->getExtraInfo(
"prodVertY");
96 mumvtxZ = particle->getExtraInfo(
"prodVertZ");
99 static DBObjPtr<BeamSpot> beamSpotDB;
100 mumvtxX = (beamSpotDB->getIPPosition()).X();
101 mumvtxY = (beamSpotDB->getIPPosition()).Y();
102 mumvtxZ = (beamSpotDB->getIPPosition()).Z();
106 double vtxX = daughter->getX();
107 double vtxY = daughter->getY();
108 double vtxZ = daughter->getZ();
110 double p = daughter->getP();
111 double pX = daughter->getPx();
112 double pY = daughter->getPy();
113 double pZ = daughter->getPz();
120 double lX = vtxX - mumvtxX;
121 double lY = vtxY - mumvtxY;
122 double lZ = vtxZ - mumvtxZ;
125 double fD = lX * nX + lY * nY + lZ * nZ;
131 TMatrixFSym dauCov = daughter->getMomentumVertexErrorMatrix();
132 TMatrixFSym mumCov = particle->getVertexErrorMatrix();
133 if (particle == daughter) {
134 if (hasRAVEBeamConstrainedProductionVertex(particle)) {
135 std::vector<std::string> directions = {
"x",
"y",
"z"};
136 for (
unsigned int i = 0; i < directions.size(); i++) {
137 for (
unsigned int j = 0; j < directions.size(); j++) {
138 mumCov[i][j] = particle->getExtraInfo(boost::str(boost::format(
"prodVertS%s%s") % directions[i] % directions[j]));
142 static DBObjPtr<BeamSpot> beamSpotDB;
143 mumCov = beamSpotDB->getCovVertex();
150 for (
int i = 0; i < 10; i++)
151 for (
int j = 0; j < 10; j++)
153 Cov[i][j] = dauCov[i][j];
154 else if (i > 6 && j > 6)
155 Cov[i][j] = mumCov[i - 7][j - 7];
159 if (mode ==
"distance") {
160 TMatrixF deriv(10, 1);
161 deriv[0][0] = (lX - nX * fD) / p;
162 deriv[1][0] = (lY - nY * fD) / p;
163 deriv[2][0] = (lZ - nZ * fD) / p;
174 tmp.Mult(Cov, deriv);
176 TMatrixF result(1, 1);
177 result.Mult(deriv.T(), tmp);
179 outErr = sqrt(result[0][0]);
182 if (mode ==
"time") {
183 TMatrixF deriv(10, 1);
197 tmp.Mult(Cov, deriv);
199 TMatrixF result(1, 1);
200 result.Mult(deriv.T(), tmp);
201 outErr = sqrt(result[0][0]);
204 outErr = std::numeric_limits<float>::quiet_NaN();
205 return std::numeric_limits<float>::quiet_NaN();
209 inline double getMCFlightInfoBtw(
const MCParticle* mcparticle,
const std::string& mode)
212 if (mcparticle ==
nullptr)
213 return std::numeric_limits<float>::quiet_NaN();
216 if (mode ==
"distance") {
217 TVector3 deltaVtx = mcparticle->getDecayVertex() - mcparticle->getProductionVertex();
218 double distance = deltaVtx.Mag();
220 B2WARNING(
"Negative true flight distance, it's forbidden -> something went wrong.");
225 if (mode ==
"time") {
226 double lifetime = mcparticle->getLifetime();
227 double mass = mcparticle->getMass();
228 double time = std::numeric_limits<float>::quiet_NaN();
230 B2WARNING(
"you are asking for the proper time of a massless particle which is not allowed, returning -99.");
232 double energy = mcparticle->getEnergy();
233 time = lifetime / energy * mass;
237 B2WARNING(
"Negative true proper time, it's forbidden -> something went wrong.");
242 B2WARNING(
"MCFlightInfo helper function called with mode '" << mode
243 <<
"'. Only 'distance' and 'time' are available.");
244 return std::numeric_limits<float>::quiet_NaN();
248 double flightDistance(
const Particle* part)
250 double flightDistanceError = std::numeric_limits<float>::quiet_NaN();
251 return getFlightInfoBtw(part, part, flightDistanceError,
"distance");
254 double flightTime(
const Particle* part)
256 double flightTimeError = std::numeric_limits<float>::quiet_NaN();
257 return getFlightInfoBtw(part, part, flightTimeError,
"time");
260 double flightDistanceErr(
const Particle* part)
262 double flightDistanceError = std::numeric_limits<float>::quiet_NaN();
263 getFlightInfoBtw(part, part, flightDistanceError,
"distance");
264 return flightDistanceError;
267 double flightTimeErr(
const Particle* part)
269 double flightTimeError = std::numeric_limits<float>::quiet_NaN();
270 getFlightInfoBtw(part, part, flightTimeError,
"time");
271 return flightTimeError;
274 inline double getVertexDistance(
const Particle* particle,
const Particle* daughter,
double& vertexDistanceErr,
275 bool prodVertIsIP =
false)
277 if (!particle || !daughter) {
278 vertexDistanceErr = std::numeric_limits<float>::quiet_NaN();
279 return std::numeric_limits<float>::quiet_NaN();
283 double prodVtxX = particle->getX();
284 double prodVtxY = particle->getY();
285 double prodVtxZ = particle->getZ();
286 if (particle == daughter || prodVertIsIP) {
287 if (particle->hasExtraInfo(
"prodVertX")) prodVtxX = particle->getExtraInfo(
"prodVertX");
288 if (particle->hasExtraInfo(
"prodVertY")) prodVtxY = particle->getExtraInfo(
"prodVertY");
289 if (particle->hasExtraInfo(
"prodVertZ")) prodVtxZ = particle->getExtraInfo(
"prodVertZ");
293 double vtxX = daughter->getX();
294 double vtxY = daughter->getY();
295 double vtxZ = daughter->getZ();
298 double lX = vtxX - prodVtxX;
299 double lY = vtxY - prodVtxY;
300 double lZ = vtxZ - prodVtxZ;
303 double lD = sqrt(lX * lX + lY * lY + lZ * lZ);
306 TMatrixFSym decCov = daughter->getVertexErrorMatrix();
307 TMatrixFSym prodCov = particle->getVertexErrorMatrix();
308 if (particle == daughter || prodVertIsIP) {
309 if (particle->hasExtraInfo(
"prodVertSxx")) prodCov[0][0] = particle->getExtraInfo(
"prodVertSxx");
310 if (particle->hasExtraInfo(
"prodVertSxy")) prodCov[0][1] = particle->getExtraInfo(
"prodVertSxy");
311 if (particle->hasExtraInfo(
"prodVertSxz")) prodCov[0][2] = particle->getExtraInfo(
"prodVertSxz");
312 if (particle->hasExtraInfo(
"prodVertSyx")) prodCov[1][0] = particle->getExtraInfo(
"prodVertSyx");
313 if (particle->hasExtraInfo(
"prodVertSyy")) prodCov[1][1] = particle->getExtraInfo(
"prodVertSyy");
314 if (particle->hasExtraInfo(
"prodVertSyz")) prodCov[1][2] = particle->getExtraInfo(
"prodVertSyz");
315 if (particle->hasExtraInfo(
"prodVertSzx")) prodCov[2][0] = particle->getExtraInfo(
"prodVertSzx");
316 if (particle->hasExtraInfo(
"prodVertSzy")) prodCov[2][1] = particle->getExtraInfo(
"prodVertSzy");
317 if (particle->hasExtraInfo(
"prodVertSzz")) prodCov[2][2] = particle->getExtraInfo(
"prodVertSzz");
324 for (
int i = 0; i < 6; i++)
325 for (
int j = 0; j < 6; j++)
327 Cov[i][j] = prodCov[i][j];
328 else if (i > 2 && j > 2)
329 Cov[i][j] = decCov[i - 3][j - 3];
333 TMatrixF deriv(6, 1);
334 deriv[0][0] = - lX / lD;
335 deriv[1][0] = - lY / lD;
336 deriv[2][0] = - lZ / lD;
337 deriv[3][0] = lX / lD;
338 deriv[4][0] = lY / lD;
339 deriv[5][0] = lZ / lD;
343 tmp.Mult(Cov, deriv);
345 TMatrixF result(1, 1);
346 result.Mult(deriv.T(), tmp);
348 vertexDistanceErr = sqrt(result[0][0]);
352 double vertexDistance(
const Particle* part)
354 double vertexDistanceError = std::numeric_limits<float>::quiet_NaN();
355 if (!part->hasExtraInfo(
"prodVertX") || !part->hasExtraInfo(
"prodVertY") || !part->hasExtraInfo(
"prodVertZ")) {
356 return std::numeric_limits<float>::quiet_NaN();
358 return getVertexDistance(part, part, vertexDistanceError);
361 double vertexDistanceErr(
const Particle* part)
363 double vertexDistanceError = std::numeric_limits<float>::quiet_NaN();
364 if (!part->hasExtraInfo(
"prodVertX") || !part->hasExtraInfo(
"prodVertY") || !part->hasExtraInfo(
"prodVertZ")) {
365 return std::numeric_limits<float>::quiet_NaN();
367 getVertexDistance(part, part, vertexDistanceError);
368 return vertexDistanceError;
371 double vertexDistanceSignificance(
const Particle* part)
373 double vertexDistanceError = std::numeric_limits<float>::quiet_NaN();
374 if (!part->hasExtraInfo(
"prodVertX") || !part->hasExtraInfo(
"prodVertY") || !part->hasExtraInfo(
"prodVertZ")) {
375 return std::numeric_limits<float>::quiet_NaN();
377 return getVertexDistance(part, part, vertexDistanceError) / vertexDistanceError;
382 int daughterNumber = -1;
383 int grandDaughterNumber = -1;
384 if (arguments.size() == 1 || arguments.size() == 2) {
386 daughterNumber = Belle2::convertString<int>(arguments[0]);
387 }
catch (std::invalid_argument&) {
388 B2WARNING(
"First argument of flightTimeOfDaughter function must be integer!");
392 if (arguments.size() == 2) {
394 grandDaughterNumber = Belle2::convertString<int>(arguments[1]);
395 }
catch (std::invalid_argument&) {
396 B2WARNING(
"Second argument of flightTimeOfDaughter function must be integer!");
400 if (daughterNumber > -1) {
401 auto func = [daughterNumber, grandDaughterNumber](
const Particle * particle) ->
double {
402 if (particle ==
nullptr)
403 return std::numeric_limits<float>::quiet_NaN();
404 if (daughterNumber >=
int(particle->getNDaughters()) && particle->getDaughter(daughterNumber))
405 return std::numeric_limits<float>::quiet_NaN();
406 const Particle* daughter = particle->getDaughter(daughterNumber);
407 double flightTimeErr = 0.0;
408 if (grandDaughterNumber > -1)
410 if (grandDaughterNumber < (
int)daughter->getNDaughters()) {
411 return getFlightInfoBtw(particle, daughter->getDaughter(grandDaughterNumber), flightTimeErr,
"time",
true);
414 return getFlightInfoBtw(particle, daughter, flightTimeErr,
"time");
416 return std::numeric_limits<float>::quiet_NaN();
426 int daughterNumber = -1;
427 int grandDaughterNumber = -1;
428 if (arguments.size() == 1 || arguments.size() == 2) {
430 daughterNumber = Belle2::convertString<int>(arguments[0]);
431 }
catch (std::invalid_argument&) {
432 B2WARNING(
"First argument of flightTimeOfDaughterErr function must be integer!");
436 if (arguments.size() == 2) {
438 grandDaughterNumber = Belle2::convertString<int>(arguments[1]);
439 }
catch (std::invalid_argument&) {
440 B2WARNING(
"Second argument of flightTimeOfDaughterErr function must be integer!");
444 if (daughterNumber > -1) {
445 auto func = [daughterNumber, grandDaughterNumber](
const Particle * particle) ->
double {
446 if (particle ==
nullptr)
447 return std::numeric_limits<float>::quiet_NaN();
448 if (daughterNumber >=
int(particle->getNDaughters()) && particle->getDaughter(daughterNumber))
449 return std::numeric_limits<float>::quiet_NaN();
450 const Particle* daughter = particle->getDaughter(daughterNumber);
451 double flightTimeErr = 0.0;
452 if (grandDaughterNumber > -1)
454 if (grandDaughterNumber < (
int)daughter->getNDaughters()) {
455 getFlightInfoBtw(particle, daughter->getDaughter(grandDaughterNumber), flightTimeErr,
"time",
true);
456 return flightTimeErr;
459 getFlightInfoBtw(particle, daughter, flightTimeErr,
"time");
460 return flightTimeErr;
462 return std::numeric_limits<float>::quiet_NaN();
471 int daughterNumber = -1;
472 int grandDaughterNumber = -1;
473 if (arguments.size() == 1 || arguments.size() == 2) {
475 daughterNumber = Belle2::convertString<int>(arguments[0]);
476 }
catch (std::invalid_argument&) {
477 B2WARNING(
"First argument of flightDistanceOfDaughter function must be integer!");
481 if (arguments.size() == 2) {
483 grandDaughterNumber = Belle2::convertString<int>(arguments[1]);
484 }
catch (std::invalid_argument&) {
485 B2WARNING(
"Second argument of flightDistanceOfDaughter function must be integer!");
489 if (daughterNumber > -1) {
490 auto func = [daughterNumber, grandDaughterNumber](
const Particle * particle) ->
double {
491 if (particle ==
nullptr)
492 return std::numeric_limits<float>::quiet_NaN();
493 if (daughterNumber >=
int(particle->getNDaughters()) && particle->getDaughter(daughterNumber))
494 return std::numeric_limits<float>::quiet_NaN();
495 const Particle* daughter = particle->getDaughter(daughterNumber);
496 double flightDistanceErr = 0.0;
497 if (grandDaughterNumber > -1)
499 if (grandDaughterNumber < (
int)daughter->getNDaughters()) {
500 return getFlightInfoBtw(particle, daughter->getDaughter(grandDaughterNumber), flightDistanceErr,
"distance",
true);
503 return getFlightInfoBtw(particle, daughter, flightDistanceErr,
"distance");
505 return std::numeric_limits<float>::quiet_NaN();
515 int daughterNumber = -1;
516 int grandDaughterNumber = -1;
517 if (arguments.size() == 1 || arguments.size() == 2) {
519 daughterNumber = Belle2::convertString<int>(arguments[0]);
520 }
catch (std::invalid_argument&) {
521 B2WARNING(
"First argument of flightDistanceOfDaughterErr function must be integer!");
525 if (arguments.size() == 2) {
527 grandDaughterNumber = Belle2::convertString<int>(arguments[1]);
528 }
catch (std::invalid_argument&) {
529 B2WARNING(
"Second argument of flightDistanceOfDaughterErr function must be integer!");
533 if (daughterNumber > -1) {
534 auto func = [daughterNumber, grandDaughterNumber](
const Particle * particle) ->
double {
535 if (particle ==
nullptr)
536 return std::numeric_limits<float>::quiet_NaN();
537 if (daughterNumber >=
int(particle->getNDaughters()) && particle->getDaughter(daughterNumber))
538 return std::numeric_limits<float>::quiet_NaN();
539 const Particle* daughter = particle->getDaughter(daughterNumber);
540 double flightDistanceErr = 0.0;
541 if (grandDaughterNumber > -1)
543 if (grandDaughterNumber < (
int)daughter->getNDaughters()) {
544 getFlightInfoBtw(particle, daughter->getDaughter(grandDaughterNumber), flightDistanceErr,
"distance",
true);
545 return flightDistanceErr;
548 getFlightInfoBtw(particle, daughter, flightDistanceErr,
"distance");
549 return flightDistanceErr;
551 return std::numeric_limits<float>::quiet_NaN();
561 int daughterNumber = -1;
562 bool prodVertIsIP =
true;
563 if (arguments.size() == 1 || arguments.size() == 2) {
565 daughterNumber = Belle2::convertString<int>(arguments[0]);
566 }
catch (std::invalid_argument&) {
567 B2WARNING(
"First argument of vertexDistanceOfDaughter function must be integer!");
571 if (arguments.size() == 2) {
572 prodVertIsIP =
false;
574 if (daughterNumber > -1) {
575 auto func = [daughterNumber, prodVertIsIP](
const Particle * particle) ->
double {
576 if (particle ==
nullptr)
577 return std::numeric_limits<float>::quiet_NaN();
578 if (daughterNumber >=
int(particle->getNDaughters()) && particle->getDaughter(daughterNumber))
579 return std::numeric_limits<float>::quiet_NaN();
580 const Particle* daughter = particle->getDaughter(daughterNumber);
581 double vertexDistanceErr = std::numeric_limits<float>::quiet_NaN();
582 return getVertexDistance(particle, daughter, vertexDistanceErr, prodVertIsIP);
592 int daughterNumber = -1;
593 bool prodVertIsIP =
true;
594 if (arguments.size() == 1 || arguments.size() == 2) {
596 daughterNumber = Belle2::convertString<int>(arguments[0]);
597 }
catch (std::invalid_argument&) {
598 B2WARNING(
"First argument of vertexDistanceOfDaughterErr function must be integer!");
602 if (arguments.size() == 2) {
603 prodVertIsIP =
false;
605 if (daughterNumber > -1) {
606 auto func = [daughterNumber, prodVertIsIP](
const Particle * particle) ->
double {
607 if (particle ==
nullptr)
608 return std::numeric_limits<float>::quiet_NaN();
609 if (daughterNumber >=
int(particle->getNDaughters()) && particle->getDaughter(daughterNumber))
610 return std::numeric_limits<float>::quiet_NaN();
611 const Particle* daughter = particle->getDaughter(daughterNumber);
612 double vertexDistanceErr = std::numeric_limits<float>::quiet_NaN();
613 getVertexDistance(particle, daughter, vertexDistanceErr, prodVertIsIP);
614 return vertexDistanceErr;
622 Manager::FunctionPtr vertexDistanceOfDaughterSignificance(
const std::vector<std::string>& arguments)
624 int daughterNumber = -1;
625 bool prodVertIsIP =
true;
626 if (arguments.size() == 1 || arguments.size() == 2) {
628 daughterNumber = Belle2::convertString<int>(arguments[0]);
629 }
catch (std::invalid_argument&) {
630 B2WARNING(
"First argument of vertexDistanceOfDaughterSignificance function must be integer!");
634 if (arguments.size() == 2) {
635 prodVertIsIP =
false;
637 if (daughterNumber > -1) {
638 auto func = [daughterNumber, prodVertIsIP](
const Particle * particle) ->
double {
639 if (particle ==
nullptr)
640 return std::numeric_limits<float>::quiet_NaN();
641 if (daughterNumber >=
int(particle->getNDaughters()) && particle->getDaughter(daughterNumber))
642 return std::numeric_limits<float>::quiet_NaN();
643 const Particle* daughter = particle->getDaughter(daughterNumber);
644 double vertexDistanceErr = 0.0;
645 return getVertexDistance(particle, daughter, vertexDistanceErr, prodVertIsIP) / vertexDistanceErr;
654 double mcFlightDistance(
const Particle* particle)
656 if (particle ==
nullptr)
657 return std::numeric_limits<float>::quiet_NaN();
659 const MCParticle* mcparticle = particle->getMCParticle();
661 if (mcparticle ==
nullptr)
662 return std::numeric_limits<float>::quiet_NaN();
664 return getMCFlightInfoBtw(mcparticle,
"distance");
667 double mcFlightTime(
const Particle* particle)
669 if (particle ==
nullptr)
670 return std::numeric_limits<float>::quiet_NaN();
672 const MCParticle* mcparticle = particle->getMCParticle();
674 if (mcparticle ==
nullptr)
675 return std::numeric_limits<float>::quiet_NaN();
678 return getMCFlightInfoBtw(mcparticle,
"time");
683 int daughterNumber = -1;
684 int grandDaughterNumber = -1;
685 if (arguments.size() == 1 || arguments.size() == 2) {
687 daughterNumber = Belle2::convertString<int>(arguments[0]);
688 }
catch (std::invalid_argument&) {
689 B2WARNING(
"First argument of mcFlightDistanceOfDaughter function must be integer!");
693 if (arguments.size() == 2) {
695 grandDaughterNumber = Belle2::convertString<int>(arguments[1]);
696 }
catch (std::invalid_argument&) {
697 B2WARNING(
"Second argument of mcFlightDistanceOfDaughter function must be integer!");
701 if (daughterNumber > -1) {
702 auto func = [daughterNumber, grandDaughterNumber](
const Particle * particle) ->
double {
703 if (particle ==
nullptr)
704 return std::numeric_limits<float>::quiet_NaN();
705 if (daughterNumber >=
int(particle->getNDaughters()) || !particle->getDaughter(daughterNumber))
706 return std::numeric_limits<float>::quiet_NaN();
707 const Particle* daughterReco = particle->getDaughter(daughterNumber);
709 const MCParticle* daughter = daughterReco->getMCParticle();
711 double flightDistanceMC = std::numeric_limits<float>::quiet_NaN();
712 if (grandDaughterNumber > -1 && grandDaughterNumber < (
int)daughterReco->getNDaughters())
717 if (gdaughter !=
nullptr)
718 flightDistanceMC = getMCFlightInfoBtw(gdaughter,
"distance");
721 if (daughter !=
nullptr)
722 flightDistanceMC = getMCFlightInfoBtw(daughter,
"distance");
724 return flightDistanceMC;
728 B2WARNING(
"Incorrect parameters of mcFlightDistanceOfDaughter!");
734 int daughterNumber = -1;
735 int grandDaughterNumber = -1;
736 if (arguments.size() == 1 || arguments.size() == 2) {
738 daughterNumber = Belle2::convertString<int>(arguments[0]);
739 }
catch (std::invalid_argument&) {
740 B2WARNING(
"First argument of flightTimeOfDaughter function must be integer!");
744 if (arguments.size() == 2) {
746 grandDaughterNumber = Belle2::convertString<int>(arguments[1]);
747 }
catch (std::invalid_argument&) {
748 B2WARNING(
"Second argument of mcFlightTimeOfDaughter function must be integer!");
752 if (daughterNumber > -1) {
753 auto func = [daughterNumber, grandDaughterNumber](
const Particle * particle) ->
double {
754 if (particle ==
nullptr)
755 return std::numeric_limits<float>::quiet_NaN();
756 if (daughterNumber >=
int(particle->getNDaughters()) || !particle->getDaughter(daughterNumber))
757 return std::numeric_limits<float>::quiet_NaN();
758 const Particle* daughterReco = particle->getDaughter(daughterNumber);
760 const MCParticle* daughter = daughterReco->getMCParticle();
763 double flightTimeMC = std::numeric_limits<float>::quiet_NaN();
764 if (grandDaughterNumber > -1 && grandDaughterNumber < (
int)daughterReco->getNDaughters())
767 if (gdaughter !=
nullptr)
768 flightTimeMC = getMCFlightInfoBtw(gdaughter,
"time");
770 if (daughter !=
nullptr)
771 flightTimeMC = getMCFlightInfoBtw(daughter,
"time");
777 B2WARNING(
"Incorrect parameters of mcFlightTimeOfDaughter!");
782 VARIABLE_GROUP(
"Flight Information");
783 REGISTER_VARIABLE(
"flightTime", flightTime,
784 "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.");
785 REGISTER_VARIABLE(
"flightDistance", flightDistance,
786 "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.");
787 REGISTER_VARIABLE(
"flightTimeErr", flightTimeErr,
788 "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.");
789 REGISTER_VARIABLE(
"flightDistanceErr", flightDistanceErr,
790 "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.");
792 REGISTER_VARIABLE(
"flightTimeOfDaughter(daughterN, gdaughterN = -1)", flightTimeOfDaughter,
793 "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).");
794 REGISTER_VARIABLE(
"flightTimeOfDaughterErr(daughterN, gdaughterN = -1)", flightTimeOfDaughterErr,
795 "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).");
796 REGISTER_VARIABLE(
"flightDistanceOfDaughter(daughterN, gdaughterN = -1)", flightDistanceOfDaughter,
797 "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).");
798 REGISTER_VARIABLE(
"flightDistanceOfDaughterErr(daughterN, gdaughterN = -1)", flightDistanceOfDaughterErr,
799 "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).");
801 REGISTER_VARIABLE(
"mcFlightDistance", mcFlightDistance,
802 "Returns the MC flight distance of the particle");
803 REGISTER_VARIABLE(
"mcFlightTime", mcFlightTime,
804 "Returns the MC flight time of the particle");
805 REGISTER_VARIABLE(
"mcFlightDistanceOfDaughter(daughterN, gdaughterN = -1)", mcFlightDistanceOfDaughter,
806 "Returns the MC flight distance between mother and daughter particle using generated info");
807 REGISTER_VARIABLE(
"mcFlightTimeOfDaughter(daughterN, gdaughterN = -1)", mcFlightTimeOfDaughter,
808 "Returns the MC flight time between mother and daughter particle using generated info");
810 REGISTER_VARIABLE(
"vertexDistance", vertexDistance,
811 "Returns the distance between the production and decay vertex of a particle. Returns NaN if particle has no production or decay vertex.");
812 REGISTER_VARIABLE(
"vertexDistanceErr", vertexDistanceErr,
813 "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.");
814 REGISTER_VARIABLE(
"vertexDistanceSignificance", vertexDistanceSignificance,
815 "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.");
816 REGISTER_VARIABLE(
"vertexDistanceOfDaughter(daughterN, option = '')", vertexDistanceOfDaughter,
817 "If any second argument is provided it returns the distance between the decay vertices of the particle and of its daughter with index daughterN.\n"
818 "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"
819 "Returns NaN in case anything goes wrong.");
820 REGISTER_VARIABLE(
"vertexDistanceOfDaughterErr(daughterN, option = '')", vertexDistanceOfDaughterErr,
821 "If any second argument is provided it returns the uncertainty on the distance between the decay vertices of the particle and of its daughter with index daughterN.\n"
822 "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"
823 "Returns NaN in case anything goes wrong.");
824 REGISTER_VARIABLE(
"vertexDistanceOfDaughterSignificance(daughterN, option = '')", vertexDistanceOfDaughterSignificance,
825 "If any second argument is provided 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"
826 "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.
std::function< double(const Particle *)> FunctionPtr
NOTE: the python interface is documented manually in analysis/doc/Variables.rst (because we use ROOT ...
Abstract base class for different kinds of events.