10#include <analysis/variables/ROEVariables.h>
12#include <analysis/variables/Variables.h>
15#include <framework/datastore/StoreArray.h>
16#include <framework/datastore/StoreObjPtr.h>
19#include <analysis/dataobjects/Particle.h>
20#include <analysis/dataobjects/ParticleList.h>
21#include <mdst/dataobjects/MCParticle.h>
22#include <mdst/dataobjects/ECLCluster.h>
25#include <framework/logging/Logger.h>
26#include <framework/utilities/Conversion.h>
27#include <framework/gearbox/Const.h>
30#include <analysis/utility/PCmsLabTransform.h>
31#include <analysis/utility/ReferenceFrame.h>
35#include <Math/AxisAngle.h>
36#include <Math/VectorUtil.h>
49 bool isInRestOfEvent(
const Particle* particle)
52 StoreObjPtr<RestOfEvent> roeobjptr;
53 if (not roeobjptr.isValid())
56 const RestOfEvent* roe = &(*roeobjptr);
58 return isInThisRestOfEvent(particle, roe);
61 bool isCloneOfSignalSide(
const Particle* particle)
64 StoreObjPtr<RestOfEvent> roe;
65 if (not roe.isValid()) {
66 B2ERROR(
"Please use isCloneOfSignalSide variable in for_each ROE loop!");
69 auto* particleMC = particle->getMCParticle();
73 auto* signal = roe->getRelatedFrom<Particle>();
74 auto signalFSPs = signal->getFinalStateDaughters();
75 for (
auto* daughter : signalFSPs) {
76 auto* daughterMC = daughter->getMCParticle();
77 if (daughterMC == particleMC) {
84 bool hasAncestorFromSignalSide(
const Particle* particle)
86 StoreObjPtr<RestOfEvent> roe;
88 B2ERROR(
"Please use hasAncestorFromSignalSide variable in for_each ROE loop!");
91 auto* particleMC = particle->getMCParticle();
95 auto* signalReco = roe->getRelatedFrom<Particle>();
96 auto* signalMC = signalReco->getMCParticle();
97 const MCParticle* ancestorMC = particleMC->getMother();
99 if (ancestorMC == signalMC) {
102 ancestorMC = ancestorMC->getMother();
109 if (arguments.size() != 1)
110 B2FATAL(
"Wrong number of arguments (1 required) for meta function currentROEIsInList");
112 std::string listName = arguments[0];
114 auto func = [listName](
const Particle*) ->
bool {
116 StoreObjPtr<ParticleList> particleList(listName);
117 if (!(particleList.isValid()))
119 B2FATAL(
"Invalid Listname " << listName <<
" given to currentROEIsInList!");
121 StoreObjPtr<RestOfEvent> roe(
"RestOfEvent");
123 if (not roe.isValid())
126 auto* particle = roe->getRelatedFrom<Particle>();
127 if (particle ==
nullptr)
129 B2ERROR(
"Relation between particle and ROE doesn't exist! currentROEIsInList variable has to be called from ROE loop");
132 return particleList->contains(particle) ? 1 : 0;
140 if (arguments.size() != 1)
141 B2FATAL(
"Wrong number of arguments (1 required) for meta function particleRelatedToCurrentROE");
144 auto func = [var](
const Particle*) ->
double {
146 StoreObjPtr<RestOfEvent> roe(
"RestOfEvent");
148 if (not roe.isValid())
151 auto* particle = roe->getRelatedFrom<Particle>();
152 if (particle ==
nullptr)
154 B2ERROR(
"Relation between particle and ROE doesn't exist! particleRelatedToCurrentROE variable has to be called from ROE loop");
157 if (std::holds_alternative<double>(var->function(particle)))
159 return std::get<double>(var->function(particle));
160 }
else if (std::holds_alternative<int>(var->function(particle)))
162 return std::get<int>(var->function(particle));
163 }
else if (std::holds_alternative<bool>(var->function(particle)))
165 return std::get<bool>(var->function(particle));
174 if (arguments.size() == 1) {
176 auto func = [var](
const Particle * particle) ->
double {
178 const RestOfEvent* roe = particle->getRelatedTo<RestOfEvent>();
182 StoreObjPtr<RestOfEvent> roeObjPtr(
"RestOfEvent");
183 if (roeObjPtr.isValid()) {
189 B2ERROR(
"Neither relation between particle and ROE exists nor ROE object has been found!");
193 ROOT::Math::PxPyPzEVector pRecoil = T.getBeamFourMomentum() - roe->get4Vector();
194 Particle tmp(pRecoil, 0);
195 UseReferenceFrame<RestFrame> frame(&tmp);
196 if (std::holds_alternative<double>(var->function(particle)))
198 return std::get<double>(var->function(particle));
199 }
else if (std::holds_alternative<int>(var->function(particle)))
201 return std::get<int>(var->function(particle));
202 }
else if (std::holds_alternative<bool>(var->function(particle)))
204 return std::get<bool>(var->function(particle));
209 B2FATAL(
"Wrong number of arguments for meta function useROERecoilFrame");
215 int nRemainingTracksInROE(
const Particle* particle,
const std::string& maskName)
217 StoreObjPtr<RestOfEvent> roe(
"RestOfEvent");
218 if (not roe.isValid())
220 int n_roe_tracks = roe->getNTracks(maskName);
221 int n_par_tracks = 0;
222 const auto& daughters = particle->getFinalStateDaughters();
223 for (
const auto& daughter : daughters) {
224 if (daughter->getParticleSource() == Particle::EParticleSourceObject::c_Track && roe->hasParticle(daughter, maskName)) {
228 return n_roe_tracks - n_par_tracks;
235 if (arguments.size() == 1)
236 maskName = arguments[0];
237 else if (arguments.size() > 1)
238 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function nROE_RemainingTracks");
240 auto func = [maskName](
const Particle * particle) ->
int {
241 return nRemainingTracksInROE(particle, maskName);
246 int nROE_RemainingTracks(
const Particle* particle)
248 return nRemainingTracksInROE(particle);
251 int nROE_KLMClusters(
const Particle* particle)
254 const RestOfEvent* roe = getRelatedROEObject(particle);
257 B2ERROR(
"Relation between particle and ROE doesn't exist!");
261 return roe->getNKLMClusters();
264 double ROE_MC_E(
const Particle* particle)
266 const MCParticle* mcp = particle->getMCParticle();
272 ROOT::Math::PxPyPzEVector boostvec = T.getBeamFourMomentum();
273 auto mcroe4vector = boostvec - mcp->get4Vector();
275 auto frameMCRoe4Vector = frame.getMomentum(mcroe4vector);
276 return frameMCRoe4Vector.energy();
279 double ROE_MC_P(
const Particle* particle)
281 const MCParticle* mcp = particle->getMCParticle();
287 ROOT::Math::PxPyPzEVector boostvec = T.getBeamFourMomentum();
288 auto mcroe4vector = boostvec - mcp->get4Vector();
290 auto frameMCRoe4Vector = frame.getMomentum(mcroe4vector);
291 return frameMCRoe4Vector.P();
294 double ROE_MC_Px(
const Particle* particle)
296 const MCParticle* mcp = particle->getMCParticle();
302 ROOT::Math::PxPyPzEVector boostvec = T.getBeamFourMomentum();
303 auto mcroe4vector = boostvec - mcp->get4Vector();
305 auto frameMCRoe4Vector = frame.getMomentum(mcroe4vector);
307 return frameMCRoe4Vector.px();
310 double ROE_MC_Py(
const Particle* particle)
312 const MCParticle* mcp = particle->getMCParticle();
318 ROOT::Math::PxPyPzEVector boostvec = T.getBeamFourMomentum();
319 auto mcroe4vector = boostvec - mcp->get4Vector();
321 auto frameMCRoe4Vector = frame.getMomentum(mcroe4vector);
323 return frameMCRoe4Vector.py();
326 double ROE_MC_Pz(
const Particle* particle)
328 const MCParticle* mcp = particle->getMCParticle();
334 ROOT::Math::PxPyPzEVector boostvec = T.getBeamFourMomentum();
335 auto mcroe4vector = boostvec - mcp->get4Vector();
337 auto frameMCRoe4Vector = frame.getMomentum(mcroe4vector);
339 return frameMCRoe4Vector.pz();
342 double ROE_MC_Pt(
const Particle* particle)
344 const MCParticle* mcp = particle->getMCParticle();
350 ROOT::Math::PxPyPzEVector boostvec = T.getBeamFourMomentum();
351 auto mcroe4vector = boostvec - mcp->get4Vector();
353 auto frameMCRoe4Vector = frame.getMomentum(mcroe4vector);
355 return frameMCRoe4Vector.pt();
358 double ROE_MC_PTheta(
const Particle* particle)
360 const MCParticle* mcp = particle->getMCParticle();
366 ROOT::Math::PxPyPzEVector boostvec = T.getBeamFourMomentum();
367 auto mcroe4vector = boostvec - mcp->get4Vector();
369 auto frameMCRoe4Vector = frame.getMomentum(mcroe4vector);
371 return frameMCRoe4Vector.Theta();
374 double ROE_MC_M(
const Particle* particle)
376 const MCParticle* mcp = particle->getMCParticle();
382 ROOT::Math::PxPyPzEVector boostvec = T.getBeamFourMomentum();
384 return (boostvec - mcp->get4Vector()).M();
391 if (arguments.size() == 1)
392 maskName = arguments[0];
393 else if (arguments.size() > 1)
394 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function roeMC_MissFlags");
396 auto func = [maskName](
const Particle * particle) ->
double {
398 StoreArray<Particle> particles;
401 const MCParticle* mcParticle = particle->getMCParticle();
407 const MCParticle* mcMother = mcParticle->getMother();
413 std::vector<MCParticle*> mcDaughters = mcMother->getDaughters();
415 if (mcDaughters.size() != 2)
419 const MCParticle* mcROE =
nullptr;
420 if (mcDaughters[0]->getArrayIndex() == mcParticle->getArrayIndex())
421 mcROE = mcDaughters[1];
423 mcROE = mcDaughters[0];
426 const RestOfEvent* roe = getRelatedROEObject(particle);
428 std::set<const MCParticle*> mcROEObjects;
430 auto roeParticles = roe->getParticles(maskName);
431 for (
const auto* roeParticle : roeParticles)
433 const auto* mcroeParticle = roeParticle->getMCParticle();
434 if (mcroeParticle !=
nullptr) {
435 mcROEObjects.insert(mcroeParticle);
439 checkMCParticleMissingFlags(mcROE, mcROEObjects, flags);
450 if (arguments.size() == 1)
451 maskName = arguments[0];
452 else if (arguments.size() > 1)
453 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function nROE_Tracks");
455 auto func = [maskName](
const Particle * particle) ->
int {
458 const RestOfEvent* roe = getRelatedROEObject(particle);
462 B2ERROR(
"Relation between particle and ROE doesn't exist!");
466 return roe->getNTracks(maskName);
475 if (arguments.size() == 1)
476 maskName = arguments[0];
477 else if (arguments.size() > 1)
478 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function nROE_ECLClusters");
480 auto func = [maskName](
const Particle * particle) ->
int {
483 const RestOfEvent* roe = getRelatedROEObject(particle);
487 B2ERROR(
"Relation between particle and ROE doesn't exist!");
491 return roe->getNECLClusters(maskName);
500 if (arguments.size() == 1)
501 maskName = arguments[0];
502 else if (arguments.size() > 1)
503 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function nROE_NeutralECLClusters");
505 auto func = [maskName](
const Particle * particle) ->
int {
508 const RestOfEvent* roe = getRelatedROEObject(particle);
512 B2ERROR(
"Relation between particle and ROE doesn't exist!");
516 return roe->getPhotons(maskName).size();
525 if (arguments.size() == 1) {
526 maskName = arguments[0];
527 }
else if (arguments.size() > 1) {
528 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function nROE_Photons");
530 auto func = [maskName](
const Particle * particle) ->
int {
533 const RestOfEvent* roe = getRelatedROEObject(particle);
537 B2ERROR(
"Relation between particle and ROE doesn't exist!");
542 auto roeClusters = roe->getPhotons(maskName);
546 for (
auto& roeCluster : roeClusters)
558 if (arguments.size() == 1) {
559 maskName = arguments[0];
560 }
else if (arguments.size() > 1) {
561 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function nROE_NeutralHadrons");
563 auto func = [maskName](
const Particle * particle) ->
int {
566 const RestOfEvent* roe = getRelatedROEObject(particle);
570 B2ERROR(
"Relation between particle and ROE doesn't exist!");
574 return roe->getHadrons(maskName).size();
583 if (arguments.size() == 1) {
584 maskName = arguments[0];
585 }
else if (arguments.size() == 2) {
586 maskName = arguments[0];
589 }
catch (std::invalid_argument&) {
590 B2ERROR(
"First argument of nROE_Charged must be a PDG code");
593 }
else if (arguments.size() > 2) {
594 B2FATAL(
"Wrong number of arguments (2 optional) for meta function nROE_Charged");
596 auto func = [maskName, pdgCode](
const Particle * particle) ->
int {
599 const RestOfEvent* roe = getRelatedROEObject(particle);
603 B2ERROR(
"Relation between particle and ROE doesn't exist!");
607 return roe->getChargedParticles(maskName, abs(pdgCode)).size();
616 if (arguments.size() == 1) {
617 maskName = arguments[0];
618 }
else if (arguments.size() > 1) {
619 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function nROE_Composites");
621 auto func = [maskName](
const Particle * particle) ->
int {
624 const RestOfEvent* roe = getRelatedROEObject(particle);
628 B2ERROR(
"Relation between particle and ROE doesn't exist!");
632 auto particles = roe->getParticles(maskName,
false);
634 for (
auto roeParticle : particles)
636 if (roeParticle->getParticleSource() == Particle::c_Composite or
637 roeParticle->getParticleSource() == Particle::c_V0) {
648 std::string pListName;
651 if (arguments.size() == 1) {
652 pListName = arguments[0];
653 }
else if (arguments.size() == 2) {
654 pListName = arguments[0];
655 maskName = arguments[1];
657 B2FATAL(
"Wrong number of arguments (1 or 2 required) for meta function nROE_ParticlesInList");
659 auto func = [pListName, maskName](
const Particle * particle) ->
int {
662 const RestOfEvent* roe = getRelatedROEObject(particle);
666 B2ERROR(
"Relation between particle and ROE doesn't exist!");
673 StoreObjPtr<ParticleList> pList(pListName);
674 if (!pList.isValid())
675 B2FATAL(
"ParticleList " << pListName <<
" could not be found or is not valid!");
677 for (
unsigned int i = 0; i < pList->getListSize(); i++)
679 const Particle* part = pList->getParticle(i);
680 if (isInThisRestOfEvent(part, roe, maskName))
693 if (arguments.size() == 1)
694 maskName = arguments[0];
695 else if (arguments.size() > 1)
696 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function roeCharge");
698 auto func = [maskName](
const Particle * particle) ->
double {
701 const RestOfEvent* roe = getRelatedROEObject(particle);
705 B2ERROR(
"Relation between particle and ROE doesn't exist!");
710 auto roeParticles = roe->getParticles(maskName);
713 for (
auto* roeParticle : roeParticles)
715 roeCharge += roeParticle->getCharge();
727 if (arguments.size() == 1)
728 maskName = arguments[0];
729 else if (arguments.size() > 1)
730 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function roeEextra");
732 auto func = [maskName](
const Particle * particle) ->
double {
735 const RestOfEvent* roe = getRelatedROEObject(particle);
739 B2ERROR(
"Relation between particle and ROE doesn't exist!");
745 auto roeClusters = roe->getPhotons(maskName);
747 for (
auto& roeCluster : roeClusters)
749 extraE += roeCluster->getECLClusterEnergy();
751 auto roeChargedParticles = roe->getChargedParticles(maskName);
753 for (
auto& roeChargedParticle : roeChargedParticles)
755 if (roeChargedParticle->getECLCluster())
756 extraE += roeChargedParticle->getECLClusterEnergy();
768 if (arguments.size() == 1)
769 maskName = arguments[0];
770 else if (arguments.size() > 1)
771 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function roeNeextra");
773 auto func = [maskName](
const Particle * particle) ->
double {
776 const RestOfEvent* roe = getRelatedROEObject(particle);
780 B2ERROR(
"Relation between particle and ROE doesn't exist!");
783 auto roephotons = roe->getPhotons(maskName);
784 ROOT::Math::PxPyPzEVector total4vector;
785 for (
auto* photon : roephotons)
787 total4vector += photon->get4Vector();
790 auto frameRoe4Vector = frame.getMomentum(total4vector);
791 return frameRoe4Vector.energy();
800 if (arguments.size() == 1)
801 maskName = arguments[0];
802 else if (arguments.size() > 1)
803 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function roeE");
805 auto func = [maskName](
const Particle * particle) ->
double {
806 const RestOfEvent* roe = particle->getRelatedTo<RestOfEvent>();
809 B2ERROR(
"Relation between particle and ROE doesn't exist!");
813 auto frameRoe4Vector = frame.getMomentum(roe->get4Vector(maskName));
814 return frameRoe4Vector.energy();
823 if (arguments.size() == 1)
824 maskName = arguments[0];
825 else if (arguments.size() > 1)
826 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function roeM");
828 auto func = [maskName](
const Particle * particle) ->
double {
831 const RestOfEvent* roe = getRelatedROEObject(particle);
835 B2ERROR(
"Relation between particle and ROE doesn't exist!");
839 return roe->get4Vector(maskName).M();
848 if (arguments.size() == 1)
849 maskName = arguments[0];
850 else if (arguments.size() > 1)
851 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function roeP");
853 auto func = [maskName](
const Particle * particle) ->
double {
856 const RestOfEvent* roe = getRelatedROEObject(particle);
860 B2ERROR(
"Relation between particle and ROE doesn't exist!");
865 auto frameRoe4Vector = frame.getMomentum(roe->get4Vector(maskName));
866 return frameRoe4Vector.P();
875 if (arguments.size() == 1)
876 maskName = arguments[0];
877 else if (arguments.size() > 1)
878 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function roePx");
880 auto func = [maskName](
const Particle * particle) ->
double {
883 const RestOfEvent* roe = getRelatedROEObject(particle);
887 B2ERROR(
"Relation between particle and ROE doesn't exist!");
892 auto frameRoe4Vector = frame.getMomentum(roe->get4Vector(maskName));
893 return frameRoe4Vector.px();
902 if (arguments.size() == 1)
903 maskName = arguments[0];
904 else if (arguments.size() > 1)
905 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function roePy");
907 auto func = [maskName](
const Particle * particle) ->
double {
910 const RestOfEvent* roe = getRelatedROEObject(particle);
914 B2ERROR(
"Relation between particle and ROE doesn't exist!");
919 auto frameRoe4Vector = frame.getMomentum(roe->get4Vector(maskName));
920 return frameRoe4Vector.py();
929 if (arguments.size() == 1)
930 maskName = arguments[0];
931 else if (arguments.size() > 1)
932 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function roePt");
934 auto func = [maskName](
const Particle * particle) ->
double {
937 const RestOfEvent* roe = getRelatedROEObject(particle);
941 B2ERROR(
"Relation between particle and ROE doesn't exist!");
946 auto frameRoe4Vector = frame.getMomentum(roe->get4Vector(maskName));
947 return frameRoe4Vector.pt();
956 if (arguments.size() == 1)
957 maskName = arguments[0];
958 else if (arguments.size() > 1)
959 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function roePz");
961 auto func = [maskName](
const Particle * particle) ->
double {
964 const RestOfEvent* roe = getRelatedROEObject(particle);
968 B2ERROR(
"Relation between particle and ROE doesn't exist!");
973 auto frameRoe4Vector = frame.getMomentum(roe->get4Vector(maskName));
974 return frameRoe4Vector.pz();
983 if (arguments.size() == 1)
984 maskName = arguments[0];
985 else if (arguments.size() > 1)
986 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function roePTheta");
988 auto func = [maskName](
const Particle * particle) ->
double {
991 const RestOfEvent* roe = getRelatedROEObject(particle);
995 B2ERROR(
"Relation between particle and ROE doesn't exist!");
1000 auto frameRoe4Vector = frame.getMomentum(roe->get4Vector(maskName));
1001 return frameRoe4Vector.Theta();
1010 if (arguments.size() == 1)
1011 maskName = arguments[0];
1012 else if (arguments.size() > 1)
1013 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function roeDeltae");
1015 auto func = [maskName](
const Particle * particle) ->
double {
1018 const RestOfEvent* roe = getRelatedROEObject(particle);
1022 B2ERROR(
"Relation between particle and ROE doesn't exist!");
1027 ROOT::Math::PxPyPzEVector vec = T.rotateLabToCms() * roe->get4Vector(maskName);
1028 return vec.E() - T.getCMSEnergy() / 2;
1037 if (arguments.size() == 1)
1038 maskName = arguments[0];
1039 else if (arguments.size() > 1)
1040 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function roeMbc");
1042 auto func = [maskName](
const Particle * particle) ->
double {
1045 const RestOfEvent* roe = getRelatedROEObject(particle);
1049 B2ERROR(
"Relation between particle and ROE doesn't exist!");
1054 ROOT::Math::PxPyPzEVector vec = T.rotateLabToCms() * roe->get4Vector(maskName);
1056 double E = T.getCMSEnergy() / 2;
1057 double m2 = E * E - vec.P2();
1058 double mbc = m2 > 0 ? sqrt(m2) : 0;
1069 if (arguments.size() == 1)
1070 maskName = arguments[0];
1071 else if (arguments.size() > 1)
1072 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function bssMassDifference");
1074 auto func = [maskName](
const Particle * particle) ->
double {
1078 ROOT::Math::PxPyPzEVector neutrino4vec = missing4Vector(particle->getDaughter(0), maskName,
"1");
1079 ROOT::Math::PxPyPzEVector sig4vec = frame.getMomentum(particle->getDaughter(0)->get4Vector());
1081 ROOT::Math::PxPyPzEVector bsMom = neutrino4vec + sig4vec;
1082 ROOT::Math::PxPyPzEVector bssMom = bsMom + frame.getMomentum(particle->getDaughter(1)->get4Vector());
1084 return bssMom.M() - bsMom.M();
1093 if (arguments.size() == 1)
1094 maskName = arguments[0];
1095 else if (arguments.size() > 1)
1096 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function weDeltae.");
1098 auto func = [maskName](
const Particle * particle) ->
double {
1102 ROOT::Math::PxPyPzEVector boostvec = frame.getMomentum(T.getBeamFourMomentum());
1103 ROOT::Math::PxPyPzEVector sig4vec = frame.getMomentum(particle->get4Vector());
1104 ROOT::Math::PxPyPzEVector neutrino4vec = missing4Vector(particle, maskName,
"1");
1106 double E = T.getCMSEnergy();
1107 double deltaE = (sig4vec + neutrino4vec).Dot(boostvec) / E - E / 2.0;
1118 if (arguments.size() == 1) {
1119 maskName = arguments[0];
1120 }
else if (arguments.size() > 1)
1121 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function weMbc");
1123 auto func = [maskName](
const Particle * particle) ->
double {
1127 ROOT::Math::PxPyPzEVector boostvec = frame.getMomentum(T.getBeamFourMomentum());
1128 ROOT::Math::PxPyPzEVector sig4vec = frame.getMomentum(particle->get4Vector());
1129 ROOT::Math::PxPyPzEVector neutrino4vec = missing4Vector(particle, maskName,
"1");
1131 ROOT::Math::PxPyPzEVector bmom = sig4vec + neutrino4vec;
1132 double Ecms = T.getCMSEnergy();
1133 double m2 = pow((Ecms* Ecms / 2.0 + bmom.Vect().Dot(boostvec.Vect())) / boostvec.energy(), 2.0) - bmom.P2();
1134 double mbc = m2 > 0 ? sqrt(m2) : 0;
1145 if (arguments.size() == 1) {
1146 maskName = arguments[0];
1147 }
else if (arguments.size() > 1)
1148 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function weMbc");
1150 auto func = [maskName](
const Particle * particle) ->
double {
1153 ROOT::Math::PxPyPzEVector sig4vec = T.rotateLabToCms() * particle->get4Vector();
1154 ROOT::Math::PxPyPzEVector neutrino4vec = missing4Vector(particle, maskName,
"7");
1156 ROOT::Math::PxPyPzEVector bmom = sig4vec + neutrino4vec;
1157 double E = T.getCMSEnergy() / 2;
1158 double m2 = E * E - bmom.P2();
1159 double mbc = m2 > 0 ? sqrt(m2) : 0;
1168 std::string maskName;
1171 if (arguments.size() == 1) {
1172 B2WARNING(
"The single-argument form of weMissM2 is deprecated: the mask name will become a mandatory argument in a future release. Please call weMissM2(maskName, opt) instead.");
1175 }
else if (arguments.size() == 2) {
1176 maskName = arguments[0];
1179 B2FATAL(
"Wrong number of arguments (2 required) for meta function weMissM2");
1181 auto func = [maskName, opt](
const Particle * particle) ->
double {
1183 return missing4Vector(particle, maskName, opt).M2();
1190 std::string maskName;
1193 if (arguments.size() == 1) {
1194 B2WARNING(
"The single-argument form of weMissPTheta is deprecated: the mask name will become a mandatory argument in a future release. Please call weMissPTheta(maskName, opt) instead.");
1197 }
else if (arguments.size() == 2) {
1198 maskName = arguments[0];
1201 B2FATAL(
"Wrong number of arguments (2 required) for meta function weMissPTheta");
1203 auto func = [maskName, opt](
const Particle * particle) ->
double {
1206 const RestOfEvent* roe = getRelatedROEObject(particle);
1210 B2ERROR(
"Relation between particle and ROE doesn't exist!");
1214 return missing4Vector(particle, maskName, opt).Theta();
1221 std::string maskName;
1224 if (arguments.size() == 1) {
1225 B2WARNING(
"The single-argument form of weMissP is deprecated: the mask name will become a mandatory argument in a future release. Please call weMissP(maskName, opt) instead.");
1228 }
else if (arguments.size() == 2) {
1229 maskName = arguments[0];
1232 B2FATAL(
"Wrong number of arguments (2 required) for meta function weMissP");
1234 auto func = [maskName, opt](
const Particle * particle) ->
double {
1237 const RestOfEvent* roe = getRelatedROEObject(particle);
1241 B2ERROR(
"Relation between particle and ROE doesn't exist!");
1245 return missing4Vector(particle, maskName, opt).P();
1252 std::string maskName;
1255 if (arguments.size() == 1) {
1256 B2WARNING(
"The single-argument form of weMissPx is deprecated: the mask name will become a mandatory argument in a future release. Please call weMissPx(maskName, opt) instead.");
1259 }
else if (arguments.size() == 2) {
1260 maskName = arguments[0];
1263 B2FATAL(
"Wrong number of arguments (2 required) for meta function weMissPx");
1265 auto func = [maskName, opt](
const Particle * particle) ->
double {
1268 const RestOfEvent* roe = getRelatedROEObject(particle);
1272 B2ERROR(
"Relation between particle and ROE doesn't exist!");
1276 return missing4Vector(particle, maskName, opt).Px();
1283 std::string maskName;
1286 if (arguments.size() == 1) {
1287 B2WARNING(
"The single-argument form of weMissPy is deprecated: the mask name will become a mandatory argument in a future release. Please call weMissPy(maskName, opt) instead.");
1290 }
else if (arguments.size() == 2) {
1291 maskName = arguments[0];
1294 B2FATAL(
"Wrong number of arguments (2 required) for meta function weMissPy");
1296 auto func = [maskName, opt](
const Particle * particle) ->
double {
1299 const RestOfEvent* roe = getRelatedROEObject(particle);
1303 B2ERROR(
"Relation between particle and ROE doesn't exist!");
1307 return missing4Vector(particle, maskName, opt).Py();
1314 std::string maskName;
1317 if (arguments.size() == 1) {
1318 B2WARNING(
"The single-argument form of weMissPz is deprecated: the mask name will become a mandatory argument in a future release. Please call weMissPz(maskName, opt) instead.");
1321 }
else if (arguments.size() == 2) {
1322 maskName = arguments[0];
1325 B2FATAL(
"Wrong number of arguments (2 required) for meta function weMissPz");
1327 auto func = [maskName, opt](
const Particle * particle) ->
double {
1330 const RestOfEvent* roe = getRelatedROEObject(particle);
1334 B2ERROR(
"Relation between particle and ROE doesn't exist!");
1338 return missing4Vector(particle, maskName, opt).Pz();
1345 std::string maskName;
1348 if (arguments.size() == 1) {
1349 B2WARNING(
"The single-argument form of weMissE is deprecated: the mask name will become a mandatory argument in a future release. Please call weMissE(maskName, opt) instead.");
1352 }
else if (arguments.size() == 2) {
1353 maskName = arguments[0];
1356 B2FATAL(
"Wrong number of arguments (2 required) for meta function weMissE");
1358 auto func = [maskName, opt](
const Particle * particle) ->
double {
1361 const RestOfEvent* roe = getRelatedROEObject(particle);
1365 B2ERROR(
"Relation between particle and ROE doesn't exist!");
1369 return missing4Vector(particle, maskName, opt).energy();
1378 if (arguments.size() == 1)
1379 maskName = arguments[0];
1380 else if (arguments.size() > 1)
1381 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function weXiZ");
1383 auto func = [maskName](
const Particle * particle) ->
double {
1386 const RestOfEvent* roe = getRelatedROEObject(particle);
1390 B2ERROR(
"Relation between particle and ROE doesn't exist!");
1399 std::vector<const Particle*> recTrackParticles = particle->getFinalStateDaughters();
1402 for (
auto& recTrackParticle : recTrackParticles)
1404 pz += frame.getMomentum(recTrackParticle->get4Vector()).Pz();
1405 energy += frame.getMomentum(recTrackParticle->get4Vector()).E();
1409 auto roeParticles = roe->getChargedParticles(maskName);
1410 for (
auto* roeParticle : roeParticles)
1412 pz += frame.getMomentum(roeParticle->get4Vector()).Pz();
1413 energy += frame.getMomentum(roeParticle->get4Vector()).E();
1425 if (arguments.size() == 1)
1426 maskName = arguments[0];
1427 else if (arguments.size() > 1)
1428 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function weMissM2OverMissE");
1430 auto func = [maskName](
const Particle * particle) ->
double {
1433 const RestOfEvent* roe = getRelatedROEObject(particle);
1437 B2ERROR(
"Relation between particle and ROE doesn't exist!");
1441 ROOT::Math::PxPyPzEVector neutrino4vec = missing4Vector(particle, maskName,
"0");
1442 return neutrino4vec.M2() / (2.0 * neutrino4vec.energy());
1450 std::string option(
"1");
1452 if (arguments.size() == 1) {
1453 maskName = arguments[0];
1454 }
else if (arguments.size() == 2) {
1455 maskName = arguments[0];
1456 option = arguments[1];
1457 }
else if (arguments.size() > 2) {
1458 B2FATAL(
"Too many arguments. At most two arguments are allowed for meta function weQ2lnuSimple");
1461 auto func = [maskName, option](
const Particle * particle) ->
double {
1464 const RestOfEvent* roe = getRelatedROEObject(particle);
1468 B2ERROR(
"Relation between particle and ROE doesn't exist!");
1472 int n = particle->getNDaughters();
1478 const Particle* lep = particle->getDaughter(n - 1);
1479 bool enforceCMSFrame = (option ==
"4" or option ==
"7");
1480 ROOT::Math::PxPyPzEVector lep4vec = transformVector(lep->get4Vector(), enforceCMSFrame);
1481 ROOT::Math::PxPyPzEVector nu4vec = missing4Vector(particle, maskName, option);
1483 return (lep4vec + nu4vec).M2();
1491 std::string option(
"7");
1493 if (arguments.size() == 1) {
1494 maskName = arguments[0];
1495 }
else if (arguments.size() == 2) {
1496 maskName = arguments[0];
1497 option = arguments[1];
1498 }
else if (arguments.size() > 2) {
1499 B2FATAL(
"Too many arguments. At most two arguments are allowed for meta function weQ2lnu");
1502 auto func = [maskName, option](
const Particle * particle) ->
double {
1505 const RestOfEvent* roe = getRelatedROEObject(particle);
1509 B2ERROR(
"Relation between particle and ROE doesn't exist!");
1513 int n = particle->getNDaughters();
1519 const Particle* lep = particle->getDaughter(n - 1);
1520 ROOT::Math::PxPyPzEVector lep_cm = T.rotateLabToCms() * lep->get4Vector();
1522 ROOT::Math::PxPyPzEVector Y_cm = T.rotateLabToCms() * particle->get4Vector();
1523 ROOT::Math::PxPyPzEVector neu_cm = missing4Vector(particle, maskName, option);
1525 double e_beam = T.getCMSEnergy() / 2.0;
1528 double bmass = particle->getPDGMass();
1529 double pB2 = e_beam * e_beam - bmass * bmass;
1532 double cos_angle_nu = (pB2 - Y_cm.P2() - neu_cm.P2()) / (2.0 * Y_cm.P() * neu_cm.P());
1533 if (abs(cos_angle_nu) > 1)
1535 return (lep_cm + neu_cm).M2();
1538 double angle_nu = TMath::ACos(cos_angle_nu);
1540 ROOT::Math::PtEtaPhiEVector rotated_neu(-Y_cm);
1541 rotated_neu.SetE(Y_cm.E());
1543 double nu_eta = -log(tan((rotated_neu.Theta() + (TMath::Pi() - angle_nu)) / 2.));
1544 rotated_neu.SetEta(nu_eta);
1545 rotated_neu.SetPt(neu_cm.pt());
1546 rotated_neu.SetE(neu_cm.E());
1548 ROOT::Math::XYZVector Yneu_norm = Y_cm.Vect().Cross(neu_cm.Vect());
1549 ROOT::Math::XYZVector Yrot_norm = Y_cm.Vect().Cross(rotated_neu.Vect());
1553 double rot_angle = ROOT::Math::VectorUtil::Angle(Yneu_norm, Yrot_norm);
1555 ROOT::Math::PxPyPzEVector rotated_neu2(rotated_neu);
1561 ROOT::Math::AxisAngle rotation(Y_cm.Vect(), rot_angle);
1562 rotation(rotated_neu);
1564 rotation(rotated_neu2);
1566 double dot1 = rotated_neu.Vect().Dot(Yneu_norm);
1567 double dot2 = rotated_neu2.Vect().Dot(Yneu_norm);
1569 if (abs(dot2) < abs(dot1)) rotated_neu = rotated_neu2;
1571 return (lep_cm + rotated_neu).M2();
1580 if (arguments.size() == 1)
1581 maskName = arguments[0];
1582 else if (arguments.size() > 1)
1583 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function weCosThetaEll");
1585 auto func = [maskName](
const Particle * particle) ->
double {
1587 ROOT::Math::PxPyPzEVector pNu = missing4Vector(particle, maskName,
"1");
1590 ROOT::Math::PxPyPzEVector pLep;
1591 for (
unsigned i = 0; i < particle->getNDaughters(); i++)
1593 int absPDG = abs(particle->getDaughter(i)->getPDGCode());
1595 pLep = frame.getMomentum(particle->getDaughter(i)->get4Vector());
1600 ROOT::Math::PxPyPzEVector pW = pNu + pLep;
1601 ROOT::Math::PxPyPzEVector pB = frame.getMomentum(particle->get4Vector()) + pNu;
1604 ROOT::Math::XYZVector boost2W = pW.BoostToCM();
1605 pLep = ROOT::Math::Boost(boost2W) * pLep;
1606 pB = ROOT::Math::Boost(boost2W) * pB;
1608 return ROOT::Math::VectorUtil::CosTheta(pLep, pB);
1617 if (arguments.size() == 1)
1618 maskName = arguments[0];
1619 else if (arguments.size() > 1)
1620 B2FATAL(
"At most 1 argument (name of mask) accepted for meta function passesROEMask");
1622 auto func = [maskName](
const Particle * particle) ->
bool {
1624 StoreObjPtr<RestOfEvent> roeObjPtr(
"RestOfEvent");
1625 if (not roeObjPtr.isValid())
1628 const RestOfEvent* roe = &(*roeObjPtr);
1630 return isInThisRestOfEvent(particle, roe, maskName);
1635 double printROE(
const Particle* particle)
1637 const RestOfEvent* roe = getRelatedROEObject(particle);
1640 B2ERROR(
"Relation between particle and ROE doesn't exist!");
1641 }
else roe->print();
1645 bool hasCorrectROECombination(
const Particle* particle)
1647 unsigned nDaughters = particle->getNDaughters();
1648 if (nDaughters < 2) {
1649 B2ERROR(
"The particle must have at least two daughters.");
1653 for (
unsigned i = 0; i < particle->getNDaughters(); i++) {
1656 auto daughter = particle->getDaughter(i);
1657 auto roe = daughter->getRelatedFrom<RestOfEvent>();
1661 auto sourceParticle = roe->getRelatedFrom<Particle>();
1662 for (
unsigned j = 0; j < particle->getNDaughters(); j++) {
1663 if (i == j)
continue;
1664 const auto anotherDaughter = particle->getDaughter(j);
1666 if (anotherDaughter == sourceParticle)
1672 B2ERROR(
"There is no daughter particle loaded from the ROE object.");
1678 if (arguments.size() != 1)
1679 B2ERROR(
"Wrong number of arguments (1 required) for pi0Prob");
1682 mode = arguments[0];
1684 if (mode !=
"standard" and mode !=
"tight" and mode !=
"cluster" and mode !=
"both" and mode !=
"standardMC15rd"
1685 and mode !=
"tightMC15rd" and mode !=
"standardMC16rd" and mode !=
"tightMC16rd")
1686 B2ERROR(
"the given argument is not supported in pi0Prob!");
1688 auto func = [mode](
const Particle * particle) ->
double {
1689 if (mode ==
"standard")
1691 if (particle->hasExtraInfo(
"Pi0ProbOrigin")) {
1692 return particle->getExtraInfo(
"Pi0ProbOrigin");
1694 B2WARNING(
"Pi0ProbOrigin is not registered in extraInfo! \n"
1695 "the function writePi0EtaVeto has to be executed to register this extraInfo.");
1698 }
else if (mode ==
"tight")
1700 if (particle->hasExtraInfo(
"Pi0ProbTightEnergyThreshold")) {
1701 return particle->getExtraInfo(
"Pi0ProbTightEnergyThreshold");
1703 B2WARNING(
"Pi0ProbTightEnergyThreshold is not registered in extraInfo! \n"
1704 "the function writePi0EtaVeto has to be executed to register this extraInfo.");
1707 }
else if (mode ==
"cluster")
1709 if (particle->hasExtraInfo(
"Pi0ProbLargeClusterSize")) {
1710 return particle->getExtraInfo(
"Pi0ProbLargeClusterSize");
1712 B2WARNING(
"Pi0ProbLargeClusterSize is not registered in extraInfo! \n"
1713 "the function writePi0EtaVeto has to be executed to register this extraInfo.");
1716 }
else if (mode ==
"both")
1718 if (particle->hasExtraInfo(
"Pi0ProbTightEnergyThresholdAndLargeClusterSize")) {
1719 return particle->getExtraInfo(
"Pi0ProbTightEnergyThresholdAndLargeClusterSize");
1721 B2WARNING(
"Pi0ProbTightEnergyThresholdAndLargeClusterSize is not registered in extraInfo! \n"
1722 "the function writePi0EtaVeto has to be executed to register this extraInfo.");
1725 }
else if (mode ==
"standardMC15rd")
1727 if (particle->hasExtraInfo(
"Pi0ProbOriginMC15rd")) {
1728 return particle->getExtraInfo(
"Pi0ProbOriginMC15rd");
1730 B2WARNING(
"Pi0ProbOriginMC15rd is not registered in extraInfo! \n"
1731 "the function writePi0EtaVeto has to be executed to register this extraInfo.");
1734 }
else if (mode ==
"tightMC15rd")
1736 if (particle->hasExtraInfo(
"Pi0ProbTightEnergyThresholdMC15rd")) {
1737 return particle->getExtraInfo(
"Pi0ProbTightEnergyThresholdMC15rd");
1739 B2WARNING(
"Pi0ProbTightEnergyThresholdMC15rd is not registered in extraInfo! \n"
1740 "the function writePi0EtaVeto has to be executed to register this extraInfo.");
1743 }
else if (mode ==
"standardMC16rd")
1745 if (particle->hasExtraInfo(
"Pi0ProbOriginMC16rd")) {
1746 return particle->getExtraInfo(
"Pi0ProbOriginMC16rd");
1748 B2WARNING(
"Pi0ProbOriginMC16rd is not registered in extraInfo! \n"
1749 "the function writePi0EtaVeto has to be executed to register this extraInfo.");
1752 }
else if (mode ==
"tightMC16rd")
1754 if (particle->hasExtraInfo(
"Pi0ProbTightEnergyThresholdMC16rd")) {
1755 return particle->getExtraInfo(
"Pi0ProbTightEnergyThresholdMC16rd");
1757 B2WARNING(
"Pi0ProbTightEnergyThresholdMC16rd is not registered in extraInfo! \n"
1758 "the function writePi0EtaVeto has to be executed to register this extraInfo.");
1771 if (arguments.size() != 1)
1772 B2ERROR(
"Wrong number of arguments (1 required) for etaProb");
1775 mode = arguments[0];
1777 if (mode !=
"standard" and mode !=
"tight" and mode !=
"cluster" and mode !=
"both" and mode !=
"standardMC15rd"
1778 and mode !=
"tightMC15rd" and mode !=
"standardMC16rd" and mode !=
"tightMC16rd")
1779 B2ERROR(
"the given argument is not supported in etaProb!");
1781 auto func = [mode](
const Particle * particle) ->
double {
1782 if (mode ==
"standard")
1784 if (particle->hasExtraInfo(
"EtaProbOrigin")) {
1785 return particle->getExtraInfo(
"EtaProbOrigin");
1787 B2WARNING(
"EtaProbOrigin is not registered in extraInfo! \n"
1788 "the function writePi0EtaVeto has to be executed to register this extraInfo.");
1791 }
else if (mode ==
"tight")
1793 if (particle->hasExtraInfo(
"EtaProbTightEnergyThreshold")) {
1794 return particle->getExtraInfo(
"EtaProbTightEnergyThreshold");
1796 B2WARNING(
"EtaProbTightEnergyThreshold is not registered in extraInfo! \n"
1797 "the function writePi0EtaVeto has to be executed to register this extraInfo.");
1800 }
else if (mode ==
"cluster")
1802 if (particle->hasExtraInfo(
"EtaProbLargeClusterSize")) {
1803 return particle->getExtraInfo(
"EtaProbLargeClusterSize");
1805 B2WARNING(
"EtaProbLargeClusterSize is not registered in extraInfo! \n"
1806 "the function writePi0EtaVeto has to be executed to register this extraInfo.");
1809 }
else if (mode ==
"both")
1811 if (particle->hasExtraInfo(
"EtaProbTightEnergyThresholdAndLargeClusterSize")) {
1812 return particle->getExtraInfo(
"EtaProbTightEnergyThresholdAndLargeClusterSize");
1814 B2WARNING(
"EtaProbTightEnergyThresholdAndLargeClusterSize is not registered in extraInfo! \n"
1815 "the function writePi0EtaVeto has to be executed to register this extraInfo.");
1818 }
else if (mode ==
"standardMC15rd")
1820 if (particle->hasExtraInfo(
"EtaProbOriginMC15rd")) {
1821 return particle->getExtraInfo(
"EtaProbOriginMC15rd");
1823 B2WARNING(
"EtaProbOriginMC15rd is not registered in extraInfo! \n"
1824 "the function writePi0EtaVeto has to be executed to register this extraInfo.");
1827 }
else if (mode ==
"tightMC15rd")
1829 if (particle->hasExtraInfo(
"EtaProbTightEnergyThresholdMC15rd")) {
1830 return particle->getExtraInfo(
"EtaProbTightEnergyThresholdMC15rd");
1832 B2WARNING(
"EtaProbTightEnergyThresholdMC15rd is not registered in extraInfo! \n"
1833 "the function writePi0EtaVeto has to be executed to register this extraInfo.");
1836 }
else if (mode ==
"standardMC16rd")
1838 if (particle->hasExtraInfo(
"EtaProbOriginMC16rd")) {
1839 return particle->getExtraInfo(
"EtaProbOriginMC16rd");
1841 B2WARNING(
"EtaProbOriginMC16rd is not registered in extraInfo! \n"
1842 "the function writePi0EtaVeto has to be executed to register this extraInfo.");
1845 }
else if (mode ==
"tightMC16rd")
1847 if (particle->hasExtraInfo(
"EtaProbTightEnergyThresholdMC16rd")) {
1848 return particle->getExtraInfo(
"EtaProbTightEnergyThresholdMC16rd");
1850 B2WARNING(
"EtaProbTightEnergyThresholdMC16rd is not registered in extraInfo! \n"
1851 "the function writePi0EtaVeto has to be executed to register this extraInfo.");
1866 ROOT::Math::PxPyPzEVector transformVector(
const ROOT::Math::PxPyPzEVector& vec,
bool enforceCMSFrame)
1868 if (enforceCMSFrame) {
1869 UseReferenceFrame<CMSFrame> cmsFrame;
1871 return frame.getMomentum(vec);
1874 return frame.getMomentum(vec);
1878 ROOT::Math::PxPyPzEVector missing4Vector(
const Particle* particle,
const std::string& maskName,
const std::string& opt)
1881 const RestOfEvent* roe = getRelatedROEObject(particle);
1884 B2ERROR(
"Relation between particle and ROE doesn't exist!");
1885 ROOT::Math::PxPyPzEVector empty;
1889 bool enforceCMSFrame = (opt ==
"4" or opt ==
"7");
1891 ROOT::Math::PxPyPzEVector boostvec = transformVector(T.getBeamFourMomentum(), enforceCMSFrame);
1892 ROOT::Math::PxPyPzEVector rec4vec = transformVector(particle->get4Vector(), enforceCMSFrame);
1893 ROOT::Math::PxPyPzEVector roe4vec = transformVector(roe->get4Vector(maskName), enforceCMSFrame);
1895 ROOT::Math::PxPyPzEVector miss4vec;
1896 double E_beam_cms = T.getCMSEnergy() / 2.0;
1899 if (opt ==
"0" or opt ==
"5") {
1900 miss4vec = boostvec - (rec4vec + roe4vec);
1904 else if (opt ==
"1" or opt ==
"6") {
1905 miss4vec = boostvec - (rec4vec + roe4vec);
1906 miss4vec.SetE(miss4vec.P());
1910 else if (opt ==
"2") {
1911 miss4vec = boostvec - (rec4vec + roe4vec);
1912 miss4vec.SetE(boostvec.E() / 2. - rec4vec.E());
1916 else if (opt ==
"3") {
1917 miss4vec = boostvec - rec4vec;
1918 miss4vec.SetE(boostvec.E() / 2. - rec4vec.E());
1922 else if (opt ==
"4") {
1923 ROOT::Math::XYZVector pB = - roe4vec.Vect();
1924 pB = 0.340 * pB.Unit();
1925 pB -= rec4vec.Vect();
1926 miss4vec.SetPxPyPzE(pB.X(), pB.Y(), pB.Z(), E_beam_cms - rec4vec.E());
1930 else if (opt ==
"7") {
1931 miss4vec = - (rec4vec + roe4vec);
1932 miss4vec.SetE(miss4vec.P());
1933 double factorAlpha = (E_beam_cms - rec4vec.E()) / miss4vec.E();
1934 miss4vec *= factorAlpha;
1935 miss4vec.SetE(miss4vec.P());
1941 void checkMCParticleMissingFlags(
const MCParticle* mcp, std::set<const MCParticle*> mcROEObjects,
int& missingFlags)
1943 std::vector<MCParticle*> daughters = mcp->getDaughters();
1944 for (
auto& daughter : daughters) {
1949 if (mcROEObjects.find(daughter) == mcROEObjects.end()) {
1951 int pdg = abs(daughter->getPDG());
1954 if (pdg ==
Const::photon.getPDGCode() and (missingFlags & 1) == 0)
1958 else if (pdg ==
Const::electron.getPDGCode() and (missingFlags & 2) == 0)
1962 else if (pdg ==
Const::muon.getPDGCode() and (missingFlags & 4) == 0)
1966 else if (pdg ==
Const::pion.getPDGCode() and (missingFlags & 8) == 0)
1970 else if (pdg ==
Const::kaon.getPDGCode() and (missingFlags & 16) == 0)
1974 else if (pdg ==
Const::proton.getPDGCode() and (missingFlags & 32) == 0)
1978 else if (pdg ==
Const::neutron.getPDGCode() and (missingFlags & 64) == 0)
1982 else if (pdg ==
Const::Kshort.getPDGCode() and ((missingFlags & 128) == 0 or (missingFlags & 256) == 0)) {
1983 std::vector<MCParticle*> ksDaug = daughter->getDaughters();
1984 if (ksDaug.size() == 2) {
1986 if (abs(ksDaug[0]->getPDG()) ==
Const::pion.getPDGCode() and abs(ksDaug[1]->getPDG()) ==
Const::pion.getPDGCode()
1987 and (missingFlags & 128) == 0) {
1988 if (mcROEObjects.find(ksDaug[0]) == mcROEObjects.end() or mcROEObjects.find(ksDaug[1]) == mcROEObjects.end())
1989 missingFlags += 128;
1992 else if (abs(ksDaug[0]->getPDG()) ==
Const::pi0.getPDGCode() and abs(ksDaug[1]->getPDG()) ==
Const::pi0.getPDGCode()
1993 and (missingFlags & 256) == 0) {
1994 std::vector<MCParticle*> pi0Daug0 = ksDaug[0]->getDaughters();
1995 std::vector<MCParticle*> pi0Daug1 = ksDaug[1]->getDaughters();
1996 if (mcROEObjects.find(pi0Daug0[0]) == mcROEObjects.end() or
1997 mcROEObjects.find(pi0Daug0[1]) == mcROEObjects.end() or
1998 mcROEObjects.find(pi0Daug1[0]) == mcROEObjects.end() or
1999 mcROEObjects.find(pi0Daug1[1]) == mcROEObjects.end())
2000 missingFlags += 256;
2006 else if (pdg ==
Const::Klong.getPDGCode() and (missingFlags & 512) == 0)
2007 missingFlags += 512;
2010 else if ((pdg == 12 or pdg == 14 or pdg == 16) and (missingFlags & 1024) == 0)
2011 missingFlags += 1024;
2013 checkMCParticleMissingFlags(daughter, mcROEObjects, missingFlags);
2017 bool isInThisRestOfEvent(
const Particle* particle,
const RestOfEvent* roe,
const std::string& maskName)
2019 if (particle->getParticleSource() == Particle::c_Composite or
2020 particle->getParticleSource() == Particle::c_V0) {
2021 std::vector<const Particle*> fspDaug = particle->getFinalStateDaughters();
2022 for (
auto& i : fspDaug) {
2023 if (isInThisRestOfEvent(i, roe, maskName) == 0)
2028 return roe->hasParticle(particle, maskName);
2031 const RestOfEvent* getRelatedROEObject(
const Particle* particle,
bool returnHostOnly)
2034 const RestOfEvent* roe = particle->getRelatedTo<RestOfEvent>();
2035 if (!roe && !returnHostOnly) {
2036 roe = particle->getRelatedTo<RestOfEvent>(
"NestedRestOfEvents");
2042 VARIABLE_GROUP(
"Rest Of Event");
2044 REGISTER_METAVARIABLE(
"useROERecoilFrame(variable)", useROERecoilFrame,
2045 "Returns the value of the variable using the rest frame of the ROE recoil as current reference frame.\n"
2046 "Can be used inside for_each loop or outside of it if the particle has associated Rest of Event.\n"
2047 "E.g. ``useROERecoilFrame(E)`` returns the energy of a particle in the ROE recoil frame.", Manager::VariableDataType::c_double);
2049 REGISTER_VARIABLE(
"isInRestOfEvent", isInRestOfEvent,
2050 "Returns 1 if a track, ecl or klmCluster associated to particle is in the current RestOfEvent object, 0 otherwise."
2051 "One can use this variable only in a for_each loop over the RestOfEvent StoreArray.");
2053 REGISTER_VARIABLE(
"isCloneOfSignalSide", isCloneOfSignalSide,
2054 "Returns 1 if a particle is a clone of signal side final state particles, 0 otherwise. "
2055 "Requires generator information and truth-matching. "
2056 "One can use this variable only in a ``for_each`` loop over the RestOfEvent StoreArray.");
2058 REGISTER_VARIABLE(
"hasAncestorFromSignalSide", hasAncestorFromSignalSide,
2059 "Returns 1 if a particle has ancestor from signal side, 0 otherwise. "
2060 "Requires generator information and truth-matching. "
2061 "One can use this variable only in a ``for_each`` loop over the RestOfEvent StoreArray.");
2063 REGISTER_METAVARIABLE(
"currentROEIsInList(particleList)", currentROEIsInList,
2064 "[Eventbased] Returns 1 the associated particle of the current ROE is contained in the given list or its charge-conjugated."
2065 "Useful to restrict the for_each loop over ROEs to ROEs of a certain ParticleList.", Manager::VariableDataType::c_bool);
2067 REGISTER_VARIABLE(
"nROE_RemainingTracks", nROE_RemainingTracks,
2068 "Returns number of tracks in ROE - number of tracks of given particle"
2069 "One can use this variable only in a for_each loop over the RestOfEvent StoreArray.");
2071 REGISTER_METAVARIABLE(
"nROE_RemainingTracks([maskName])", nROE_RemainingTracksWithMask,
2072 "Returns number of remaining tracks between the ROE (specified via a mask) and the given particle. For the given particle only tracks are counted which are in the RoE."
2073 "One can use this variable only in a for_each loop over the RestOfEvent StoreArray."
2074 "Is required for the specific FEI. The default mask name is ``all``. :noindex:", Manager::VariableDataType::c_int);
2079 REGISTER_VARIABLE(
"nROE_KLMClusters", nROE_KLMClusters,
2080 "Returns number of all remaining KLM clusters in the related RestOfEvent object. "
2081 "This variable takes no ROE mask and always uses the default mask; use ``nROE_NeutralHadrons([maskName])``, "
2082 "which counts the same candidates, if you need a specific mask.");
2084 REGISTER_METAVARIABLE(
"nROE_Charged([maskName, PDGcode])", nROE_ChargedParticles,
2085 "Returns number of all charged particles in the related RestOfEvent object. First optional argument is ROE mask name. "
2086 "Second argument is a PDG code to count only one charged particle species, independently of charge. "
2087 "For example: ``nROE_Charged(cleanMask, 321)`` will output number of kaons in Rest Of Event with ``cleanMask``. "
2088 "The default mask name is ``all`` and the default PDG code is 0, which counts all charged particles",
2089 Manager::VariableDataType::c_int);
2091 REGISTER_METAVARIABLE(
"nROE_Photons([maskName])", nROE_Photons,
2092 "Returns number of all photons in the related RestOfEvent object, accepts 1 optional argument of ROE mask name. "
2093 "Only ECL-cluster-based ROE particles with the photon (N1) hypothesis are counted, which makes this a subset of "
2094 "``nROE_NeutralECLClusters``: ``nROE_Photons`` <= ``nROE_NeutralECLClusters`` <= ``nROE_ECLClusters``. "
2095 "The default mask name is ``all``.",
2096 Manager::VariableDataType::c_int);
2098 REGISTER_METAVARIABLE(
"nROE_NeutralHadrons([maskName])", nROE_NeutralHadrons,
2099 "Returns number of all neutral hadrons in the related RestOfEvent object, accepts 1 optional argument of ROE mask name. "
2100 "Note that only KLM-cluster-based candidates are counted, so this is the mask-aware equivalent of ``nROE_KLMClusters``; "
2101 "neutral hadron candidates built from ECL clusters are counted by ``nROE_NeutralECLClusters`` instead. "
2102 "The default mask name is ``all``.",
2103 Manager::VariableDataType::c_int);
2105 REGISTER_METAVARIABLE(
"particleRelatedToCurrentROE(var)", particleRelatedToCurrentROE,
2106 "[Eventbased] Returns variable applied to the particle which is related to the current RestOfEvent object"
2107 "One can use this variable only in a for_each loop over the RestOfEvent StoreArray.", Manager::VariableDataType::c_double);
2109 REGISTER_VARIABLE(
"roeMC_E", ROE_MC_E,
2110 "Returns true energy of unused tracks and clusters in ROE, can be used with ``use***Frame()`` function.\n\n",
"GeV");
2112 REGISTER_VARIABLE(
"roeMC_M", ROE_MC_M,
2113 "Returns true invariant mass of unused tracks and clusters in ROE\n\n",
"GeV/:math:`\\text{c}^2`");
2115 REGISTER_VARIABLE(
"roeMC_P", ROE_MC_P,
2116 "Returns true momentum of unused tracks and clusters in ROE, can be used with ``use***Frame()`` function.\n\n",
"GeV/c");
2118 REGISTER_VARIABLE(
"roeMC_Px", ROE_MC_Px,
2119 "Returns x component of true momentum of unused tracks and clusters in ROE, can be used with ``use***Frame()`` function.\n\n",
2122 REGISTER_VARIABLE(
"roeMC_Py", ROE_MC_Py,
2123 "Returns y component of true momentum of unused tracks and clusters in ROE, can be used with ``use***Frame()`` function.\n\n",
2126 REGISTER_VARIABLE(
"roeMC_Pz", ROE_MC_Pz,
2127 "Returns z component of true momentum of unused tracks and clusters in ROE, can be used with ``use***Frame()`` function.\n\n",
2130 REGISTER_VARIABLE(
"roeMC_Pt", ROE_MC_Pt,
2131 "Returns transverse component of true momentum of unused tracks and clusters in ROE, can be used with ``use***Frame()`` function.\n\n",
2134 REGISTER_VARIABLE(
"roeMC_PTheta", ROE_MC_PTheta,
2135 "Returns polar angle of true momentum of unused tracks and clusters in ROE, can be used with ``use***Frame()`` function.\n\n",
2138 REGISTER_METAVARIABLE(
"roeMC_MissFlags([maskName])", ROE_MC_MissingFlags,
2139 "Returns flags corresponding to missing particles on ROE side. The default mask name is ``all``.",
2140 Manager::VariableDataType::c_double);
2142 REGISTER_METAVARIABLE(
"nROE_Tracks([maskName])", nROE_Tracks,
2143 "Returns number of tracks in the related RestOfEvent object that pass the selection criteria. The default mask name is ``all``.",
2144 Manager::VariableDataType::c_int);
2146 REGISTER_METAVARIABLE(
"nROE_ECLClusters([maskName])", nROE_ECLClusters,
2147 "Returns number of ECL clusters in the related RestOfEvent object that pass the selection criteria. "
2148 "This counts the neutral (unmatched) clusters plus the clusters matched to charged ROE particles, so it is the "
2149 "widest of the three ECL counters: ``nROE_Photons`` <= ``nROE_NeutralECLClusters`` <= ``nROE_ECLClusters``. "
2150 "The default mask name is ``all``.",
2151 Manager::VariableDataType::c_int);
2153 REGISTER_METAVARIABLE(
"nROE_NeutralECLClusters([maskName])", nROE_NeutralECLClusters,
2154 "Returns number of neutral ECL clusters in the related RestOfEvent object that pass the selection criteria. "
2155 "This counts every ECL-cluster-based ROE particle regardless of hypothesis, and is therefore the ECL counterpart of "
2156 "``nROE_NeutralHadrons``. It differs from ``nROE_Photons``, which counts only the subset with the photon (N1) "
2157 "hypothesis, and from ``nROE_ECLClusters``, which additionally counts clusters matched to charged ROE particles. "
2158 "The default mask name is ``all``.",
2159 Manager::VariableDataType::c_int);
2161 REGISTER_METAVARIABLE(
"nROE_Composites([maskName])", nROE_Composites,
2162 "Returns number of composite particles or V0s in the related RestOfEvent object that pass the selection criteria. The default mask name is ``all``.",
2163 Manager::VariableDataType::c_int);
2165 REGISTER_METAVARIABLE(
"nROE_ParticlesInList(pListName[, maskName])", nROE_ParticlesInList,
2166 "Returns the number of particles in ROE from the given particle list. If a mask name is provided the selection criteria are applied.\n"
2167 "The default mask name is ``all``.\n"
2168 "Use of variable aliases is advised.", Manager::VariableDataType::c_int);
2170 REGISTER_METAVARIABLE(
"roeCharge([maskName])", ROE_Charge,
2171 "Returns total charge of the related RestOfEvent object. The unit of the charge is ``e``. The default mask name is ``all``.",
2172 Manager::VariableDataType::c_double);
2174 REGISTER_METAVARIABLE(
"roeEextra([maskName])", ROE_ExtraEnergy,
2175 "Returns extra energy from ECLClusters in the calorimeter that is not associated to the given Particle. The unit of the energy is ``GeV``. The default mask name is ``all``.",
2176 Manager::VariableDataType::c_double);
2178 REGISTER_METAVARIABLE(
"roeNeextra([maskName])", ROE_NeutralExtraEnergy,
2179 "Returns extra energy from neutral ECLClusters in the calorimeter that is not associated to the given Particle, can be used with ``use***Frame()`` function. The unit of the energy is ``GeV``. The default mask name is ``all``.",
2180 Manager::VariableDataType::c_double);
2182 REGISTER_METAVARIABLE(
"roeE([maskName])", ROE_E,
2183 "Returns energy of unused tracks and clusters in ROE, can be used with ``use***Frame()`` function. The unit of the energy is ``GeV``. The default mask name is ``all``.",
2184 Manager::VariableDataType::c_double);
2186 REGISTER_METAVARIABLE(
"roeM([maskName])", ROE_M,
2187 "Returns invariant mass of unused tracks and clusters in ROE. The unit of the invariant mass is :math:`\\text{GeV/c}^2`. The default mask name is ``all``.",
2188 Manager::VariableDataType::c_double);
2190 REGISTER_METAVARIABLE(
"roeP([maskName])", ROE_P,
2191 "Returns momentum of unused tracks and clusters in ROE, can be used with ``use***Frame()`` function. The unit of the momentum is ``GeV/c``. The default mask name is ``all``.",
2192 Manager::VariableDataType::c_double);
2194 REGISTER_METAVARIABLE(
"roePt([maskName])", ROE_Pt,
2195 "Returns transverse component of momentum of unused tracks and clusters in ROE, can be used with ``use***Frame()`` function. The unit of the momentum is ``GeV/c``. The default mask name is ``all``.",
2196 Manager::VariableDataType::c_double);
2198 REGISTER_METAVARIABLE(
"roePx([maskName])", ROE_Px,
2199 "Returns x component of momentum of unused tracks and clusters in ROE, can be used with ``use***Frame()`` function. The unit of the momentum is ``GeV/c``. The default mask name is ``all``.",
2200 Manager::VariableDataType::c_double);
2202 REGISTER_METAVARIABLE(
"roePy([maskName])", ROE_Py,
2203 "Returns y component of momentum of unused tracks and clusters in ROE, can be used with ``use***Frame()`` function. The unit of the momentum is ``GeV/c``. The default mask name is ``all``.",
2204 Manager::VariableDataType::c_double);
2206 REGISTER_METAVARIABLE(
"roePz([maskName])", ROE_Pz,
2207 "Returns z component of momentum of unused tracks and clusters in ROE, can be used with ``use***Frame()`` function. The unit of the momentum is ``GeV/c``. The default mask name is ``all``.",
2208 Manager::VariableDataType::c_double);
2210 REGISTER_METAVARIABLE(
"roePTheta([maskName])", ROE_PTheta,
2211 "Returns theta angle of momentum of unused tracks and clusters in ROE, can be used with ``use***Frame()`` function. The unit of the angle is ``rad``. The default mask name is ``all``.",
2212 Manager::VariableDataType::c_double);
2214 REGISTER_METAVARIABLE(
"roeDeltae([maskName])", ROE_DeltaE,
2215 "Returns energy difference of the related RestOfEvent object with respect to :math:`E_\\mathrm{cms}/2`. The unit of the energy is ``GeV``. The default mask name is ``all``.",
2216 Manager::VariableDataType::c_double);
2218 REGISTER_METAVARIABLE(
"roeMbc([maskName])", ROE_Mbc,
2219 "Returns beam constrained mass of the related RestOfEvent object with respect to :math:`E_\\mathrm{cms}/2`. The unit of the beam constrained mass is :math:`\\text{GeV/c}^2`. The default mask name is ``all``.",
2220 Manager::VariableDataType::c_double);
2222 REGISTER_METAVARIABLE(
"weDeltae([maskName])", WE_DeltaE, R
"DOC(
2223 Returns the energy difference of the B meson, corrected with the missing neutrino momentum (reconstructed side + neutrino) with respect to :math:`E_{\mathrm{cms}}/2`.
2224 The variable can be used with the ``use***Frame()`` function. The unit of the energy is ``GeV``. The default mask name is ``all``.)DOC",
2225 Manager::VariableDataType::c_double);
2227 REGISTER_METAVARIABLE("weMbc([maskName])", WE_Mbc, R
"DOC(
2228 Returns beam constrained mass of B meson, corrected with the missing neutrino momentum (reconstructed side + neutrino) with respect to :math:`E_{\mathrm{cms}}/2`.
2229 The variable can be used with the ``use***Frame()`` function. The unit of the beam constrained mass is :math:`\text{GeV/c}^2`. The default mask name is ``all``.)DOC",
2230 Manager::VariableDataType::c_double);
2232 REGISTER_METAVARIABLE("weMbcWithdEZero([maskName])", WE_MbcWithdEZero, R
"DOC(
2233 Returns beam constrained mass of B meson, corrected with the missing neutrino momentum (reconstructed side + neutrino) with respect to :math:`E_{\mathrm{cms}}/2`.
2234 The missing neutrino momentum is scaled so that the energy difference :math:`d_E = 0`. The unit of the beam constrained mass is :math:`\text{GeV/c}^2`. The default mask name is ``all``.)DOC",
2235 Manager::VariableDataType::c_double);
2237 REGISTER_METAVARIABLE("weMissM2(maskName, opt)", WE_MissM2, R
"DOC(
2238 Returns the invariant mass squared of the missing momentum (see :b2:var:`weMissE` possible options).
2239 The variable can be used with the ``use***Frame()`` function.
2240 The unit of the invariant mass squared is :math:`[\text{GeV}/\text{c}^2]^2`. Providing only ``opt`` (relying on the default mask name ``all``) is deprecated; always provide both arguments.)DOC",
2241 Manager::VariableDataType::c_double);
2243 REGISTER_METAVARIABLE("weMissPTheta(maskName, opt)", WE_MissPTheta, R
"DOC(
2244 Returns the polar angle of the missing momentum (see possible :b2:var:`weMissE` options).
2245 The variable can be used with the ``use***Frame()`` function.
2246 The unit of the polar angle is ``rad``. Providing only ``opt`` (relying on the default mask name ``all``) is deprecated; always provide both arguments.)DOC",
2247 Manager::VariableDataType::c_double);
2249 REGISTER_METAVARIABLE("weMissP(maskName, opt)", WE_MissP, R
"DOC(
2250 Returns the magnitude of the missing momentum (see possible :b2:var:`weMissE` options).
2251 The variable can be used with the ``use***Frame()`` function.
2252 The unit of the magnitude of missing momentum is ``GeV/c``. Providing only ``opt`` (relying on the default mask name ``all``) is deprecated; always provide both arguments.)DOC",
2253 Manager::VariableDataType::c_double);
2255 REGISTER_METAVARIABLE("weMissPx(maskName, opt)", WE_MissPx, R
"DOC(
2256 Returns the x component of the missing momentum (see :b2:var:`weMissE` possible options).
2257 The variable can be used with the ``use***Frame()`` function.
2258 The unit of the missing momentum is ``GeV/c``. Providing only ``opt`` (relying on the default mask name ``all``) is deprecated; always provide both arguments.)DOC",
2259 Manager::VariableDataType::c_double);
2261 REGISTER_METAVARIABLE("weMissPy(maskName, opt)", WE_MissPy, R
"DOC(
2262 Returns the y component of the missing momentum (see :b2:var:`weMissE` possible options).
2263 The variable can be used with the ``use***Frame()`` function.
2264 The unit of the missing momentum is ``GeV/c``. Providing only ``opt`` (relying on the default mask name ``all``) is deprecated; always provide both arguments.)DOC",
2265 Manager::VariableDataType::c_double);
2267 REGISTER_METAVARIABLE("weMissPz(maskName, opt)", WE_MissPz, R
"DOC(
2268 Returns the z component of the missing momentum (see :b2:var:`weMissE` possible options).
2269 The variable can be used with the ``use***Frame()`` function.
2270 The unit of the missing momentum is ``GeV/c``. Providing only ``opt`` (relying on the default mask name ``all``) is deprecated; always provide both arguments.)DOC",
2271 Manager::VariableDataType::c_double);
2273 REGISTER_METAVARIABLE("weMissE(maskName, opt)", WE_MissE,
2274 R
"DOC(Returns the energy of the missing momentum. The variable can be used with the ``use***Frame()`` function. The unit of the Energy is ``GeV`` . Possible options ``opt`` are the following:
2276- ``0``: use energy and momentum of charged particles and photons
2277- ``1``: same as ``0``, fix :math:`E_\mathrm{miss} = p_\mathrm{miss}`
2278- ``2``: same as ``0``, fix :math:`E_\mathrm{roe} = E_\mathrm{cms}/2`
2279- ``3``: use only energy and momentum of signal side
2280- ``4``: same as ``3``, update with direction of ROE momentum. Only works in CMS frame.
2281- ``7``: correct pmiss 3-momentum vector with factor alpha so that :math:`d_E = 0` (used for :math:`M_\mathrm{bc}` calculation). Only works in CMS frame. Providing only ``opt`` (relying on the default mask name ``all``) is deprecated; always provide both arguments.)DOC",
2282 Manager::VariableDataType::c_double);
2284 REGISTER_METAVARIABLE("weXiZ([maskName])", WE_xiZ,
2285 "Returns Xi_z in event (for Bhabha suppression and two-photon scattering). The unit of this variable is ``1/c``. The default mask name is ``all``.",
2286 Manager::VariableDataType::c_double);
2288 REGISTER_METAVARIABLE(
"bssMassDifference([maskName])", bssMassDifference,
2289 "Bs* - Bs mass difference. The unit of the mass is :math:`\\text{GeV/c}^2`. The default mask name is ``all``.",
2290 Manager::VariableDataType::c_double);
2292 REGISTER_METAVARIABLE(
"weCosThetaEll([maskName])", WE_cosThetaEll, R
"DOC(
2294Returns the cosine of the angle between :math:`M` and lepton in :math:`W` rest frame in the decays of the type:
2295:math:`M \to h_1 ... h_n \ell`, where W 4-momentum is given as
2298 p_W = p_\ell + p_\nu.
2300The neutrino momentum is calculated from ROE taking into account the specified mask, and setting
2303 E_{\nu} = |p_{miss}|.
2305The default mask name is ``all``.
2307)DOC", Manager::VariableDataType::c_double);
2309 REGISTER_METAVARIABLE("weQ2lnuSimple([maskName, option])", WE_q2lnuSimple,
2310 "Returns the momentum transfer squared, :math:`q^2`, calculated in CMS as :math:`q^2 = (p_l + p_\\nu)^2`, \n"
2311 "where :math:`B \\to H_1\\dots H_n \\ell \\nu_\\ell`. Lepton is assumed to be the last reconstructed daughter. \n"
2312 "By default, option is set to ``1`` (see :b2:var:`weMissE`). Unless you know what you are doing, keep this default value. The default mask name is ``all``. The unit of the momentum transfer squared is :math:`[\\text{GeV}/\\text{c}]^2`.", Manager::VariableDataType::c_double);
2314 REGISTER_METAVARIABLE(
"weQ2lnu([maskName, option])", WE_q2lnu,
2315 "Returns the momentum transfer squared, :math:`q^2`, calculated in CMS as :math:`q^2 = (p_l + p_\\nu)^2`, \n"
2316 "where :math:`B \\to H_1\\dots H_n \\ell \\nu_\\ell`. Lepton is assumed to be the last reconstructed daughter. \n"
2317 "This calculation uses constraints from dE = 0 and Mbc = Mb to correct the neutrino direction. \n"
2318 "By default, option is set to ``7`` (see :b2:var:`weMissE`). Unless you know what you are doing, keep this default value. The default mask name is ``all``. The unit of the momentum transfer squared is :math:`[\\text{GeV}/\\text{c}]^2`.", Manager::VariableDataType::c_double);
2320 REGISTER_METAVARIABLE(
"weMissM2OverMissE([maskName])", WE_MissM2OverMissE,
2321 "Returns missing mass squared over missing energy. The unit of the missing mass squared is :math:`\\text{GeV/c}^4`. The default mask name is ``all``.", Manager::VariableDataType::c_double);
2323 REGISTER_METAVARIABLE(
"passesROEMask([maskName])", passesROEMask,
2324 "Returns boolean value if a particle passes a certain mask or not. Only to be used in for_each path. The default mask name is ``all``.", Manager::VariableDataType::c_bool);
2326 REGISTER_VARIABLE(
"printROE", printROE,
2327 "For debugging, prints indices of all particles in the ROE and all masks. Returns 0.");
2329 REGISTER_VARIABLE(
"hasCorrectROECombination", hasCorrectROECombination,
2330 "Returns 1 if there is correct combination of daughter particles between the particle that is the basis of the ROE and the particle loaded from the ROE. "
2331 "Returns 0 if there is not correct combination or if there is no daughter particle loaded from the ROE.");
2333 REGISTER_METAVARIABLE(
"pi0Prob(mode)", pi0Prob,
2334 "Returns pi0 probability, where mode is used to specify the selection criteria for soft photon. \n"
2335 "The following strings are available. \n\n"
2336 "- ``standard``: loose energy cut and no clusterNHits cut are applied to soft photon \n"
2337 "- ``tight``: tight energy cut and no clusterNHits cut are applied to soft photon \n"
2338 "- ``cluster``: loose energy cut and clusterNHits cut are applied to soft photon \n"
2339 "- ``both``: tight energy cut and clusterNHits cut are applied to soft photon \n"
2340 "- ``standardMC15rd``: loose energy cut is applied to soft photon and the weight files are trained using MC15rd \n"
2341 "- ``tightMC15rd``: tight energy cut is applied to soft photon and the weight files are trained using MC15rd \n"
2342 "- ``standardMC16rd``: loose energy cut is applied to soft photon and the weight files are trained using MC16rd \n"
2343 "- ``tightMC16rd``: tight energy cut is applied to soft photon and the weight files are trained using MC16rd \n\n"
2344 "You can find more details in `writePi0EtaVeto` function in modularAnalysis.py.", Manager::VariableDataType::c_double);
2346 REGISTER_METAVARIABLE(
"etaProb(mode)", etaProb,
2347 "Returns eta probability, where mode is used to specify the selection criteria for soft photon. \n"
2348 "The following strings are available. \n\n"
2349 "- ``standard``: loose energy cut and no clusterNHits cut are applied to soft photon \n"
2350 "- ``tight``: tight energy cut and no clusterNHits cut are applied to soft photon \n"
2351 "- ``cluster``: loose energy cut and clusterNHits cut are applied to soft photon \n"
2352 "- ``both``: tight energy cut and clusterNHits cut are applied to soft photon \n"
2353 "- ``standardMC15rd``: loose energy cut is applied to soft photon and the weight files are trained using MC15rd \n"
2354 "- ``tightMC15rd``: tight energy cut is applied to soft photon and the weight files are trained using MC15rd \n"
2355 "- ``standardMC16rd``: loose energy cut is applied to soft photon and the weight files are trained using MC16rd \n"
2356 "- ``tightMC16rd``: tight energy cut is applied to soft photon and the weight files are trained using MC16rd \n\n"
2357 "You can find more details in `writePi0EtaVeto` function in modularAnalysis.py.", Manager::VariableDataType::c_double);
static const ParticleType neutron
neutron particle
static const ParticleType pi0
neutral pion particle
static const ChargedStable muon
muon particle
static const ChargedStable pion
charged pion particle
static const ParticleType Klong
K^0_L particle.
static const ChargedStable proton
proton particle
static const ParticleType Kshort
K^0_S particle.
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
@ c_nPhotons
CR is split into n photons (N1)
@ c_PrimaryParticle
bit 0: Particle is primary particle.
static const ReferenceFrame & GetCurrent()
Get current rest frame.
static constexpr const char * c_defaultMaskName
Default mask name.
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.
T convertString(const std::string &str)
Converts a string to type T (one of float, double, long double, int, long int, unsigned long int).
Abstract base class for different kinds of events.