Belle II Software  release-08-01-10
UncertainHelix.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 #include <framework/dataobjects/UncertainHelix.h>
9 
10 #include <TMatrixD.h>
11 
12 #include <cassert>
13 
14 using namespace Belle2;
15 using namespace HelixParameterIndex;
16 
18  Helix(),
19  m_covariance(5),
20  m_pValue(0)
21 {
22 }
23 
24 UncertainHelix::UncertainHelix(const ROOT::Math::XYZVector& position,
25  const ROOT::Math::XYZVector& momentum,
26  const short int charge,
27  const double bZ,
28  const TMatrixDSym& cartesianCovariance,
29  const double pValue) :
30  Helix(ROOT::Math::XYZVector(0.0, 0.0, position.Z()), momentum, charge, bZ),
31  m_covariance(cartesianCovariance), // Initialize the covariance matrix to the 6x6 covariance and reduce it afterwards
32  m_pValue(pValue)
33 {
34  // Maybe push these out of this function:
35  // Indices of the cartesian coordinates
36  const int iX = 0;
37  const int iY = 1;
38  const int iZ = 2;
39  const int iPx = 3;
40  const int iPy = 4;
41  const int iPz = 5;
42 
43  // We initialised the m_covariance to the cartesian covariance and
44  // reduce it now to the real 5x5 matrix that should be there.
45 
46  // 1. Rotate to a system where phi0 = 0
47  TMatrixD jacobianRot(6, 6);
48  jacobianRot.Zero();
49 
50  const double px = momentum.X();
51  const double py = momentum.Y();
52  const double pt = hypot(px, py);
53  const double cosPhi0 = px / pt;
54  const double sinPhi0 = py / pt;
55 
56  // Passive rotation matrix by phi0:
57  jacobianRot(iX, iX) = cosPhi0;
58  jacobianRot(iX, iY) = sinPhi0;
59  jacobianRot(iY, iX) = -sinPhi0;
60  jacobianRot(iY, iY) = cosPhi0;
61  jacobianRot(iZ, iZ) = 1.0;
62 
63  jacobianRot(iPx, iPx) = cosPhi0;
64  jacobianRot(iPx, iPy) = sinPhi0;
65  jacobianRot(iPy, iPx) = -sinPhi0;
66  jacobianRot(iPy, iPy) = cosPhi0;
67  jacobianRot(iPz, iPz) = 1.0;
68 
69  m_covariance.Similarity(jacobianRot);
70 
71  // 2. Translate to perigee parameters on the position
72  const double pz = momentum.Z();
73  const double invPt = 1 / pt;
74  const double invPtSquared = invPt * invPt;
75  const double alpha = getAlpha(bZ);
76 
77  TMatrixD jacobianToHelixParameters(5, 6);
78  jacobianToHelixParameters.Zero();
79 
80  jacobianToHelixParameters(iD0, iY) = -1;
81  jacobianToHelixParameters(iPhi0, iX) = charge * invPt / alpha;
82  jacobianToHelixParameters(iPhi0, iPy) = invPt;
83  jacobianToHelixParameters(iOmega, iPx) = -charge * invPtSquared / alpha;
84  jacobianToHelixParameters(iTanLambda, iPx) = - pz * invPtSquared;
85  jacobianToHelixParameters(iTanLambda, iPz) = invPt;
86  jacobianToHelixParameters(iZ0, iX) = - pz * invPt;
87  jacobianToHelixParameters(iZ0, iZ) = 1;
88  m_covariance.Similarity(jacobianToHelixParameters);
89 
90  // The covariance m_covariance is now the correct 5x5 covariance matrix.
91  assert(m_covariance.GetNrows() == 5);
92 
93  // 3. Extrapolate to the origin.
94  /* const double arcLength2D = */ passiveMoveBy(-position.X(), -position.Y(), 0.0);
95 }
96 
97 
99  const double& phi0,
100  const double& omega,
101  const double& z0,
102  const double& tanLambda,
103  const TMatrixDSym& covariance,
104  const double pValue) :
105  Helix(d0, phi0, omega, z0, tanLambda),
106  m_covariance(covariance),
107  m_pValue(pValue)
108 {
109 }
110 
111 
112 
113 TMatrixDSym UncertainHelix::getCartesianCovariance(const double bZ_tesla) const
114 {
115  // 0. Define indices
116  // Maybe push these out of this function:
117  // Indices of the cartesian coordinates
118  const int iX = 0;
119  const int iY = 1;
120  const int iZ = 2;
121  const int iPx = 3;
122  const int iPy = 4;
123  const int iPz = 5;
124 
125  // Transform covariance matrix
126  TMatrixD jacobianInflate(6, 5);
127  jacobianInflate.Zero();
128 
129  // 1. Inflate the perigee covariance to a cartesian covariance where phi0 == 0 is assumed
130  // The real phi0 is a simple rotation which can be handled in the next step.
131  // Jacobian matrix for the translation
132 
133  const double& d0 = getD0();
134  const double& omega = getOmega();
135  const double& tanLambda = getTanLambda();
136 
137  const double alpha = getAlpha(bZ_tesla);
138  const double absAlphaOmega = alpha * std::fabs(omega);
139  const double signedAlphaOmega2 = absAlphaOmega * omega;
140 
141  const double invAbsAlphaOmega = 1.0 / absAlphaOmega;
142  const double invSignedAlphaOmega2 = 1.0 / signedAlphaOmega2;
143 
144  // Position after the move.
145  jacobianInflate(iX, iPhi0) = d0;
146  jacobianInflate(iY, iD0) = -1.0;
147  jacobianInflate(iZ, iZ0) = 1.0;
148 
149  // Momentum
150  jacobianInflate(iPx, iOmega) = -invSignedAlphaOmega2;
151  jacobianInflate(iPy, iPhi0) = invAbsAlphaOmega;
152  jacobianInflate(iPz, iOmega) = -tanLambda * invSignedAlphaOmega2;
153  jacobianInflate(iPz, iTanLambda) = invAbsAlphaOmega;
154 
155  TMatrixDSym cov6 = m_covariance; //copy
156  cov6.Similarity(jacobianInflate);
157 
159  const double& cosPhi0 = getCosPhi0();
160  const double& sinPhi0 = getSinPhi0();
161 
162  TMatrixD jacobianRot(6, 6);
163  jacobianRot.Zero();
164 
165  // Active rotation matrix by phi0:
166  jacobianRot(iX, iX) = cosPhi0;
167  jacobianRot(iX, iY) = -sinPhi0;
168  jacobianRot(iY, iX) = sinPhi0;
169  jacobianRot(iY, iY) = cosPhi0;
170  jacobianRot(iZ, iZ) = 1.0;
171 
172  jacobianRot(iPx, iPx) = cosPhi0;
173  jacobianRot(iPx, iPy) = -sinPhi0;
174  jacobianRot(iPy, iPx) = sinPhi0;
175  jacobianRot(iPy, iPy) = cosPhi0;
176  jacobianRot(iPz, iPz) = 1.0;
177 
178  cov6.Similarity(jacobianRot);
179  return cov6;
180 }
181 
183 {
184  Helix::reverse();
185 
186  // D0, omega and tan lambda have to be taken to their opposites
187  // Phi0 is augmented by pi which does not change its covariances
188  // Z0 stays the same
189  TMatrixD jacobianReverse(5, 5);
190  jacobianReverse.UnitMatrix();
191  jacobianReverse(iD0, iD0) = -1;
192  jacobianReverse(iOmega, iOmega) = -1;
193  jacobianReverse(iTanLambda, iTanLambda) = -1;
194 
195  m_covariance.Similarity(jacobianReverse);
196 }
197 
198 double UncertainHelix::passiveMoveBy(const double& byX,
199  const double& byY,
200  const double& byZ)
201 {
202  // Move the covariance matrix first to have access to the original parameters
203  TMatrixD jacobianPassiveMove(5, 5);
204  calcPassiveMoveByJacobian(byX, byY, jacobianPassiveMove);
205  m_covariance.Similarity(jacobianPassiveMove);
206  return Helix::passiveMoveBy(byX, byY, byZ);
207 }
Helix parameter class.
Definition: Helix.h:48
Hep3Vector momentum(double dPhi=0.) const
returns momentum vector after rotating angle dPhi in phi direction.
Definition: Helix.cc:259
double cosPhi0(void) const
Return cos phi0.
Definition: Helix.h:500
double sinPhi0(void) const
Return sin phi0.
Definition: Helix.h:492
UncertainHelix()
Default constuctor initialising all members to zero.
void reverse()
Reverses the direction of travel of the helix in place.
TMatrixDSym getCartesianCovariance(const double bZ_tesla=1.5) const
Getter for the position and momentum covariance matrix.
double passiveMoveBy(const ROOT::Math::XYZVector &by)
Moves origin of the coordinate system (passive transformation) by the given vector.
TMatrixDSym m_covariance
5x5 covariance of the perigee parameters.
Abstract base class for different kinds of events.