Belle II Software  release-08-01-10
VertexVariables.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/variables/VertexVariables.h>
10 
11 #include <analysis/dataobjects/Particle.h>
12 #include <analysis/utility/ReferenceFrame.h>
13 
14 #include <framework/database/DBObjPtr.h>
15 #include <framework/logging/Logger.h>
16 #include <framework/utilities/Conversion.h>
17 
18 #include <TMatrixFSym.h>
19 
20 #include <mdst/dbobjects/BeamSpot.h>
21 #include <mdst/dataobjects/MCParticle.h>
22 #include <mdst/dataobjects/Track.h>
23 #include <mdst/dataobjects/TrackFitResult.h>
24 
25 
26 namespace Belle2 {
31  class Particle;
32 
33  namespace Variable {
34 
35  // Generated vertex information
36  double mcDecayVertexX(const Particle* part)
37  {
38  auto* mcparticle = part->getMCParticle();
39  if (!mcparticle) return Const::doubleNaN;
40  return mcparticle->getDecayVertex().X();
41  }
42 
43  double mcDecayVertexY(const Particle* part)
44  {
45  auto* mcparticle = part->getMCParticle();
46  if (!mcparticle) return Const::doubleNaN;
47  return mcparticle->getDecayVertex().Y();
48  }
49 
50  double mcDecayVertexZ(const Particle* part)
51  {
52  auto* mcparticle = part->getMCParticle();
53  if (!mcparticle) return Const::doubleNaN;
54  return mcparticle->getDecayVertex().Z();
55  }
56 
57  double mcDecayVertexRho(const Particle* part)
58  {
59  auto* mcparticle = part->getMCParticle();
60  if (!mcparticle) return Const::doubleNaN;
61  return mcparticle->getDecayVertex().Rho();
62  }
63 
64  B2Vector3D getMcDecayVertexFromIP(const MCParticle* mcparticle)
65  {
66  static DBObjPtr<BeamSpot> beamSpotDB;
67  const auto& frame = ReferenceFrame::GetCurrent();
68  return frame.getVertex(mcparticle->getDecayVertex() - ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
69  }
70 
71  double mcDecayVertexFromIPX(const Particle* part)
72  {
73  auto* mcparticle = part->getMCParticle();
74  if (!mcparticle) return Const::doubleNaN;
75  return getMcDecayVertexFromIP(mcparticle).X();
76  }
77 
78  double mcDecayVertexFromIPY(const Particle* part)
79  {
80  auto* mcparticle = part->getMCParticle();
81  if (!mcparticle) return Const::doubleNaN;
82  return getMcDecayVertexFromIP(mcparticle).Y();
83  }
84 
85  double mcDecayVertexFromIPZ(const Particle* part)
86  {
87  auto* mcparticle = part->getMCParticle();
88  if (!mcparticle) return Const::doubleNaN;
89  return getMcDecayVertexFromIP(mcparticle).Z();
90  }
91 
92  double mcDecayVertexFromIPRho(const Particle* part)
93  {
94  auto* mcparticle = part->getMCParticle();
95  if (!mcparticle) return Const::doubleNaN;
96  return getMcDecayVertexFromIP(mcparticle).Perp();
97  }
98 
99  double mcDecayVertexFromIPDistance(const Particle* part)
100  {
101  auto* mcparticle = part->getMCParticle();
102  if (!mcparticle) return Const::doubleNaN;
103  return getMcDecayVertexFromIP(mcparticle).Mag();
104  }
105 
106  double mcProductionVertexX(const Particle* part)
107  {
108  auto* mcparticle = part->getMCParticle();
109  if (!mcparticle) return Const::doubleNaN;
110  return mcparticle->getProductionVertex().X();
111  }
112 
113  double mcProductionVertexY(const Particle* part)
114  {
115  auto* mcparticle = part->getMCParticle();
116  if (!mcparticle) return Const::doubleNaN;
117  return mcparticle->getProductionVertex().Y();
118  }
119 
120  double mcProductionVertexZ(const Particle* part)
121  {
122  auto* mcparticle = part->getMCParticle();
123  if (!mcparticle) return Const::doubleNaN;
124  return mcparticle->getProductionVertex().Z();
125  }
126 
127  B2Vector3D getMcProductionVertexFromIP(const MCParticle* mcparticle)
128  {
129  static DBObjPtr<BeamSpot> beamSpotDB;
130  const auto& frame = ReferenceFrame::GetCurrent();
131  return frame.getVertex(mcparticle->getProductionVertex() - ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
132  }
133 
134  double mcProductionVertexFromIPX(const Particle* part)
135  {
136  auto* mcparticle = part->getMCParticle();
137  if (!mcparticle) return Const::doubleNaN;
138  return getMcProductionVertexFromIP(mcparticle).X();
139  }
140 
141  double mcProductionVertexFromIPY(const Particle* part)
142  {
143  auto* mcparticle = part->getMCParticle();
144  if (!mcparticle) return Const::doubleNaN;
145  return getMcProductionVertexFromIP(mcparticle).Y();
146  }
147 
148  double mcProductionVertexFromIPZ(const Particle* part)
149  {
150  auto* mcparticle = part->getMCParticle();
151  if (!mcparticle) return Const::doubleNaN;
152  return getMcProductionVertexFromIP(mcparticle).Z();
153  }
154 
155  // vertex or POCA with respect to origin ------------------------------
156 
157  double particleX(const Particle* part)
158  {
159  const auto& frame = ReferenceFrame::GetCurrent();
160  return frame.getVertex(part).X();
161  }
162 
163  double particleY(const Particle* part)
164  {
165  const auto& frame = ReferenceFrame::GetCurrent();
166  return frame.getVertex(part).Y();
167  }
168 
169  double particleZ(const Particle* part)
170  {
171  const auto& frame = ReferenceFrame::GetCurrent();
172  return frame.getVertex(part).Z();
173  }
174 
175  inline double getParticleUncertaintyByIndex(const Particle* part, unsigned int index)
176  {
177  if (!part) {
178  B2FATAL("The particle provide does not exist.");
179  }
180  const auto& errMatrix = part->getVertexErrorMatrix();
181  return std::sqrt(errMatrix(index, index));
182  }
183 
184  double particleDXUncertainty(const Particle* part)
185  {
186  // uncertainty on x (with respect to the origin)
187  return getParticleUncertaintyByIndex(part, 0);
188  }
189 
190  double particleDYUncertainty(const Particle* part)
191  {
192  // uncertainty on y (with respect to the origin)
193  return getParticleUncertaintyByIndex(part, 1);
194  }
195 
196  double particleDZUncertainty(const Particle* part)
197  {
198  // uncertainty on z (with respect to the origin)
199  return getParticleUncertaintyByIndex(part, 2);
200  }
201 
202  //----------------------------------------------------------------------------------
203  // vertex or POCA with respect to measured IP
204 
205  B2Vector3D getVertexD(const Particle* part)
206  {
207  static DBObjPtr<BeamSpot> beamSpotDB;
208  const auto& frame = ReferenceFrame::GetCurrent();
209  auto trackFit = part->getTrackFitResult();
210  if (!trackFit)
211  return frame.getVertex(part->getVertex() - ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
212 
213  UncertainHelix helix = trackFit->getUncertainHelix();
214  helix.passiveMoveBy(ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
215  return frame.getVertex(helix.getPerigee());
216  }
217 
218 
219  double particleDX(const Particle* part)
220  {
221  return getVertexD(part).X();
222  }
223 
224  double particleDY(const Particle* part)
225  {
226  return getVertexD(part).Y();
227  }
228 
229  double particleDZ(const Particle* part)
230  {
231  return getVertexD(part).Z();
232  }
233 
234  double particleDRho(const Particle* part)
235  {
236  return getVertexD(part).Perp();
237  }
238 
239  double particleDPhi(const Particle* part)
240  {
241  return getVertexD(part).Phi();
242  }
243 
244  double particleDCosTheta(const Particle* part)
245  {
246  return getVertexD(part).CosTheta();
247  }
248 
249  double particleDistance(const Particle* part)
250  {
251  return getVertexD(part).Mag();
252  }
253 
254  double particleDistanceSignificance(const Particle* part)
255  {
256  // significance is defined as s = r/sigma_r, therefore:
257  // s &= \frac{r}{\sqrt{ \sum_{ij} \frac{\partial r}{x_i} V_{ij} \frac{\partial r}{x_j}}}
258  // &= \frac{r^2}{\sqrt{\vec{x}V\vec{x}}}
259  // where:
260  // r &= \sqrt{\vec{x}*\vec{x}}
261  // and V_{ij} is the covariance matrix
262  static DBObjPtr<BeamSpot> beamSpotDB;
263  const auto& frame = ReferenceFrame::GetCurrent();
264  const B2Vector3D& vertex = frame.getVertex(part->getVertex() - ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
265  const TMatrixFSym& vertexErr = frame.getVertexErrorMatrix(static_cast<TMatrixDSym>(part->getVertexErrorMatrix()) +
266  beamSpotDB->getCovVertex());
267  const double denominator = vertex * B2Vector3D(vertexErr * vertex);
268  if (denominator <= 0) return Const::doubleNaN;
269 
270  return vertex.Mag2() / std::sqrt(denominator);
271  }
272 
273  // Production vertex position
274 
275  double particleProductionX(const Particle* part)
276  {
277  if (!part->hasExtraInfo("prodVertX")) return Const::doubleNaN;
278  return part->getExtraInfo("prodVertX");
279  }
280 
281  double particleProductionY(const Particle* part)
282  {
283  if (!part->hasExtraInfo("prodVertY")) return Const::doubleNaN;
284  return part->getExtraInfo("prodVertY");
285  }
286 
287  double particleProductionZ(const Particle* part)
288  {
289  if (!part->hasExtraInfo("prodVertZ")) return Const::doubleNaN;
290  return part->getExtraInfo("prodVertZ");
291  }
292 
293  // Production vertex covariance matrix
294  double particleProductionCovElement(const Particle* part, const std::vector<double>& indices)
295  {
296  if (indices.size() != 2) {
297  B2FATAL("Number of arguments of prodVertexCov function is incorrect!");
298  }
299 
300  int ielement = std::lround(indices[0]);
301  int jelement = std::lround(indices[1]);
302 
303  if (std::min(ielement, jelement) < 0 || std::max(ielement, jelement) > 2) {
304  B2ERROR("Range of indexes of prodVertexCov function is incorrect!");
305  }
306 
307  const std::vector<char> names = {'x', 'y', 'z'};
308  const std::string prodVertS = Form("prodVertS%c%c", names[ielement], names[jelement]);
309 
310  if (!part->hasExtraInfo(prodVertS)) return Const::doubleNaN;
311  return part->getExtraInfo(prodVertS);
312  }
313 
314  double particleProductionXErr(const Particle* part)
315  {
316  if (!part->hasExtraInfo("prodVertSxx")) return Const::doubleNaN;
317  return std::sqrt(part->getExtraInfo("prodVertSxx"));
318  }
319 
320  double particleProductionYErr(const Particle* part)
321  {
322  if (!part->hasExtraInfo("prodVertSyy")) return Const::doubleNaN;
323  return std::sqrt(part->getExtraInfo("prodVertSyy"));
324  }
325 
326  double particleProductionZErr(const Particle* part)
327  {
328  if (!part->hasExtraInfo("prodVertSzz")) return Const::doubleNaN;
329  return std::sqrt(part->getExtraInfo("prodVertSzz"));
330  }
331 
332  VARIABLE_GROUP("Vertex Information");
333  // Generated vertex information
334  REGISTER_VARIABLE("mcDecayVertexX", mcDecayVertexX,
335  "Returns the x position of the decay vertex of the matched generated particle. Returns nan if the particle has no matched generated particle.\n\n",
336  "cm");
337  REGISTER_VARIABLE("mcDecayVertexY", mcDecayVertexY,
338  "Returns the y position of the decay vertex of the matched generated particle. Returns nan if the particle has no matched generated particle.\n\n",
339  "cm");
340  REGISTER_VARIABLE("mcDecayVertexZ", mcDecayVertexZ,
341  "Returns the z position of the decay vertex of the matched generated particle. Returns nan if the particle has no matched generated particle.\n\n",
342  "cm");
343  REGISTER_VARIABLE("mcDecayVertexRho", mcDecayVertexRho,
344  "Returns the transverse position of the decay vertex of the matched generated particle. Returns nan if the particle has no matched generated particle.\n\n",
345  "cm");
346  REGISTER_VARIABLE("mcDecayVertexFromIPX", mcDecayVertexFromIPX,
347  "Returns the x position of the decay vertex of the matched generated particle wrt the IP. Returns nan if the particle has no matched generated particle.\n\n",
348  "cm");
349  REGISTER_VARIABLE("mcDecayVertexFromIPY", mcDecayVertexFromIPY,
350  "Returns the y position of the decay vertex of the matched generated particle wrt the IP. Returns nan if the particle has no matched generated particle.\n\n",
351  "cm");
352  REGISTER_VARIABLE("mcDecayVertexFromIPZ", mcDecayVertexFromIPZ,
353  "Returns the z position of the decay vertex of the matched generated particle wrt the IP. Returns nan if the particle has no matched generated particle.\n\n",
354  "cm");
355  REGISTER_VARIABLE("mcDecayVertexFromIPRho", mcDecayVertexFromIPRho,
356  "Returns the transverse position of the decay vertex of the matched generated particle wrt the IP. Returns nan if the particle has no matched generated particle.\n\n",
357  "cm");
358  REGISTER_VARIABLE("mcDecayVertexFromIPDistance", mcDecayVertexFromIPDistance,
359  "Returns the distance of the decay vertex of the matched generated particle from the IP. Returns nan if the particle has no matched generated particle.\n\n",
360  "cm");
361  REGISTER_VARIABLE("mcProductionVertexX", mcProductionVertexX,
362  "Returns the x position of production vertex of matched generated particle. Returns nan if the particle has no matched generated particle.\n\n",
363  "cm");
364  REGISTER_VARIABLE("mcProductionVertexY", mcProductionVertexY,
365  "Returns the y position of production vertex of matched generated particle. Returns nan if the particle has no matched generated particle.\n\n",
366  "cm");
367  REGISTER_VARIABLE("mcProductionVertexZ", mcProductionVertexZ,
368  "Returns the z position of production vertex of matched generated particle. Returns nan if the particle has no matched generated particle.\n\n",
369  "cm");
370  REGISTER_VARIABLE("mcProductionVertexFromIPX", mcProductionVertexFromIPX,
371  "Returns the x position of the production vertex of the matched generated particle wrt the IP. Returns nan if the particle has no matched generated particle.\n\n",
372  "cm");
373  REGISTER_VARIABLE("mcProductionVertexFromIPY", mcProductionVertexFromIPY,
374  "Returns the y position of the production vertex of the matched generated particle wrt the IP. Returns nan if the particle has no matched generated particle.\n\n",
375  "cm");
376  REGISTER_VARIABLE("mcProductionVertexFromIPZ", mcProductionVertexFromIPZ,
377  "Returns the z position of the production vertex of the matched generated particle wrt the IP. Returns nan if the particle has no matched generated particle.\n\n",
378  "cm");
379 
380  // Decay vertex position
381  REGISTER_VARIABLE("distance", particleDistance,
382  R"DOC(3D distance between the IP and the particle decay vertex, if available.
383 
384 In case the particle has been created from a track, the distance is defined between the POCA and IP.
385 If the particle is built from an ECL cluster, the decay vertex is set to the nominal IP.
386 If the particle is created from a KLM cluster, the distance is calculated between the IP and the cluster itself.
387 
388 )DOC", "cm");
389 
390  REGISTER_VARIABLE("significanceOfDistance", particleDistanceSignificance,
391  "significance of distance from vertex or POCA to interaction point(-1 in case of numerical problems)");
392  REGISTER_VARIABLE("dx", particleDX, "vertex or POCA in case of tracks x with respect to IP\n\n", "cm");
393  REGISTER_VARIABLE("dy", particleDY, "vertex or POCA in case of tracks y with respect to IP\n\n", "cm");
394  REGISTER_VARIABLE("dz", particleDZ, "vertex or POCA in case of tracks z with respect to IP\n\n", "cm");
395  REGISTER_VARIABLE("x", particleX,
396  "x coordinate of vertex in case of composite particle, or point of closest approach (POCA) in case of a track\n\n", "cm");
397  REGISTER_VARIABLE("y", particleY,
398  "y coordinate of vertex in case of composite particle, or point of closest approach (POCA) in case of a track\n\n", "cm");
399  REGISTER_VARIABLE("z", particleZ,
400  "z coordinate of vertex in case of composite particle, or point of closest approach (POCA) in case of a track\n\n", "cm");
401  REGISTER_VARIABLE("x_uncertainty", particleDXUncertainty, "uncertainty on x (measured with respect to the origin)\n\n", "cm");
402  REGISTER_VARIABLE("y_uncertainty", particleDYUncertainty, "uncertainty on y (measured with respect to the origin)\n\n", "cm");
403  REGISTER_VARIABLE("z_uncertainty", particleDZUncertainty, "uncertainty on z (measured with respect to the origin)\n\n", "cm");
404  REGISTER_VARIABLE("dr", particleDRho, "transverse distance with respect to IP for a vertex; track abs(d0) relative to IP for a track.\n\n",
405  "cm");
406  REGISTER_VARIABLE("dphi", particleDPhi, "vertex azimuthal angle of the vertex or POCA in degrees with respect to IP\n\n", "rad");
407  REGISTER_VARIABLE("dcosTheta", particleDCosTheta, "vertex or POCA polar angle with respect to IP");
408  // Production vertex position
409  REGISTER_VARIABLE("prodVertexX", particleProductionX,
410  "Returns the x position of particle production vertex. Returns NaN if particle has no production vertex.\n\n", "cm");
411  REGISTER_VARIABLE("prodVertexY", particleProductionY,
412  "Returns the y position of particle production vertex.\n\n", "cm");
413  REGISTER_VARIABLE("prodVertexZ", particleProductionZ,
414  "Returns the z position of particle production vertex.\n\n", "cm");
415  // Production vertex covariance matrix
416  REGISTER_VARIABLE("prodVertexCov(i,j)", particleProductionCovElement,
417  "Returns the ij covariance matrix component of particle production vertex, arguments i,j should be 0, 1 or 2. Returns NaN if particle has no production covariance matrix.\n\n",
418  ":math:`\\text{cm}^2`");
419  REGISTER_VARIABLE("prodVertexXErr", particleProductionXErr,
420  "Returns the x position uncertainty of particle production vertex. Returns NaN if particle has no production vertex.\n\n", "cm");
421  REGISTER_VARIABLE("prodVertexYErr", particleProductionYErr,
422  "Returns the y position uncertainty of particle production vertex.\n\n", "cm");
423  REGISTER_VARIABLE("prodVertexZErr", particleProductionZErr,
424  "Returns the z position uncertainty of particle production vertex.\n\n", "cm");
425 
426  }
428 }
DataType Phi() const
The azimuth angle.
Definition: B2Vector3.h:151
DataType Z() const
access variable Z (= .at(2) without boundary check)
Definition: B2Vector3.h:435
DataType CosTheta() const
Cosine of the polar angle.
Definition: B2Vector3.h:155
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
DataType Mag() const
The magnitude (rho in spherical coordinate system).
Definition: B2Vector3.h:159
DataType Perp() const
The transverse component (R in cylindrical coordinate system).
Definition: B2Vector3.h:200
static const double doubleNaN
quiet_NaN
Definition: Const.h:694
static const ReferenceFrame & GetCurrent()
Get current rest frame.
B2Vector3< double > B2Vector3D
typedef for common usage with double
Definition: B2Vector3.h:516
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.