10#include <analysis/variables/KinkVariables.h> 
   13#include <analysis/dataobjects/Particle.h> 
   16#include <framework/dataobjects/Helix.h> 
   19#include <mdst/dataobjects/Track.h> 
   20#include <mdst/dataobjects/Kink.h> 
   21#include <mdst/dataobjects/MCParticle.h> 
   22#include <mdst/dataobjects/TrackFitResult.h> 
   23#include <mdst/dataobjects/HitPatternCDC.h> 
   24#include <mdst/dataobjects/HitPatternVXD.h> 
   27#include <framework/logging/Logger.h> 
   32#include <Math/Boost.h> 
   46    Helix kinkDaughterHelixAtKinkVertex(
const Kink* kink)
 
   48      Helix daughterHelixAtKinkVertex = kink->getDaughterTrackFitResult()->getHelix();
 
   49      daughterHelixAtKinkVertex.passiveMoveBy(kink->getFittedVertexX(), kink->getFittedVertexY(), 0);
 
   50      return daughterHelixAtKinkVertex;
 
   53    ROOT::Math::XYZVector kinkDaughterMomentumAtKinkVertex(
const Kink* kink)
 
   56      {kink->getFittedVertexX(), kink->getFittedVertexY(), kink->getFittedVertexZ()}).Z();
 
   57      Helix daughterHelixAtKinkVertex = kink->getDaughterTrackFitResult()->getHelix();
 
   58      daughterHelixAtKinkVertex.passiveMoveBy(kink->getFittedVertexX(), kink->getFittedVertexY(), 0);
 
   59      return daughterHelixAtKinkVertex.getMomentum(BzAtKinkVertex);
 
   62    Helix kinkMotherHelixAtKinkVertex(
const Kink* kink)
 
   64      Helix motherHelixAtKinkVertex = kink->getMotherTrackFitResultEnd()->getHelix();
 
   65      motherHelixAtKinkVertex.passiveMoveBy(kink->getFittedVertexX(), kink->getFittedVertexY(), 0);
 
   66      return motherHelixAtKinkVertex;
 
   69    ROOT::Math::XYZVector kinkMotherMomentumAtKinkVertex(
const Kink* kink)
 
   72      {kink->getFittedVertexX(), kink->getFittedVertexY(), kink->getFittedVertexZ()}).Z();
 
   73      Helix motherHelixAtKinkVertex = kink->getMotherTrackFitResultEnd()->getHelix();
 
   74      motherHelixAtKinkVertex.passiveMoveBy(kink->getFittedVertexX(), kink->getFittedVertexY(), 0);
 
   75      return motherHelixAtKinkVertex.getMomentum(BzAtKinkVertex);
 
   78    double kinkDaughterMomentumAndCosThetaInMotherRF(
const Particle* part, Const::ChargedStable motherType,
 
   79                                                     Const::ChargedStable daughterType, 
bool returnCosTheta)
 
   81      const Kink* kink = part->getKink();
 
   84      ROOT::Math::XYZVector motherMomentumAtKinkVertex = kinkMotherMomentumAtKinkVertex(kink);
 
   85      ROOT::Math::XYZVector daughterMomentumAtKinkVertex = kinkDaughterMomentumAtKinkVertex(kink);
 
   87      double motherEnergy = sqrt(motherMomentumAtKinkVertex.Mag2() + motherType.getMass() * motherType.getMass());
 
   88      double daughterEnergy = sqrt(daughterMomentumAtKinkVertex.Mag2() + daughterType.getMass() * daughterType.getMass());
 
   90      ROOT::Math::PxPyPzEVector mother4MomentumAtKinkVertex(motherMomentumAtKinkVertex.X(),
 
   91                                                            motherMomentumAtKinkVertex.Y(),
 
   92                                                            motherMomentumAtKinkVertex.Z(),
 
   94      int signDiff = kink->getMotherTrackFitResultEnd()->getChargeSign() * kink->getDaughterTrackFitResult()->getChargeSign();
 
   95      ROOT::Math::PxPyPzEVector daughter4MomentumAtKinkVertex(signDiff * daughterMomentumAtKinkVertex.X(),
 
   96                                                              signDiff * daughterMomentumAtKinkVertex.Y(),
 
   97                                                              signDiff * daughterMomentumAtKinkVertex.Z(),
 
  100      ROOT::Math::XYZVector motherBoostAtKinkVertex = mother4MomentumAtKinkVertex.BoostToCM();
 
  101      daughter4MomentumAtKinkVertex = ROOT::Math::Boost(motherBoostAtKinkVertex) * daughter4MomentumAtKinkVertex;
 
  104        return daughter4MomentumAtKinkVertex.Vect().Unit().Dot(mother4MomentumAtKinkVertex.Vect().Unit());
 
  106        return sqrt(daughter4MomentumAtKinkVertex.Vect().Mag2());
 
  109    ROOT::Math::PxPyPzEVector kinkMotherMCP4AtDecayVertex(
const MCParticle* p)
 
  111      ROOT::Math::PxPyPzEVector P4(0, 0, 0, 0);
 
  112      ROOT::Math::XYZVector mcDecayVertex = p->getDecayVertex();
 
  113      std::vector<MCParticle*> mcDaughters = p->getDaughters();
 
  114      for (std::vector<MCParticle*>::iterator daughterIter = mcDaughters.begin();
 
  115           daughterIter != mcDaughters.end(); ++daughterIter) {
 
  116        ROOT::Math::XYZVector mcDaughterVertex = (*daughterIter)->getVertex();
 
  117        if ((mcDaughterVertex - mcDecayVertex).Mag2() < 1)
 
  118          P4 += (*daughterIter)->get4Vector();
 
  123    double kinkDaughterMCMomentumAndCosThetaInMotherRF(
const Particle* part, 
bool returnCosTheta)
 
  125      const Kink* kink = part->getKink();
 
  128      const Track* motherTrack = kink->getMotherTrack();
 
  129      const Track* daughterTrack = kink->getDaughterTrack();
 
  132      const MCParticle* motherMCParticle = motherTrack->getRelated<MCParticle>();
 
  133      const MCParticle* daughterMCParticle = daughterTrack->getRelated<MCParticle>();
 
  137      ROOT::Math::PxPyPzEVector mother4MomentumAtDecayVertex = kinkMotherMCP4AtDecayVertex(motherMCParticle);
 
  138      ROOT::Math::PxPyPzEVector daughter4MomentumAtProductionVertex = daughterMCParticle->get4Vector();
 
  140      ROOT::Math::XYZVector motherBoostAtDecayVertex = mother4MomentumAtDecayVertex.BoostToCM();
 
  141      ROOT::Math::PxPyPzEVector daughter4MomentumAtDecayVertex = ROOT::Math::Boost(motherBoostAtDecayVertex) *
 
  142                                                                 daughter4MomentumAtProductionVertex;
 
  145        return daughter4MomentumAtDecayVertex.Vect().Unit().Dot(mother4MomentumAtDecayVertex.Vect().Unit());
 
  147        return sqrt(daughter4MomentumAtDecayVertex.Vect().Mag2());
 
  154    double kinkVertexX(
const Particle* part)
 
  156      const Kink* kink = part->getKink();
 
  158      return kink->getFittedVertexX();
 
  161    double kinkVertexY(
const Particle* part)
 
  163      const Kink* kink = part->getKink();
 
  165      return kink->getFittedVertexY();
 
  168    double kinkVertexZ(
const Particle* part)
 
  170      const Kink* kink = part->getKink();
 
  172      return kink->getFittedVertexZ();
 
  175    double kinkFilterID(
const Particle* part)
 
  177      const Kink* kink = part->getKink();
 
  179      return kink->getPrefilterFlag();
 
  182    double kinkCombinedFitResultFlag(
const Particle* part)
 
  184      const Kink* kink = part->getKink();
 
  186      if (kinkFilterID(part) < 3)
 
  187        return kink->getCombinedFitResultFlag();
 
  192    double kinkCombinedFitResultFlagBit1(
const Particle* part)
 
  194      double flag = kinkCombinedFitResultFlag(part);
 
  196        return static_cast<int>(flag) & 0b0001;
 
  201    double kinkCombinedFitResultFlagBit2(
const Particle* part)
 
  203      double flag = kinkCombinedFitResultFlag(part);
 
  205        return  static_cast<bool>(
static_cast<int>(flag) & 0b0010);
 
  210    double kinkCombinedFitResultFlagBit3(
const Particle* part)
 
  212      double flag = kinkCombinedFitResultFlag(part);
 
  214        return  static_cast<bool>(
static_cast<int>(flag) & 0b0100);
 
  219    double kinkCombinedFitResultFlagBit4(
const Particle* part)
 
  221      double flag = kinkCombinedFitResultFlag(part);
 
  223        return  static_cast<bool>(
static_cast<int>(flag) & 0b1000);
 
  228    double kinkSplitTrackDistanceAtVertexFlag(
const Particle* part)
 
  230      const Kink* kink = part->getKink();
 
  232      if (kinkFilterID(part) < 3)
 
  235        return kink->getSplitTrackDistanceAtVertexFlag();
 
  238    double kinkNumberOfReassignedHits(
const Particle* part)
 
  240      const Kink* kink = part->getKink();
 
  242      return kink->getNumberOfReassignedHits();
 
  245    double kinkIsSameCharge(
const Particle* part)
 
  247      const Kink* kink = part->getKink();
 
  250      return kink->getMotherTrackFitResultEnd()->getChargeSign() *
 
  251             kink->getDaughterTrackFitResult()->getChargeSign() > 0 ? true : 
false;
 
  256    double kinkDaughterMomentumInMotherRF(
const Particle* part)
 
  258      if (!(part->hasExtraInfo(
"kinkDaughterPDGCode")))
 
  260      Const::ChargedStable daughterType(abs(part->getExtraInfo(
"kinkDaughterPDGCode")));
 
  261      Const::ChargedStable motherType(abs(part->getPDGCode()));
 
  262      return kinkDaughterMomentumAndCosThetaInMotherRF(part, motherType, daughterType, 
false);
 
  265    double kinkDaughterCosThetaInMotherRF(
const Particle* part)
 
  267      if (!(part->hasExtraInfo(
"kinkDaughterPDGCode")))
 
  269      Const::ChargedStable daughterType(abs(part->getExtraInfo(
"kinkDaughterPDGCode")));
 
  270      Const::ChargedStable motherType(abs(part->getPDGCode()));
 
  271      return kinkDaughterMomentumAndCosThetaInMotherRF(part, motherType, daughterType, 
true);
 
  274    double kinkDaughterMomentumInMotherRFKPi(
const Particle* part)
 
  279    double kinkDaughterCosThetaInMotherRFKPi(
const Particle* part)
 
  284    double kinkDaughterMomentumInMotherRFKMu(
const Particle* part)
 
  289    double kinkDaughterCosThetaInMotherRFKMu(
const Particle* part)
 
  294    double kinkDaughterMomentumInMotherRFPiMu(
const Particle* part)
 
  299    double kinkDaughterCosThetaInMotherRFPiMu(
const Particle* part)
 
  304    double kinkDaughterMomentumInMotherRFMuE(
const Particle* part)
 
  309    double kinkDaughterCosThetaInMotherRFMuE(
const Particle* part)
 
  318      if (arguments.size() == 1) {
 
  320        auto func = [var](
const Particle * particle) -> 
double {
 
  321          if (particle->getParticleSource() != Particle::EParticleSourceObject::c_Kink) 
return Const::doubleNaN;
 
  322          const Kink* kink = particle->getKink();
 
  324          if (not particle->hasExtraInfo(
"kinkDaughterPDGCode")) 
return Const::doubleNaN;
 
  325          Particle tmpParticle(kink, Const::ChargedStable(abs(particle->getExtraInfo(
"kinkDaughterPDGCode"))), kink->getTrackFitResultIndexDaughter());
 
  326          auto var_result = var->function(&tmpParticle);
 
  327          if (std::holds_alternative<double>(var_result))
 
  329            return std::get<double>(var_result);
 
  330          } 
else if (std::holds_alternative<int>(var_result))
 
  332            return std::get<int>(var_result);
 
  333          } 
else if (std::holds_alternative<bool>(var_result))
 
  335            return std::get<bool>(var_result);
 
  343        B2FATAL(
"Wrong number of arguments for meta function kinkDaughterTrack");
 
  349      if (arguments.size() == 1) {
 
  351        auto func = [var](
const Particle * particle) -> 
double {
 
  352          if (particle->getParticleSource() != Particle::EParticleSourceObject::c_Kink) 
return Const::doubleNaN;
 
  353          const Kink* kink = particle->getKink();
 
  355          if (not particle->hasExtraInfo(
"kinkDaughterPDGCode")) 
return Const::doubleNaN;
 
  356          Particle tmpParticle(kink->getDaughterTrack()->getArrayIndex(), kink->getDaughterTrack()->getTrackFitResultWithClosestMass(
Const::pion), Const::ChargedStable(abs(particle->getExtraInfo(
"kinkDaughterPDGCode"))));
 
  357          auto var_result = var->function(&tmpParticle);
 
  358          if (std::holds_alternative<double>(var_result))
 
  360            return std::get<double>(var_result);
 
  361          } 
else if (std::holds_alternative<int>(var_result))
 
  363            return std::get<int>(var_result);
 
  364          } 
else if (std::holds_alternative<bool>(var_result))
 
  366            return std::get<bool>(var_result);
 
  374        B2FATAL(
"Wrong number of arguments for meta function kinkDaughterInitTrack");
 
  378    double kinkDaughterTrackD0AtKinkVertex(
const Particle* part)
 
  380      const Kink* kink = part->getKink();
 
  383      Helix daughterHelixAtKinkVertex = kinkDaughterHelixAtKinkVertex(kink);
 
  384      return daughterHelixAtKinkVertex.getD0();
 
  387    double kinkDaughterTrackZ0AtKinkVertex(
const Particle* part)
 
  389      const Kink* kink = part->getKink();
 
  392      Helix daughterHelixAtKinkVertex = kinkDaughterHelixAtKinkVertex(kink);
 
  393      return daughterHelixAtKinkVertex.getZ0();
 
  396    double kinkDaughterPtAtKinkVertex(
const Particle* part)
 
  398      const Kink* kink = part->getKink();
 
  401      ROOT::Math::XYZVector daughterMomentumAtKinkVertex = kinkDaughterMomentumAtKinkVertex(kink);
 
  402      return sqrt(daughterMomentumAtKinkVertex.Perp2());
 
  405    double kinkDaughterPzAtKinkVertex(
const Particle* part)
 
  407      const Kink* kink = part->getKink();
 
  410      ROOT::Math::XYZVector daughterMomentumAtKinkVertex = kinkDaughterMomentumAtKinkVertex(kink);
 
  411      return daughterMomentumAtKinkVertex.Z();
 
  414    double kinkDaughterPAtKinkVertex(
const Particle* part)
 
  416      const Kink* kink = part->getKink();
 
  419      ROOT::Math::XYZVector daughterMomentumAtKinkVertex = kinkDaughterMomentumAtKinkVertex(kink);
 
  420      return sqrt(daughterMomentumAtKinkVertex.Mag2());
 
  427      if (arguments.size() == 1) {
 
  429        auto func = [var](
const Particle * particle) -> 
double {
 
  430          if (particle->getParticleSource() != Particle::EParticleSourceObject::c_Kink) 
return Const::doubleNaN;
 
  431          const Kink* kink = particle->getKink();
 
  433          Particle tmpParticle(kink->getMotherTrack()->getArrayIndex(), kink->getMotherTrack()->getTrackFitResultWithClosestMass(
Const::pion), 
Const::pion);
 
  434          auto var_result = var->function(&tmpParticle);
 
  435          if (std::holds_alternative<double>(var_result))
 
  437            return std::get<double>(var_result);
 
  438          } 
else if (std::holds_alternative<int>(var_result))
 
  440            return std::get<int>(var_result);
 
  441          } 
else if (std::holds_alternative<bool>(var_result))
 
  443            return std::get<bool>(var_result);
 
  451        B2FATAL(
"Wrong number of arguments for meta function kinkMotherInitTrack");
 
  455    double kinkMotherTrackD0AtKinkVertex(
const Particle* part)
 
  457      const Kink* kink = part->getKink();
 
  460      Helix motherHelixAtKinkVertex = kinkMotherHelixAtKinkVertex(kink);
 
  461      return motherHelixAtKinkVertex.getD0();
 
  464    double kinkMotherTrackZ0AtKinkVertex(
const Particle* part)
 
  466      const Kink* kink = part->getKink();
 
  469      Helix motherHelixAtKinkVertex = kinkMotherHelixAtKinkVertex(kink);
 
  470      return motherHelixAtKinkVertex.getZ0();
 
  473    double kinkMotherPtAtKinkVertex(
const Particle* part)
 
  475      const Kink* kink = part->getKink();
 
  478      ROOT::Math::XYZVector motherMomentumAtKinkVertex = kinkMotherMomentumAtKinkVertex(kink);
 
  479      return sqrt(motherMomentumAtKinkVertex.Perp2());
 
  482    double kinkMotherPzAtKinkVertex(
const Particle* part)
 
  484      const Kink* kink = part->getKink();
 
  487      ROOT::Math::XYZVector motherMomentumAtKinkVertex = kinkMotherMomentumAtKinkVertex(kink);
 
  488      return motherMomentumAtKinkVertex.Z();
 
  491    double kinkMotherPAtKinkVertex(
const Particle* part)
 
  493      const Kink* kink = part->getKink();
 
  496      ROOT::Math::XYZVector motherMomentumAtKinkVertex = kinkMotherMomentumAtKinkVertex(kink);
 
  497      return sqrt(motherMomentumAtKinkVertex.Mag2());
 
  503    double particleIsInKink(
const Particle* part)
 
  505      const Track* track = part->getTrack();
 
  508      const short trackIndex = track->getArrayIndex();
 
  509      StoreArray<Kink> kinks;
 
  511      for (
int i = 0; i < kinks.getEntries(); i++) {
 
  512        const Kink* kink = kinks[i];
 
  513        const short motherTrackIndex = kink->getMotherTrackIndex();
 
  514        const short daughterTrackIndex = kink->getDaughterTrackIndex();
 
  515        if (trackIndex == motherTrackIndex || trackIndex == daughterTrackIndex)
 
  522    double particleIsMotherInKink(
const Particle* part)
 
  524      const Track* track = part->getTrack();
 
  527      const short trackIndex = track->getArrayIndex();
 
  528      StoreArray<Kink> kinks;
 
  530      for (
int i = 0; i < kinks.getEntries(); i++) {
 
  531        const Kink* kink = kinks[i];
 
  532        const short motherTrackIndex = kink->getMotherTrackIndex();
 
  533        if (trackIndex == motherTrackIndex)
 
  540    double particleIsDaughterInKink(
const Particle* part)
 
  542      const Track* track = part->getTrack();
 
  545      const short trackIndex = track->getArrayIndex();
 
  546      StoreArray<Kink> kinks;
 
  548      for (
int i = 0; i < kinks.getEntries(); i++) {
 
  549        const Kink* kink = kinks[i];
 
  550        const short daughterTrackIndex = kink->getDaughterTrackIndex();
 
  551        if (trackIndex == daughterTrackIndex)
 
  557    double particleIsSplitKink(
const Particle* part)
 
  559      const Track* track = part->getTrack();
 
  562      const short trackIndex = track->getArrayIndex();
 
  563      StoreArray<Kink> kinks;
 
  565      for (
int i = 0; i < kinks.getEntries(); i++) {
 
  566        const Kink* kink = kinks[i];
 
  567        const short motherTrackIndex = kink->getMotherTrackIndex();
 
  568        const short daughterTrackIndex = kink->getDaughterTrackIndex();
 
  569        if (trackIndex == motherTrackIndex && motherTrackIndex == daughterTrackIndex)
 
  579    double kinkPairIsMCRelated(
const Particle* part)
 
  581      const Kink* kink = part->getKink();
 
  584      const Track* motherTrack = kink->getMotherTrack();
 
  585      const Track* daughterTrack = kink->getDaughterTrack();
 
  589      const MCParticle* motherMCParticle = motherTrack->getRelated<MCParticle>();
 
  590      const MCParticle* daughterMCParticle = daughterTrack->getRelated<MCParticle>();
 
  592      if (!motherMCParticle || !daughterMCParticle) 
return false;
 
  593      if (motherMCParticle == daughterMCParticle) 
return true;
 
  594      if (daughterMCParticle->getMother() && daughterMCParticle->getMother() == motherMCParticle) 
return true;
 
  598    double kinkPairIsClone(
const Particle* part)
 
  600      const Kink* kink = part->getKink();
 
  603      const Track* motherTrack = kink->getMotherTrack();
 
  604      const Track* daughterTrack = kink->getDaughterTrack();
 
  608      const MCParticle* motherMCParticle = motherTrack->getRelated<MCParticle>();
 
  609      const MCParticle* daughterMCParticle = daughterTrack->getRelated<MCParticle>();
 
  611      if (!motherMCParticle || !daughterMCParticle) 
return false;
 
  612      if (motherMCParticle == daughterMCParticle) 
return true;
 
  616    double kinkPairIsReal(
const Particle* part)
 
  618      const Kink* kink = part->getKink();
 
  621      const Track* motherTrack = kink->getMotherTrack();
 
  622      const Track* daughterTrack = kink->getDaughterTrack();
 
  626      const MCParticle* motherMCParticle = motherTrack->getRelated<MCParticle>();
 
  627      const MCParticle* daughterMCParticle = daughterTrack->getRelated<MCParticle>();
 
  629      if (!motherMCParticle || !daughterMCParticle) 
return false;
 
  630      if (daughterMCParticle->getMother() && daughterMCParticle->getMother() == motherMCParticle) 
return true;
 
  634    double kinkPairIsDecayInFlight(
const Particle* part)
 
  636      const Kink* kink = part->getKink();
 
  639      const Track* motherTrack = kink->getMotherTrack();
 
  640      const Track* daughterTrack = kink->getDaughterTrack();
 
  644      const MCParticle* motherMCParticle = motherTrack->getRelated<MCParticle>();
 
  645      const MCParticle* daughterMCParticle = daughterTrack->getRelated<MCParticle>();
 
  647      if (!motherMCParticle || !daughterMCParticle) 
return false;
 
  648      if (daughterMCParticle->getMother() &&
 
  649          daughterMCParticle->getMother() == motherMCParticle &&
 
  650          daughterMCParticle->getSecondaryPhysicsProcess() == 201) 
return true;
 
  654    double kinkPairIsHadronScattering(
const Particle* part)
 
  656      const Kink* kink = part->getKink();
 
  659      const Track* motherTrack = kink->getMotherTrack();
 
  660      const Track* daughterTrack = kink->getDaughterTrack();
 
  664      const MCParticle* motherMCParticle = motherTrack->getRelated<MCParticle>();
 
  665      const MCParticle* daughterMCParticle = daughterTrack->getRelated<MCParticle>();
 
  667      if (!motherMCParticle || !daughterMCParticle) 
return false;
 
  668      if (daughterMCParticle->getMother() &&
 
  669          daughterMCParticle->getMother() == motherMCParticle &&
 
  670          daughterMCParticle->getSecondaryPhysicsProcess() == 121) 
return true;
 
  676    double kinkDaughterMomentumInMotherRFMC(
const Particle* part)
 
  678      return kinkDaughterMCMomentumAndCosThetaInMotherRF(part, 
false);
 
  681    double kinkDaughterCosThetaInMotherRFMC(
const Particle* part)
 
  683      return kinkDaughterMCMomentumAndCosThetaInMotherRF(part, 
true);
 
  690      if (arguments.size() == 1) {
 
  692        auto func = [var](
const Particle * particle) -> 
double {
 
  693          if (particle->getParticleSource() != Particle::EParticleSourceObject::c_Kink) 
return Const::doubleNaN;
 
  694          const Kink* kink = particle->getKink();
 
  696          const Track* daughterTrack = kink->getDaughterTrack();
 
  698          Particle tmpParticle(daughterTrack->getRelated<MCParticle>());
 
  699          auto var_result = var->function(&tmpParticle);
 
  700          if (std::holds_alternative<double>(var_result))
 
  702            return std::get<double>(var_result);
 
  703          } 
else if (std::holds_alternative<int>(var_result))
 
  705            return std::get<int>(var_result);
 
  706          } 
else if (std::holds_alternative<bool>(var_result))
 
  708            return std::get<bool>(var_result);
 
  716        B2FATAL(
"Wrong number of arguments for meta function kinkPairDaughterMC");
 
  724      if (arguments.size() == 1) {
 
  726        auto func = [var](
const Particle * particle) -> 
double {
 
  727          if (particle->getParticleSource() != Particle::EParticleSourceObject::c_Kink) 
return Const::doubleNaN;
 
  728          const Kink* kink = particle->getKink();
 
  730          const Track* motherTrack = kink->getMotherTrack();
 
  732          Particle tmpParticle(motherTrack->getRelated<MCParticle>());
 
  733          auto var_result = var->function(&tmpParticle);
 
  734          if (std::holds_alternative<double>(var_result))
 
  736            return std::get<double>(var_result);
 
  737          } 
else if (std::holds_alternative<int>(var_result))
 
  739            return std::get<int>(var_result);
 
  740          } 
else if (std::holds_alternative<bool>(var_result))
 
  742            return std::get<bool>(var_result);
 
  750        B2FATAL(
"Wrong number of arguments for meta function kinkPairMotherMC");
 
  754    const MCParticle* kinkPairMotherMCParticle(
const Particle* part)
 
  756      const Kink* kink = part->getKink();
 
  757      if (!kink) 
return nullptr;
 
  759      const Track* motherTrack = kink->getMotherTrack();
 
  760      const Track* daughterTrack = kink->getDaughterTrack();
 
  762      if (motherTrack == daughterTrack) 
return nullptr;
 
  764      return motherTrack->getRelated<MCParticle>();
 
  767    double kinkPairMotherMCPXAtDecayVertex(
const Particle* part)
 
  769      const MCParticle* motherMCParticle = kinkPairMotherMCParticle(part);
 
  771      return kinkMotherMCP4AtDecayVertex(motherMCParticle).X();
 
  774    double kinkPairMotherMCPYAtDecayVertex(
const Particle* part)
 
  776      const MCParticle* motherMCParticle = kinkPairMotherMCParticle(part);
 
  778      return kinkMotherMCP4AtDecayVertex(motherMCParticle).Y();
 
  781    double kinkPairMotherMCPZAtDecayVertex(
const Particle* part)
 
  783      const MCParticle* motherMCParticle = kinkPairMotherMCParticle(part);
 
  785      return kinkMotherMCP4AtDecayVertex(motherMCParticle).Z();
 
  788    double kinkPairMotherMCPTAtDecayVertex(
const Particle* part)
 
  790      const MCParticle* motherMCParticle = kinkPairMotherMCParticle(part);
 
  792      return sqrt(kinkMotherMCP4AtDecayVertex(motherMCParticle).Vect().Perp2());
 
  795    double kinkPairMotherMCPAtDecayVertex(
const Particle* part)
 
  797      const MCParticle* motherMCParticle = kinkPairMotherMCParticle(part);
 
  799      return sqrt(kinkMotherMCP4AtDecayVertex(motherMCParticle).Vect().Mag2());
 
  802    double kinkPairMotherMCEAtDecayVertex(
const Particle* part)
 
  804      const MCParticle* motherMCParticle = kinkPairMotherMCParticle(part);
 
  806      return kinkMotherMCP4AtDecayVertex(motherMCParticle).E();
 
  812    VARIABLE_GROUP(
"Kink");
 
  817    REGISTER_VARIABLE(
"kinkVertexX", kinkVertexX, 
"x coordinate of kink vertex");
 
  818    REGISTER_VARIABLE(
"kinkVertexY", kinkVertexY, 
"y coordinate of kink vertex");
 
  819    REGISTER_VARIABLE(
"kinkVertexZ", kinkVertexZ, 
"z coordinate of kink vertex");
 
  820    REGISTER_VARIABLE(
"kinkFilterID", kinkFilterID, 
"Filter ID with which kink was preselected");
 
  821    REGISTER_VARIABLE(
"kinkCombinedFitResultFlag", kinkCombinedFitResultFlag, 
"Flag of the combined kink fit result");
 
  822    REGISTER_VARIABLE(
"kinkCombinedFitResultFlagB1", kinkCombinedFitResultFlagBit1,
 
  823                      "The first bit of the flag of the combined kink fit result");
 
  824    REGISTER_VARIABLE(
"kinkCombinedFitResultFlagB2", kinkCombinedFitResultFlagBit2,
 
  825                      "The second bit of the flag of the combined kink fit result");
 
  826    REGISTER_VARIABLE(
"kinkCombinedFitResultFlagB3", kinkCombinedFitResultFlagBit3,
 
  827                      "The third bit of the flag of the combined kink fit result");
 
  828    REGISTER_VARIABLE(
"kinkCombinedFitResultFlagB4", kinkCombinedFitResultFlagBit4,
 
  829                      "The fourth bit of the flag of the combined kink fit result");
 
  830    REGISTER_VARIABLE(
"kinkSplitTrackDistanceAtVertexFlag", kinkSplitTrackDistanceAtVertexFlag,
 
  831                      "Flag showing if the split kink failed the distance criteria at the kink vertex");
 
  832    REGISTER_VARIABLE(
"kinkNumberOfReassignedHits", kinkNumberOfReassignedHits,
 
  833                      "Number of reassigned hits between kink mother and daughter tracks");
 
  834    REGISTER_VARIABLE(
"kinkIsSameCharge", kinkIsSameCharge,
 
  835                      "Check if charges of mother and daughter tracks are the same");
 
  838    REGISTER_VARIABLE(
"kinkDaughterMomentumInMotherRestFrame", kinkDaughterMomentumInMotherRF,
 
  839                      "Kink daughter momentum in mother rest frame with default pair of mass hypotheses," 
  840                      " set by a user in the decay string");
 
  841    REGISTER_VARIABLE(
"kinkDaughterCosAngleInMotherRestFrame", kinkDaughterCosThetaInMotherRF,
 
  842                      "Kink daughter direction in mother rest frame with respect to mother momentum direction in the lab frame" 
  843                      " with default pair of mass hypotheses, set by a user in the decay string");
 
  844    REGISTER_VARIABLE(
"kinkDaughterMomentumInMotherRestFrameKPiHypothesis", kinkDaughterMomentumInMotherRFKPi,
 
  845                      "Kink daughter momentum in mother rest frame with pion and kaon mass hypotheses");
 
  846    REGISTER_VARIABLE(
"kinkDaughterCosAngleInMotherRestFrameKPiHypothesis", kinkDaughterCosThetaInMotherRFKPi,
 
  847                      "Kink daughter direction in mother rest frame with respect to mother momentum direction in the lab frame" 
  848                      " with pion and kaon mass hypotheses");
 
  849    REGISTER_VARIABLE(
"kinkDaughterMomentumInMotherRestFrameKMuHypothesis", kinkDaughterMomentumInMotherRFKMu,
 
  850                      "Kink daughter momentum in mother rest frame with muon and kaon mass hypotheses");
 
  851    REGISTER_VARIABLE(
"kinkDaughterCosAngleInMotherRestFrameKMuHypothesis", kinkDaughterCosThetaInMotherRFKMu,
 
  852                      "Kink daughter direction in mother rest frame with respect to mother momentum direction in the lab frame" 
  853                      " with muon and kaon mass hypotheses");
 
  854    REGISTER_VARIABLE(
"kinkDaughterMomentumInMotherRestFramePiMuHypothesis", kinkDaughterMomentumInMotherRFPiMu,
 
  855                      "Kink daughter momentum in mother rest frame with muon and pion mass hypotheses");
 
  856    REGISTER_VARIABLE(
"kinkDaughterCosAngleInMotherRestFramePiMuHypothesis", kinkDaughterCosThetaInMotherRFPiMu,
 
  857                      "Kink daughter direction in mother rest frame with respect to mother momentum direction in the lab frame" 
  858                      " with muon and pion mass hypotheses");
 
  859    REGISTER_VARIABLE(
"kinkDaughterMomentumInMotherRestFrameMuEHypothesis", kinkDaughterMomentumInMotherRFMuE,
 
  860                      "Kink daughter momentum in mother rest frame with electron and muon mass hypotheses");
 
  861    REGISTER_VARIABLE(
"kinkDaughterCosAngleInMotherRestFrameMuEHypothesis", kinkDaughterCosThetaInMotherRFMuE,
 
  862                      "Kink daughter direction in mother rest frame with respect to mother momentum direction in the lab frame" 
  863                      " with electron and muon mass hypotheses");
 
  866    REGISTER_METAVARIABLE(
"kinkDaughterTrack(variable)", kinkDaughterTrack,
 
  867                          "Returns variable for the kink daughter track", Manager::VariableDataType::c_double);
 
  868    REGISTER_METAVARIABLE(
"kinkDaughterInitTrack(variable)", kinkDaughterInitTrack,
 
  869                          "Returns variable for the initial kink daughter track", Manager::VariableDataType::c_double);
 
  870    REGISTER_VARIABLE(
"kinkDaughterTrackD0AtKinkVertex", kinkDaughterTrackD0AtKinkVertex,
 
  871                      "D0 impact parameter of kink daughter track at kink vertex");
 
  872    REGISTER_VARIABLE(
"kinkDaughterTrackZ0AtKinkVertex", kinkDaughterTrackZ0AtKinkVertex,
 
  873                      "Z0 impact parameter of kink daughter track at kink vertex");
 
  874    REGISTER_VARIABLE(
"kinkDaughterPtAtKinkVertex", kinkDaughterPtAtKinkVertex,
 
  875                      "Pt of kink daughter track at kink vertex");
 
  876    REGISTER_VARIABLE(
"kinkDaughterPzAtKinkVertex", kinkDaughterPzAtKinkVertex,
 
  877                      "Pz of kink daughter track at kink vertex");
 
  878    REGISTER_VARIABLE(
"kinkDaughterPAtKinkVertex", kinkDaughterPAtKinkVertex,
 
  879                      "P of kink daughter track at kink vertex");
 
  882    REGISTER_METAVARIABLE(
"kinkMotherInitTrack(variable)", kinkMotherInitTrack,
 
  883                          "Returns variable for the initial kink mother track fit", Manager::VariableDataType::c_double);
 
  884    REGISTER_VARIABLE(
"kinkMotherTrackD0AtKinkVertex", kinkMotherTrackD0AtKinkVertex,
 
  885                      "D0 impact parameter of kink mother track at kink vertex");
 
  886    REGISTER_VARIABLE(
"kinkMotherTrackZ0AtKinkVertex", kinkMotherTrackZ0AtKinkVertex,
 
  887                      "Z0 impact parameter of kink mother track at kink vertex");
 
  888    REGISTER_VARIABLE(
"kinkMotherPtAtKinkVertex", kinkMotherPtAtKinkVertex,
 
  889                      "Pt of kink mother track at kink vertex");
 
  890    REGISTER_VARIABLE(
"kinkMotherPzAtKinkVertex", kinkMotherPzAtKinkVertex,
 
  891                      "Pz of kink mother track at kink vertex");
 
  892    REGISTER_VARIABLE(
"kinkMotherPAtKinkVertex", kinkMotherPAtKinkVertex,
 
  893                      "P of kink mother track at kink vertex");
 
  897    REGISTER_VARIABLE(
"particleIsInKink", particleIsInKink,
 
  898                      "Particle is used in a Kink object");
 
  899    REGISTER_VARIABLE(
"particleIsMotherInKink", particleIsMotherInKink,
 
  900                      "Particle is a mother in a Kink object");
 
  901    REGISTER_VARIABLE(
"particleIsDaughterInKink", particleIsDaughterInKink,
 
  902                      "Particle is a daughter in a Kink object");
 
  903    REGISTER_VARIABLE(
"particleIsSplitKink", particleIsSplitKink,
 
  904                      "Particle is a split track in a Kink object");
 
  910    REGISTER_VARIABLE(
"kinkIsMCRelated", kinkPairIsMCRelated,
 
  911                      "Mother and daughter tracks have MC relations and two of them are related");
 
  912    REGISTER_VARIABLE(
"kinkIsClone", kinkPairIsClone,
 
  913                      "Mother and daughter tracks have the same MCParticle relation");
 
  914    REGISTER_VARIABLE(
"kinkIsReal", kinkPairIsReal,
 
  915                      "Mother and daughter tracks are mother/daughter related");
 
  916    REGISTER_VARIABLE(
"kinkIsDecayInFlight", kinkPairIsDecayInFlight,
 
  917                      "Kink is a decay-in-flight");
 
  918    REGISTER_VARIABLE(
"kinkIsHadronScattering", kinkPairIsHadronScattering,
 
  919                      "Kink is a hadron scattering");
 
  922    REGISTER_VARIABLE(
"kinkDaughterMCMomentumInMotherRestFrame", kinkDaughterMomentumInMotherRFMC,
 
  923                      "Kink daughter momentum in mother rest frame MC (works only for kink created from a track pair)\n" 
  924                      "Makes sense only for real decays-in-flight; however, it is not checked here");
 
  925    REGISTER_VARIABLE(
"kinkDaughterMCCosAngleInMotherRestFrame", kinkDaughterCosThetaInMotherRFMC,
 
  926                      "Kink daughter direction in mother rest frame with respect to mother momentum direction in the lab frame" 
  927                      " MC (works only for kink created from a track pair)\n" 
  928                      "Makes sense only for real decays-in-flight; however, it is not checked here");
 
  931    REGISTER_METAVARIABLE(
"kinkPairDaughterMC(variable)", kinkPairDaughterMC,
 
  932                          "Returns MC variable for the kink daughter for kinks created from two separate tracks", Manager::VariableDataType::c_double);
 
  935    REGISTER_METAVARIABLE(
"kinkPairMotherMC(variable)", kinkPairMotherMC,
 
  936                          "Returns MC variable for the kink mother for kinks created from two separate tracks", Manager::VariableDataType::c_double);
 
  937    REGISTER_VARIABLE(
"kinkMotherMCPXAtDV", kinkPairMotherMCPXAtDecayVertex,
 
  938                      "Generated PX of the kink mother at the decay vertex for kinks created from two separate tracks");
 
  939    REGISTER_VARIABLE(
"kinkMotherMCPYAtDV", kinkPairMotherMCPYAtDecayVertex,
 
  940                      "Generated PY of the kink mother at the decay vertex for kinks created from two separate tracks");
 
  941    REGISTER_VARIABLE(
"kinkMotherMCPZAtDV", kinkPairMotherMCPZAtDecayVertex,
 
  942                      "Generated PZ of the kink mother at the decay vertex for kinks created from two separate tracks");
 
  943    REGISTER_VARIABLE(
"kinkMotherMCPTAtDV", kinkPairMotherMCPTAtDecayVertex,
 
  944                      "Generated PT of the kink mother at the decay vertex for kinks created from two separate tracks");
 
  945    REGISTER_VARIABLE(
"kinkMotherMCPAtDV", kinkPairMotherMCPAtDecayVertex,
 
  946                      "Generated P of the kink mother at the decay vertex for kinks created from two separate tracks");
 
  947    REGISTER_VARIABLE(
"kinkMotherMCEAtDV", kinkPairMotherMCEAtDecayVertex,
 
  948                      "Generated E of the kink mother at the decay vertex for kinks created from two separate tracks");
 
static ROOT::Math::XYZVector getFieldInTesla(const ROOT::Math::XYZVector &pos)
return the magnetic field at a given position in Tesla.
static const ChargedStable muon
muon particle
static const ChargedStable pion
charged pion particle
static const double doubleNaN
quiet_NaN
static const ChargedStable kaon
charged kaon particle
static const ChargedStable electron
electron particle
std::function< VarVariant(const Particle *)> FunctionPtr
functions stored take a const Particle* and return VarVariant.
const Var * getVariable(std::string name)
Get the variable belonging to the given key.
static Manager & Instance()
get singleton instance.
Abstract base class for different kinds of events.