9 #include <analysis/variables/VertexVariables.h>
10 #include <analysis/utility/ReferenceFrame.h>
12 #include <framework/database/DBObjPtr.h>
13 #include <framework/logging/Logger.h>
14 #include <framework/utilities/Conversion.h>
16 #include <TMatrixFSym.h>
19 #include <mdst/dbobjects/BeamSpot.h>
20 #include <mdst/dataobjects/MCParticle.h>
21 #include <mdst/dataobjects/Track.h>
22 #include <mdst/dataobjects/TrackFitResult.h>
34 static const double realNaN = std::numeric_limits<double>::quiet_NaN();
37 double mcDecayVertexX(
const Particle* part)
39 auto* mcparticle = part->getMCParticle();
40 if (!mcparticle)
return realNaN;
41 return mcparticle->getDecayVertex().X();
44 double mcDecayVertexY(
const Particle* part)
46 auto* mcparticle = part->getMCParticle();
47 if (!mcparticle)
return realNaN;
48 return mcparticle->getDecayVertex().Y();
51 double mcDecayVertexZ(
const Particle* part)
53 auto* mcparticle = part->getMCParticle();
54 if (!mcparticle)
return realNaN;
55 return mcparticle->getDecayVertex().Z();
58 double mcDecayVertexRho(
const Particle* part)
60 auto* mcparticle = part->getMCParticle();
61 if (!mcparticle)
return realNaN;
62 return mcparticle->getDecayVertex().Perp();
65 TVector3 getMcDecayVertexFromIP(
const MCParticle* mcparticle)
67 static DBObjPtr<BeamSpot> beamSpotDB;
69 return frame.getVertex(mcparticle->getDecayVertex() - beamSpotDB->getIPPosition());
72 double mcDecayVertexFromIPX(
const Particle* part)
74 auto* mcparticle = part->getMCParticle();
75 if (!mcparticle)
return realNaN;
76 return getMcDecayVertexFromIP(mcparticle).X();
79 double mcDecayVertexFromIPY(
const Particle* part)
81 auto* mcparticle = part->getMCParticle();
82 if (!mcparticle)
return realNaN;
83 return getMcDecayVertexFromIP(mcparticle).Y();
86 double mcDecayVertexFromIPZ(
const Particle* part)
88 auto* mcparticle = part->getMCParticle();
89 if (!mcparticle)
return realNaN;
90 return getMcDecayVertexFromIP(mcparticle).Z();
93 double mcDecayVertexFromIPRho(
const Particle* part)
95 auto* mcparticle = part->getMCParticle();
96 if (!mcparticle)
return realNaN;
97 return getMcDecayVertexFromIP(mcparticle).Perp();
100 double mcDecayVertexFromIPDistance(
const Particle* part)
102 auto* mcparticle = part->getMCParticle();
103 if (!mcparticle)
return realNaN;
104 return getMcDecayVertexFromIP(mcparticle).Mag();
107 double mcProductionVertexX(
const Particle* part)
109 auto* mcparticle = part->getMCParticle();
110 if (!mcparticle)
return realNaN;
111 return mcparticle->getProductionVertex().X();
114 double mcProductionVertexY(
const Particle* part)
116 auto* mcparticle = part->getMCParticle();
117 if (!mcparticle)
return realNaN;
118 return mcparticle->getProductionVertex().Y();
121 double mcProductionVertexZ(
const Particle* part)
123 auto* mcparticle = part->getMCParticle();
124 if (!mcparticle)
return realNaN;
125 return mcparticle->getProductionVertex().Z();
128 TVector3 getMcProductionVertexFromIP(
const MCParticle* mcparticle)
130 static DBObjPtr<BeamSpot> beamSpotDB;
132 return frame.getVertex(mcparticle->getProductionVertex() - beamSpotDB->getIPPosition());
135 double mcProductionVertexFromIPX(
const Particle* part)
137 auto* mcparticle = part->getMCParticle();
138 if (!mcparticle)
return realNaN;
139 return getMcProductionVertexFromIP(mcparticle).X();
142 double mcProductionVertexFromIPY(
const Particle* part)
144 auto* mcparticle = part->getMCParticle();
145 if (!mcparticle)
return realNaN;
146 return getMcProductionVertexFromIP(mcparticle).Y();
149 double mcProductionVertexFromIPZ(
const Particle* part)
151 auto* mcparticle = part->getMCParticle();
152 if (!mcparticle)
return realNaN;
153 return getMcProductionVertexFromIP(mcparticle).Z();
158 double particleX(
const Particle* part)
161 return frame.getVertex(part).X();
164 double particleY(
const Particle* part)
167 return frame.getVertex(part).Y();
170 double particleZ(
const Particle* part)
173 return frame.getVertex(part).Z();
176 inline double getParticleUncertaintyByIndex(
const Particle* part,
unsigned int index)
179 B2FATAL(
"The particle provide does not exist.");
181 const auto& errMatrix = part->getVertexErrorMatrix();
182 return std::sqrt(errMatrix(index, index));
185 double particleDXUncertainty(
const Particle* part)
188 return getParticleUncertaintyByIndex(part, 0);
191 double particleDYUncertainty(
const Particle* part)
194 return getParticleUncertaintyByIndex(part, 1);
197 double particleDZUncertainty(
const Particle* part)
200 return getParticleUncertaintyByIndex(part, 2);
206 TVector3 getVertexD(
const Particle* part)
208 static DBObjPtr<BeamSpot> beamSpotDB;
210 auto trackFit = part->getTrackFitResult();
212 return frame.getVertex(part->getVertex() - beamSpotDB->getIPPosition());
214 UncertainHelix helix = trackFit->getUncertainHelix();
215 helix.passiveMoveBy(beamSpotDB->getIPPosition());
216 return frame.getVertex(helix.getPerigee());
220 double particleDX(
const Particle* part)
222 return getVertexD(part).X();
225 double particleDY(
const Particle* part)
227 return getVertexD(part).Y();
230 double particleDZ(
const Particle* part)
232 return getVertexD(part).Z();
235 double particleDRho(
const Particle* part)
237 return getVertexD(part).Perp();
240 double particleDPhi(
const Particle* part)
242 return getVertexD(part).Phi();
245 double particleDCosTheta(
const Particle* part)
247 return getVertexD(part).CosTheta();
250 double particleDistance(
const Particle* part)
252 return getVertexD(part).Mag();
255 double particleDistanceSignificance(
const Particle* part)
263 static DBObjPtr<BeamSpot> beamSpotDB;
265 const TVector3& vertex = frame.getVertex(part->getVertex() - beamSpotDB->getIPPosition());
266 const TMatrixFSym& vertexErr = frame.getVertexErrorMatrix(
static_cast<TMatrixDSym
>(part->getVertexErrorMatrix()) +
267 beamSpotDB->getCovVertex());
268 const double denominator = vertex * (vertexErr * vertex);
269 if (denominator <= 0)
return realNaN;
271 return vertex.Mag2() / std::sqrt(denominator);
276 double particleProductionX(
const Particle* part)
278 if (!part->hasExtraInfo(
"prodVertX"))
return realNaN;
279 return part->getExtraInfo(
"prodVertX");
282 double particleProductionY(
const Particle* part)
284 if (!part->hasExtraInfo(
"prodVertY"))
return realNaN;
285 return part->getExtraInfo(
"prodVertY");
288 double particleProductionZ(
const Particle* part)
290 if (!part->hasExtraInfo(
"prodVertZ"))
return realNaN;
291 return part->getExtraInfo(
"prodVertZ");
297 if (arguments.size() != 2) {
298 B2FATAL(
"Number of arguments of prodVertexCov function is incorrect!");
304 ielement = Belle2::convertString<int>(arguments[0]);
305 jelement = Belle2::convertString<int>(arguments[1]);
306 }
catch (std::invalid_argument&) {
307 B2ERROR(
"Arguments of prodVertexCov function must be integer!");
311 if (std::min(ielement, jelement) < 0 || std::max(ielement, jelement) > 2) {
312 B2ERROR(
"Range of indexes of prodVertexCov function is incorrect!");
316 const std::vector<char> names = {
'x',
'y',
'z'};
317 const std::string prodVertS = Form(
"prodVertS%c%c", names[ielement] , names[jelement]);
319 return [prodVertS](
const Particle * part) ->
double {
320 if (!part->hasExtraInfo(prodVertS))
return realNaN;
321 return part->getExtraInfo(prodVertS);
325 double particleProductionXErr(
const Particle* part)
327 if (!part->hasExtraInfo(
"prodVertSxx"))
return realNaN;
328 return std::sqrt(part->getExtraInfo(
"prodVertSxx"));
331 double particleProductionYErr(
const Particle* part)
333 if (!part->hasExtraInfo(
"prodVertSyy"))
return realNaN;
334 return std::sqrt(part->getExtraInfo(
"prodVertSyy"));
337 double particleProductionZErr(
const Particle* part)
339 if (!part->hasExtraInfo(
"prodVertSzz"))
return realNaN;
340 return std::sqrt(part->getExtraInfo(
"prodVertSzz"));
343 VARIABLE_GROUP(
"Vertex Information");
345 REGISTER_VARIABLE(
"mcDecayVertexX", mcDecayVertexX,
346 "Returns the x position of the decay vertex of the matched generated particle. Returns nan if the particle has no matched generated particle.");
347 REGISTER_VARIABLE(
"mcDecayVertexY", mcDecayVertexY,
348 "Returns the y position of the decay vertex of the matched generated particle. Returns nan if the particle has no matched generated particle.");
349 REGISTER_VARIABLE(
"mcDecayVertexZ", mcDecayVertexZ,
350 "Returns the z position of the decay vertex of the matched generated particle. Returns nan if the particle has no matched generated particle.");
351 REGISTER_VARIABLE(
"mcDecayVertexRho", mcDecayVertexRho,
352 "Returns the transverse position of the decay vertex of the matched generated particle. Returns nan if the particle has no matched generated particle.");
353 REGISTER_VARIABLE(
"mcDecayVertexFromIPX", mcDecayVertexFromIPX,
354 "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.");
355 REGISTER_VARIABLE(
"mcDecayVertexFromIPY", mcDecayVertexFromIPY,
356 "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.");
357 REGISTER_VARIABLE(
"mcDecayVertexFromIPZ", mcDecayVertexFromIPZ,
358 "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.");
359 REGISTER_VARIABLE(
"mcDecayVertexFromIPRho", mcDecayVertexFromIPRho,
360 "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.");
361 REGISTER_VARIABLE(
"mcDecayVertexFromIPDistance", mcDecayVertexFromIPDistance,
362 "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.");
365 REGISTER_VARIABLE(
"mcProductionVertexY", mcProductionVertexY,
366 "Returns the y position of production vertex of matched generated particle. Returns nan if the particle has no matched generated particle.");
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.");
369 REGISTER_VARIABLE(
"mcProductionVertexFromIPX", mcProductionVertexFromIPX,
370 "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.");
371 REGISTER_VARIABLE(
"mcProductionVertexFromIPY", mcProductionVertexFromIPY,
372 "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.");
373 REGISTER_VARIABLE(
"mcProductionVertexFromIPZ", mcProductionVertexFromIPZ,
374 "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.");
377 REGISTER_VARIABLE(
"distance", particleDistance,
378 R
"DOC(3D distance between the IP and the particle decay vertex, if available.
380 In case the particle has been created from a track, the distance is defined between the POCA and IP.
381 If the particle is built from an ECL cluster, the decay vertex is set to the nominal IP.
382 If the particle is created from a KLM cluster, the distance is calculated between the IP and the cluster itself.)DOC");
384 REGISTER_VARIABLE("significanceOfDistance", particleDistanceSignificance,
385 "significance of distance from vertex or POCA to interaction point(-1 in case of numerical problems)");
386 REGISTER_VARIABLE(
"dx", particleDX,
"vertex or POCA in case of tracks x in respect to IP");
387 REGISTER_VARIABLE(
"dy", particleDY,
"vertex or POCA in case of tracks y in respect to IP");
388 REGISTER_VARIABLE(
"dz", particleDZ,
"vertex or POCA in case of tracks z in respect to IP");
389 REGISTER_VARIABLE(
"x", particleX,
390 "x coordinate of vertex in case of composite particle, or point of closest approach (POCA) in case of a track");
391 REGISTER_VARIABLE(
"y", particleY,
392 "y coordinate of vertex in case of composite particle, or point of closest approach (POCA) in case of a track");
393 REGISTER_VARIABLE(
"z", particleZ,
394 "z coordinate of vertex in case of composite particle, or point of closest approach (POCA) in case of a track");
395 REGISTER_VARIABLE(
"x_uncertainty", particleDXUncertainty,
"uncertainty on x (measured with respect to the origin)");
396 REGISTER_VARIABLE(
"y_uncertainty", particleDYUncertainty,
"uncertainty on y (measured with respect to the origin)");
397 REGISTER_VARIABLE(
"z_uncertainty", particleDZUncertainty,
"uncertainty on z (measured with respect to the origin)");
398 REGISTER_VARIABLE(
"dr", particleDRho,
"transverse distance in respect to IP for a vertex; track d0 relative to IP for a track.");
399 REGISTER_VARIABLE(
"dphi", particleDPhi,
"vertex azimuthal angle of the vertex or POCA in degrees in respect to IP");
400 REGISTER_VARIABLE(
"dcosTheta", particleDCosTheta,
"vertex or POCA polar angle in respect to IP");
402 REGISTER_VARIABLE(
"prodVertexX", particleProductionX,
403 "Returns the x position of particle production vertex. Returns NaN if particle has no production vertex.");
404 REGISTER_VARIABLE(
"prodVertexY", particleProductionY,
405 "Returns the y position of particle production vertex.");
406 REGISTER_VARIABLE(
"prodVertexZ", particleProductionZ,
407 "Returns the z position of particle production vertex.");
409 REGISTER_VARIABLE(
"prodVertexCov(i,j)", particleProductionCovElement,
410 "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.");
411 REGISTER_VARIABLE(
"prodVertexXErr", particleProductionXErr,
412 "Returns the x position uncertainty of particle production vertex. Returns NaN if particle has no production vertex.");
413 REGISTER_VARIABLE(
"prodVertexYErr", particleProductionYErr,
414 "Returns the y position uncertainty of particle production vertex.");
415 REGISTER_VARIABLE(
"prodVertexZErr", particleProductionZErr,
416 "Returns the z position uncertainty of particle production vertex.");
static const ReferenceFrame & GetCurrent()
Get current rest frame.
std::function< double(const Particle *)> FunctionPtr
NOTE: the python interface is documented manually in analysis/doc/Variables.rst (because we use ROOT ...
static const double realNaN
shortcut for NaN of double type
Abstract base class for different kinds of events.