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