Belle II Software  release-06-02-00
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 #include <TVector3.h>
42 
43 #include <ostream>
44 
45 using namespace Belle2;
46 using namespace TrackFindingCDC;
47 
49  const CDCTrajectorySZ& trajectorySZ)
50  : m_localOrigin(trajectory2D.getLocalOrigin())
51  , m_localHelix(trajectory2D.getLocalCircle(), trajectorySZ.getSZLine())
52  , m_flightTime(trajectory2D.getFlightTime())
53 {
54 }
55 
57  : CDCTrajectory3D(trajectory2D, CDCTrajectorySZ::basicAssumption())
58 {
59 }
60 
62  const double time,
63  const Vector3D& mom3D,
64  const double charge,
65  const double bZ)
66  : m_localOrigin(pos3D)
67  , m_localHelix(CDCBFieldUtil::absMom2DToCurvature(mom3D.xy().norm(), charge, bZ),
68  mom3D.xy().unit(),
69  0.0,
70  mom3D.cotTheta(),
71  0.0)
72  , m_flightTime(time)
73 {
74 }
75 
77  const double time,
78  const Vector3D& mom3D,
79  const double charge)
80  : CDCTrajectory3D(pos3D, time, mom3D, charge, CDCBFieldUtil::getBFieldZ(pos3D))
81 {
82 }
83 
84 CDCTrajectory3D::CDCTrajectory3D(const MCParticle& mcParticle, const double bZ)
85  : CDCTrajectory3D(Vector3D{mcParticle.getProductionVertex()},
86  mcParticle.getProductionTime(),
87  Vector3D{mcParticle.getMomentum()},
88  mcParticle.getCharge(),
89  bZ)
90 {
91 }
92 
94  : CDCTrajectory3D(Vector3D{mcParticle.getProductionVertex()},
95  mcParticle.getProductionTime(),
96  Vector3D{mcParticle.getMomentum()},
97  mcParticle.getCharge())
98 {
99 }
100 
101 CDCTrajectory3D::CDCTrajectory3D(const genfit::TrackCand& gfTrackCand, const double bZ)
102  : CDCTrajectory3D(Vector3D{gfTrackCand.getPosSeed()},
103  gfTrackCand.getTimeSeed(),
104  Vector3D{gfTrackCand.getMomSeed()},
105  gfTrackCand.getChargeSeed(),
106  bZ)
107 {
108  // Maybe push these out of this function:
109  // Indices of the cartesian coordinates
110  const int iX = 0;
111  const int iY = 1;
112  const int iZ = 2;
113  const int iPx = 3;
114  const int iPy = 4;
115  const int iPz = 5;
116 
117  const TMatrixDSym& seedCov = gfTrackCand.getCovSeed();
118  CovarianceMatrix<6> cov6 = TMatrixConversion::fromTMatrix<6>(seedCov);
119 
120  // 1. Rotate to a system where phi0 = 0
121  JacobianMatrix<6, 6> jacobianRot = JacobianMatrixUtil::zero<6, 6>();
122 
123  const double px = gfTrackCand.getStateSeed()[iPx];
124  const double py = gfTrackCand.getStateSeed()[iPy];
125  const double pt = hypot2(px, py);
126 
127  const double cosPhi0 = px / pt;
128  const double sinPhi0 = py / pt;
129 
130  // Passive rotation matrix by phi0:
131  jacobianRot(iX, iX) = cosPhi0;
132  jacobianRot(iX, iY) = sinPhi0;
133  jacobianRot(iY, iX) = -sinPhi0;
134  jacobianRot(iY, iY) = cosPhi0;
135  jacobianRot(iZ, iZ) = 1.0;
136 
137  jacobianRot(iPx, iPx) = cosPhi0;
138  jacobianRot(iPx, iPy) = sinPhi0;
139  jacobianRot(iPy, iPx) = -sinPhi0;
140  jacobianRot(iPy, iPy) = cosPhi0;
141  jacobianRot(iPz, iPz) = 1.0;
142 
143  // Apply transformation inplace
144  CovarianceMatrixUtil::transport(jacobianRot, cov6);
145 
146  // 2. Translate to perigee parameters
147  JacobianMatrix<5, 6> jacobianReduce = JacobianMatrixUtil::zero<5, 6>();
148 
149  const double invPt = 1 / pt;
150  const double invPtSquared = invPt * invPt;
151  const double pz = gfTrackCand.getStateSeed()[iPz];
152  const double alpha = CDCBFieldUtil::getAlphaFromBField(bZ);
153  const double charge = gfTrackCand.getChargeSeed();
154 
155  using namespace NHelixParameterIndices;
156  jacobianReduce(c_Curv, iPx) = charge * invPtSquared / alpha ;
157  jacobianReduce(c_Phi0, iPy) = invPt;
158  jacobianReduce(c_I, iY) = 1;
159  jacobianReduce(c_TanL, iPx) = - pz * invPtSquared;
160  jacobianReduce(c_TanL, iPz) = invPt;
161  jacobianReduce(c_Z0, iZ) = 1;
162  // Note the column corresponding to iX is completely zero as expectable.
163 
164  CovarianceMatrix<5> cov5 = CovarianceMatrixUtil::transported(jacobianReduce, cov6);
165  const HelixCovariance& helixCovariance = cov5;
166 
167  // The covariance should now be the correct 5x5 covariance matrix.
168  m_localHelix.setHelixCovariance(helixCovariance);
169 }
170 
172  : CDCTrajectory3D(gfTrackCand, CDCBFieldUtil::getBFieldZ(Vector3D{gfTrackCand.getPosSeed()}))
173 {
174 }
175 
176 namespace {
177  CovarianceMatrix<6> calculateCovarianceMatrix(const UncertainHelix& localHelix,
178  const Vector3D& momentum,
179  const ESign charge,
180  const double bZ)
181  {
182  const double impactXY = localHelix->impactXY();
183  const Vector2D& phi0Vec = localHelix->phi0Vec();
184 
185  const double cosPhi0 = phi0Vec.x();
186  const double sinPhi0 = phi0Vec.y();
187 
188  const double curvatureXY = localHelix->curvatureXY();
189  const double tanLambda = localHelix->tanLambda();
190 
191  // 0. Define indices
192  // Maybe push these out of this function:
193  // Indices of the cartesian coordinates
194  const int iX = 0;
195  const int iY = 1;
196  const int iZ = 2;
197  const int iPx = 3;
198  const int iPy = 4;
199  const int iPz = 5;
200 
201  CovarianceMatrix<5> cov5 = localHelix.helixCovariance();
202 
203  // 1. Inflat the perigee covariance to a cartesian covariance where phi0 = 0 is assumed
204  // Jacobian matrix for the translation
205  JacobianMatrix<6, 5> jacobianInflate = JacobianMatrixUtil::zero<6, 5>();
206 
207  const double alpha = CDCBFieldUtil::getAlphaFromBField(bZ);
208  const double chargeAlphaCurv = charge * alpha * curvatureXY;
209  const double chargeAlphaCurv2 = charge * alpha * std::pow(curvatureXY, 2);
210 
211  const double invChargeAlphaCurv = 1.0 / chargeAlphaCurv;
212  const double invChargeAlphaCurv2 = 1.0 / chargeAlphaCurv2;
213 
214  using namespace NHelixParameterIndices;
215  // Position
216  jacobianInflate(iX, c_Phi0) = -impactXY;
217  jacobianInflate(iY, c_I) = 1.0;
218  jacobianInflate(iZ, c_Z0) = 1.0;
219 
220  // Momentum
221  if (bZ == 0) {
222  jacobianInflate(iPx, c_Curv) = 0;
223  jacobianInflate(iPy, c_Phi0) = momentum.cylindricalR();
224  jacobianInflate(iPz, c_Curv) = 0;
225  jacobianInflate(iPz, c_TanL) = momentum.cylindricalR();
226  } else {
227  jacobianInflate(iPx, c_Curv) = invChargeAlphaCurv2;
228  jacobianInflate(iPy, c_Phi0) = - invChargeAlphaCurv;
229  jacobianInflate(iPz, c_Curv) = tanLambda * invChargeAlphaCurv2;
230  jacobianInflate(iPz, c_TanL) = - invChargeAlphaCurv;
231  }
232 
233  // Transform
234  CovarianceMatrix<6> cov6 = CovarianceMatrixUtil::transported(jacobianInflate, cov5);
235 
237  JacobianMatrix<6, 6> jacobianRot = JacobianMatrixUtil::zero<6, 6>();
238 
239  // Active rotation matrix by phi0:
240  jacobianRot(iX, iX) = cosPhi0;
241  jacobianRot(iX, iY) = -sinPhi0;
242  jacobianRot(iY, iX) = sinPhi0;
243  jacobianRot(iY, iY) = cosPhi0;
244  jacobianRot(iZ, iZ) = 1.0;
245 
246  jacobianRot(iPx, iPx) = cosPhi0;
247  jacobianRot(iPx, iPy) = -sinPhi0;
248  jacobianRot(iPy, iPx) = sinPhi0;
249  jacobianRot(iPy, iPy) = cosPhi0;
250  jacobianRot(iPz, iPz) = 1.0;
251 
252  // Apply transformation inplace
253  CovarianceMatrixUtil::transport(jacobianRot, cov6);
254 
255  // 3. Forward the covariance matrix.
256  return cov6;
257  }
258 }
259 
260 
262 {
263  Vector3D position = getSupport();
264  return fillInto(trackCand, CDCBFieldUtil::getBFieldZ(position));
265 }
266 
267 bool CDCTrajectory3D::fillInto(genfit::TrackCand& gfTrackCand, const double bZ) const
268 {
269  // Set the start parameters
270  Vector3D position = getSupport();
271  Vector3D momentum = bZ == 0 ? getFlightDirection3DAtSupport() : getMom3DAtSupport(bZ);
272  ESign charge = getChargeSign();
273 
274  // Do not propagate invalid fits, signal that the fit is invalid to the caller.
275  if (not ESignUtil::isValid(charge) or momentum.hasNAN() or position.hasNAN()) {
276  return false;
277  }
278 
279  gfTrackCand.setPosMomSeed(position, momentum, charge);
280 
281  const CovarianceMatrix<6> cov6 = calculateCovarianceMatrix(getLocalHelix(), momentum, charge, bZ);
282  TMatrixDSym covSeed = TMatrixConversion::toTMatrix(cov6);
283 
284  gfTrackCand.setCovSeed(covSeed);
285 
286  return true;
287 }
288 
290 {
291  // Set the start parameters
292  Vector3D momentum = bZ == 0 ? getFlightDirection3DAtSupport() : getMom3DAtSupport(bZ);
293  ESign charge = getChargeSign();
294  return calculateCovarianceMatrix(getLocalHelix(), momentum, charge, bZ);
295 }
296 
297 bool CDCTrajectory3D::isCurler(double factor) const
298 {
299  const CDCWireTopology& topology = CDCWireTopology::getInstance();
300  return getMaximalCylindricalR() < factor * topology.getOuterCylindricalR();
301 }
302 
304 {
305  return CDCBFieldUtil::ccwInfoToChargeSign(getLocalHelix()->circleXY().orientation());
306 }
307 
308 double CDCTrajectory3D::getAbsMom3D(const double bZ) const
309 {
310  double tanLambda = getLocalHelix()->tanLambda();
311  double factor2DTo3D = hypot2(1, tanLambda);
312  double curvatureXY = getLocalHelix()->curvatureXY();
313  double absMom2D = CDCBFieldUtil::curvatureToAbsMom2D(curvatureXY, bZ);
314  return factor2DTo3D * absMom2D;
315 }
316 
318 {
319  Vector3D position = getSupport();
320  double tanLambda = getLocalHelix()->tanLambda();
321  double factor2DTo3D = hypot2(1, tanLambda);
322  double curvatureXY = getLocalHelix()->curvatureXY();
323  double absMom2D = CDCBFieldUtil::curvatureToAbsMom2D(curvatureXY, position);
324  return factor2DTo3D * absMom2D;
325 }
326 
327 double CDCTrajectory3D::shiftPeriod(int nPeriods)
328 {
329  double arcLength2D = m_localHelix.shiftPeriod(nPeriods);
330  m_flightTime += arcLength2D / Const::speedOfLight;
331  return arcLength2D;
332 }
333 
335 {
336  return CDCTrajectory2D(getLocalOrigin().xy(),
337  getLocalHelix().uncertainCircleXY(),
338  getFlightTime());
339 }
340 
342 {
343  UncertainSZLine globalSZLine = getLocalHelix().uncertainSZLine();
344  globalSZLine.passiveMoveBy(Vector2D(0, -getLocalOrigin().z()));
345  return CDCTrajectorySZ(globalSZLine);
346 }
347 
348 
350 {
351  // Down cast since we do not necessarily wont the covariance matrix transformed as well
352  PerigeeCircle result(getLocalHelix()->circleXY());
353  result.passiveMoveBy(-getLocalOrigin().xy());
354  return result;
355 }
356 
358 {
359  return getLocalHelix().uncertainCircleXY();
360 }
361 
363 {
364  return getLocalHelix().uncertainSZLine();
365 }
366 
367 double CDCTrajectory3D::setLocalOrigin(const Vector3D& localOrigin)
368 {
369  double arcLength2D = calcArcLength2D(localOrigin);
370  double factor2DTo3D = hypot2(1, getTanLambda());
371  double arcLength3D = arcLength2D * factor2DTo3D;
372  m_flightTime += arcLength3D / Const::speedOfLight;
374  m_localOrigin = localOrigin;
375  return arcLength2D;
376 }
377 
378 std::ostream& TrackFindingCDC::operator<<(std::ostream& output, const CDCTrajectory3D& trajectory3D)
379 {
380  return output << "Local origin : " << trajectory3D.getLocalOrigin() << ", "
381  << "local helix : " << trajectory3D.getLocalHelix();
382 }
static const double speedOfLight
[cm/ns]
Definition: Const.h:575
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:32
bool hasNAN() const
Checks if one of the coordinates is NAN.
Definition: Vector3D.h:155
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.