9 #include <analysis/variables/VertexVariables.h>
11 #include <analysis/dataobjects/Particle.h>
12 #include <analysis/utility/ReferenceFrame.h>
14 #include <framework/database/DBObjPtr.h>
15 #include <framework/logging/Logger.h>
16 #include <framework/utilities/Conversion.h>
18 #include <TMatrixFSym.h>
20 #include <mdst/dbobjects/BeamSpot.h>
21 #include <mdst/dataobjects/MCParticle.h>
22 #include <mdst/dataobjects/Track.h>
23 #include <mdst/dataobjects/TrackFitResult.h>
35 static const double realNaN = std::numeric_limits<double>::quiet_NaN();
38 double mcDecayVertexX(
const Particle* part)
40 auto* mcparticle = part->getMCParticle();
41 if (!mcparticle)
return realNaN;
42 return mcparticle->getDecayVertex().X();
45 double mcDecayVertexY(
const Particle* part)
47 auto* mcparticle = part->getMCParticle();
48 if (!mcparticle)
return realNaN;
49 return mcparticle->getDecayVertex().Y();
52 double mcDecayVertexZ(
const Particle* part)
54 auto* mcparticle = part->getMCParticle();
55 if (!mcparticle)
return realNaN;
56 return mcparticle->getDecayVertex().Z();
59 double mcDecayVertexRho(
const Particle* part)
61 auto* mcparticle = part->getMCParticle();
62 if (!mcparticle)
return realNaN;
63 return mcparticle->getDecayVertex().Rho();
66 B2Vector3D getMcDecayVertexFromIP(
const MCParticle* mcparticle)
68 static DBObjPtr<BeamSpot> beamSpotDB;
70 return frame.getVertex(mcparticle->getDecayVertex() - ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
73 double mcDecayVertexFromIPX(
const Particle* part)
75 auto* mcparticle = part->getMCParticle();
76 if (!mcparticle)
return realNaN;
77 return getMcDecayVertexFromIP(mcparticle).
X();
80 double mcDecayVertexFromIPY(
const Particle* part)
82 auto* mcparticle = part->getMCParticle();
83 if (!mcparticle)
return realNaN;
84 return getMcDecayVertexFromIP(mcparticle).
Y();
87 double mcDecayVertexFromIPZ(
const Particle* part)
89 auto* mcparticle = part->getMCParticle();
90 if (!mcparticle)
return realNaN;
91 return getMcDecayVertexFromIP(mcparticle).
Z();
94 double mcDecayVertexFromIPRho(
const Particle* part)
96 auto* mcparticle = part->getMCParticle();
97 if (!mcparticle)
return realNaN;
98 return getMcDecayVertexFromIP(mcparticle).
Perp();
101 double mcDecayVertexFromIPDistance(
const Particle* part)
103 auto* mcparticle = part->getMCParticle();
104 if (!mcparticle)
return realNaN;
105 return getMcDecayVertexFromIP(mcparticle).
Mag();
108 double mcProductionVertexX(
const Particle* part)
110 auto* mcparticle = part->getMCParticle();
111 if (!mcparticle)
return realNaN;
112 return mcparticle->getProductionVertex().X();
115 double mcProductionVertexY(
const Particle* part)
117 auto* mcparticle = part->getMCParticle();
118 if (!mcparticle)
return realNaN;
119 return mcparticle->getProductionVertex().Y();
122 double mcProductionVertexZ(
const Particle* part)
124 auto* mcparticle = part->getMCParticle();
125 if (!mcparticle)
return realNaN;
126 return mcparticle->getProductionVertex().Z();
129 B2Vector3D getMcProductionVertexFromIP(
const MCParticle* mcparticle)
131 static DBObjPtr<BeamSpot> beamSpotDB;
133 return frame.getVertex(mcparticle->getProductionVertex() - ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
136 double mcProductionVertexFromIPX(
const Particle* part)
138 auto* mcparticle = part->getMCParticle();
139 if (!mcparticle)
return realNaN;
140 return getMcProductionVertexFromIP(mcparticle).
X();
143 double mcProductionVertexFromIPY(
const Particle* part)
145 auto* mcparticle = part->getMCParticle();
146 if (!mcparticle)
return realNaN;
147 return getMcProductionVertexFromIP(mcparticle).
Y();
150 double mcProductionVertexFromIPZ(
const Particle* part)
152 auto* mcparticle = part->getMCParticle();
153 if (!mcparticle)
return realNaN;
154 return getMcProductionVertexFromIP(mcparticle).
Z();
159 double particleX(
const Particle* part)
162 return frame.getVertex(part).X();
165 double particleY(
const Particle* part)
168 return frame.getVertex(part).Y();
171 double particleZ(
const Particle* part)
174 return frame.getVertex(part).Z();
177 inline double getParticleUncertaintyByIndex(
const Particle* part,
unsigned int index)
180 B2FATAL(
"The particle provide does not exist.");
182 const auto& errMatrix = part->getVertexErrorMatrix();
183 return std::sqrt(errMatrix(index, index));
186 double particleDXUncertainty(
const Particle* part)
189 return getParticleUncertaintyByIndex(part, 0);
192 double particleDYUncertainty(
const Particle* part)
195 return getParticleUncertaintyByIndex(part, 1);
198 double particleDZUncertainty(
const Particle* part)
201 return getParticleUncertaintyByIndex(part, 2);
209 static DBObjPtr<BeamSpot> beamSpotDB;
211 auto trackFit = part->getTrackFitResult();
213 return frame.getVertex(part->getVertex() - ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
215 UncertainHelix helix = trackFit->getUncertainHelix();
216 helix.passiveMoveBy(ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
217 return frame.getVertex(helix.getPerigee());
221 double particleDX(
const Particle* part)
223 return getVertexD(part).
X();
226 double particleDY(
const Particle* part)
228 return getVertexD(part).
Y();
231 double particleDZ(
const Particle* part)
233 return getVertexD(part).
Z();
236 double particleDRho(
const Particle* part)
238 return getVertexD(part).
Perp();
241 double particleDPhi(
const Particle* part)
243 return getVertexD(part).
Phi();
246 double particleDCosTheta(
const Particle* part)
251 double particleDistance(
const Particle* part)
253 return getVertexD(part).
Mag();
256 double particleDistanceSignificance(
const Particle* part)
264 static DBObjPtr<BeamSpot> beamSpotDB;
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;
272 return vertex.Mag2() / std::sqrt(denominator);
277 double particleProductionX(
const Particle* part)
279 if (!part->hasExtraInfo(
"prodVertX"))
return realNaN;
280 return part->getExtraInfo(
"prodVertX");
283 double particleProductionY(
const Particle* part)
285 if (!part->hasExtraInfo(
"prodVertY"))
return realNaN;
286 return part->getExtraInfo(
"prodVertY");
289 double particleProductionZ(
const Particle* part)
291 if (!part->hasExtraInfo(
"prodVertZ"))
return realNaN;
292 return part->getExtraInfo(
"prodVertZ");
296 double particleProductionCovElement(
const Particle* part,
const std::vector<double>& indices)
298 if (indices.size() != 2) {
299 B2FATAL(
"Number of arguments of prodVertexCov function is incorrect!");
302 int ielement = std::lround(indices[0]);
303 int jelement = std::lround(indices[1]);
305 if (std::min(ielement, jelement) < 0 || std::max(ielement, jelement) > 2) {
306 B2ERROR(
"Range of indexes of prodVertexCov function is incorrect!");
309 const std::vector<char> names = {
'x',
'y',
'z'};
310 const std::string prodVertS = Form(
"prodVertS%c%c", names[ielement], names[jelement]);
312 if (!part->hasExtraInfo(prodVertS))
return realNaN;
313 return part->getExtraInfo(prodVertS);
316 double particleProductionXErr(
const Particle* part)
318 if (!part->hasExtraInfo(
"prodVertSxx"))
return realNaN;
319 return std::sqrt(part->getExtraInfo(
"prodVertSxx"));
322 double particleProductionYErr(
const Particle* part)
324 if (!part->hasExtraInfo(
"prodVertSyy"))
return realNaN;
325 return std::sqrt(part->getExtraInfo(
"prodVertSyy"));
328 double particleProductionZErr(
const Particle* part)
330 if (!part->hasExtraInfo(
"prodVertSzz"))
return realNaN;
331 return std::sqrt(part->getExtraInfo(
"prodVertSzz"));
334 VARIABLE_GROUP(
"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.",
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.",
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.",
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.",
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.",
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.",
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.",
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.",
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.",
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.",
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.",
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.",
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.",
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.",
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.",
383 REGISTER_VARIABLE(
"distance", particleDistance,
384 R
"DOC(3D distance between the IP and the particle decay vertex, if available.
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");
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.",
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");
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");
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");
DataType Phi() const
The azimuth angle.
DataType Z() const
access variable Z (= .at(2) without boundary check)
DataType CosTheta() const
Cosine of the polar angle.
DataType X() const
access variable X (= .at(0) without boundary check)
DataType Y() const
access variable Y (= .at(1) without boundary check)
DataType Mag() const
The magnitude (rho in spherical coordinate system).
DataType Perp() const
The transverse component (R in cylindrical coordinate system).
static const ReferenceFrame & GetCurrent()
Get current rest frame.
B2Vector3< double > B2Vector3D
typedef for common usage with double
Abstract base class for different kinds of events.