Belle II Software development
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 B2Vector3D getMcDecayVertexFromIP(const MCParticle* mcparticle)
64 {
65 static DBObjPtr<BeamSpot> beamSpotDB;
66 const auto& frame = ReferenceFrame::GetCurrent();
67 return frame.getVertex(mcparticle->getDecayVertex() - ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
68 }
69
70 double mcDecayVertexFromIPX(const Particle* part)
71 {
72 auto* mcparticle = part->getMCParticle();
73 if (!mcparticle) return Const::doubleNaN;
74 return getMcDecayVertexFromIP(mcparticle).X();
75 }
76
77 double mcDecayVertexFromIPY(const Particle* part)
78 {
79 auto* mcparticle = part->getMCParticle();
80 if (!mcparticle) return Const::doubleNaN;
81 return getMcDecayVertexFromIP(mcparticle).Y();
82 }
83
84 double mcDecayVertexFromIPZ(const Particle* part)
85 {
86 auto* mcparticle = part->getMCParticle();
87 if (!mcparticle) return Const::doubleNaN;
88 return getMcDecayVertexFromIP(mcparticle).Z();
89 }
90
91 double mcDecayVertexFromIPRho(const Particle* part)
92 {
93 auto* mcparticle = part->getMCParticle();
94 if (!mcparticle) return Const::doubleNaN;
95 return getMcDecayVertexFromIP(mcparticle).Perp();
96 }
97
98 double mcDecayVertexFromIPDistance(const Particle* part)
99 {
100 auto* mcparticle = part->getMCParticle();
101 if (!mcparticle) return Const::doubleNaN;
102 return getMcDecayVertexFromIP(mcparticle).Mag();
103 }
104
105 double mcProductionVertexX(const Particle* part)
106 {
107 auto* mcparticle = part->getMCParticle();
108 if (!mcparticle) return Const::doubleNaN;
109 return mcparticle->getProductionVertex().X();
110 }
111
112 double mcProductionVertexY(const Particle* part)
113 {
114 auto* mcparticle = part->getMCParticle();
115 if (!mcparticle) return Const::doubleNaN;
116 return mcparticle->getProductionVertex().Y();
117 }
118
119 double mcProductionVertexZ(const Particle* part)
120 {
121 auto* mcparticle = part->getMCParticle();
122 if (!mcparticle) return Const::doubleNaN;
123 return mcparticle->getProductionVertex().Z();
124 }
125
126 B2Vector3D getMcProductionVertexFromIP(const MCParticle* mcparticle)
127 {
128 static DBObjPtr<BeamSpot> beamSpotDB;
129 const auto& frame = ReferenceFrame::GetCurrent();
130 return frame.getVertex(mcparticle->getProductionVertex() - ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
131 }
132
133 double mcProductionVertexFromIPX(const Particle* part)
134 {
135 auto* mcparticle = part->getMCParticle();
136 if (!mcparticle) return Const::doubleNaN;
137 return getMcProductionVertexFromIP(mcparticle).X();
138 }
139
140 double mcProductionVertexFromIPY(const Particle* part)
141 {
142 auto* mcparticle = part->getMCParticle();
143 if (!mcparticle) return Const::doubleNaN;
144 return getMcProductionVertexFromIP(mcparticle).Y();
145 }
146
147 double mcProductionVertexFromIPZ(const Particle* part)
148 {
149 auto* mcparticle = part->getMCParticle();
150 if (!mcparticle) return Const::doubleNaN;
151 return getMcProductionVertexFromIP(mcparticle).Z();
152 }
153
154 // vertex or POCA with respect to origin ------------------------------
155
156 double particleX(const Particle* part)
157 {
158 const auto& frame = ReferenceFrame::GetCurrent();
159 return frame.getVertex(part).X();
160 }
161
162 double particleY(const Particle* part)
163 {
164 const auto& frame = ReferenceFrame::GetCurrent();
165 return frame.getVertex(part).Y();
166 }
167
168 double particleZ(const Particle* part)
169 {
170 const auto& frame = ReferenceFrame::GetCurrent();
171 return frame.getVertex(part).Z();
172 }
173
174 inline double getParticleUncertaintyByIndex(const Particle* part, unsigned int index)
175 {
176 if (!part) {
177 B2FATAL("The particle provide does not exist.");
178 }
179 const auto& errMatrix = part->getVertexErrorMatrix();
180 return std::sqrt(errMatrix(index, index));
181 }
182
183 double particleDXUncertainty(const Particle* part)
184 {
185 // uncertainty on x (with respect to the origin)
186 return getParticleUncertaintyByIndex(part, 0);
187 }
188
189 double particleDYUncertainty(const Particle* part)
190 {
191 // uncertainty on y (with respect to the origin)
192 return getParticleUncertaintyByIndex(part, 1);
193 }
194
195 double particleDZUncertainty(const Particle* part)
196 {
197 // uncertainty on z (with respect to the origin)
198 return getParticleUncertaintyByIndex(part, 2);
199 }
200
201 //----------------------------------------------------------------------------------
202 // vertex or POCA with respect to measured IP
203
204 B2Vector3D getVertexD(const Particle* part)
205 {
206 static DBObjPtr<BeamSpot> beamSpotDB;
207 const auto& frame = ReferenceFrame::GetCurrent();
208 auto trackFit = part->getTrackFitResult();
209 if (!trackFit)
210 return frame.getVertex(part->getVertex() - ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
211
212 UncertainHelix helix = trackFit->getUncertainHelix();
213 helix.passiveMoveBy(ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
214 return frame.getVertex(helix.getPerigee());
215 }
216
217
218 double particleDX(const Particle* part)
219 {
220 return getVertexD(part).X();
221 }
222
223 double particleDY(const Particle* part)
224 {
225 return getVertexD(part).Y();
226 }
227
228 double particleDZ(const Particle* part)
229 {
230 return getVertexD(part).Z();
231 }
232
233 double particleDRho(const Particle* part)
234 {
235 return getVertexD(part).Perp();
236 }
237
238 double particleDPhi(const Particle* part)
239 {
240 return getVertexD(part).Phi();
241 }
242
243 double particleDCosTheta(const Particle* part)
244 {
245 return getVertexD(part).CosTheta();
246 }
247
248 double particleDistance(const Particle* part)
249 {
250 return getVertexD(part).Mag();
251 }
252
253 double particleDistanceSignificance(const Particle* part)
254 {
255 // significance is defined as s = r/sigma_r, therefore:
256 // s &= \frac{r}{\sqrt{ \sum_{ij} \frac{\partial r}{x_i} V_{ij} \frac{\partial r}{x_j}}}
257 // &= \frac{r^2}{\sqrt{\vec{x}V\vec{x}}}
258 // where:
259 // r &= \sqrt{\vec{x}*\vec{x}}
260 // and V_{ij} is the covariance matrix
261 static DBObjPtr<BeamSpot> beamSpotDB;
262 const auto& frame = ReferenceFrame::GetCurrent();
263 const B2Vector3D& vertex = frame.getVertex(part->getVertex() - ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
264 const TMatrixFSym& vertexErr = frame.getVertexErrorMatrix(static_cast<TMatrixDSym>(part->getVertexErrorMatrix()) +
265 beamSpotDB->getCovVertex());
266 const double denominator = vertex * B2Vector3D(vertexErr * vertex);
267 if (denominator <= 0) return Const::doubleNaN;
268
269 return vertex.Mag2() / std::sqrt(denominator);
270 }
271
272 // Production vertex position
273
274 double particleProductionX(const Particle* part)
275 {
276 if (part->hasExtraInfo("prodVertX")) return part->getExtraInfo("prodVertX");
277 else if (part->hasExtraInfo("prodVertexX")) return part->getExtraInfo("prodVertexX");
278 else return Const::doubleNaN;
279 }
280
281 double particleProductionY(const Particle* part)
282 {
283 if (part->hasExtraInfo("prodVertY")) return part->getExtraInfo("prodVertY");
284 else if (part->hasExtraInfo("prodVertexY")) return part->getExtraInfo("prodVertexY");
285 else return Const::doubleNaN;
286 }
287
288 double particleProductionZ(const Particle* part)
289 {
290 if (part->hasExtraInfo("prodVertZ")) return part->getExtraInfo("prodVertZ");
291 else if (part->hasExtraInfo("prodVertexZ")) return part->getExtraInfo("prodVertexZ");
292 else return Const::doubleNaN;
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 Const::doubleNaN;
313 return part->getExtraInfo(prodVertS);
314 }
315
316 double particleProductionXErr(const Particle* part)
317 {
318 if (!part->hasExtraInfo("prodVertSxx")) return Const::doubleNaN;
319 return std::sqrt(part->getExtraInfo("prodVertSxx"));
320 }
321
322 double particleProductionYErr(const Particle* part)
323 {
324 if (!part->hasExtraInfo("prodVertSyy")) return Const::doubleNaN;
325 return std::sqrt(part->getExtraInfo("prodVertSyy"));
326 }
327
328 double particleProductionZErr(const Particle* part)
329 {
330 if (!part->hasExtraInfo("prodVertSzz")) return Const::doubleNaN;
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.\n\n",
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.\n\n",
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.\n\n",
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.\n\n",
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.\n\n",
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.\n\n",
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.\n\n",
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.\n\n",
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.\n\n",
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.\n\n",
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.\n\n",
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.\n\n",
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.\n\n",
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.\n\n",
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.\n\n",
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
386In case the particle has been created from a track, the distance is defined between the POCA and IP.
387If the particle is built from an ECL cluster, the decay vertex is set to the nominal IP.
388If the particle is created from a KLM cluster, the distance is calculated between the IP and the cluster itself.
389
390)DOC", "cm");
391
392 REGISTER_VARIABLE("significanceOfDistance", particleDistanceSignificance,
393 "significance of distance from vertex or POCA to interaction point(-1 in case of numerical problems)");
394 REGISTER_VARIABLE("dx", particleDX, "vertex or POCA in case of tracks x with respect to IP\n\n", "cm");
395 REGISTER_VARIABLE("dy", particleDY, "vertex or POCA in case of tracks y with respect to IP\n\n", "cm");
396 REGISTER_VARIABLE("dz", particleDZ, "vertex or POCA in case of tracks z with respect to IP\n\n", "cm");
397 REGISTER_VARIABLE("x", particleX,
398 "x 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("y", particleY,
400 "y 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("z", particleZ,
402 "z coordinate of vertex in case of composite particle, or point of closest approach (POCA) in case of a track\n\n", "cm");
403 REGISTER_VARIABLE("x_uncertainty", particleDXUncertainty, "uncertainty on x (measured with respect to the origin)\n\n", "cm");
404 REGISTER_VARIABLE("y_uncertainty", particleDYUncertainty, "uncertainty on y (measured with respect to the origin)\n\n", "cm");
405 REGISTER_VARIABLE("z_uncertainty", particleDZUncertainty, "uncertainty on z (measured with respect to the origin)\n\n", "cm");
406 REGISTER_VARIABLE("dr", particleDRho, "transverse distance with respect to IP for a vertex; track abs(d0) relative to IP for a track.\n\n",
407 "cm");
408 REGISTER_VARIABLE("dphi", particleDPhi, "vertex azimuthal angle of the vertex or POCA in degrees with respect to IP\n\n", "rad");
409 REGISTER_VARIABLE("dcosTheta", particleDCosTheta, "vertex or POCA polar angle with respect to IP");
410 // Production vertex position
411 REGISTER_VARIABLE("prodVertexX", particleProductionX,
412 "Returns the x position of particle production vertex. Returns NaN if particle has no production vertex.\n\n", "cm");
413 REGISTER_VARIABLE("prodVertexY", particleProductionY,
414 "Returns the y position of particle production vertex.\n\n", "cm");
415 REGISTER_VARIABLE("prodVertexZ", particleProductionZ,
416 "Returns the z position of particle production vertex.\n\n", "cm");
417 // Production vertex covariance matrix
418 REGISTER_VARIABLE("prodVertexCov(i,j)", particleProductionCovElement,
419 "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",
420 ":math:`\\text{cm}^2`");
421 REGISTER_VARIABLE("prodVertexXErr", particleProductionXErr,
422 "Returns the x position uncertainty of particle production vertex. Returns NaN if particle has no production vertex.\n\n", "cm");
423 REGISTER_VARIABLE("prodVertexYErr", particleProductionYErr,
424 "Returns the y position uncertainty of particle production vertex.\n\n", "cm");
425 REGISTER_VARIABLE("prodVertexZErr", particleProductionZErr,
426 "Returns the z position uncertainty of particle production vertex.\n\n", "cm");
427
428 }
430}
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:703
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.