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