Belle II Software  release-08-01-10
DistanceCalculatorModule.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 
9 #include <analysis/modules/DistanceCalculator/DistanceCalculatorModule.h>
10 
11 #include <Eigen/Dense>
12 #include <iostream>
13 
14 using namespace std;
15 using namespace Belle2;
16 
17 const float eps = 1E-6;
18 
19 //-----------------------------------------------------------------
20 // Register the Module
21 //-----------------------------------------------------------------
22 REG_MODULE(DistanceCalculator);
23 
24 //-----------------------------------------------------------------
25 // Implementation
26 //-----------------------------------------------------------------
27 
28 DistanceCalculatorModule::DistanceCalculatorModule() : Module(),
29  m_distanceCovMatrix(3)
30 {
31  // Set module properties
32  setDescription("Calculates distance between two vertices, distance of closest approach between a vertex and a track, distance of closest approach between two tracks, distance of closest approach between a vertex/track and Btube");
33 
34  // Parameter definitions
35  addParam("listName", m_listName, "", std::string(""));
36  addParam("decayString", m_decayString, "", std::string(""));
37  addParam("mode", m_mode,
38  "Specifies how the distance is calculated:\n"
39  "vertextrack: calculate the distance of closest approach between a track and a vertex, taking the first candidate as vertex, default\n"
40  "trackvertex: calculate the distance of closest approach between a track and a vertex, taking the first candidate as track,\n"
41  "2tracks: calculates the distance of closest approach between two tracks,\n"
42  "2vertices: calculates the distance between two vertices,\n"
43  "vertexbtube: calculates the distance of closest approach between a vertex and a Btube,\n"
44  "trackbtube: calculates the distance of closest approach between a track and a Btube",
45  std::string("vertextrack"));
46 
47  m_distance = Eigen::Matrix<double, Eigen::Dynamic, 1>::Zero(3);
48 }
49 
51 {
52 }
53 
55 {
56  if (m_decayString != "") {
58  } else {
59  B2FATAL("Please provide a decay string for DistanceCalculatorModule");
60  }
61  m_plist.isRequired(m_listName);
62 }
63 
64 Eigen::Vector3d getDocaTrackVertex(const Particle* pTrack, const Particle* pVertex)
65 {
66  Eigen::Vector3d v(pTrack->getPx(), pTrack->getPy(), pTrack->getPz());
67  Eigen::Vector3d p_ray(pTrack->getX(), pTrack->getY(), pTrack->getZ());
68  Eigen::Vector3d p(pVertex->getX(), pVertex->getY(), pVertex->getZ());
69  Eigen::Vector3d v_dir = v.normalized();
70  Eigen::Vector3d r = p - p_ray;
71  return r.dot(v_dir) * v_dir - r;
72 }
73 
74 TMatrixFSym getDocaTrackVertexError(const Particle* pTrack, const Particle* pVertex)
75 {
76  //covariance matrix of r
77  TMatrixFSym err_r = pTrack->getVertexErrorMatrix() + pVertex->getVertexErrorMatrix();
78  Eigen::Vector3d V(pTrack->getPx(), pTrack->getPy(), pTrack->getPz());
79  Eigen::Vector3d v = V.normalized();
80  //d_j = r_j - v_j * v_k r_k
81  //Jij = del_i d_j = delta_ij - v_i * v_j
82  //Since the vector of closest approach is a linear function of r, its
83  //propagation of errors is exact
84  TMatrixFSym Jacobian(3);
85  //Fill the jacobian matrix according to the equation:
86  // J_ij = delta_ij -v(i)v(j)
87  for (int i = 0; i < 3; i++)
88  for (int j = 0; j < 3; j++)
89  Jacobian(i, j) = -v(i) * v(j);
90  for (int i = 0; i < 3; i++)
91  Jacobian(i, i) += 1;
92 
93  return err_r.Similarity(Jacobian); //calculates J * err_r * J^T, and returns it
94 }
95 
96 /*
97  * This method calculates the Doca vector between two tracks (i.e. lines)
98  * This is done using the following equation:
99  * d = (n*(x1-x2))n
100  * where d is the doca vector, n is a unit vector that is orthogonal to both lines,
101  * and x1 and x2 are points on the first and second line respectively
102  */
103 Eigen::Vector3d getDocaTracks(const Particle* p1, const Particle* p2)
104 {
105  Eigen::Vector3d v1(p1->getPx(), p1->getPy(), p1->getPz());
106  Eigen::Vector3d v2(p2->getPx(), p2->getPy(), p2->getPz());
107  Eigen::Vector3d n = v1.cross(v2); //The doca vector must be orthogonal to both lines.
108  if (n.norm() < eps) {
109  //if tracks are parallel then the distance is independent of the point on the line
110  //and we can use the old way to calculate the DOCA
111  return getDocaTrackVertex(p1, p2);
112  }
113  Eigen::Vector3d n_dir = n.normalized();
114  Eigen::Vector3d p1v(p1->getX(), p1->getY(), p1->getZ());
115  Eigen::Vector3d p2v(p2->getX(), p2->getY(), p2->getZ());
116  Eigen::Vector3d r = p1v - p2v;
117  return r.dot(n_dir) * n_dir;
118 }
119 
120 TMatrixFSym getDocaTracksError(const Particle* p1, const Particle* p2)
121 {
122  //covariance matrix of r
123  TMatrixFSym err_r = p1->getVertexErrorMatrix() + p2->getVertexErrorMatrix();
124  Eigen::Vector3d p1p(p1->getPx(), p1->getPy(), p1->getPz());
125  Eigen::Vector3d p2p(p2->getPx(), p2->getPy(), p2->getPz());
126  Eigen::Vector3d n = p1p.cross(p2p);
127  if (n.norm() < eps) {
128  return getDocaTrackVertexError(p1, p2);
129  }
130  Eigen::Vector3d n_dir = n.normalized();
131  //d_j = n_dir_j * n_dir_k r_k
132  //Jij = del_i d_j = n_dir_i * n_dir_j
133  //Since the vector of closest approach is a linear function of r, it's
134  //propagation of errors is exact
135  TMatrixFSym Jacobian(3);
136  //Fill the jacobian matrix according to the equation:
137  // J_ij = n(i)n(j)
138  for (int i = 0; i < 3; i++)
139  for (int j = 0; j < 3; j++)
140  Jacobian(i, j) = n_dir(i) * n_dir(j);
141  return err_r.Similarity(Jacobian); //calculates J * err_r * J^T, and returns it
142 }
143 
144 Eigen::Vector3d getDistanceVertices(const Particle* p1, const Particle* p2)
145 {
146  Eigen::Vector3d p1v(p1->getX(), p1->getY(), p1->getZ());
147  Eigen::Vector3d p2v(p2->getX(), p2->getY(), p2->getZ());
148  Eigen::Vector3d r = p2v - p1v;
149  return r;
150 }
151 
152 TMatrixFSym getDistanceVerticesErrors(const Particle* p1, const Particle* p2)
153 {
154  TMatrixFSym err_r = p1->getVertexErrorMatrix() + p2->getVertexErrorMatrix();
155  return err_r;
156 }
157 
159 {
160  if (m_mode == "2tracks") {
161  m_distance = getDocaTracks(p1, p2);
162  }
163  if (m_mode == "2vertices") {
164  m_distance = getDistanceVertices(p1, p2);
165  }
166  if (m_mode == "vertextrack") {
167  m_distance = getDocaTrackVertex(p2, p1);
168  }
169  if (m_mode == "trackvertex") {
170  m_distance = getDocaTrackVertex(p1, p2);
171  }
172 }
173 
175 {
176  if (m_mode == "2tracks") {
177  m_distanceCovMatrix = getDocaTracksError(p1, p2);
178  }
179  if (m_mode == "2vertices") {
180  m_distanceCovMatrix = getDistanceVerticesErrors(p1, p2);
181  }
182  if (m_mode == "vertextrack") {
183  m_distanceCovMatrix = getDocaTrackVertexError(p2, p1);
184  }
185  if (m_mode == "trackvertex") {
186  m_distanceCovMatrix = getDocaTrackVertexError(p1, p2);
187  }
188 }
189 
190 Eigen::Vector3d getDocaBtubeVertex(const Particle* pVertex, const Btube* tube)
191 {
192  Eigen::Vector3d v(tube->getTubeDirection()(0, 0), tube->getTubeDirection()(1, 0), tube->getTubeDirection()(2, 0));
193  Eigen::Vector3d p_ray(tube->getTubeCenter()(0, 0), tube->getTubeCenter()(1, 0), tube->getTubeCenter()(2, 0));
194  Eigen::Vector3d p(pVertex->getX(), pVertex->getY(), pVertex->getZ());
195  Eigen::Vector3d v_dir = v.normalized();
196  Eigen::Vector3d r = p - p_ray;
197  return r.dot(v_dir) * v_dir - r;
198 }
199 
200 TMatrixFSym getDocaBtubeVertexError(const Particle* pVertex, const Btube* tube)
201 {
202  TMatrixFSym err_r = tube->getTubeCenterErrorMatrix() + pVertex->getVertexErrorMatrix();
203  Eigen::Vector3d V(tube->getTubeDirection()(0, 0), tube->getTubeDirection()(1, 0), tube->getTubeDirection()(2, 0));
204  Eigen::Vector3d v = V.normalized();
205  TMatrixFSym Jacobian(3);
206  for (int i = 0; i < 3; i++)
207  for (int j = 0; j < 3; j++)
208  Jacobian(i, j) = -v(i) * v(j);
209  for (int i = 0; i < 3; i++)
210  Jacobian(i, i) += 1;
211 
212  return err_r.Similarity(Jacobian);
213 }
214 
215 Eigen::Vector3d getDocaBtubeTrack(const Particle* pTrack, const Btube* tube)
216 {
217  Eigen::Vector3d v1(pTrack->getPx(), pTrack->getPy(), pTrack->getPz());
218  Eigen::Vector3d v2 = tube->getTubeDirection();
219  Eigen::Vector3d n = v1.cross(v2); //The doca vector must be orthogonal to both lines.
220  if (n.norm() < eps) {
221  //if tracks are parallel then the distance is independent of the point on the line
222  //and we can use the old way to calculate the DOCA
223  return getDocaBtubeVertex(pTrack, tube);
224  }
225  Eigen::Vector3d n_dir = n.normalized();
226  Eigen::Vector3d pv(pTrack->getX(), pTrack->getY(), pTrack->getZ());
227  Eigen::Vector3d p2v(tube->getTubeCenter()(0, 0), tube->getTubeCenter()(1, 0), tube->getTubeCenter()(2, 0));
228  Eigen::Vector3d r = pv - p2v;
229  return r.dot(n_dir) * n_dir;
230 }
231 
232 TMatrixFSym getDocaBtubeTrackError(const Particle* pTrack, const Btube* tube)
233 {
234  TMatrixFSym err_r = pTrack->getVertexErrorMatrix() + tube->getTubeCenterErrorMatrix();
235  Eigen::Vector3d p1p(pTrack->getPx(), pTrack->getPy(), pTrack->getPz());
236  Eigen::Vector3d p2p(tube->getTubeDirection()(0, 0), tube->getTubeDirection()(1, 0), tube->getTubeDirection()(2, 0));
237  Eigen::Vector3d n = p1p.cross(p2p);
238  if (n.norm() < eps) {
239  return getDocaBtubeVertexError(pTrack, tube);
240  }
241  Eigen::Vector3d n_dir = n.normalized();
242  TMatrixFSym Jacobian(3);
243  for (int i = 0; i < 3; i++)
244  for (int j = 0; j < 3; j++)
245  Jacobian(i, j) = n_dir(i) * n_dir(j);
246  return err_r.Similarity(Jacobian);
247 }
248 
250 {
251  if (m_mode == "vertexbtube") {
252  m_distance = getDocaBtubeVertex(p, t);
253  }
254  if (m_mode == "trackbtube") {
255  m_distance = getDocaBtubeTrack(p, t);
256  }
257 }
258 
260 {
261  if (m_mode == "vertexbtube") {
262  m_distanceCovMatrix = getDocaBtubeVertexError(p, t);
263  }
264  if (m_mode == "trackbtube") {
265  m_distanceCovMatrix = getDocaBtubeTrackError(p, t);
266  }
267 }
268 
270 {
271  unsigned int n = m_plist->getListSize();
272  for (unsigned int i = 0; i < n; i++) {
273  Particle* particle = m_plist->getParticle(i);
274  std::vector<const Particle*> selectedParticles = m_decayDescriptor.getSelectionParticles(particle);
275  if ((m_mode == "vertexbtube") || (m_mode == "trackbtube")) {
276  if (selectedParticles.size() == 1) {
277  const Btube* t = particle->getRelatedTo<Btube>();
278  if (!t) {
279  B2FATAL("No associated Btube found");
280  }
281  const Particle* p0 = selectedParticles[0];
282  getBtubeDistance(p0, t);
283  getBtubeDistanceErrors(particle, t);
284  }
285  } else {
286  if (selectedParticles.size() == 2) {
287  const Particle* p1 = selectedParticles[0];
288  const Particle* p2 = selectedParticles[1];
289  getDistance(p1, p2);
290  getDistanceErrors(p1, p2);
291  }
292  }
293  Eigen::Matrix3d DistanceCovMatrix_eigen;
294  DistanceCovMatrix_eigen.resize(3, 3);
295  for (int row = 0; row < 3; row++) {
296  for (int column = 0; column < 3; column++) {
297  DistanceCovMatrix_eigen(row, column) = m_distanceCovMatrix[row][column]; //converting from TMatrixFSym to Eigen
298  }
299  }
300  float DistanceMag = m_distance.norm();
301  double dist_err = 0;
302  if (DistanceMag != 0) {
303  Eigen::Vector3d dist_dir = m_distance.normalized();
304  dist_err = sqrt(((dist_dir.transpose()) * (DistanceCovMatrix_eigen * dist_dir)).norm());
305  }
306  particle->writeExtraInfo("CalculatedDistance", DistanceMag);
307  particle->writeExtraInfo("CalculatedDistanceError", dist_err);
308  //The Distance vector always points from the "vertex" to the "track/btube", if a single vertex is involved. In case of two vertices, it points from the "first" vertex to the "second" vertex. For two tracks or one track and btube, the direction is along "first track x second track" or "track x btube"
309  particle->writeExtraInfo("CalculatedDistanceVector_X", m_distance(0));
310  particle->writeExtraInfo("CalculatedDistanceVector_Y", m_distance(1));
311  particle->writeExtraInfo("CalculatedDistanceVector_Z", m_distance(2));
312  //Save the Covariance Matrix
313  particle->writeExtraInfo("CalculatedDistanceCovMatrixXX", m_distanceCovMatrix[0][0]);
314  particle->writeExtraInfo("CalculatedDistanceCovMatrixXY", m_distanceCovMatrix[0][1]);
315  particle->writeExtraInfo("CalculatedDistanceCovMatrixXZ", m_distanceCovMatrix[0][2]);
316  particle->writeExtraInfo("CalculatedDistanceCovMatrixYX", m_distanceCovMatrix[1][0]);
317  particle->writeExtraInfo("CalculatedDistanceCovMatrixYY", m_distanceCovMatrix[1][1]);
318  particle->writeExtraInfo("CalculatedDistanceCovMatrixYZ", m_distanceCovMatrix[1][2]);
319  particle->writeExtraInfo("CalculatedDistanceCovMatrixZX", m_distanceCovMatrix[2][0]);
320  particle->writeExtraInfo("CalculatedDistanceCovMatrixZY", m_distanceCovMatrix[2][1]);
321  particle->writeExtraInfo("CalculatedDistanceCovMatrixZZ", m_distanceCovMatrix[2][2]);
322  }
323 }
R E
internal precision of FFTW codelets
For each MCParticle with hits in the CDC, this class stores some summarising information on those hit...
Definition: Btube.h:27
TMatrixFSym getTubeCenterErrorMatrix() const
Returns Btube Center Error Matrix.
Definition: Btube.h:85
Eigen::Matrix< double, 3, 1 > getTubeCenter() const
Returns Btube center.
Definition: Btube.h:64
Eigen::Matrix< double, 3, 1 > getTubeDirection() const
Returns Btube direction.
Definition: Btube.h:71
bool init(const std::string &str)
Initialise the DecayDescriptor from given string.
std::vector< const Particle * > getSelectionParticles(const Particle *particle)
Get a vector of pointers with selected daughters in the decay tree.
TMatrixFSym m_distanceCovMatrix
covariance matrix of distance
virtual void initialize() override
declare data store elements
virtual void event() override
process event
std::string m_listName
name of particle list
void getBtubeDistanceErrors(const Particle *p, const Btube *t)
returns the error on the distance between the btube and the object (depending on m_mode)
void getDistanceErrors(const Particle *p1, const Particle *p2)
returns the error on the distance between tracks or vertex objects (depending on the m_mode)
Eigen::Vector3d m_distance
distance between two objects (track/vertex/Btube and vertex/track)
DecayDescriptor m_decayDescriptor
decay descriptor which specifies which particles are used to calculate the distance
void getDistance(const Particle *p1, const Particle *p2)
returns the distance between tracks or vertex objects (depending on the m_mode)
void getBtubeDistance(const Particle *p, const Btube *t)
returns the distance between the btube and the object (depending on m_mode)
StoreObjPtr< ParticleList > m_plist
input particle list
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
Class to store reconstructed particles.
Definition: Particle.h:75
double getPx() const
Returns x component of momentum.
Definition: Particle.h:553
TMatrixFSym getVertexErrorMatrix() const
Returns the 3x3 position error sub-matrix.
Definition: Particle.cc:451
double getPz() const
Returns z component of momentum.
Definition: Particle.h:571
double getX() const
Returns x component of vertex position.
Definition: Particle.h:598
double getPy() const
Returns y component of momentum.
Definition: Particle.h:562
double getZ() const
Returns z component of vertex position.
Definition: Particle.h:616
double getY() const
Returns y component of vertex position.
Definition: Particle.h:607
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
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.
const std::vector< double > v2
MATLAB generated random vector.
const std::vector< double > v1
MATLAB generated random vector.