Belle II Software  release-08-01-10
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 
44 using namespace Belle2;
45 using 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 
83 CDCTrajectory3D::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 
100 CDCTrajectory3D::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 
171  : CDCTrajectory3D(gfTrackCand, CDCBFieldUtil::getBFieldZ(Vector3D{gfTrackCand.getPosSeed()}))
172 {
173 }
174 
175 namespace {
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 
261 {
262  Vector3D position = getSupport();
263  return fillInto(trackCand, CDCBFieldUtil::getBFieldZ(position));
264 }
265 
266 bool 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 
296 bool CDCTrajectory3D::isCurler(double factor) const
297 {
298  const CDCWireTopology& topology = CDCWireTopology::getInstance();
299  return getMaximalCylindricalR() < factor * topology.getOuterCylindricalR();
300 }
301 
303 {
304  return CDCBFieldUtil::ccwInfoToChargeSign(getLocalHelix()->circleXY().orientation());
305 }
306 
307 double 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 
326 double CDCTrajectory3D::shiftPeriod(int nPeriods)
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 {
342  UncertainSZLine globalSZLine = getLocalHelix().uncertainSZLine();
343  globalSZLine.passiveMoveBy(Vector2D(0, -getLocalOrigin().z()));
344  return CDCTrajectorySZ(globalSZLine);
345 }
346 
347 
349 {
350  // Down cast since we do not necessarily wont the covariance matrix transformed as well
351  PerigeeCircle result(getLocalHelix()->circleXY());
352  result.passiveMoveBy(-getLocalOrigin().xy());
353  return result;
354 }
355 
357 {
358  return getLocalHelix().uncertainCircleXY();
359 }
360 
362 {
363  return getLocalHelix().uncertainSZLine();
364 }
365 
366 double CDCTrajectory3D::setLocalOrigin(const Vector3D& localOrigin)
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 
377 std::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:686
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 stength in z direction at the origin ( in Tesla )
static double getAlphaFromBField(double bField)
Translater 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.
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 UncertainHelix & getLocalHelix() const
Getter for the helix in local coordinates.
double m_flightTime
Memory for the estimation of the time at which the particle arrived at the support point.
const Vector3D & getLocalOrigin() const
Getter for the origin of the local coordinate system.
Vector3D getSupport() const
Getter for the support point of the trajectory in global coordinates, where arcLength2D = 0.
Linear trajectory in sz space.
Class representating 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.
const Vector2D & phi0Vec() const
Getter for the direction vector in the xy projection at the perigee of the helix.
Definition: Helix.h:295
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
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.
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...
const HelixCovariance & helixCovariance() const
Getter for the whole covariance matrix of the perigee parameters.
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 handeling of orientation relat...
Definition: Vector2D.h:35
double x() const
Getter for the x coordinate.
Definition: Vector2D.h:607
double y() const
Getter for the y coordinate.
Definition: Vector2D.h:617
A three dimensional vector.
Definition: Vector3D.h:33
bool hasNAN() const
Checks if one of the coordinates is NAN.
Definition: Vector3D.h:165
Track candidate – seed values and indices.
Definition: TrackCand.h:69
void setPosMomSeed(const TVector3 &pos, const TVector3 &mom, const double charge)
sets the state to seed the track fitting.
Definition: TrackCand.cc:258
void setCovSeed(const TMatrixDSym &cov6D)
set the covariance matrix seed (6D).
Definition: TrackCand.h:175
const TMatrixDSym & getCovSeed() const
get the covariance matrix seed (6D).
Definition: TrackCand.h:131
const TVectorD & getStateSeed() const
Returns the 6D seed state; should be in global coordinates.
Definition: TrackCand.h:134
std::ostream & operator<<(std::ostream &output, const IntervalOfValidity &iov)
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
@ c_I
Constant to address the impact parameter.
@ c_Phi0
Constant to address the azimuth angle of the direction of flight.
@ c_TanL
Constant to address the tan lambda dip out of the xy plane.
@ c_Z0
Constant to address the z start position.
@ c_Curv
Constant to address the curvature in the xy plane.
Abstract base class for different kinds of events.
static void transport(const JacobianMatrix< N, N > &jacobian, CovarianceMatrix< N > &cov)
Transport the covariance matrix inplace with the given jacobian matrix.
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 TMatrixDSym toTMatrix(const CovarianceMatrix< N > &cov)
Translate the covariance matrix to the TMatrix representation.