Belle II Software  release-08-01-10
ClusterUtils.cc
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 #include <analysis/ClusterUtility/ClusterUtils.h>
10 #include <framework/logging/Logger.h>
11 
12 using namespace Belle2;
13 using namespace ROOT::Math;
14 
15 // -----------------------------------------------------------------------------
16 ClusterUtils::ClusterUtils() = default;
17 
18 // -----------------------------------------------------------------------------
20 {
21  // Use the geometry origin (0,0,0) and *not* the IP position
22  return Get4MomentumFromCluster(cluster, XYZVector(0.0, 0.0, 0.0), hypo);
23 }
24 
26 {
27 
28  // Use the default vertex from the beam parameters if none is given.
29  return Get4MomentumFromCluster(cluster, GetIPPosition(), hypo);
30 }
31 
32 const PxPyPzEVector ClusterUtils::Get4MomentumFromCluster(const ECLCluster* cluster, const XYZVector& vertex,
34 {
35 
36  // Get particle direction from vertex and reconstructed cluster position.
37  XYZVector direction(cluster->getClusterPosition().X() - vertex.X(),
38  cluster->getClusterPosition().Y() - vertex.Y(),
39  cluster->getClusterPosition().Z() - vertex.Z());
40 
41  // Always ignore mass here (even for neutral hadrons) therefore the magnitude
42  // of the momentum is equal to the cluster energy under this hypo.
43  const double E = cluster->getEnergy(hypo); //must not be changed or clusterE getters will be wrong
44  const double px = E * sin(direction.Theta()) * cos(direction.Phi());
45  const double py = E * sin(direction.Theta()) * sin(direction.Phi());
46  const double pz = E * cos(direction.Theta());
47 
48  const PxPyPzEVector l(px, py, pz, E);
49  return l;
50 }
51 
52 // -----------------------------------------------------------------------------
53 
55 {
56 
57  return GetJacobiMatrix4x6FromCluster(cluster, GetIPPosition(), hypo);
58 }
59 
60 const TMatrixD ClusterUtils::GetJacobiMatrix4x6FromCluster(const ECLCluster* cluster, const XYZVector& vertex,
62 {
63 
64  // Calculate the Jacobi matrix J = dpx/dE dpx/dphi dpx/dtheta dpx/dx dpy/dy dpz/dz
65  // ...
66  // dpx/dE dE/dphi dE/dtheta dpx/dx dE/dy dE/dz
67  TMatrixD jacobian(4, 6);
68 
69  const double R = cluster->getR();
70  const double energy = cluster->getEnergy(hypo);
71  const double theta = cluster->getTheta();
72  const double phi = cluster->getPhi();
73 
74  const double st = sin(theta);
75  const double ct = cos(theta);
76  const double sp = sin(phi);
77  const double cp = cos(phi);
78 
79  const double clx = R * st * cp; // cluster position x
80  const double cly = R * st * sp; // cluster position y
81  const double clz = R * ct; // cluster position z
82 
83  const double vx = vertex.X(); // vertex position x
84  const double vy = vertex.Y(); // vertex position y
85  const double vz = vertex.Z(); // vertex position z
86 
87  const double dx = clx - vx; // direction vector x
88  const double dy = cly - vy; // direction vector y
89  const double dz = clz - vz; // direction vector z
90  const double dx2 = dx * dx; // direction vector x squared
91  const double dy2 = dy * dy; // direction vector y squared
92  const double dz2 = dz * dz; // direction vector z squared
93 
94  const double r2 = (dx * dx + dy * dy + dz * dz);
95  const double r12 = sqrt(r2);
96  const double r32 = pow(r2, 1.5);
97 
98  // px = E * dx/r
99  jacobian(0, 0) = dx / r12; // dpx/dE
100  jacobian(0, 1) = -energy * R * ((dx * dy * cp) + ((dy2 + dz2) * sp)) * st / (r32); // dpx/dphi
101  jacobian(0, 2) = energy * R * (((dy2 + dz2) * cp * ct) - (dx * dy * ct * sp) + (dx * dz * st)) / (r32); // dpx/dtheta
102  jacobian(0, 3) = -energy * (dy2 + dz2) / (r32); // dpx/dvx
103  jacobian(0, 4) = energy * dx * dy / (r32); // dpx/dvy
104  jacobian(0, 5) = energy * dx * dz / (r32); //dpx/dvz
105 
106  // py = E * dy/r
107  jacobian(1, 0) = dy / r12; // dpy/dE
108  jacobian(1, 1) = energy * R * (((dx2 + dz2) * cp) + (dx * dy * sp)) * st / (r32); // dpy/dphi
109  jacobian(1, 2) = energy * R * ((-dx * dy * cp * ct) + ((dx2 + dz2) * ct * sp) + (dy * dz * st)) / (r32); // dpz/dtheta
110  jacobian(1, 3) = energy * dx * dy / (r32); // dpy/dvx
111  jacobian(1, 4) = -energy * (dx2 + dz2) / (r32); // dpy/dvy
112  jacobian(1, 5) = energy * dy * dz / (r32); //dpy/dvz
113 
114  // pz = E * dz/r
115  jacobian(2, 0) = dz / r12; // dpz/dE
116  jacobian(2, 1) = energy * R * dz * (-dy * cp + dx * sp) * st / (r32); // dpz/dphi
117  jacobian(2, 2) = -energy * R * ((dx * dz * cp * ct) + (dy * dz * ct * sp) + (dx2 + dy2) * st) / (r32); // dpz/dtheta
118  jacobian(2, 3) = energy * dx * dz / (r32); // dpz/dvx
119  jacobian(2, 4) = energy * dy * dz / (r32); // dpz/dvy
120  jacobian(2, 5) = -energy * (dx2 + dy2) / (r32); //dpz/ydvz
121 
122  // E
123  jacobian(3, 0) = 1.0; // dE/dE
124  jacobian(3, 1) = 0.0; // dE/dphi
125  jacobian(3, 2) = 0.0; // dE/dtheta
126  jacobian(3, 3) = 0.0; // dE/dvx
127  jacobian(3, 4) = 0.0; // dE/dvy
128  jacobian(3, 5) = 0.0; // dE/dvz
129 
130  //jacobian.Print();
131  return jacobian;
132 
133 }
134 
135 const TMatrixDSym ClusterUtils::GetCovarianceMatrix4x4FromCluster(const ECLCluster* cluster, const TMatrixD& jacobiMatrix)
136 {
137 
138  return GetCovarianceMatrix4x4FromCluster(cluster, GetIPPositionCovarianceMatrix(), jacobiMatrix);
139 }
140 
141 const TMatrixDSym ClusterUtils::GetCovarianceMatrix4x4FromCluster(const ECLCluster* cluster, const TMatrixDSym& covmatvertex,
142  const TMatrixD& jacobiMatrix)
143 {
144 
145  // Get the covariance matrix (theta, phi, energy) from the ECL cluster.
146  TMatrixDSym covmatecl = cluster->getCovarianceMatrix3x3();
147 
148  // Combine into the total covariance matrix from the ECL cluster (0..2) and the IP(3..5) as two 3x3 block matrices.
149  TMatrixDSym covmatcombined(6);
150  for (int i = 0; i < 3; i++) {
151  for (int j = 0; j <= i ; j++) {
152  covmatcombined(i, j) = covmatcombined(j, i) = covmatecl(i, j);
153  covmatcombined(i + 3, j + 3) = covmatcombined(j + 3, i + 3) = covmatvertex(i, j);
154  }
155  }
156 
157  TMatrixDSym covmatCart(4);
158  covmatCart = covmatcombined.Similarity(jacobiMatrix);
159  return covmatCart;
160 }
161 
162 // -----------------------------------------------------------------------------
163 
164 const TMatrixDSym ClusterUtils::GetCovarianceMatrix7x7FromCluster(const ECLCluster* cluster, const TMatrixD& jacobiMatrix)
165 {
166 
167  return GetCovarianceMatrix7x7FromCluster(cluster, GetIPPositionCovarianceMatrix(), jacobiMatrix);
168 }
169 
171  const TMatrixDSym& covmatvertex, const TMatrixD& jacobiMatrix)
172 {
173  TMatrixDSym covmat4x4 = GetCovarianceMatrix4x4FromCluster(cluster, covmatvertex, jacobiMatrix);
174 
175  TMatrixDSym covmatCart(7);
176 
177  // px, py, pz, E
178  for (int i = 0; i < 4; i++) {
179  for (int j = 0; j <= i ; j++) {
180  covmatCart(i, j) = covmatCart(j, i) = covmat4x4(i, j);
181  }
182  }
183 
184  // x, y, z
185  for (int i = 0; i < 3; i++) {
186  for (int j = 0; j <= i ; j++) {
187  covmatCart(i + 4, j + 4) = covmatCart(j + 4, i + 4) = covmatvertex(i, j);
188  }
189  }
190 
191  return covmatCart;
192 }
193 
194 
195 // -----------------------------------------------------------------------------
197 {
198  if (!m_beamSpotDB) {
199  B2WARNING("Beamspot not available, using (0, 0, 0) as IP position instead.");
200  return XYZVector(0.0, 0.0, 0.0);
201  } else return XYZVector(m_beamSpotDB->getIPPosition().X(), m_beamSpotDB->getIPPosition().Y(), m_beamSpotDB->getIPPosition().Z());
202 }
203 
204 // -----------------------------------------------------------------------------
206 {
207  if (!m_beamSpotDB) {
208  B2WARNING("Beam parameters not available, using ((1, 0, 0), (0, 1, 0), (0, 0, 1)) as IP covariance matrix instead.");
209 
210  TMatrixDSym covmat(3);
211  for (int i = 0; i < 3; ++i) {
212  covmat(i, i) = 1.0; // 1.0*1.0 cm^2
213  }
214  return covmat;
215  } else return m_beamSpotDB->getCovVertex();
216 }
R E
internal precision of FFTW codelets
double R
typedef autogenerated by FFTW
const TMatrixDSym GetCovarianceMatrix7x7FromCluster(const ECLCluster *cluster, const TMatrixD &jacobiMatrix)
Returns 7x7 covariance matrix (px, py, pz, E, x, y, z)
const ROOT::Math::PxPyPzEVector Get4MomentumFromCluster(const ECLCluster *cluster, ECLCluster::EHypothesisBit hypo)
Returns four momentum vector.
Definition: ClusterUtils.cc:25
const TMatrixD GetJacobiMatrix4x6FromCluster(const ECLCluster *cluster, ECLCluster::EHypothesisBit hypo)
Returns 4x6 Jacobi matrix (px, py, pz, E)
Definition: ClusterUtils.cc:54
const ROOT::Math::PxPyPzEVector GetCluster4MomentumFromCluster(const ECLCluster *cluster, ECLCluster::EHypothesisBit hypo)
Returns cluster four momentum vector.
Definition: ClusterUtils.cc:19
const TMatrixDSym GetCovarianceMatrix4x4FromCluster(const ECLCluster *cluster, const TMatrixD &jacobiMatrix)
Returns 4x4 covariance matrix (px, py, pz, E)
const TMatrixDSym GetIPPositionCovarianceMatrix()
Returns default IP position covariance matrix from beam parameters.
ClusterUtils()
Constructor.
const ROOT::Math::XYZVector GetIPPosition()
Returns default IP position from beam parameters.
ECL cluster data.
Definition: ECLCluster.h:27
EHypothesisBit
The hypothesis bits for this ECLCluster (Connected region (CR) is split using this hypothesis.
Definition: ECLCluster.h:31
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.