Belle II Software  release-08-01-10
CDCTrajectory2D.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/CDCTrajectory2D.h>
9 
10 #include <tracking/trackFindingCDC/eventdata/trajectories/CDCBFieldUtil.h>
11 
12 #include <tracking/trackFindingCDC/topology/CDCWireTopology.h>
13 #include <tracking/trackFindingCDC/topology/CDCWireLayer.h>
14 #include <tracking/trackFindingCDC/topology/WireLine.h>
15 #include <tracking/trackFindingCDC/topology/ISuperLayer.h>
16 
17 #include <tracking/trackFindingCDC/geometry/UncertainPerigeeCircle.h>
18 #include <tracking/trackFindingCDC/geometry/PerigeeCircle.h>
19 #include <tracking/trackFindingCDC/geometry/Vector3D.h>
20 #include <tracking/trackFindingCDC/geometry/Vector2D.h>
21 
22 #include <tracking/trackFindingCDC/numerics/EForwardBackward.h>
23 #include <tracking/trackFindingCDC/numerics/ESign.h>
24 #include <tracking/trackFindingCDC/numerics/Quadratic.h>
25 
26 #include <framework/gearbox/Const.h>
27 
28 #include <vector>
29 #include <utility>
30 #include <ostream>
31 #include <cmath>
32 #include <cassert>
33 
34 using namespace Belle2;
35 using namespace TrackFindingCDC;
36 
38  : m_localOrigin()
39  , m_localPerigeeCircle()
40 {
41 }
42 
44  : m_localOrigin(0.0, 0.0)
45  , m_localPerigeeCircle(perigeeCircle)
46 {
47 }
48 
50  const UncertainPerigeeCircle& localPerigeeCircle,
51  double flightTime)
52  : m_localOrigin(localOrigin)
53  , m_localPerigeeCircle(localPerigeeCircle)
54  , m_flightTime(flightTime)
55 {
56 }
57 
59  const double time,
60  const Vector2D& mom2D,
61  const double charge,
62  const double bZ)
63  : m_localOrigin(pos2D)
64  , m_localPerigeeCircle(CDCBFieldUtil::absMom2DToCurvature(mom2D.norm(), charge, bZ),
65  mom2D.unit(),
66  0.0)
67  , m_flightTime(time)
68 {
69 }
70 
72  const double time,
73  const Vector2D& mom2D,
74  const double charge)
75  : m_localOrigin(pos2D)
76  , m_localPerigeeCircle(CDCBFieldUtil::absMom2DToCurvature(mom2D.norm(), charge, pos2D),
77  mom2D.unit(),
78  0.0)
79  , m_flightTime(time)
80 {
81 }
82 
84 {
85  return not getLocalCircle()->isInvalid();
86 }
87 
89 {
90  m_localOrigin.set(0.0, 0.0);
92  m_flightTime = NAN;
93 }
94 
96 {
99 }
100 
101 
103 {
104  CDCTrajectory2D result = *this;
105  result.reverse();
106  return result;
107 }
108 
109 std::array<double, 2> CDCTrajectory2D::reconstructBothZ(const WireLine& wireLine,
110  const double distance,
111  const double z) const
112 {
113  Vector2D globalPos2D = wireLine.sagPos2DAtZ(z);
114  Vector2D movePerZ = wireLine.sagMovePerZ(z);
115 
116  Vector2D localPos2D = globalPos2D - getLocalOrigin();
117  const PerigeeCircle& localCircle = getLocalCircle();
118 
119  double fastDistance = distance != 0.0 ? localCircle.fastDistance(distance) : 0.0;
120 
121  double c = localCircle.fastDistance(localPos2D) - fastDistance;
122  double b = localCircle.gradient(localPos2D).dot(movePerZ);
123  double a = localCircle.n3() * movePerZ.normSquared();
124 
125  const std::pair<double, double> solutionsDeltaZ = solveQuadraticABC(a, b, c);
126 
127  // Put the solution of smaller deviation first
128  const std::array<double, 2> solutionsZ{solutionsDeltaZ.second + z, solutionsDeltaZ.first + z};
129  return solutionsZ;
130 }
131 
133  const double distance,
134  const double z) const
135 {
136  const std::array<double, 2> solutionsZ = reconstructBothZ(wireLine, distance, z);
137 
138  bool firstIsInCDC = (wireLine.backwardZ() < solutionsZ[0] and
139  solutionsZ[0] < wireLine.forwardZ());
140  bool secondIsInCDC = (wireLine.backwardZ() < solutionsZ[1] and
141  solutionsZ[1] < wireLine.forwardZ());
142 
143  // Prefer the solution with the smaller deviation from the given z position which is the first
144  assert(not(std::fabs(solutionsZ[0] - z) > std::fabs(solutionsZ[1] - z)));
145  const double recoZ = (firstIsInCDC or not secondIsInCDC) ? solutionsZ[0] : solutionsZ[1];
146  return recoZ;
147 }
148 
149 std::array<Vector3D, 2> CDCTrajectory2D::reconstructBoth3D(const WireLine& wireLine,
150  const double distance,
151  const double z) const
152 {
153  const std::array<double, 2> solutionsZ = reconstructBothZ(wireLine, distance, z);
154 
155  const Vector3D firstRecoWirePos3D = wireLine.sagPos3DAtZ(solutionsZ[0]);
156  const Vector3D secondRecoWirePos3D = wireLine.sagPos3DAtZ(solutionsZ[1]);
157  return {{{getClosest(firstRecoWirePos3D.xy()), firstRecoWirePos3D.z()},
158  {getClosest(secondRecoWirePos3D.xy()), secondRecoWirePos3D.z()}
159  }};
160 }
161 
163  const double distance,
164  const double z) const
165 {
166  const double recoZ = reconstructZ(wireLine, distance, z);
167  const Vector3D recoWirePos2D = wireLine.sagPos3DAtZ(recoZ);
168  return Vector3D(getClosest(recoWirePos2D.xy()), recoZ);
169 }
170 
172 {
173  return getLocalCircle()->closest(point - getLocalOrigin()) + getLocalOrigin();
174 }
175 
176 ISuperLayer CDCTrajectory2D::getISuperLayerAfter(ISuperLayer iSuperLayer, bool movingOutward) const
177 {
179 
180  ISuperLayer minimalISuperLayer = getMinimalISuperLayer();
181  ISuperLayer maximalISuperLayer = getMaximalISuperLayer();
182  if (minimalISuperLayer == maximalISuperLayer) return ISuperLayerUtil::c_Invalid; // No next super layer to go to
183  if (iSuperLayer == minimalISuperLayer) return ISuperLayerUtil::getNextOutwards(iSuperLayer);
184  if (iSuperLayer == maximalISuperLayer) return ISuperLayerUtil::getNextInwards(iSuperLayer);
185 
186  if (movingOutward) {
187  return ISuperLayerUtil::getNextOutwards(iSuperLayer);
188  } else {
189  return ISuperLayerUtil::getNextInwards(iSuperLayer);
190  }
191 }
192 
193 ISuperLayer CDCTrajectory2D::getISuperLayerAfterStart(bool movingOutward) const
194 {
195  ISuperLayer iSuperLayer = getStartISuperLayer();
196  return getISuperLayerAfter(iSuperLayer, movingOutward);
197 }
198 
199 ISuperLayer CDCTrajectory2D::getISuperLayerAfterStart(const EForwardBackward forwardBackwardInfo) const
200 {
201  bool movingOutward = isMovingOutward();
202  if (forwardBackwardInfo == EForwardBackward::c_Backward) {
203  movingOutward = not movingOutward;
204  }
205  return getISuperLayerAfterStart(movingOutward);
206 }
207 
209 {
210  return getISuperLayerAfterStart(EForwardBackward::c_Forward);
211 }
212 
214 {
215  return getISuperLayerAfterStart(EForwardBackward::c_Backward);
216 }
217 
218 ISuperLayer CDCTrajectory2D::getAxialISuperLayerAfterStart(const EForwardBackward forwardBackwardInfo) const
219 {
220  bool movingOutward = isMovingOutward();
221  if (forwardBackwardInfo == EForwardBackward::c_Backward) {
222  movingOutward = not movingOutward;
223  }
224  ISuperLayer startISuperLayer = getStartISuperLayer();
225  if (ISuperLayerUtil::isInvalid(startISuperLayer)) return ISuperLayerUtil::c_Invalid;
226 
227  ISuperLayer nextISuperLayer = getISuperLayerAfter(startISuperLayer, movingOutward);
228  if (ISuperLayerUtil::isInvalid(nextISuperLayer)) return ISuperLayerUtil::c_Invalid;
229  if (ISuperLayerUtil::isAxial(nextISuperLayer)) return nextISuperLayer;
230 
231  ISuperLayer iSuperLayerStep = nextISuperLayer - startISuperLayer;
232  assert(std::abs(iSuperLayerStep) == 1);
233  bool nextMovingOutward = iSuperLayerStep > 0;
234  return getISuperLayerAfter(nextISuperLayer, nextMovingOutward);
235 }
236 
238 {
239  return getAxialISuperLayerAfterStart(EForwardBackward::c_Forward);
240 }
241 
243 {
244  return getAxialISuperLayerAfterStart(EForwardBackward::c_Backward);
245 }
246 
248 {
249  double maximalCylindricalR = getMaximalCylindricalR();
250  return CDCWireTopology::getInstance().getISuperLayerAtCylindricalR(maximalCylindricalR);
251 }
252 
254 {
255  double startCylindricalR = getLocalOrigin().cylindricalR();
257 }
258 
260 {
261  double minimalCylindricalR = getMinimalCylindricalR();
262  return CDCWireTopology::getInstance().getISuperLayerAtCylindricalR(minimalCylindricalR);
263 }
264 
265 bool CDCTrajectory2D::isCurler(double factor) const
266 {
267  const CDCWireTopology& topology = CDCWireTopology::getInstance();
268  return getMaximalCylindricalR() < factor * topology.getOuterCylindricalR();
269 }
270 
271 bool CDCTrajectory2D::isOriginer(double factor) const
272 {
273  const CDCWireTopology& topology = CDCWireTopology::getInstance();
274  return getMinimalCylindricalR() < factor * topology.getInnerCylindricalR();
275 }
276 
277 
279 {
280  return CDCBFieldUtil::ccwInfoToChargeSign(getLocalCircle()->orientation());
281 }
282 
283 double CDCTrajectory2D::getAbsMom2D(const double bZ) const
284 {
285  return CDCBFieldUtil::curvatureToAbsMom2D(getLocalCircle()->curvature(), bZ);
286 }
287 
289 {
290  Vector2D position = getSupport();
291  return CDCBFieldUtil::curvatureToAbsMom2D(getLocalCircle()->curvature(), position);
292 }
293 
295 {
296  const CDCWireTopology& topology = CDCWireTopology::getInstance();
297  const CDCWireLayer& innerMostLayer = topology.getWireLayers().front();
298  double innerCylindricalR = innerMostLayer.getInnerCylindricalR();
299 
300  const Vector2D support = getSupport();
301  const PerigeeCircle globalCircle = getGlobalCircle();
302  if (support.cylindricalR() < innerCylindricalR) {
303  // If we start within the inner volumn of the CDC we want the trajectory to enter the CDC
304  // and not stop at first intersection with the inner wall.
305  // Therefore we take the inner exit that comes after the apogee (far point of the circle).
306  const Vector2D apogee = globalCircle.apogee();
307  return globalCircle.atCylindricalRForwardOf(apogee, innerCylindricalR);
308 
309  } else {
310  return globalCircle.atCylindricalRForwardOf(support, innerCylindricalR);
311  }
312 }
313 
315 {
316  const CDCWireTopology& topology = CDCWireTopology::getInstance();
317  const CDCWireLayer& outerMostLayer = topology.getWireLayers().back();
318  double outerCylindricalR = outerMostLayer.getOuterCylindricalR() * factor;
319 
320  const Vector2D support = getSupport();
321  const PerigeeCircle globalCircle = getGlobalCircle();
322  if (support.cylindricalR() > outerCylindricalR) {
323  // If we start outside of the volume of the CDC we want the trajectory to enter the CDC
324  // and not stop at first intersection with the outer wall.
325  // Therefore we take the outer exit that comes after the perigee.
326  const Vector2D perigee = globalCircle.perigee();
327  return globalCircle.atCylindricalRForwardOf(perigee, outerCylindricalR);
328 
329  } else {
330  return getGlobalCircle().atCylindricalRForwardOf(support, outerCylindricalR);
331  }
332 }
333 
335 {
336  const Vector2D outerExit = getOuterExit();
337  const Vector2D innerExit = getInnerExit();
338  const Vector2D localExit = getLocalCircle()->chooseNextForwardOf(Vector2D(0, 0),
339  outerExit - getLocalOrigin(),
340  innerExit - getLocalOrigin());
341  return localExit + getLocalOrigin();
342 }
343 
345  const Vector2D& mom2D,
346  const double charge)
347 {
348  m_localOrigin = pos2D;
349  double curvature = CDCBFieldUtil::absMom2DToCurvature(mom2D.norm(), charge, pos2D);
350  Vector2D phiVec = mom2D.unit();
351  double impact = 0.0;
352  m_localPerigeeCircle = UncertainPerigeeCircle(curvature, phiVec, impact);
353 }
354 
355 double CDCTrajectory2D::setLocalOrigin(const Vector2D& localOrigin)
356 {
357  double arcLength2D = calcArcLength2D(localOrigin);
358  m_flightTime += arcLength2D / Const::speedOfLight;
360  m_localOrigin = localOrigin;
361  return arcLength2D;
362 }
363 
364 
365 std::ostream& TrackFindingCDC::operator<<(std::ostream& output, const CDCTrajectory2D& trajectory2D)
366 {
367  return output << "Local origin : " << trajectory2D.getLocalOrigin() << ", "
368  << "local circle : " << trajectory2D.getLocalCircle();
369 }
static const double speedOfLight
[cm/ns]
Definition: Const.h:686
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 absMom2DToCurvature(double absMom2D, double charge, double bZ)
Conversion helper for momenta to two dimensional curvature.
Particle trajectory as it is seen in xy projection represented as a circle.
void setPosMom2D(const Vector2D &pos2D, const Vector2D &mom2D, double charge)
Setter for start point and momentum at the start point subjected to the charge sign.
double getMaximalCylindricalR() const
Getter for the maximal distance from the origin.
CDCTrajectory2D reversed() const
Returns the reverse trajectory as a copy.
PerigeeCircle getGlobalCircle() const
Getter for the circle in global coordinates.
ISuperLayer getAxialISuperLayerAfterStart(EForwardBackward forwardBackwardInfo) const
Indicates which axial superlayer is traversed after the one, where the start point of the trajectory ...
Vector2D getOuterExit(double factor=1) const
Calculates the point where the trajectory meets the outer wall of the CDC.
ISuperLayer getISuperLayerAfter(ISuperLayer iSuperLayer, bool movingOutward) const
Returns which superlayer is traversed after the current one following the trajectory outward or inwar...
std::array< double, 2 > reconstructBothZ(const WireLine &wireLine, double distance=0.0, double z=0) const
Gives the two z postions where the given drift circle on the wire line touches the trajectory.
void reverse()
Reverses the trajectory in place.
bool isOriginer(double factor=1) const
Checks if the trajectory intersects with the inner radius of the CDC time the given tolerance factor.
ISuperLayer getStartISuperLayer() const
Indicates the superlayer the trajectory starts in.
Vector2D m_localOrigin
Memory for local coordinate origin of the circle representing the trajectory in global coordinates.
double setLocalOrigin(const Vector2D &localOrigin)
Setter for the origin of the local coordinate system.
const Vector2D & getLocalOrigin() const
Getter for the origin of the local coordinate system.
double calcArcLength2D(const Vector2D &point) const
Calculate the travel distance from the start position of the trajectory.
ESign getChargeSign() const
Gets the charge sign of the trajectory.
ISuperLayer getISuperLayerAfterStart(bool movingOutward) const
Returns which superlayer is traversed after the current one following the trajectory outward or inwar...
ISuperLayer getPreviousISuperLayer() const
Indicates which superlayer the trajectory traverses before the one, where the start point of the traj...
bool isCurler(double factor=1) const
Checks if the trajectory leaves the outer radius of the CDC times the given tolerance factor.
ISuperLayer getMinimalISuperLayer() const
Indicates the minimal superlayer the trajectory traverses.
double reconstructZ(const WireLine &wireLine, double distance=0.0, double z=0) const
Gives the one z postions within the CDC closest to the given z where the given drift circle on the wi...
bool isFitted() const
Checks if the circle is already set to a valid value.
Vector2D getSupport() const
Get the support point of the trajectory in global coordinates.
double getMinimalCylindricalR() const
Getter for the minimal distance from the origin - same as absolute value of the impact parameter.
ISuperLayer getPreviousAxialISuperLayer() const
Indicates which axial superlayer the trajectory traverses before the one, where the start point of th...
std::array< Vector3D, 2 > reconstructBoth3D(const WireLine &wireLine, double distance=0.0, double z=0) const
Gives the two three dimensional points where the drift circle touches the wire line.
ISuperLayer getMaximalISuperLayer() const
Indicates the maximal superlayer the trajectory traverses.
Vector2D getClosest(const Vector2D &point) const
Calculates the closest approach on the trajectory to the given point.
Vector2D getExit() const
Calculates the point where the trajectory leaves the CDC.
double getAbsMom2D() const
Get the estimation for the absolute value of the transvers momentum.
UncertainPerigeeCircle m_localPerigeeCircle
Memory for the generalized circle describing the trajectory in coordinates from the local origin.
CDCTrajectory2D()
Default constructor for ROOT compatibility.
void clear()
Clears all information from this trajectoy.
const UncertainPerigeeCircle & getLocalCircle() const
Getter for the cirlce in local coordinates.
bool isMovingOutward() const
Indicates if the trajectory is moving outwards or inwards (to or away from the origin) from the start...
ISuperLayer getNextISuperLayer() const
Indicates which superlayer the trajectory traverses after the one, where the start point of the traje...
ISuperLayer getNextAxialISuperLayer() const
Indicates which axial superlayer the trajectory traverses after the one, where the start point of the...
Vector2D getInnerExit() const
Calculates the point where the trajectory meets the inner wall of the CDC.
Vector3D reconstruct3D(const WireLine &wireLine, double distance=0.0, double z=0) const
Gives the one three dimensional postions within the CDC closest to the given z where the given drift ...
double m_flightTime
Memory for the estimation of the time at which the particle arrived at the support point.
Class representating a sense wire layer in the central drift chamber.
Definition: CDCWireLayer.h:42
double getInnerCylindricalR() const
Getter for inner radius of the layer as taken from the CDCGeometryPar.
Definition: CDCWireLayer.h:245
double getOuterCylindricalR() const
Getter for outer radius of the layer as taken from the CDCGeometryPar.
Definition: CDCWireLayer.h:249
Class representating the sense wire arrangement in the whole of the central drift chamber.
ISuperLayer getISuperLayerAtCylindricalR(double cylindricalR)
Returns the logical superlayer number at the given radius.
double getInnerCylindricalR() const
Getter for the inner radius of the inner most wire layer.
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 std::vector< Belle2::TrackFindingCDC::CDCWireLayer > & getWireLayers() const
Getter for the underlying storing layer vector.
Extension of the generalized circle also caching the perigee coordinates.
Definition: PerigeeCircle.h:36
double fastDistance(const Vector2D &point) const
Getter for the linearised distance measure to a point.
Vector2D perigee() const
Getter for the perigee point.
Vector2D gradient(const Vector2D &point) const
Gradient of the distance field, hence indicates the direction of increasing distance.
Vector2D atCylindricalRForwardOf(const Vector2D &startPoint, double cylindricalR) const
Approach on the circle with the given cylindrical radius that lies in the forward direction of a star...
bool isInvalid() const
Indicates if all circle parameters are zero.
Vector2D chooseNextForwardOf(const Vector2D &start, const Vector2D &end1, const Vector2D &end2) const
Returns the one of two end point which is first reached from the given start if one stricly follows t...
Vector2D apogee() const
Getter for the apogee of the circle. If it was a line both components will be infinity.
double n3() const
Getter for the generalised circle parameter n3.
Vector2D closest(const Vector2D &point) const
Calculates the point of closest approach on the circle to the given point.
Adds an uncertainty matrix to the circle in perigee parameterisation.
void reverse()
Flips the orientation of the circle in place.
void passiveMoveBy(const Vector2D &by)
Moves the coordinate system by the vector by and calculates the new perigee and its covariance matrix...
void invalidate()
Sets all circle parameters to zero including the covariance matrix.
A two dimensional vector which is equipped with functions for correct handeling of orientation relat...
Definition: Vector2D.h:35
double dot(const Vector2D &rhs) const
Calculates the two dimensional dot product.
Definition: Vector2D.h:170
void set(const double first, const double second)
Setter for both coordinate.
Definition: Vector2D.h:662
double cylindricalR() const
Gives the cylindrical radius of the vector. Same as norm()
Definition: Vector2D.h:569
double normSquared() const
Calculates .
Definition: Vector2D.h:181
Vector2D unit() const
Returns a unit vector colaligned with this.
Definition: Vector2D.h:333
double norm() const
Calculates the length of the vector.
Definition: Vector2D.h:187
A three dimensional vector.
Definition: Vector3D.h:33
const Vector2D & xy() const
Getter for the xy projected vector ( reference ! )
Definition: Vector3D.h:508
double z() const
Getter for the z coordinate.
Definition: Vector3D.h:496
A three dimensional limited line represented by its closest approach to the z-axes (reference positio...
Definition: WireLine.h:31
Vector2D sagMovePerZ(const double z) const
Gives the two dimensional position with wire sag effect of the line at the given z value.
Definition: WireLine.h:75
double backwardZ() const
Gives the backward z coodinate.
Definition: WireLine.h:134
double forwardZ() const
Gives the forward z coodinate.
Definition: WireLine.h:130
Vector3D sagPos3DAtZ(const double z) const
Gives the three dimensional position with wire sag effect of the line at the given z value.
Definition: WireLine.h:56
Vector2D sagPos2DAtZ(const double z) const
Gives the two dimensional position with wire sag effect of the line at the given z value.
Definition: WireLine.h:60
std::ostream & operator<<(std::ostream &output, const IntervalOfValidity &iov)
HepGeom::Vector3D< double > Vector3D
3D Vector
Definition: Cell.h:34
ESign
Enumeration for the distinct sign values of floating point variables.
Definition: ESign.h:27
EForwardBackward
Enumeration to represent the distinct possibilities of the right left passage information.
Abstract base class for different kinds of events.
static const ISuperLayer c_Invalid
Constant making an invalid superlayer id.
Definition: ISuperLayer.h:65
static bool isAxial(ISuperLayer iSuperLayer)
Returns if the super layer with the given id is axial.
Definition: ISuperLayer.cc:21
static ISuperLayer getNextInwards(ISuperLayer iSuperLayer)
Returns the super layer that is inside of the given super layer.
Definition: ISuperLayer.cc:63
static bool isInvalid(ISuperLayer iSuperLayer)
Indicates if the given number corresponds to a true cdc superlayer - excludes the logic ids for inner...
Definition: ISuperLayer.cc:38
static ISuperLayer getNextOutwards(ISuperLayer iSuperLayer)
Returns the super layer that is outside of the given super layer.
Definition: ISuperLayer.cc:72