11 #include <analysis/variables/VertexVariables.h>
12 #include <analysis/variables/TrackVariables.h>
13 #include <analysis/utility/ReferenceFrame.h>
15 #include <framework/database/DBObjPtr.h>
16 #include <framework/logging/Logger.h>
17 #include <framework/utilities/Conversion.h>
19 #include <boost/algorithm/string.hpp>
20 #include <boost/format.hpp>
22 #include <TMatrixFSym.h>
25 #include <mdst/dbobjects/BeamSpot.h>
26 #include <mdst/dataobjects/MCParticle.h>
27 #include <mdst/dataobjects/Track.h>
28 #include <mdst/dataobjects/TrackFitResult.h>
40 double mcDecayVertexX(
const Particle* part)
42 auto* mcparticle = part->getRelatedTo<MCParticle>();
44 return mcparticle->getDecayVertex().X();
46 return std::numeric_limits<double>::quiet_NaN();
49 double mcDecayVertexY(
const Particle* part)
51 auto* mcparticle = part->getRelatedTo<MCParticle>();
53 return mcparticle->getDecayVertex().Y();
55 return std::numeric_limits<double>::quiet_NaN();
58 double mcDecayVertexZ(
const Particle* part)
60 auto* mcparticle = part->getRelatedTo<MCParticle>();
62 return mcparticle->getDecayVertex().Z();
64 return std::numeric_limits<double>::quiet_NaN();
67 double mcDecayVertexRho(
const Particle* part)
69 auto* mcparticle = part->getRelatedTo<MCParticle>();
71 return mcparticle->getDecayVertex().Perp();
73 return std::numeric_limits<double>::quiet_NaN();
76 double mcDecayVertexFromIPX(
const Particle* part)
78 auto* mcparticle = part->getRelatedTo<MCParticle>();
80 static DBObjPtr<BeamSpot> beamSpotDB;
82 return frame.getVertex(mcparticle->getDecayVertex() - beamSpotDB->getIPPosition()).X();
84 return std::numeric_limits<double>::quiet_NaN();
87 double mcDecayVertexFromIPY(
const Particle* part)
89 auto* mcparticle = part->getRelatedTo<MCParticle>();
91 static DBObjPtr<BeamSpot> beamSpotDB;
93 return frame.getVertex(mcparticle->getDecayVertex() - beamSpotDB->getIPPosition()).Y();
95 return std::numeric_limits<double>::quiet_NaN();
98 double mcDecayVertexFromIPZ(
const Particle* part)
100 auto* mcparticle = part->getRelatedTo<MCParticle>();
102 static DBObjPtr<BeamSpot> beamSpotDB;
104 return frame.getVertex(mcparticle->getDecayVertex() - beamSpotDB->getIPPosition()).Z();
106 return std::numeric_limits<double>::quiet_NaN();
109 double mcDecayVertexFromIPRho(
const Particle* part)
111 auto* mcparticle = part->getRelatedTo<MCParticle>();
113 static DBObjPtr<BeamSpot> beamSpotDB;
115 return frame.getVertex(mcparticle->getDecayVertex() - beamSpotDB->getIPPosition()).Perp();
117 return std::numeric_limits<double>::quiet_NaN();
120 double mcDecayVertexFromIPDistance(
const Particle* part)
122 auto* mcparticle = part->getRelatedTo<MCParticle>();
124 static DBObjPtr<BeamSpot> beamSpotDB;
126 return frame.getVertex(mcparticle->getDecayVertex() - beamSpotDB->getIPPosition()).Mag();
128 return std::numeric_limits<double>::quiet_NaN();
131 double mcProductionVertexX(
const Particle* part)
133 auto* mcparticle = part->getRelatedTo<MCParticle>();
135 return mcparticle->getProductionVertex().X();
137 return std::numeric_limits<double>::quiet_NaN();
140 double mcProductionVertexY(
const Particle* part)
142 auto* mcparticle = part->getRelatedTo<MCParticle>();
144 return mcparticle->getProductionVertex().Y();
146 return std::numeric_limits<double>::quiet_NaN();
149 double mcProductionVertexZ(
const Particle* part)
151 auto* mcparticle = part->getRelatedTo<MCParticle>();
153 return mcparticle->getProductionVertex().Z();
155 return std::numeric_limits<double>::quiet_NaN();
158 double mcProductionVertexFromIPX(
const Particle* part)
160 auto* mcparticle = part->getRelatedTo<MCParticle>();
162 static DBObjPtr<BeamSpot> beamSpotDB;
164 return frame.getVertex(mcparticle->getProductionVertex() - beamSpotDB->getIPPosition()).X();
166 return std::numeric_limits<double>::quiet_NaN();
169 double mcProductionVertexFromIPY(
const Particle* part)
171 auto* mcparticle = part->getRelatedTo<MCParticle>();
173 static DBObjPtr<BeamSpot> beamSpotDB;
175 return frame.getVertex(mcparticle->getProductionVertex() - beamSpotDB->getIPPosition()).Y();
177 return std::numeric_limits<double>::quiet_NaN();
180 double mcProductionVertexFromIPZ(
const Particle* part)
182 auto* mcparticle = part->getRelatedTo<MCParticle>();
184 static DBObjPtr<BeamSpot> beamSpotDB;
186 return frame.getVertex(mcparticle->getProductionVertex() - beamSpotDB->getIPPosition()).Z();
188 return std::numeric_limits<double>::quiet_NaN();
193 double particleX(
const Particle* part)
196 return frame.getVertex(part).X();
199 double particleY(
const Particle* part)
202 return frame.getVertex(part).Y();
205 double particleZ(
const Particle* part)
208 return frame.getVertex(part).Z();
211 inline double getParticleUncertaintyByIndex(
const Particle* part,
unsigned int index)
214 B2FATAL(
"The particle provide does not exist.");
216 const auto& errMatrix = part->getVertexErrorMatrix();
217 return std::sqrt(errMatrix(index, index));
220 double particleDXUncertainty(
const Particle* part)
223 return getParticleUncertaintyByIndex(part, 0);
226 double particleDYUncertainty(
const Particle* part)
229 return getParticleUncertaintyByIndex(part, 1);
232 double particleDZUncertainty(
const Particle* part)
235 return getParticleUncertaintyByIndex(part, 2);
240 double particleDX(
const Particle* part)
242 static DBObjPtr<BeamSpot> beamSpotDB;
244 auto trackFit = getTrackFitResultFromParticle(part);
246 return frame.getVertex(part->getVertex() - beamSpotDB->getIPPosition()).X();
248 UncertainHelix helix = trackFit->getUncertainHelix();
249 helix.passiveMoveBy(beamSpotDB->getIPPosition());
250 return frame.getVertex(helix.getPerigee()).X();
254 double particleDY(
const Particle* part)
256 static DBObjPtr<BeamSpot> beamSpotDB;
258 auto trackFit = getTrackFitResultFromParticle(part);
260 return frame.getVertex(part->getVertex() - beamSpotDB->getIPPosition()).Y();
262 UncertainHelix helix = trackFit->getUncertainHelix();
263 helix.passiveMoveBy(beamSpotDB->getIPPosition());
264 return frame.getVertex(helix.getPerigee()).Y();
268 double particleDZ(
const Particle* part)
270 static DBObjPtr<BeamSpot> beamSpotDB;
272 auto trackFit = getTrackFitResultFromParticle(part);
274 return frame.getVertex(part->getVertex() - beamSpotDB->getIPPosition()).Z();
276 UncertainHelix helix = trackFit->getUncertainHelix();
277 helix.passiveMoveBy(beamSpotDB->getIPPosition());
278 return frame.getVertex(helix.getPerigee()).Z();
282 double particleDRho(
const Particle* part)
284 static DBObjPtr<BeamSpot> beamSpotDB;
286 auto trackFit = getTrackFitResultFromParticle(part);
288 return frame.getVertex(part->getVertex() - beamSpotDB->getIPPosition()).Perp();
290 UncertainHelix helix = trackFit->getUncertainHelix();
291 helix.passiveMoveBy(beamSpotDB->getIPPosition());
292 return frame.getVertex(helix.getPerigee()).Perp();
296 double particleDPhi(
const Particle* part)
298 static DBObjPtr<BeamSpot> beamSpotDB;
300 auto trackFit = getTrackFitResultFromParticle(part);
302 return frame.getVertex(part->getVertex() - beamSpotDB->getIPPosition()).Phi();
304 UncertainHelix helix = trackFit->getUncertainHelix();
305 helix.passiveMoveBy(beamSpotDB->getIPPosition());
306 return frame.getVertex(helix.getPerigee()).Phi();
310 double particleDCosTheta(
const Particle* part)
312 static DBObjPtr<BeamSpot> beamSpotDB;
314 auto trackFit = getTrackFitResultFromParticle(part);
316 return frame.getVertex(part->getVertex() - beamSpotDB->getIPPosition()).CosTheta();
318 UncertainHelix helix = trackFit->getUncertainHelix();
319 helix.passiveMoveBy(beamSpotDB->getIPPosition());
320 return frame.getVertex(helix.getPerigee()).CosTheta();
324 double particleDistance(
const Particle* part)
326 static DBObjPtr<BeamSpot> beamSpotDB;
328 auto trackFit = getTrackFitResultFromParticle(part);
330 return frame.getVertex(part->getVertex() - beamSpotDB->getIPPosition()).Mag();
332 UncertainHelix helix = trackFit->getUncertainHelix();
333 helix.passiveMoveBy(beamSpotDB->getIPPosition());
334 return frame.getVertex(helix.getPerigee()).Mag();
338 double particleDistanceSignificance(
const Particle* part)
346 static DBObjPtr<BeamSpot> beamSpotDB;
348 const auto& vertex = frame.getVertex(part->getVertex() - beamSpotDB->getIPPosition());
349 const auto& vertexErr = frame.getVertexErrorMatrix(
static_cast<TMatrixDSym
>(part->getVertexErrorMatrix()) +
350 beamSpotDB->getCovVertex());
351 auto denominator = vertex * (vertexErr * vertex);
352 if (denominator <= 0) {
353 return std::numeric_limits<double>::quiet_NaN();
355 return vertex.Mag2() / std::sqrt(denominator);
360 double particleProductionX(
const Particle* part)
362 if (part->hasExtraInfo(
"prodVertX")) {
363 return part->getExtraInfo(
"prodVertX");
365 return std::numeric_limits<double>::quiet_NaN();
368 double particleProductionY(
const Particle* part)
370 if (part->hasExtraInfo(
"prodVertY")) {
371 return part->getExtraInfo(
"prodVertY");
373 return std::numeric_limits<double>::quiet_NaN();
376 double particleProductionZ(
const Particle* part)
378 if (part->hasExtraInfo(
"prodVertZ")) {
379 return part->getExtraInfo(
"prodVertZ");
381 return std::numeric_limits<double>::quiet_NaN();
389 if (arguments.size() == 2) {
391 ielement = Belle2::convertString<int>(arguments[0]);
392 jelement = Belle2::convertString<int>(arguments[1]);
393 }
catch (std::invalid_argument&) {
394 B2ERROR(
"Arguments of prodVertexCov function must be integer!");
398 if (ielement > -1 && jelement > -1 && ielement < 3 && jelement < 3) {
399 auto func = [ielement, jelement](
const Particle * part) ->
double {
400 std::vector<std::string> names = {
"x",
"y",
"z"};
401 std::string prodVertS = boost::str(boost::format(
"prodVertS%s%s") % names[ielement] % names[jelement]);
402 if (part->hasExtraInfo(prodVertS))
404 return part->getExtraInfo(prodVertS);
406 return std::numeric_limits<double>::quiet_NaN();
410 B2WARNING(
"Arguments of prodVertexCov function are incorrect!");
414 double particleProductionXErr(
const Particle* part)
416 if (part->hasExtraInfo(
"prodVertSxx")) {
417 return std::sqrt(part->getExtraInfo(
"prodVertSxx"));
419 return std::numeric_limits<double>::quiet_NaN();
422 double particleProductionYErr(
const Particle* part)
424 if (part->hasExtraInfo(
"prodVertSyy")) {
425 return std::sqrt(part->getExtraInfo(
"prodVertSyy"));
427 return std::numeric_limits<double>::quiet_NaN();
430 double particleProductionZErr(
const Particle* part)
432 if (part->hasExtraInfo(
"prodVertSzz")) {
433 return std::sqrt(part->getExtraInfo(
"prodVertSzz"));
435 return std::numeric_limits<double>::quiet_NaN();
438 VARIABLE_GROUP(
"Vertex Information");
440 REGISTER_VARIABLE(
"mcDecayVertexX", mcDecayVertexX,
441 "Returns the x position of the decay vertex of the matched generated particle. Returns nan if the particle has no matched generated particle.");
442 REGISTER_VARIABLE(
"mcDecayVertexY", mcDecayVertexY,
443 "Returns the y position of the decay vertex of the matched generated particle. Returns nan if the particle has no matched generated particle.");
444 REGISTER_VARIABLE(
"mcDecayVertexZ", mcDecayVertexZ,
445 "Returns the z position of the decay vertex of the matched generated particle. Returns nan if the particle has no matched generated particle.");
446 REGISTER_VARIABLE(
"mcDecayVertexRho", mcDecayVertexRho,
447 "Returns the transverse position of the decay vertex of the matched generated particle. Returns nan if the particle has no matched generated particle.");
448 REGISTER_VARIABLE(
"mcDecayVertexFromIPX", mcDecayVertexFromIPX,
449 "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.");
450 REGISTER_VARIABLE(
"mcDecayVertexFromIPY", mcDecayVertexFromIPY,
451 "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.");
452 REGISTER_VARIABLE(
"mcDecayVertexFromIPZ", mcDecayVertexFromIPZ,
453 "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.");
454 REGISTER_VARIABLE(
"mcDecayVertexFromIPRho", mcDecayVertexFromIPRho,
455 "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.");
456 REGISTER_VARIABLE(
"mcDecayVertexFromIPDistance", mcDecayVertexFromIPDistance,
457 "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.");
458 REGISTER_VARIABLE(
"mcProductionVertexX", mcProductionVertexX,
459 "Returns the x position of production vertex of matched generated particle. Returns nan if the particle has no matched generated particle.");
460 REGISTER_VARIABLE(
"mcProductionVertexY", mcProductionVertexY,
461 "Returns the y position of production vertex of matched generated particle. Returns nan if the particle has no matched generated particle.");
462 REGISTER_VARIABLE(
"mcProductionVertexZ", mcProductionVertexZ,
463 "Returns the z position of production vertex of matched generated particle. Returns nan if the particle has no matched generated particle.");
464 REGISTER_VARIABLE(
"mcProductionVertexFromIPX", mcProductionVertexFromIPX,
465 "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.");
466 REGISTER_VARIABLE(
"mcProductionVertexFromIPY", mcProductionVertexFromIPY,
467 "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.");
468 REGISTER_VARIABLE(
"mcProductionVertexFromIPZ", mcProductionVertexFromIPZ,
469 "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.");
472 REGISTER_VARIABLE(
"distance", particleDistance,
473 R
"DOC(3D distance between the IP and the particle decay vertex, if available.
475 In case the particle has been created from a track, the distance is defined between the POCA and IP.
476 If the particle is built from an ECL cluster, the decay vertex is set to the nominal IP.
477 If the particle is created from a KLM cluster, the distance is calculated between the IP and the cluster itself.)DOC");
479 REGISTER_VARIABLE("significanceOfDistance", particleDistanceSignificance,
480 "significance of distance from vertex or POCA to interaction point(-1 in case of numerical problems)");
481 REGISTER_VARIABLE(
"dx", particleDX,
"vertex or POCA in case of tracks x in respect to IP");
482 REGISTER_VARIABLE(
"dy", particleDY,
"vertex or POCA in case of tracks y in respect to IP");
483 REGISTER_VARIABLE(
"dz", particleDZ,
"vertex or POCA in case of tracks z in respect to IP");
484 REGISTER_VARIABLE(
"x", particleX,
485 "x coordinate of vertex in case of composite particle, or point of closest approach (POCA) in case of a track");
486 REGISTER_VARIABLE(
"y", particleY,
487 "y coordinate of vertex in case of composite particle, or point of closest approach (POCA) in case of a track");
488 REGISTER_VARIABLE(
"z", particleZ,
489 "z coordinate of vertex in case of composite particle, or point of closest approach (POCA) in case of a track");
490 REGISTER_VARIABLE(
"x_uncertainty", particleDXUncertainty,
"uncertainty on x (measured with respect to the origin)");
491 REGISTER_VARIABLE(
"y_uncertainty", particleDYUncertainty,
"uncertainty on y (measured with respect to the origin)");
492 REGISTER_VARIABLE(
"z_uncertainty", particleDZUncertainty,
"uncertainty on z (measured with respect to the origin)");
493 REGISTER_VARIABLE(
"dr", particleDRho,
"transverse distance in respect to IP for a vertex; track d0 relative to IP for a track.");
494 REGISTER_VARIABLE(
"dphi", particleDPhi,
"vertex azimuthal angle of the vertex or POCA in degrees in respect to IP");
495 REGISTER_VARIABLE(
"dcosTheta", particleDCosTheta,
"vertex or POCA polar angle in respect to IP");
497 REGISTER_VARIABLE(
"prodVertexX", particleProductionX,
498 "Returns the x position of particle production vertex. Returns NaN if particle has no production vertex.");
499 REGISTER_VARIABLE(
"prodVertexY", particleProductionY,
500 "Returns the y position of particle production vertex.");
501 REGISTER_VARIABLE(
"prodVertexZ", particleProductionZ,
502 "Returns the z position of particle production vertex.");
504 REGISTER_VARIABLE(
"prodVertexCov(i,j)", particleProductionCovElement,
505 "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.");
506 REGISTER_VARIABLE(
"prodVertexXErr", particleProductionXErr,
507 "Returns the x position uncertainty of particle production vertex. Returns NaN if particle has no production vertex.");
508 REGISTER_VARIABLE(
"prodVertexYErr", particleProductionYErr,
509 "Returns the y position uncertainty of particle production vertex.");
510 REGISTER_VARIABLE(
"prodVertexZErr", particleProductionZErr,
511 "Returns the z position uncertainty of particle production vertex.");