Belle II Software development
KlongCalculatorUtils.h
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#pragma once
10
11// dataobjects
12#include <analysis/dataobjects/Particle.h>
13#include <mdst/dataobjects/KLMCluster.h>
14#include <mdst/dataobjects/ECLCluster.h>
15#include <analysis/ClusterUtility/ClusterUtils.h>
16
17// ROOT
18#include <Math/Vector4D.h>
19
20#include <vector>
21
22namespace Belle2 {
41 static bool calculateBtoKlongX(ROOT::Math::PxPyPzEVector& BMomentum,
42 ROOT::Math::PxPyPzEVector& KMomentum,
43 const std::vector<Particle*> daughters,
44 const double m_b,
45 int& idx)
46 {
47
48 bool k_check = false;
49 ROOT::Math::PxPyPzEVector klDaughters; // 4-vector of K_L
50 ROOT::Math::PxPyPzEVector pDaughters; // 4-vector of other daughters
51 double m_j = 0;
52 for (auto daughter : daughters) {
53 if (daughter->getPDGCode() == Const::Klong.getPDGCode()) {
54 if (k_check)
55 B2FATAL("More than one K_L is detected! This tool accepts only one K_L in the final state.");
56
57 const Belle2::KLMCluster* klm_cluster = daughter->getKLMCluster();
58 if (klm_cluster)
59 klDaughters = klm_cluster->getMomentum();
60 else {
61 const Belle2::ECLCluster* ecl_cluster = daughter->getECLCluster();
62 if (ecl_cluster) {
63 ClusterUtils clutls;
65 } else {
66 B2ERROR("K_L candidate must have related KLM or ECL cluster!");
67 }
68 }
69 k_check = true;
70 } else {
71 pDaughters += daughter->get4Vector();
72
73 // if there is only two daughter (e.g. K_L J/psi), use the PDG mass of the other daughter.
74 m_j = daughter->getPDGMass();
75 idx = daughter->getArrayIndex() + idx * 100;
76 }
77 }
78
79 if (!k_check)
80 B2FATAL("This tool is meant to reconstruct decays with a K_L0 in the final state. There is no K_L0 in this decay!");
81
82 // if there are more than two daughters, use the invariant mass of sum of the other daughters.
83 if (daughters.size() == 3) {
84 m_j = pDaughters.M();
85 }
86
87 const double m_k2 = Const::Klong.getMass() * Const::Klong.getMass();
88
89 const double s_p = (klDaughters.Vect().Unit()).Dot(pDaughters.Vect());
90 const double m_sum = (m_b * m_b) - (m_j * m_j) - m_k2;
91
92 const double s_p2 = s_p * s_p;
93 const double m_sum2 = m_sum * m_sum;
94 const double s_pm = s_p * m_sum;
95 const double e_j2 = pDaughters.E() * pDaughters.E();
96
97 const double k_mag1 = (s_pm + std::sqrt(s_p2 * m_sum2 - 4 * (e_j2 - s_p2) * (e_j2 * m_k2 - m_sum2 / 4))) / (2 *
98 (e_j2 - s_p2));
99 const double k_mag2 = (s_pm - std::sqrt(s_p2 * m_sum2 - 4 * (e_j2 - s_p2) * (e_j2 * m_k2 - m_sum2 / 4))) / (2 *
100 (e_j2 - s_p2));
101
102
103 ROOT::Math::PxPyPzEVector missDaughters;
104
105 if (k_mag1 > 0)
106 missDaughters = k_mag1 * klDaughters / klDaughters.P();
107 else
108 missDaughters = k_mag2 * klDaughters / klDaughters.P();
109
110 missDaughters.SetE(std::sqrt(m_k2 + missDaughters.P2()));
111
112 if (isnan(missDaughters.P()))
113 return false;
114
115 ROOT::Math::PxPyPzEVector mom = pDaughters + missDaughters;
116 mom.SetE(std::sqrt(m_b * m_b + mom.P2()));
117 if (isnan(mom.P()))
118 return false;
119
120 KMomentum = missDaughters;
121 BMomentum = mom;
122
123 return true;
124 };
125
126 };
128}
Class to provide momentum-related information from ECLClusters.
Definition: ClusterUtils.h:36
const ROOT::Math::PxPyPzEVector Get4MomentumFromCluster(const ECLCluster *cluster, ECLCluster::EHypothesisBit hypo)
Returns four momentum vector.
Definition: ClusterUtils.cc:25
int getPDGCode() const
PDG code.
Definition: Const.h:473
double getMass() const
Particle mass.
Definition: UnitConst.cc:356
static const ParticleType Klong
K^0_L particle.
Definition: Const.h:678
ECL cluster data.
Definition: ECLCluster.h:27
@ c_neutralHadron
CR is reconstructed as a neutral hadron (N2)
KLM cluster data.
Definition: KLMCluster.h:28
Abstract base class for different kinds of events.
Utility class to calculate the Klong kinematics.
static bool calculateBtoKlongX(ROOT::Math::PxPyPzEVector &BMomentum, ROOT::Math::PxPyPzEVector &KMomentum, const std::vector< Particle * > daughters, const double m_b, int &idx)
Calculate kinematics of two body B decays containing a K_L0.