Belle II Software development
CDCTrajectory3D.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 <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectory3D.h>
9
10#include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectory2D.h>
11#include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectorySZ.h>
12
13#include <tracking/trackFindingCDC/eventdata/trajectories/CDCBFieldUtil.h>
14
15#include <tracking/trackFindingCDC/topology/CDCWireTopology.h>
16
17#include <tracking/trackFindingCDC/geometry/UncertainHelix.h>
18#include <tracking/trackFindingCDC/geometry/Helix.h>
19#include <tracking/trackFindingCDC/geometry/HelixParameters.h>
20#include <tracking/trackFindingCDC/geometry/UncertainPerigeeCircle.h>
21#include <tracking/trackFindingCDC/geometry/UncertainSZLine.h>
22#include <tracking/trackFindingCDC/geometry/PerigeeCircle.h>
23
24#include <tracking/trackFindingCDC/geometry/Vector3D.h>
25#include <tracking/trackFindingCDC/geometry/Vector2D.h>
26
27#include <tracking/trackFindingCDC/numerics/ESign.h>
28#include <tracking/trackFindingCDC/numerics/Quadratic.h>
29
30#include <tracking/trackFindingCDC/numerics/CovarianceMatrixUtil.h>
31#include <tracking/trackFindingCDC/numerics/JacobianMatrixUtil.h>
32#include <tracking/trackFindingCDC/numerics/TMatrixConversion.h>
33
34#include <genfit/TrackCand.h>
35
36#include <mdst/dataobjects/MCParticle.h>
37
38#include <framework/gearbox/Const.h>
39
40#include <TMatrixDSym.h>
41
42#include <ostream>
43
44using namespace Belle2;
45using namespace TrackFindingCDC;
46
48 const CDCTrajectorySZ& trajectorySZ)
49 : m_localOrigin(trajectory2D.getLocalOrigin())
50 , m_localHelix(trajectory2D.getLocalCircle(), trajectorySZ.getSZLine())
51 , m_flightTime(trajectory2D.getFlightTime())
52{
53}
54
56 : CDCTrajectory3D(trajectory2D, CDCTrajectorySZ::basicAssumption())
57{
58}
59
61 const double time,
62 const Vector3D& mom3D,
63 const double charge,
64 const double bZ)
65 : m_localOrigin(pos3D)
66 , m_localHelix(CDCBFieldUtil::absMom2DToCurvature(mom3D.xy().norm(), charge, bZ),
67 mom3D.xy().unit(),
68 0.0,
69 mom3D.cotTheta(),
70 0.0)
71 , m_flightTime(time)
72{
73}
74
76 const double time,
77 const Vector3D& mom3D,
78 const double charge)
79 : CDCTrajectory3D(pos3D, time, mom3D, charge, CDCBFieldUtil::getBFieldZ(pos3D))
80{
81}
82
83CDCTrajectory3D::CDCTrajectory3D(const MCParticle& mcParticle, const double bZ)
84 : CDCTrajectory3D(Vector3D{mcParticle.getProductionVertex()},
85 mcParticle.getProductionTime(),
86 Vector3D{mcParticle.getMomentum()},
87 mcParticle.getCharge(),
88 bZ)
89{
90}
91
93 : CDCTrajectory3D(Vector3D{mcParticle.getProductionVertex()},
94 mcParticle.getProductionTime(),
95 Vector3D{mcParticle.getMomentum()},
96 mcParticle.getCharge())
97{
98}
99
100CDCTrajectory3D::CDCTrajectory3D(const genfit::TrackCand& gfTrackCand, const double bZ)
101 : CDCTrajectory3D(Vector3D{gfTrackCand.getPosSeed()},
102 gfTrackCand.getTimeSeed(),
103 Vector3D{gfTrackCand.getMomSeed()},
104 gfTrackCand.getChargeSeed(),
105 bZ)
106{
107 // Maybe push these out of this function:
108 // Indices of the cartesian coordinates
109 const int iX = 0;
110 const int iY = 1;
111 const int iZ = 2;
112 const int iPx = 3;
113 const int iPy = 4;
114 const int iPz = 5;
115
116 const TMatrixDSym& seedCov = gfTrackCand.getCovSeed();
117 CovarianceMatrix<6> cov6 = TMatrixConversion::fromTMatrix<6>(seedCov);
118
119 // 1. Rotate to a system where phi0 = 0
120 JacobianMatrix<6, 6> jacobianRot = JacobianMatrixUtil::zero<6, 6>();
121
122 const double px = gfTrackCand.getStateSeed()[iPx];
123 const double py = gfTrackCand.getStateSeed()[iPy];
124 const double pt = hypot2(px, py);
125
126 const double cosPhi0 = px / pt;
127 const double sinPhi0 = py / pt;
128
129 // Passive rotation matrix by phi0:
130 jacobianRot(iX, iX) = cosPhi0;
131 jacobianRot(iX, iY) = sinPhi0;
132 jacobianRot(iY, iX) = -sinPhi0;
133 jacobianRot(iY, iY) = cosPhi0;
134 jacobianRot(iZ, iZ) = 1.0;
135
136 jacobianRot(iPx, iPx) = cosPhi0;
137 jacobianRot(iPx, iPy) = sinPhi0;
138 jacobianRot(iPy, iPx) = -sinPhi0;
139 jacobianRot(iPy, iPy) = cosPhi0;
140 jacobianRot(iPz, iPz) = 1.0;
141
142 // Apply transformation inplace
143 CovarianceMatrixUtil::transport(jacobianRot, cov6);
144
145 // 2. Translate to perigee parameters
146 JacobianMatrix<5, 6> jacobianReduce = JacobianMatrixUtil::zero<5, 6>();
147
148 const double invPt = 1 / pt;
149 const double invPtSquared = invPt * invPt;
150 const double pz = gfTrackCand.getStateSeed()[iPz];
151 const double alpha = CDCBFieldUtil::getAlphaFromBField(bZ);
152 const double charge = gfTrackCand.getChargeSeed();
153
154 using namespace NHelixParameterIndices;
155 jacobianReduce(c_Curv, iPx) = charge * invPtSquared / alpha ;
156 jacobianReduce(c_Phi0, iPy) = invPt;
157 jacobianReduce(c_I, iY) = 1;
158 jacobianReduce(c_TanL, iPx) = - pz * invPtSquared;
159 jacobianReduce(c_TanL, iPz) = invPt;
160 jacobianReduce(c_Z0, iZ) = 1;
161 // Note the column corresponding to iX is completely zero as expectable.
162
163 CovarianceMatrix<5> cov5 = CovarianceMatrixUtil::transported(jacobianReduce, cov6);
164 const HelixCovariance& helixCovariance = cov5;
165
166 // The covariance should now be the correct 5x5 covariance matrix.
167 m_localHelix.setHelixCovariance(helixCovariance);
168}
169
170CDCTrajectory3D::CDCTrajectory3D(const genfit::TrackCand& gfTrackCand)
171 : CDCTrajectory3D(gfTrackCand, CDCBFieldUtil::getBFieldZ(Vector3D{gfTrackCand.getPosSeed()}))
172{
173}
174
175namespace {
176 CovarianceMatrix<6> calculateCovarianceMatrix(const UncertainHelix& localHelix,
177 const Vector3D& momentum,
178 const ESign charge,
179 const double bZ)
180 {
181 const double impactXY = localHelix->impactXY();
182 const Vector2D& phi0Vec = localHelix->phi0Vec();
183
184 const double cosPhi0 = phi0Vec.x();
185 const double sinPhi0 = phi0Vec.y();
186
187 const double curvatureXY = localHelix->curvatureXY();
188 const double tanLambda = localHelix->tanLambda();
189
190 // 0. Define indices
191 // Maybe push these out of this function:
192 // Indices of the cartesian coordinates
193 const int iX = 0;
194 const int iY = 1;
195 const int iZ = 2;
196 const int iPx = 3;
197 const int iPy = 4;
198 const int iPz = 5;
199
200 CovarianceMatrix<5> cov5 = localHelix.helixCovariance();
201
202 // 1. Inflat the perigee covariance to a cartesian covariance where phi0 = 0 is assumed
203 // Jacobian matrix for the translation
204 JacobianMatrix<6, 5> jacobianInflate = JacobianMatrixUtil::zero<6, 5>();
205
206 const double alpha = CDCBFieldUtil::getAlphaFromBField(bZ);
207 const double chargeAlphaCurv = static_cast<double>(charge) * alpha * curvatureXY;
208 const double chargeAlphaCurv2 = static_cast<double>(charge) * alpha * std::pow(curvatureXY, 2);
209
210 const double invChargeAlphaCurv = 1.0 / chargeAlphaCurv;
211 const double invChargeAlphaCurv2 = 1.0 / chargeAlphaCurv2;
212
213 using namespace NHelixParameterIndices;
214 // Position
215 jacobianInflate(iX, c_Phi0) = -impactXY;
216 jacobianInflate(iY, c_I) = 1.0;
217 jacobianInflate(iZ, c_Z0) = 1.0;
218
219 // Momentum
220 if (bZ == 0) {
221 jacobianInflate(iPx, c_Curv) = 0;
222 jacobianInflate(iPy, c_Phi0) = momentum.cylindricalR();
223 jacobianInflate(iPz, c_Curv) = 0;
224 jacobianInflate(iPz, c_TanL) = momentum.cylindricalR();
225 } else {
226 jacobianInflate(iPx, c_Curv) = invChargeAlphaCurv2;
227 jacobianInflate(iPy, c_Phi0) = - invChargeAlphaCurv;
228 jacobianInflate(iPz, c_Curv) = tanLambda * invChargeAlphaCurv2;
229 jacobianInflate(iPz, c_TanL) = - invChargeAlphaCurv;
230 }
231
232 // Transform
233 CovarianceMatrix<6> cov6 = CovarianceMatrixUtil::transported(jacobianInflate, cov5);
234
236 JacobianMatrix<6, 6> jacobianRot = JacobianMatrixUtil::zero<6, 6>();
237
238 // Active rotation matrix by phi0:
239 jacobianRot(iX, iX) = cosPhi0;
240 jacobianRot(iX, iY) = -sinPhi0;
241 jacobianRot(iY, iX) = sinPhi0;
242 jacobianRot(iY, iY) = cosPhi0;
243 jacobianRot(iZ, iZ) = 1.0;
244
245 jacobianRot(iPx, iPx) = cosPhi0;
246 jacobianRot(iPx, iPy) = -sinPhi0;
247 jacobianRot(iPy, iPx) = sinPhi0;
248 jacobianRot(iPy, iPy) = cosPhi0;
249 jacobianRot(iPz, iPz) = 1.0;
250
251 // Apply transformation inplace
252 CovarianceMatrixUtil::transport(jacobianRot, cov6);
253
254 // 3. Forward the covariance matrix.
255 return cov6;
256 }
257}
258
259
260bool CDCTrajectory3D::fillInto(genfit::TrackCand& trackCand) const
261{
262 Vector3D position = getSupport();
263 return fillInto(trackCand, CDCBFieldUtil::getBFieldZ(position));
264}
265
266bool CDCTrajectory3D::fillInto(genfit::TrackCand& gfTrackCand, const double bZ) const
267{
268 // Set the start parameters
269 Vector3D position = getSupport();
270 Vector3D momentum = bZ == 0 ? getFlightDirection3DAtSupport() : getMom3DAtSupport(bZ);
271 ESign charge = getChargeSign();
272
273 // Do not propagate invalid fits, signal that the fit is invalid to the caller.
274 if (not ESignUtil::isValid(charge) or momentum.hasNAN() or position.hasNAN()) {
275 return false;
276 }
277
278 gfTrackCand.setPosMomSeed(position, momentum, charge);
279
280 const CovarianceMatrix<6> cov6 = calculateCovarianceMatrix(getLocalHelix(), momentum, charge, bZ);
281 TMatrixDSym covSeed = TMatrixConversion::toTMatrix(cov6);
282
283 gfTrackCand.setCovSeed(covSeed);
284
285 return true;
286}
287
289{
290 // Set the start parameters
291 Vector3D momentum = bZ == 0 ? getFlightDirection3DAtSupport() : getMom3DAtSupport(bZ);
292 ESign charge = getChargeSign();
293 return calculateCovarianceMatrix(getLocalHelix(), momentum, charge, bZ);
294}
295
296bool CDCTrajectory3D::isCurler(double factor) const
297{
299 return getMaximalCylindricalR() < factor * topology.getOuterCylindricalR();
300}
301
303{
304 return CDCBFieldUtil::ccwInfoToChargeSign(getLocalHelix()->circleXY().orientation());
305}
306
307double CDCTrajectory3D::getAbsMom3D(const double bZ) const
308{
309 double tanLambda = getLocalHelix()->tanLambda();
310 double factor2DTo3D = hypot2(1, tanLambda);
311 double curvatureXY = getLocalHelix()->curvatureXY();
312 double absMom2D = CDCBFieldUtil::curvatureToAbsMom2D(curvatureXY, bZ);
313 return factor2DTo3D * absMom2D;
314}
315
317{
318 Vector3D position = getSupport();
319 double tanLambda = getLocalHelix()->tanLambda();
320 double factor2DTo3D = hypot2(1, tanLambda);
321 double curvatureXY = getLocalHelix()->curvatureXY();
322 double absMom2D = CDCBFieldUtil::curvatureToAbsMom2D(curvatureXY, position);
323 return factor2DTo3D * absMom2D;
324}
325
327{
328 double arcLength2D = m_localHelix.shiftPeriod(nPeriods);
329 m_flightTime += arcLength2D / Const::speedOfLight;
330 return arcLength2D;
331}
332
334{
335 return CDCTrajectory2D(getLocalOrigin().xy(),
336 getLocalHelix().uncertainCircleXY(),
337 getFlightTime());
338}
339
341{
343 globalSZLine.passiveMoveBy(Vector2D(0, -getLocalOrigin().z()));
344 return CDCTrajectorySZ(globalSZLine);
345}
346
347
349{
350 // Down cast since we do not necessarily won't the covariance matrix transformed as well
351 PerigeeCircle result(getLocalHelix()->circleXY());
352 result.passiveMoveBy(-getLocalOrigin().xy());
353 return result;
354}
355
357{
359}
360
362{
364}
365
367{
368 double arcLength2D = calcArcLength2D(localOrigin);
369 double factor2DTo3D = hypot2(1, getTanLambda());
370 double arcLength3D = arcLength2D * factor2DTo3D;
371 m_flightTime += arcLength3D / Const::speedOfLight;
373 m_localOrigin = localOrigin;
374 return arcLength2D;
375}
376
377std::ostream& TrackFindingCDC::operator<<(std::ostream& output, const CDCTrajectory3D& trajectory3D)
378{
379 return output << "Local origin : " << trajectory3D.getLocalOrigin() << ", "
380 << "local helix : " << trajectory3D.getLocalHelix();
381}
static const double speedOfLight
[cm/ns]
Definition: Const.h:695
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
Helper functions to interact with the magnetic field.
Definition: CDCBFieldUtil.h:23
static double curvatureToAbsMom2D(double curvature, double bZ)
Conversion helper for two dimensional curvature to momenta.
static ESign ccwInfoToChargeSign(ERotation ccwInfo)
Conversion helper from clockwise or counterclockwise travel to the charge sign.
static double getBFieldZ()
Getter for the signed magnetic field strength in z direction at the origin ( in Tesla )
static double getAlphaFromBField(double bField)
Translator from magnetic field strength in Tesla to the alpha value.
Particle trajectory as it is seen in xy projection represented as a circle.
Particle full three dimensional trajectory.
UncertainPerigeeCircle getLocalCircle() const
Getter for the circle in local coordinates.
double calcArcLength2D(const Vector3D &point) const
Calculate the travel distance from the start position of the trajectory.
Vector3D m_localOrigin
Memory for local coordinate origin of the circle representing the trajectory in global coordinates.
double getMaximalCylindricalR() const
Getter for the maximal distance from the origin.
bool fillInto(genfit::TrackCand &trackCand) const
Copies the trajectory information to the Genfit track candidate.
double getAbsMom3D() const
Get the estimation for the absolute value of the transvers momentum.
CovarianceMatrix< 6 > getCartesianCovariance(double bZ) const
Convert the helix parameters to the cartesian coordinates x,y,z,px,py,pz.
PerigeeCircle getGlobalCircle() const
Getter for the circle in global coordinates.
double getFlightTime() const
Getter for the time when the particle reached the support point position.
CDCTrajectory2D getTrajectory2D() const
Getter for the two dimensional trajectory.
ESign getChargeSign() const
Gets the charge sign of the trajectory.
double shiftPeriod(int nPeriods)
Adjusts the z0 to the one that lies n periods forward.
bool isCurler(double factor=1) const
Checks if the trajectory leaves the outer radius of the CDC times the given tolerance factor.
UncertainSZLine getLocalSZLine() const
Getter for the sz line starting from the local origin.
CDCTrajectory3D()
Default constructor for ROOT compatibility.
Vector3D getFlightDirection3DAtSupport() const
Get the unit momentum at the start point of the trajectory.
CDCTrajectorySZ getTrajectorySZ() const
Getter for the sz trajectory.
const UncertainHelix & getLocalHelix() const
Getter for the helix in local coordinates.
double getTanLambda() const
Getter for the slope of z over the transverse travel distance s.
Vector3D getMom3DAtSupport() const
Get the momentum at the start point of the trajectory.
UncertainHelix m_localHelix
Memory for the generalized circle describing the trajectory in coordinates from the local origin.
double setLocalOrigin(const Vector3D &localOrigin)
Setter for the origin of the local coordinate system.
const Vector3D & getLocalOrigin() const
Getter for the origin of the local coordinate system.
double m_flightTime
Memory for the estimation of the time at which the particle arrived at the support point.
Vector3D getSupport() const
Getter for the support point of the trajectory in global coordinates, where arcLength2D = 0.
Linear trajectory in sz space.
Class representing the sense wire arrangement in the whole of the central drift chamber.
static CDCWireTopology & getInstance()
Getter for the singleton instance of the wire topology.
double getOuterCylindricalR() const
Getter for the outer radius of the outer most wire layer.
double impactXY() const
Getter for the signed distance to the z axes at the perigee point.
Definition: Helix.h:210
double tanLambda() const
Getter for the proportinality factor from arc length in xy space to z.
Definition: Helix.h:240
double curvatureXY() const
Getter for the signed curvature in the xy projection.
Definition: Helix.h:204
const Vector2D & phi0Vec() const
Getter for the direction vector in the xy projection at the perigee of the helix.
Definition: Helix.h:295
Extension of the generalized circle also caching the perigee coordinates.
Definition: PerigeeCircle.h:36
A matrix implementation to be used as an interface typ through out the track finder.
Definition: PlainMatrix.h:40
A general helix class including a covariance matrix.
const HelixCovariance & helixCovariance() const
Getter for the whole covariance matrix of the perigee parameters.
UncertainSZLine uncertainSZLine() const
Reduces the helix to an sz line carrying over the relevant parts of the convariance matrix.
void setHelixCovariance(const HelixCovariance &helixCovariance)
Setter for the whole covariance matrix of the perigee parameters.
double shiftPeriod(int nPeriods)
Adjust the arclength measure to start n periods later.
void passiveMoveBy(const Vector3D &by)
Moves the coordinate system by the vector by and calculates the new perigee and its covariance matrix...
UncertainPerigeeCircle uncertainCircleXY() const
Projects the helix into the xy plain carrying over the relevant parts of the convariance matrix.
Adds an uncertainty matrix to the circle in perigee parameterisation.
A line in sz where s is the transverse travel distance as seen in the xy projection with uncertaintie...
void passiveMoveBy(const Vector2D &bySZ)
Moves the coordinate system by the vector by and calculates the new sz line and its covariance matrix...
A two dimensional vector which is equipped with functions for correct handling of orientation relate...
Definition: Vector2D.h:32
double x() const
Getter for the x coordinate.
Definition: Vector2D.h:595
double y() const
Getter for the y coordinate.
Definition: Vector2D.h:605
A three dimensional vector.
Definition: Vector3D.h:33
bool hasNAN() const
Checks if one of the coordinates is NAN.
Definition: Vector3D.h:165
ESign
Enumeration for the distinct sign values of floating point variables.
Definition: ESign.h:27
bool isValid(ESign s)
Returns true if sign is ESign::c_Plus, ESign::c_Minus or ESign::c_Zero.
Definition: ESign.h:46
Abstract base class for different kinds of events.
static CovarianceMatrix< M > transported(const JacobianMatrix< M, N > &jacobian, const CovarianceMatrix< N > &cov)
Return a copy of the covariance matrix transported with the given jacobian matrix.
static void transport(const JacobianMatrix< N, N > &jacobian, CovarianceMatrix< N > &cov)
Transport the covariance matrix inplace with the given jacobian matrix.
static TMatrixDSym toTMatrix(const CovarianceMatrix< N > &cov)
Translate the covariance matrix to the TMatrix representation.