Belle II Software  release-08-01-10
PlaneTriggerTrackTimeEstimatorModule.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/modules/fitter/timeEstimator/PlaneTriggerTrackTimeEstimatorModule.h>
9 
10 #include <tracking/dataobjects/RecoTrack.h>
11 #include <framework/dataobjects/Helix.h>
12 #include <framework/geometry/BFieldManager.h>
13 #include <framework/geometry/B2Vector3.h>
14 
15 using namespace Belle2;
16 
17 REG_MODULE(PlaneTriggerTrackTimeEstimator);
18 
20 {
21  addParam("triggerPlanePosition", m_param_triggerPlanePosition, "3-Position of the plane of the trigger.",
23 
24  addParam("triggerPlaneDirection", m_param_triggerPlaneNormalDirection, "3-Normal direction of the plane of the trigger.",
26 }
27 
29  measuredStateOnPlane)
30 const
31 {
32  B2ASSERT("Position must have 3 components.", m_param_triggerPlanePosition.size() == 3);
33  B2ASSERT("Normal direction must have 3 components.", m_param_triggerPlaneNormalDirection.size() == 3);
34 
38 
39  try {
40  const double s = measuredStateOnPlane.extrapolateToPlane(genfit::SharedPlanePtr(new genfit::DetPlane(triggerPlanePosition,
41  triggerPlaneNormalDirection)));
42 
43  // Negative, because we extrapolated in the wrong direction
44  return -s;
45  } catch (const genfit::Exception& e) {
46  B2WARNING("Extrapolation failed: " << e.what());
47  return 0;
48  }
49 
50 }
51 
53 {
54  B2ASSERT("Position must have 3 components.", m_param_triggerPlanePosition.size() == 3);
55  B2ASSERT("Normal direction must have 3 components.", m_param_triggerPlaneNormalDirection.size() == 3);
56 
57  const ROOT::Math::XYZVector& momentum = recoTrack.getMomentumSeed();
58  const short int charge = recoTrack.getChargeSeed();
59  const ROOT::Math::XYZVector& position = recoTrack.getPositionSeed();
60 
61  const double bZ = BFieldManager::getField(0, 0, 0).Z() / Unit::T;
62  const Helix h(position, momentum, charge, bZ);
63 
64  const double arcLengthAtPosition = h.getArcLength2DAtXY(position.X(), position.Y());
65 
66  double arcLengthOfIntersection = NAN;
67 
71 
72  // Currently, there are only one cases implemented!
73  // Case 1: Plane for a certain z:
74  if (triggerPlaneNormalDirection.X() == 0 and triggerPlaneNormalDirection.Y() == 0) {
75  // This is the easiest case: We just have so solve tan lambda * arcLength + z0 = p_z
76  arcLengthOfIntersection = (triggerPlanePosition.Z() - h.getZ0()) / h.getTanLambda();
77  } else if (triggerPlaneNormalDirection.Z() == 0) {
78  // This case is a bit harder. We have to find solutions for n_x * x + n_y * y = n_x * p_x + n_y * p_y
79  // with n_i the i-th component of the normal vector, p_i the i-th component of the position vector
80  // and x or y given by the helix function.
81 
82  // We make our life a bit easier and rotate the plane (as well as the normal vector) by -phi0. This makes the
83  // helix (and all the equations) much easier.
84  triggerPlaneNormalDirection.RotateZ(-h.getPhi0());
85  triggerPlanePosition.RotateZ(-h.getPhi0());
86 
87  const double n_x = triggerPlaneNormalDirection.X();
88  const double n_y = triggerPlaneNormalDirection.Y();
89 
90  // We first define n_x * p_x + n_y * p_y as alpha
91  const double alpha = triggerPlanePosition.Dot(triggerPlaneNormalDirection);
92 
93  // we do a case distinction between cosmics and "normal" tracks:
94  if (fabs(h.getOmega()) < 1e-3) {
95  // in case of cosmics, this is quite easy
96  const double arcLengthOfTrigger = (alpha + n_y * h.getD0()) / n_x;
97 
98  arcLengthOfIntersection = arcLengthAtPosition - arcLengthOfTrigger;
99  } else {
100  // And then we define a reoccuring element in the equation as beta
101  const double beta = n_y * h.getOmega() * h.getD0() + alpha * h.getOmega();
102 
103  // The equation we have top solve is now
104  // -n_x * A - n_y * (1 - sqrt(1 - A^2)) = beta
105  // with A = sin(\chi) and cos = sqrt(1 - sin^2)
106 
107  // there are two possible solutions, and we want the positive one
108  const double A1 = (sqrt(n_x * n_x * n_y * n_y - 2 * beta * n_y * n_y * n_y - beta * beta * n_y * n_y) - beta * n_x - n_x * n_y) /
109  (n_x * n_x + n_y * n_y);
110  const double A2 = (-sqrt(n_x * n_x * n_y * n_y - 2 * beta * n_y * n_y * n_y - beta * beta * n_y * n_y) - beta * n_x - n_x * n_y) /
111  (n_x * n_x + n_y * n_y);
112 
113  const double x1_unrotated = -A1 / h.getOmega();
114  const double y1_unrotated = -(1 - sqrt(1 - A1 * A1)) / h.getOmega() - h.getD0();
115  const double x2_unrotated = -A2 / h.getOmega();
116  const double y2_unrotated = -(1 - sqrt(1 - A2 * A2)) / h.getOmega() - h.getD0();
117 
118  const double x1_rotated = h.getCosPhi0() * x1_unrotated + h.getSinPhi0() * y1_unrotated;
119  const double y1_rotated = -h.getSinPhi0() * x1_unrotated + h.getCosPhi0() * y1_unrotated;
120  const double x2_rotated = h.getCosPhi0() * x2_unrotated + h.getSinPhi0() * y2_unrotated;
121  const double y2_rotated = -h.getSinPhi0() * x2_unrotated + h.getCosPhi0() * y2_unrotated;
122 
123  // Finaly, we can calculate the arc length
124  const double arcLengthOfTrigger1 = h.getArcLength2DAtXY(x1_rotated, y1_rotated);
125  const double arcLengthOfTrigger2 = h.getArcLength2DAtXY(x2_rotated, y2_rotated);
126 
127  const double arcLengthOfIntersection1 = arcLengthAtPosition - arcLengthOfTrigger1;
128  const double arcLengthOfIntersection2 = arcLengthAtPosition - arcLengthOfTrigger2;
129 
130  arcLengthOfIntersection = fabs(arcLengthOfIntersection1) < fabs(arcLengthOfIntersection2) ? arcLengthOfIntersection1 :
131  arcLengthOfIntersection2;
132  }
133  } else {
134  // All the other cases are not algebraically solvable. As I do not think they will be necessary, we do not
135  // spend time on constructing a numerical solution here.
136  B2FATAL("This case for the normal direction is not implemented for using tracking seeds!");
137  }
138 
139  const double s = arcLengthOfIntersection * hypot(1, h.getTanLambda());
140  return s;
141 }
DataType Z() const
access variable Z (= .at(2) without boundary check)
Definition: B2Vector3.h:435
DataType X() const
access variable X (= .at(0) without boundary check)
Definition: B2Vector3.h:431
DataType Y() const
access variable Y (= .at(1) without boundary check)
Definition: B2Vector3.h:433
void RotateZ(DataType angle)
Rotates the B2Vector3 around the z-axis.
Definition: B2Vector3.h:359
DataType Dot(const B2Vector3< DataType > &p) const
Scalar product.
Definition: B2Vector3.h:290
Base Module estimating the track time of RecoTracks - before or after the fit.
Helix parameter class.
Definition: Helix.h:48
double estimateFlightLengthUsingSeedInformation(const RecoTrack &recoTrack) const override
Estimate the flight length using only the tracking seeds.
double estimateFlightLengthUsingFittedInformation(genfit::MeasuredStateOnPlane &measuredStateOnPlane) const override
Estimate the flight length to the given plane using the extrapolation of the fit.
std::vector< double > m_param_triggerPlaneNormalDirection
3-Normal direction of the plane of the trigger.
std::vector< double > m_param_triggerPlanePosition
3-Position of the plane of the trigger.
PlaneTriggerTrackTimeEstimatorModule()
Initilialize the module parameters.
This is the Reconstruction Event-Data Model Track.
Definition: RecoTrack.h:79
ROOT::Math::XYZVector getPositionSeed() const
Return the position seed stored in the reco track. ATTENTION: This is not the fitted position.
Definition: RecoTrack.h:480
short int getChargeSeed() const
Return the charge seed stored in the reco track. ATTENTION: This is not the fitted charge.
Definition: RecoTrack.h:508
ROOT::Math::XYZVector getMomentumSeed() const
Return the momentum seed stored in the reco track. ATTENTION: This is not the fitted momentum.
Definition: RecoTrack.h:487
static const double T
[tesla]
Definition: Unit.h:120
Detector plane.
Definition: DetPlane.h:59
Exception class for error handling in GENFIT (provides storage for diagnostic information)
Definition: Exception.h:48
#StateOnPlane with additional covariance matrix.
REG_MODULE(arichBtest)
Register the Module.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
static void getField(const double *pos, double *field)
return the magnetic field at a given position.
Definition: BFieldManager.h:91
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.
std::shared_ptr< genfit::DetPlane > SharedPlanePtr
Shared Pointer to a DetPlane.