Belle II Software development
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/trackingUtilities/eventdata/trajectories/CDCTrajectory2D.h>
9
10#include <tracking/trackingUtilities/eventdata/trajectories/CDCBFieldUtil.h>
11
12#include <cdc/topology/CDCWireTopology.h>
13#include <cdc/topology/CDCWireLayer.h>
14#include <cdc/topology/WireLine.h>
15#include <cdc/topology/ISuperLayer.h>
16
17#include <tracking/trackingUtilities/geometry/UncertainPerigeeCircle.h>
18#include <tracking/trackingUtilities/geometry/PerigeeCircle.h>
19#include <tracking/trackingUtilities/geometry/Vector3D.h>
20#include <tracking/trackingUtilities/geometry/Vector2D.h>
21
22#include <tracking/trackingUtilities/numerics/EForwardBackward.h>
23#include <tracking/trackingUtilities/numerics/ESign.h>
24#include <tracking/trackingUtilities/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
34using namespace Belle2;
35using namespace CDC;
36using namespace TrackingUtilities;
37
43
45 : m_localOrigin(0.0, 0.0)
46 , m_localPerigeeCircle(perigeeCircle)
47{
48}
49
51 const UncertainPerigeeCircle& localPerigeeCircle,
52 double flightTime)
53 : m_localOrigin(localOrigin)
54 , m_localPerigeeCircle(localPerigeeCircle)
55 , m_flightTime(flightTime)
56{
57}
58
60 const double time,
61 const Vector2D& mom2D,
62 const double charge,
63 const double bZ)
64 : m_localOrigin(pos2D)
65 , m_localPerigeeCircle(CDCBFieldUtil::absMom2DToCurvature(mom2D.norm(), charge, bZ),
66 mom2D.unit(),
67 0.0)
68 , m_flightTime(time)
69{
70}
71
73 const double time,
74 const Vector2D& mom2D,
75 const double charge)
76 : m_localOrigin(pos2D)
77 , m_localPerigeeCircle(CDCBFieldUtil::absMom2DToCurvature(mom2D.norm(), charge, pos2D),
78 mom2D.unit(),
79 0.0)
80 , m_flightTime(time)
81{
82}
83
85{
86 return not getLocalCircle()->isInvalid();
87}
88
90{
91 m_localOrigin.set(0.0, 0.0);
92 m_localPerigeeCircle.invalidate();
93 m_flightTime = NAN;
94}
95
101
102
104{
105 CDCTrajectory2D result = *this;
106 result.reverse();
107 return result;
108}
109
110std::array<double, 2> CDCTrajectory2D::reconstructBothZ(const WireLine& wireLine,
111 const double distance,
112 const double z) const
113{
114 Vector2D globalPos2D = wireLine.sagPos2DAtZ(z);
115 Vector2D movePerZ = wireLine.sagMovePerZ(z);
116
117 Vector2D localPos2D = globalPos2D - getLocalOrigin();
118 const PerigeeCircle& localCircle = getLocalCircle();
119
120 double fastDistance = distance != 0.0 ? localCircle.fastDistance(distance) : 0.0;
121
122 double c = localCircle.fastDistance(localPos2D) - fastDistance;
123 double b = localCircle.gradient(localPos2D).dot(movePerZ);
124 double a = localCircle.n3() * movePerZ.normSquared();
125
126 const std::pair<double, double> solutionsDeltaZ = solveQuadraticABC(a, b, c);
127
128 // Put the solution of smaller deviation first
129 const std::array<double, 2> solutionsZ{solutionsDeltaZ.second + z, solutionsDeltaZ.first + z};
130 return solutionsZ;
131}
132
134 const double distance,
135 const double z) const
136{
137 const std::array<double, 2> solutionsZ = reconstructBothZ(wireLine, distance, z);
138
139 bool firstIsInCDC = (wireLine.backwardZ() < solutionsZ[0] and
140 solutionsZ[0] < wireLine.forwardZ());
141 bool secondIsInCDC = (wireLine.backwardZ() < solutionsZ[1] and
142 solutionsZ[1] < wireLine.forwardZ());
143
144 // Prefer the solution with the smaller deviation from the given z position which is the first
145 assert(not(std::fabs(solutionsZ[0] - z) > std::fabs(solutionsZ[1] - z)));
146 const double recoZ = (firstIsInCDC or not secondIsInCDC) ? solutionsZ[0] : solutionsZ[1];
147 return recoZ;
148}
149
150std::array<Vector3D, 2> CDCTrajectory2D::reconstructBoth3D(const WireLine& wireLine,
151 const double distance,
152 const double z) const
153{
154 const std::array<double, 2> solutionsZ = reconstructBothZ(wireLine, distance, z);
155
156 const Vector3D firstRecoWirePos3D = wireLine.sagPos3DAtZ(solutionsZ[0]);
157 const Vector3D secondRecoWirePos3D = wireLine.sagPos3DAtZ(solutionsZ[1]);
158 return {{{getClosest(firstRecoWirePos3D.xy()), firstRecoWirePos3D.z()},
159 {getClosest(secondRecoWirePos3D.xy()), secondRecoWirePos3D.z()}
160 }};
161}
162
164 const double distance,
165 const double z) const
166{
167 const double recoZ = reconstructZ(wireLine, distance, z);
168 const Vector3D recoWirePos2D = wireLine.sagPos3DAtZ(recoZ);
169 return Vector3D(getClosest(recoWirePos2D.xy()), recoZ);
170}
171
173{
174 return getLocalCircle()->closest(point - getLocalOrigin()) + getLocalOrigin();
175}
176
178{
180
181 ISuperLayer minimalISuperLayer = getMinimalISuperLayer();
182 ISuperLayer maximalISuperLayer = getMaximalISuperLayer();
183 if (minimalISuperLayer == maximalISuperLayer) return ISuperLayerUtil::c_Invalid; // No next super layer to go to
184 if (iSuperLayer == minimalISuperLayer) return ISuperLayerUtil::getNextOutwards(iSuperLayer);
185 if (iSuperLayer == maximalISuperLayer) return ISuperLayerUtil::getNextInwards(iSuperLayer);
186
187 if (movingOutward) {
188 return ISuperLayerUtil::getNextOutwards(iSuperLayer);
189 } else {
190 return ISuperLayerUtil::getNextInwards(iSuperLayer);
191 }
192}
193
195{
196 ISuperLayer iSuperLayer = getStartISuperLayer();
197 return getISuperLayerAfter(iSuperLayer, movingOutward);
198}
199
200ISuperLayer CDCTrajectory2D::getISuperLayerAfterStart(const EForwardBackward forwardBackwardInfo) const
201{
202 bool movingOutward = isMovingOutward();
203 if (forwardBackwardInfo == EForwardBackward::c_Backward) {
204 movingOutward = not movingOutward;
205 }
206 return getISuperLayerAfterStart(movingOutward);
207}
208
210{
211 return getISuperLayerAfterStart(EForwardBackward::c_Forward);
212}
213
215{
216 return getISuperLayerAfterStart(EForwardBackward::c_Backward);
217}
218
219ISuperLayer CDCTrajectory2D::getAxialISuperLayerAfterStart(const EForwardBackward forwardBackwardInfo) const
220{
221 bool movingOutward = isMovingOutward();
222 if (forwardBackwardInfo == EForwardBackward::c_Backward) {
223 movingOutward = not movingOutward;
224 }
225 ISuperLayer startISuperLayer = getStartISuperLayer();
226 if (ISuperLayerUtil::isInvalid(startISuperLayer)) return ISuperLayerUtil::c_Invalid;
227
228 ISuperLayer nextISuperLayer = getISuperLayerAfter(startISuperLayer, movingOutward);
229 if (ISuperLayerUtil::isInvalid(nextISuperLayer)) return ISuperLayerUtil::c_Invalid;
230 if (ISuperLayerUtil::isAxial(nextISuperLayer)) return nextISuperLayer;
231
232 ISuperLayer iSuperLayerStep = nextISuperLayer - startISuperLayer;
233 assert(std::abs(iSuperLayerStep) == 1);
234 bool nextMovingOutward = iSuperLayerStep > 0;
235 return getISuperLayerAfter(nextISuperLayer, nextMovingOutward);
236}
237
239{
240 return getAxialISuperLayerAfterStart(EForwardBackward::c_Forward);
241}
242
244{
245 return getAxialISuperLayerAfterStart(EForwardBackward::c_Backward);
246}
247
249{
250 double maximalCylindricalR = getMaximalCylindricalR();
252}
253
255{
256 double startCylindricalR = getLocalOrigin().cylindricalR();
258}
259
261{
262 double minimalCylindricalR = getMinimalCylindricalR();
264}
265
266bool CDCTrajectory2D::isCurler(double factor) const
267{
269 return getMaximalCylindricalR() < factor * topology.getOuterCylindricalR();
270}
271
272bool CDCTrajectory2D::isOriginer(double factor) const
273{
275 return getMinimalCylindricalR() < factor * topology.getInnerCylindricalR();
276}
277
278
280{
281 return CDCBFieldUtil::ccwInfoToChargeSign(getLocalCircle()->orientation());
282}
283
284double CDCTrajectory2D::getAbsMom2D(const double bZ) const
285{
286 return CDCBFieldUtil::curvatureToAbsMom2D(getLocalCircle()->curvature(), bZ);
287}
288
290{
291 Vector2D position = getSupport();
292 return CDCBFieldUtil::curvatureToAbsMom2D(getLocalCircle()->curvature(), position);
293}
294
296{
298 const CDCWireLayer& innerMostLayer = topology.getWireLayers().front();
299 double innerCylindricalR = innerMostLayer.getInnerCylindricalR();
300
301 const Vector2D support = getSupport();
302 const PerigeeCircle globalCircle = getGlobalCircle();
303 if (support.cylindricalR() < innerCylindricalR) {
304 // If we start within the inner volume of the CDC we want the trajectory to enter the CDC
305 // and not stop at first intersection with the inner wall.
306 // Therefore we take the inner exit that comes after the apogee (far point of the circle).
307 const Vector2D apogee = globalCircle.apogee();
308 return globalCircle.atCylindricalRForwardOf(apogee, innerCylindricalR);
309
310 } else {
311 return globalCircle.atCylindricalRForwardOf(support, innerCylindricalR);
312 }
313}
314
316{
318 const CDCWireLayer& outerMostLayer = topology.getWireLayers().back();
319 double outerCylindricalR = outerMostLayer.getOuterCylindricalR() * factor;
320
321 const Vector2D support = getSupport();
322 const PerigeeCircle globalCircle = getGlobalCircle();
323 if (support.cylindricalR() > outerCylindricalR) {
324 // If we start outside of the volume of the CDC we want the trajectory to enter the CDC
325 // and not stop at first intersection with the outer wall.
326 // Therefore we take the outer exit that comes after the perigee.
327 const Vector2D perigee = globalCircle.perigee();
328 return globalCircle.atCylindricalRForwardOf(perigee, outerCylindricalR);
329
330 } else {
331 return getGlobalCircle().atCylindricalRForwardOf(support, outerCylindricalR);
332 }
333}
334
336{
337 const Vector2D outerExit = getOuterExit();
338 const Vector2D innerExit = getInnerExit();
339 const Vector2D localExit = getLocalCircle()->chooseNextForwardOf(Vector2D(0, 0),
340 outerExit - getLocalOrigin(),
341 innerExit - getLocalOrigin());
342 return localExit + getLocalOrigin();
343}
344
346 const Vector2D& mom2D,
347 const double charge)
348{
349 m_localOrigin = pos2D;
350 double curvature = CDCBFieldUtil::absMom2DToCurvature(mom2D.norm(), charge, pos2D);
351 Vector2D phiVec = mom2D.unit();
352 double impact = 0.0;
353 m_localPerigeeCircle = UncertainPerigeeCircle(curvature, phiVec, impact);
354}
355
357{
358 double arcLength2D = calcArcLength2D(localOrigin);
359 m_flightTime += arcLength2D / Const::speedOfLight;
360 m_localPerigeeCircle.passiveMoveBy(localOrigin - m_localOrigin);
361 m_localOrigin = localOrigin;
362 return arcLength2D;
363}
364
365
366std::ostream& TrackingUtilities::operator<<(std::ostream& output, const CDCTrajectory2D& trajectory2D)
367{
368 return output << "Local origin : " << trajectory2D.getLocalOrigin() << ", "
369 << "local circle : " << trajectory2D.getLocalCircle();
370}
Class representing a sense wire layer in the central drift chamber.
double getInnerCylindricalR() const
Getter for inner radius of the layer as taken from the CDCGeometryPar.
double getOuterCylindricalR() const
Getter for outer radius of the layer as taken from the CDCGeometryPar.
Class representing the sense wire arrangement in the whole of the central drift chamber.
const std::vector< CDCWireLayer > & getWireLayers() const
Getter for the underlying storing layer vector.
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.
A three dimensional limited line represented by its closest approach to the z-axes (reference positio...
Definition WireLine.h:33
ROOT::Math::XYVector 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:68
double backwardZ() const
Gives the backward z coordinate.
Definition WireLine.h:152
ROOT::Math::XYZVector 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:61
double forwardZ() const
Gives the forward z coordinate.
Definition WireLine.h:148
ROOT::Math::XYVector 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:83
static const double speedOfLight
[cm/ns]
Definition Const.h:695
Helper functions to interact with the magnetic field.
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.
CDC::ISuperLayer getAxialISuperLayerAfterStart(EForwardBackward forwardBackwardInfo) const
Indicates which axial superlayer is traversed after the one, where the start point of the trajectory ...
CDC::ISuperLayer getISuperLayerAfter(CDC::ISuperLayer iSuperLayer, bool movingOutward) const
Returns which superlayer is traversed after the current one following the trajectory outward or inwar...
Vector2D getOuterExit(double factor=1) const
Calculates the point where the trajectory meets the outer wall of the CDC.
double reconstructZ(const CDC::WireLine &wireLine, double distance=0.0, double z=0) const
Gives the one z positions within the CDC closest to the given z where the given drift circle on the w...
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.
CDC::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.
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.
CDC::ISuperLayer getISuperLayerAfterStart(bool movingOutward) const
Returns which superlayer is traversed after the current one following the trajectory outward or inwar...
std::array< Vector3D, 2 > reconstructBoth3D(const CDC::WireLine &wireLine, double distance=0.0, double z=0) const
Gives the two three dimensional points where the drift circle touches the wire line.
CDC::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.
CDC::ISuperLayer getMinimalISuperLayer() const
Indicates the minimal superlayer the trajectory traverses.
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.
const Vector2D & getLocalOrigin() const
Getter for the origin of the local coordinate system.
CDC::ISuperLayer getPreviousAxialISuperLayer() const
Indicates which axial superlayer the trajectory traverses before the one, where the start point of th...
CDC::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.
const UncertainPerigeeCircle & getLocalCircle() const
Getter for the circle in local coordinates.
std::array< double, 2 > reconstructBothZ(const CDC::WireLine &wireLine, double distance=0.0, double z=0) const
Gives the two z positions where the given drift circle on the wire line touches the trajectory.
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 trajectory.
bool isMovingOutward() const
Indicates if the trajectory is moving outwards or inwards (to or away from the origin) from the start...
CDC::ISuperLayer getNextISuperLayer() const
Indicates which superlayer the trajectory traverses after the one, where the start point of the traje...
CDC::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 CDC::WireLine &wireLine, double distance=0.0, double z=0) const
Gives the one three dimensional positions 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.
Extension of the generalized circle also caching the perigee coordinates.
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 strictly follows ...
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.
A two dimensional vector which is equipped with functions for correct handling of orientation relate...
Definition Vector2D.h:36
double dot(const Vector2D &rhs) const
Calculates the two dimensional dot product.
Definition Vector2D.h:178
double cylindricalR() const
Gives the cylindrical radius of the vector. Same as norm()
Definition Vector2D.h:588
double normSquared() const
Calculates .
Definition Vector2D.h:195
Vector2D unit() const
Returns a unit vector colaligned with this.
Definition Vector2D.h:352
double norm() const
Calculates the length of the vector.
Definition Vector2D.h:206
A three dimensional vector.
Definition Vector3D.h:34
const Vector2D & xy() const
Getter for the xy projected vector ( reference ! )
Definition Vector3D.h:513
double z() const
Getter for the z coordinate.
Definition Vector3D.h:501
HepGeom::Vector3D< double > Vector3D
3D Vector
Definition Cell.h:34
signed short ISuperLayer
The type of the layer and superlayer ids.
Definition ISuperLayer.h:24
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.
static ISuperLayer getNextInwards(ISuperLayer iSuperLayer)
Returns the super layer that is inside of the given super layer.
static bool isInvalid(ISuperLayer iSuperLayer)
Indicates if the given number corresponds to a true cdc superlayer - excludes the logic ids for inner...
static ISuperLayer getNextOutwards(ISuperLayer iSuperLayer)
Returns the super layer that is outside of the given super layer.