10#include <analysis/variables/TrackVariables.h>
13#include <analysis/VariableManager/Manager.h>
15#include <analysis/dataobjects/Particle.h>
16#include <analysis/utility/DetectorSurface.h>
19#include <framework/datastore/StoreObjPtr.h>
20#include <framework/dataobjects/Helix.h>
23#include <mdst/dbobjects/BeamSpot.h>
24#include <mdst/dataobjects/Track.h>
25#include <mdst/dataobjects/MCParticle.h>
26#include <mdst/dataobjects/TrackFitResult.h>
27#include <mdst/dataobjects/EventLevelTrackingInfo.h>
28#include <mdst/dataobjects/HitPatternVXD.h>
29#include <mdst/dataobjects/ECLCluster.h>
32#include <framework/logging/Logger.h>
47 auto trackFit = part->getTrackFitResult();
52 if (trackFit->getHitPatternCDC().getNHits() + trackFit->getHitPatternVXD().getNdf() < 1) {
53 trackFit = part->getTrack()->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(part->getPDGCode())));
55 if (det == Const::EDetector::CDC) {
56 return trackFit->getHitPatternCDC().getNHits();
57 }
else if (det == Const::EDetector::SVD) {
58 return trackFit->getHitPatternVXD().getNSVDHits();
59 }
else if (det == Const::EDetector::PXD) {
60 return trackFit->getHitPatternVXD().getNPXDHits();
66 double trackNCDCHits(
const Particle* part)
68 return trackNHits(part, Const::EDetector::CDC);
71 double trackNSVDHits(
const Particle* part)
73 return trackNHits(part, Const::EDetector::SVD);
76 double trackNPXDHits(
const Particle* part)
78 return trackNHits(part, Const::EDetector::PXD);
81 double trackNVXDHits(
const Particle* part)
83 return trackNPXDHits(part) + trackNSVDHits(part);
86 double trackNDF(
const Particle* part)
88 auto trackFit = part->getTrackFitResult();
90 return trackFit->getNDF();
93 double trackChi2(
const Particle* part)
95 auto trackFit = part->getTrackFitResult();
97 return trackFit->getChi2();
100 double trackFirstSVDLayer(
const Particle* part)
102 auto trackFit = part->getTrackFitResult();
106 if (trackFit->getHitPatternCDC().getNHits() + trackFit->getHitPatternVXD().getNdf() < 1) {
107 trackFit = part->getTrack()->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(part->getPDGCode())));
109 return trackFit->getHitPatternVXD().getFirstSVDLayer();
112 double trackFirstPXDLayer(
const Particle* part)
114 auto trackFit = part->getTrackFitResult();
118 if (trackFit->getHitPatternCDC().getNHits() + trackFit->getHitPatternVXD().getNdf() < 1) {
119 trackFit = part->getTrack()->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(part->getPDGCode())));
121 return trackFit->getHitPatternVXD().getFirstPXDLayer(HitPatternVXD::PXDMode::normal);
124 double trackFirstCDCLayer(
const Particle* part)
126 auto trackFit = part->getTrackFitResult();
130 if (trackFit->getHitPatternCDC().getNHits() + trackFit->getHitPatternVXD().getNdf() < 1) {
131 trackFit = part->getTrack()->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(part->getPDGCode())));
133 return trackFit->getHitPatternCDC().getFirstLayer();
136 double trackLastCDCLayer(
const Particle* part)
138 auto trackFit = part->getTrackFitResult();
142 if (trackFit->getHitPatternCDC().getNHits() + trackFit->getHitPatternVXD().getNdf() < 1) {
143 trackFit = part->getTrack()->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(part->getPDGCode())));
145 return trackFit->getHitPatternCDC().getLastLayer();
148 double trackD0(
const Particle* part)
150 auto trackFit = part->getTrackFitResult();
152 return trackFit->getD0();
155 double trackPhi0(
const Particle* part)
157 auto trackFit = part->getTrackFitResult();
159 return trackFit->getPhi0();
162 double trackOmega(
const Particle* part)
164 auto trackFit = part->getTrackFitResult();
166 return trackFit->getOmega();
169 double trackZ0(
const Particle* part)
171 auto trackFit = part->getTrackFitResult();
173 return trackFit->getZ0();
176 double trackTanLambda(
const Particle* part)
178 auto trackFit = part->getTrackFitResult();
180 return trackFit->getTanLambda();
183 double trackD0FromIP(
const Particle* part)
185 auto trackFit = part->getTrackFitResult();
187 static DBObjPtr<BeamSpot> beamSpotDB;
188 auto helix = trackFit->getHelix();
189 helix.passiveMoveBy(ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
190 return helix.getD0();
193 double trackZ0FromIP(
const Particle* part)
195 auto trackFit = part->getTrackFitResult();
197 static DBObjPtr<BeamSpot> beamSpotDB;
198 auto helix = trackFit->getHelix();
199 helix.passiveMoveBy(ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
200 return helix.getZ0();
203 double trackPhi0FromIP(
const Particle* part)
205 auto trackFit = part->getTrackFitResult();
207 static DBObjPtr<BeamSpot> beamSpotDB;
208 auto helix = trackFit->getHelix();
209 helix.passiveMoveBy(ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
210 return helix.getPhi0();
213 double trackD0Error(
const Particle* part)
215 auto trackFit = part->getTrackFitResult();
218 double errorSquared = trackFit->getCovariance5()[0][0];
220 return sqrt(errorSquared);
223 double trackPhi0Error(
const Particle* part)
225 auto trackFit = part->getTrackFitResult();
228 double errorSquared = trackFit->getCovariance5()[1][1];
230 return sqrt(errorSquared);
233 double trackOmegaError(
const Particle* part)
235 auto trackFit = part->getTrackFitResult();
238 double errorSquared = trackFit->getCovariance5()[2][2];
240 return sqrt(errorSquared);
243 double trackZ0Error(
const Particle* part)
245 auto trackFit = part->getTrackFitResult();
248 double errorSquared = trackFit->getCovariance5()[3][3];
250 return sqrt(errorSquared);
253 double trackTanLambdaError(
const Particle* part)
255 auto trackFit = part->getTrackFitResult();
258 double errorSquared = trackFit->getCovariance5()[4][4];
260 return sqrt(errorSquared);
263 double trackFitCovariance(
const Particle* particle,
const std::vector<double>& indices)
265 if (indices.size() != 2) {
266 B2FATAL(
"Exactly two indices must be provided to the variable trackFitCovariance!");
268 if (*(std::min_element(indices.begin(), indices.end())) < 0 or *(std::max_element(indices.begin(), indices.end())) > 4) {
269 B2FATAL(
"The indices provided to the variable trackFitCovariance must be in the range 0 - 4!");
271 auto trackFit = particle->getTrackFitResult();
273 return trackFit->getCovariance5()[indices[0]][indices[1]];
276 double trackPValue(
const Particle* part)
278 auto trackFit = part->getTrackFitResult();
280 return trackFit->getPValue();
283 double trackFitHypothesisPDG(
const Particle* part)
285 auto trackFit = part->getTrackFitResult();
287 return trackFit->getParticleType().getPDGCode();
290 double trackNECLClusters(
const Particle* part)
292 const Track* track = part->getTrack();
297 for (
const ECLCluster& cluster : track->getRelationsTo<ECLCluster>())
304 B2Vector3D getPositionOnHelix(
const TrackFitResult* trackFit,
const std::vector<double>& pars)
306 const double r = pars[0];
307 const double zfwd = pars[1];
308 const double zbwd = pars[2];
311 const double z0 = trackFit->getZ0();
312 const double tanlambda = trackFit->getTanLambda();
313 const Helix h = trackFit->getHelix();
316 const double arcLength = h.getArcLength2DAtCylindricalR(r);
317 const double lHelixRadius = arcLength > 0 ? arcLength : std::numeric_limits<double>::max();
320 const double lFWD = (zfwd - z0) / tanlambda > 0 ? (zfwd - z0) / tanlambda : std::numeric_limits<double>::max();
323 const double lBWD = (zbwd - z0) / tanlambda > 0 ? (zbwd - z0) / tanlambda : std::numeric_limits<double>::max();
326 const double l = std::min({lHelixRadius, lFWD, lBWD});
328 return h.getPositionAtArcLength2D(l);
331 B2Vector3D getPositionOnHelix(
const Particle* part,
const std::vector<double>& pars)
333 if (pars.size() == 4 and pars[3]) {
334 const Track* track = part->getTrack();
338 auto highestProbMass = part->getMostLikelyTrackFitResult().first;
339 const TrackFitResult* trackFit = track->getTrackFitResultWithClosestMass(highestProbMass);
340 return getPositionOnHelix(trackFit, pars);
342 const TrackFitResult* trackFit = part->getTrackFitResult();
343 return getPositionOnHelix(trackFit, pars);
348 double trackHelixExtTheta(
const Particle* part,
const std::vector<double>& pars)
350 const auto nParams = pars.size();
351 if (nParams != 3 && nParams != 4) {
352 B2FATAL(
"Exactly three (+1 optional) parameters (r, zfwd, zbwd, [useHighestProbMass]) required for helixExtTheta.");
355 B2Vector3D position = getPositionOnHelix(part, pars);
357 return position.Theta();
361 double trackHelixExtPhi(
const Particle* part,
const std::vector<double>& pars)
363 const auto nParams = pars.size();
364 if (nParams != 3 && nParams != 4) {
365 B2FATAL(
"Exactly three (+1 optional) parameters (r, zfwd, zbwd, [useHighestProbMass]) required for helixExtPhi.");
368 B2Vector3D position = getPositionOnHelix(part, pars);
370 return position.Phi();
375 if (arguments.size() != 1 && arguments.size() != 2)
376 B2FATAL(
"Exactly one (+1 optional) parameter (detector_surface_name, [useHighestProbMass]) is required for helixExtThetaOnDet.");
378 std::vector<double> parameters(3);
379 const std::string det = arguments[0];
389 B2FATAL(
"Given detector surface name is not supported.");
391 if (arguments.size() == 2)
392 parameters.push_back(std::stod(arguments[1]));
394 auto func = [parameters](
const Particle * part) ->
double {
396 B2Vector3D position = getPositionOnHelix(part, parameters);
398 return position.Theta();
405 if (arguments.size() != 1 && arguments.size() != 2)
406 B2FATAL(
"Exactly one (+1 optional) parameter (detector_surface_name, [useHighestProbMass]) is required for helixExtPhiOnDet.");
408 std::vector<double> parameters(3);
409 const std::string det = arguments[0];
419 B2FATAL(
"Given detector surface name is not supported.");
421 if (arguments.size() == 2)
422 parameters.push_back(std::stod(arguments[1]));
424 auto func = [parameters](
const Particle * part) ->
double {
426 B2Vector3D position = getPositionOnHelix(part, parameters);
428 return position.Phi();
439 double nExtraCDCHits(
const Particle*)
441 StoreObjPtr<EventLevelTrackingInfo> elti;
443 return elti->getNCDCHitsNotAssigned();
448 double nExtraCDCHitsPostCleaning(
const Particle*)
450 StoreObjPtr<EventLevelTrackingInfo> elti;
452 return elti->getNCDCHitsNotAssignedPostCleaning();
456 double hasExtraCDCHitsInLayer(
const Particle*,
const std::vector<double>& layer)
458 StoreObjPtr<EventLevelTrackingInfo> elti;
460 int ilayer = std::lround(layer[0]);
461 return elti->hasCDCLayer(ilayer);
465 double hasExtraCDCHitsInSuperLayer(
const Particle*,
const std::vector<double>& layer)
467 StoreObjPtr<EventLevelTrackingInfo> elti;
469 int ilayer = std::lround(layer[0]);
470 return elti->hasCDCSLayer(ilayer);
474 double nExtraCDCSegments(
const Particle*)
476 StoreObjPtr<EventLevelTrackingInfo> elti;
478 return elti->getNCDCSegments();
482 double nExtraVXDHitsInLayer(
const Particle*,
const std::vector<double>& layer)
484 StoreObjPtr<EventLevelTrackingInfo> elti;
486 int ilayer = std::lround(layer[0]);
487 return elti->getNVXDClustersInLayer(ilayer);
491 double nExtraVXDHits(
const Particle*)
493 StoreObjPtr<EventLevelTrackingInfo> elti;
496 for (uint16_t ilayer = 1; ilayer < 7; ++ilayer)
497 out += elti->getNVXDClustersInLayer(ilayer);
502 double svdFirstSampleTime(
const Particle*)
504 StoreObjPtr<EventLevelTrackingInfo> elti;
506 return elti->getSVDFirstSampleTime();
513 double trackFindingFailureFlag(
const Particle*)
515 StoreObjPtr<EventLevelTrackingInfo> elti;
517 return elti->hasAnErrorFlag();
523 const ROOT::Math::XYZVector mcProdVertex = mcparticle->getVertex();
524 const ROOT::Math::XYZVector mcMomentum = mcparticle->getMomentum();
526 const double mcParticleCharge = mcparticle->getCharge();
527 return Belle2::Helix(mcProdVertex, mcMomentum, mcParticleCharge, BzAtProdVertex);
530 double getMCHelixParameterAtIndex(
const Particle* particle,
const int index)
534 const MCParticle* mcparticle = particle->getMCParticle();
538 const std::vector<double> mcHelixPars{mcHelix.getD0(), mcHelix.getPhi0(), mcHelix.getOmega(), mcHelix.getZ0(), mcHelix.getTanLambda()};
539 return mcHelixPars.at(index);
542 double getHelixParameterPullAtIndex(
const Particle* particle,
const int index)
546 const MCParticle* mcparticle = particle->getMCParticle();
553 const TMatrixDSym& measCovariance = measHelix.
getCovariance();
556 const std::vector<double> mcHelixPars = {mcHelix.getD0(), mcHelix.getPhi0(), mcHelix.getOmega(), mcHelix.getZ0(), mcHelix.getTanLambda()};
557 const std::vector<double> measHelixPars = {measHelix.getD0(), measHelix.getPhi0(), measHelix.getOmega(), measHelix.getZ0(), measHelix.getTanLambda()};
559 return (mcHelixPars.at(index) - measHelixPars.at(index)) / std::sqrt(measCovariance(index, index));
562 double getHelixMCD0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 0); }
563 double getHelixMCPhi0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 1); }
564 double getHelixMCOmega(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 2); }
565 double getHelixMCZ0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 3); }
566 double getHelixMCTanLambda(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 4); }
568 double getHelixD0Pull(
const Particle* part)
570 return getHelixParameterPullAtIndex(part, 0);
573 double getHelixPhi0Pull(
const Particle* part)
575 return getHelixParameterPullAtIndex(part, 1);
578 double getHelixOmegaPull(
const Particle* part)
580 return getHelixParameterPullAtIndex(part, 2);
583 double getHelixZ0Pull(
const Particle* part)
585 return getHelixParameterPullAtIndex(part, 3);
588 double getHelixTanLambdaPull(
const Particle* part)
590 return getHelixParameterPullAtIndex(part, 4);
593 double getTrackTime(
const Particle* part)
595 const Track* track = part->getTrack();
597 return track->getTrackTime();
600 double isTrackFlippedAndRefitted(
const Particle* part)
602 auto track = part->getTrack();
604 return track->isFlippedAndRefitted() ? 1 : 0;
607 double getTrackLength(
const Particle* part)
609 auto trackFit = part->getTrackFitResult();
612 const double lastCDCLayer = trackLastCDCLayer(part);
613 if (std::isnan(lastCDCLayer) or lastCDCLayer < 0)
618 return trackFit->getHelix().getArcLength2DAtCylindricalR(r);
622 VARIABLE_GROUP(
"Tracking");
624 REGISTER_VARIABLE(
"mcD0", getHelixMCD0, R
"DOC(
625Returns the MC value of :math:`d_0`, the signed distance to the
626point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
628.. seealso:: :b2:var:`d0`
630Returns NaN if the particle is not related to any MCParticle.
633 REGISTER_VARIABLE(
"mcPhi0", getHelixMCPhi0, R
"DOC(
634Returns the MC value of :math:`\phi_0`, the angle of the transverse momentum
635in the :math:`r-\phi` plane.
637.. seealso:: :b2:var:`phi0`
639Returns NaN if the particle is not related to any MCParticle.
642 REGISTER_VARIABLE(
"mcOmega", getHelixMCOmega, R
"DOC(
643Returns the MC value of :math:`\omega`, the curvature of the track.
645.. seealso:: :b2:var:`omega`
647Returns NaN if the particle is not related to any MCParticle.
649)DOC", ":math:`\\text{cm}^{-1}`");
650 REGISTER_VARIABLE(
"mcZ0", getHelixMCZ0, R
"DOC(
651Returns the MC value of :math:`z_0`, the z-coordinate of the
652point-of-closest-approach (POCA).
654.. seealso:: :b2:var:`z0`
656Returns NaN if the particle is not related to any MCParticle.
659 REGISTER_VARIABLE(
"mcTanLambda", getHelixMCTanLambda, R
"DOC(
660Returns the MC value of :math:`\tan\lambda`, the slope of the track in the
663.. seealso:: :b2:var:`tanLambda`
665Returns NaN if the particle is not related to any MCParticle.
668 REGISTER_VARIABLE("d0Pull", getHelixD0Pull, R
"DOC(
669The pull of the tracking parameter :math:`d_0` for the reconstructed
670pattern-recognition track, with respect to the MC track. That is:
674 \frac{d_0^\textrm{MC} - d_0^\textrm{PR}}{\sigma_{d_0; \textrm{PR}}}
676.. seealso:: :b2:var:`d0`, :b2:var:`d0Err`
678Returns NaN if no MC particle is related or if called on something other than a
681 REGISTER_VARIABLE("phi0Pull", getHelixPhi0Pull, R
"DOC(
682The pull of the tracking parameter :math:`\phi_0` for the reconstructed
683pattern-recognition track, with respect to the MC track. That is:
687 \frac{\phi_0^\textrm{MC} - \phi_0^\textrm{PR}}{\sigma_{\phi_0; \textrm{PR}}}
689.. seealso:: :b2:var:`phi0`, :b2:var:`phi0Err`
691Returns NaN if no MC particle is related or if called on something other than a
694 REGISTER_VARIABLE("omegaPull", getHelixOmegaPull, R
"DOC(
695The pull of the tracking parameter :math:`\omega` for the reconstructed
696pattern-recognition track, with respect to the MC track. That is:
700 \frac{\omega^\textrm{MC} - \omega^\textrm{PR}}{\sigma_{\omega; \textrm{PR}}}
702.. seealso:: :b2:var:`omega`, :b2:var:`omegaErr`
704Returns NaN if no MC particle is related or if called on something other than a
707 REGISTER_VARIABLE("z0Pull", getHelixZ0Pull, R
"DOC(
708The pull of the tracking parameter :math:`z_0` for the reconstructed
709pattern-recognition track, with respect to the MC track. That is:
713 \frac{z_0^\textrm{MC} - z_0^\textrm{PR}}{\sigma_{z_0; \textrm{PR}}}
715.. seealso:: :b2:var:`z0`, :b2:var:`z0Err`
717Returns NaN if no MC particle is related or if called on something other than a
720 REGISTER_VARIABLE("tanLambdaPull", getHelixTanLambdaPull, R
"DOC(
721The pull of the tracking parameter :math:`\tan\lambda` for the reconstructed
722pattern-recognition track, with respect to the MC track. That is:
726 \frac{(\tan\lambda)^\textrm{MC} - (\tan\lambda)^\textrm{PR}}{\sigma_{\tan\lambda; \textrm{PR}}}
728.. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaErr`
730Returns NaN if no MC particle is related or if called on something other than a
733 REGISTER_VARIABLE("nCDCHits", trackNCDCHits,
734 "The number of CDC hits associated to the track. Returns NaN if called for something other than a track-based particle.");
735 REGISTER_VARIABLE(
"nSVDHits", trackNSVDHits,
736 "The number of SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
737 REGISTER_VARIABLE(
"nPXDHits", trackNPXDHits,
738 "The number of PXD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
739 REGISTER_VARIABLE(
"nVXDHits", trackNVXDHits,
740 "The number of PXD and SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
741 REGISTER_VARIABLE(
"ndf", trackNDF, R
"DOC(
742Returns the number of degrees of freedom of the track fit.
746 Note that this is not simply the number of hits -5 due to outlier hit
749Returns NaN if called for something other than a track-based particle, or for
750mdst files processed with basf2 versions older than ``release-05-01``.
752 REGISTER_VARIABLE("chi2", trackChi2, R
"DOC(
753Returns the :math:`\chi^2` of the track fit. This is actually computed based on
754:b2:var:`pValue` and :b2:var:`ndf`.
756.. note:: Note that for :b2:var:`pValue` exactly equal to 0 it returns infinity.
758Returns NaN if called for something other than a track-based particle, or for
759mdst files processed with basf2 versions older than ``release-05-01``.
761 REGISTER_VARIABLE("firstSVDLayer", trackFirstSVDLayer,
762 "The first activated SVD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
763 REGISTER_VARIABLE(
"firstPXDLayer", trackFirstPXDLayer,
764 "The first activated PXD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
765 REGISTER_VARIABLE(
"firstCDCLayer", trackFirstCDCLayer,
766 "The first activated CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
767 REGISTER_VARIABLE(
"lastCDCLayer", trackLastCDCLayer,
768 "The last CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
769 REGISTER_VARIABLE(
"d0", trackD0, R
"DOC(
770Returns the tracking parameter :math:`d_0`, the signed distance to the
771point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
775 Tracking parameters are with respect to the origin (0,0,0). For the
776 POCA with respect to the measured beam interaction point, see
777 :b2:var:`dr` (you probably want this unless you're doing a tracking
778 study or some debugging) and :b2:var:`d0FromIP`.
780Returns NaN if called for something other than a track-based particle.
783 REGISTER_VARIABLE(
"phi0", trackPhi0, R
"DOC(
784Returns the tracking parameter :math:`\phi_0`, the angle of the transverse
785momentum in the :math:`r-\phi` plane.
789 Tracking parameters are with respect to the origin (0,0,0). For the
790 POCA with respect to the measured beam interaction point, see
791 :b2:var:`phi0FromIP`.
793Returns NaN if called for something other than a track-based particle.
796 REGISTER_VARIABLE(
"omega", trackOmega, R
"DOC(
797Returns the tracking parameter :math:`\omega`, the curvature of the track.
799Returns NaN if called for something other than a track-based particle.
801)DOC", ":math:`\\text{cm}^{-1}`");
802 REGISTER_VARIABLE(
"z0", trackZ0, R
"DOC(
803Returns the tracking parameter :math:`z_0`, the z-coordinate of the
804point-of-closest-approach (POCA).
808 Tracking parameters are with respect to the origin (0,0,0). For the
809 POCA with respect to the measured beam interaction point, see
810 :b2:var:`dz` (you probably want this unless you're doing a tracking
811 study or some debugging) and :b2:var:`z0FromIP`.
813Returns NaN if called for something other than a track-based particle.
816 REGISTER_VARIABLE(
"tanLambda", trackTanLambda, R
"DOC(
817Returns :math:`\tan\lambda`, the slope of the track in the :math:`r-z` plane.
819Returns NaN if called for something other than a track-based particle.
821 REGISTER_VARIABLE("d0FromIP", trackD0FromIP, R
"DOC(
822Returns the tracking parameter :math:`d_0`, the signed distance to the
823point-of-closest-approach (POCA) in the :math:`r-\phi` plane, with respect to the measured beam interaction point.
825Returns NaN if called for something other than a track-based particle.
828 REGISTER_VARIABLE(
"z0FromIP", trackZ0FromIP, R
"DOC(
829Returns the tracking parameter :math:`z_0`, the z-coordinate of the
830point-of-closest-approach (POCA), with respect to the measured beam interaction point.
832Returns NaN if called for something other than a track-based particle.
835 REGISTER_VARIABLE(
"phi0FromIP", trackPhi0FromIP, R
"DOC(
836Returns the tracking parameter :math:`\phi_0`, the angle of the transverse
837momentum in the :math:`r-\phi` plane, with respect to the measured beam interaction point.
839Returns NaN if called for something other than a track-based particle.
842 REGISTER_VARIABLE(
"d0Err", trackD0Error, R
"DOC(
843Returns the uncertainty on :math:`d_0`, the signed distance to the
844point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
846.. seealso:: :b2:var:`d0`, :b2:var:`d0Pull`
848Returns NaN if called for something other than a track-based particle.
851 REGISTER_VARIABLE(
"phi0Err", trackPhi0Error, R
"DOC(
852Returns the uncertainty on :math:`\phi_0`, the angle of the transverse momentum
853in the :math:`r-\phi` plane.
855.. seealso:: :b2:var:`phi0`, :b2:var:`phi0Pull`
857Returns NaN if called for something other than a track-based particle.
860 REGISTER_VARIABLE(
"omegaErr", trackOmegaError, R
"DOC(
861Returns the uncertainty on :math:`\omega`, the curvature of the track.
863.. seealso:: :b2:var:`omega`, :b2:var:`omegaPull`
865Returns NaN if called for something other than a track-based particle.
867)DOC", ":math:`\\text{cm}^{-1}`");
868 REGISTER_VARIABLE(
"z0Err", trackZ0Error, R
"DOC(
869Returns the uncertainty on :math:`z_0`, the z-coordinate of the
870point-of-closest-approach (POCA).
872.. seealso:: :b2:var:`z0`, :b2:var:`z0Pull`
874Returns NaN if called for something other than a track-based particle."
877 REGISTER_VARIABLE(
"tanLambdaErr", trackTanLambdaError, R
"DOC(
878Returns the uncertainty on :math:`\tan\lambda`, the slope of the track in the
881.. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaPull`
883Returns NaN if called for something other than a track-based particle.
885 REGISTER_VARIABLE("trackFitCovariance(i, j)", trackFitCovariance, R
"DOC(
886 The track fit covariance matrix element corresponding to the two indices is returned.
887 This is the association between integers and parameters:
893 * 4: :math:`\tan\lambda`
897 The covariance is returned. This means that the return value can be negative.
898 Furthermore, it's the squared value of the track fit error variables :b2:var:`d0Err`, etc.
899 when selecting the diagonal entries.
902 REGISTER_VARIABLE("pValue", trackPValue, R
"DOC(
903The :math:`\chi^2` probability of the **track** fit.
907 This is the p-value of the track-fit. It does not get updated after
908 vertex fitting or kinematic fitting, and is meaningless for composite
911 See :b2:var:`chiProb` (you probably want this for high-level analysis).
913Returns NaN if called for something other than a track-based particle.
915 REGISTER_VARIABLE("trackFitHypothesisPDG", trackFitHypothesisPDG, R
"DOC(
916Returns the PDG code of the track hypothesis actually used for the fit.
917Returns NaN if called for something other than a track-based particle.
919 REGISTER_VARIABLE("trackNECLClusters", trackNECLClusters, R
"DOC(
920Returns a count of the number of ECLClusters matched to the track. This is
921always 0 or 1 with newer versions of ECL reconstruction.
925 For high-level analysis it is recommended to require the presence of a
926 matched ECL cluster along with a minimum energy requirement. A
927 track-based particle will have a clusterE if it is matched (NaN if
928 there is no cluster match for the track.
930 .. code-block:: python
932 import modularAnalysis as ma
933 # minimum energy of 200 MeV
934 ma.fillParticleList("e+:clusters", "clusterE > 0.2", path)
936 # these two are equivalent
937 ma.fillParticleList("e+:unmatched", "isNAN(clusterE) == 1", path)
938 ma.fillParticleList("e+:unmatched2", "trackNECLClusters == 0", path)
940Returns NaN if called for something other than a track-based particle.
942 REGISTER_VARIABLE("helixExtTheta(radius [cm], z fwd [cm], z bwd [cm], useHighestProbMass=0)", trackHelixExtTheta,
943 R
"DOC(Returns theta of extrapolated helix parameters. If ``useHighestProbMass=1`` is set, the extrapolation will
944 use the track fit result for the mass hypothesis with the highest pValue.
947 REGISTER_VARIABLE(
"helixExtPhi(radius, z fwd, z bwd, useHighestProbMass=0)", trackHelixExtPhi,
948 "Returns phi of extrapolated helix parameters. If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.\n\n",
951 REGISTER_METAVARIABLE(
"helixExtThetaOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtThetaOnDet,
952 R
"DOC(Returns theta of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
953 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
954 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
955 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
957 ..note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
958 )DOC", Manager::VariableDataType::c_double);
959 REGISTER_METAVARIABLE("helixExtPhiOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtPhiOnDet,
960 R
"DOC(Returns phi of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
961 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
962 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
963 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
965 ..note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
966 )DOC", Manager::VariableDataType::c_double);
969 REGISTER_VARIABLE("nExtraCDCHits", nExtraCDCHits, R
"DOC(
970[Eventbased] The number of CDC hits in the event not assigned to any track.
972Returns NaN if there is no event-level tracking information available.
974 REGISTER_VARIABLE("nExtraCDCHitsPostCleaning", nExtraCDCHitsPostCleaning, R
"DOC(
975[Eventbased] Returns a count of the number of CDC hits in the event not assigned
976to any track nor very likely beam background (i.e. hits that survive a cleanup
979Returns NaN if there is no event-level tracking information available.
981 REGISTER_VARIABLE("hasExtraCDCHitsInLayer(i)", hasExtraCDCHitsInLayer, R
"DOC(
982[Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC layer,
985Returns NaN if there is no event-level tracking information available.
987 REGISTER_VARIABLE("hasExtraCDCHitsInSuperLayer(i)", hasExtraCDCHitsInSuperLayer, R
"DOC(
988[Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC
989SuperLayer, 0 otherwise.
991Returns NaN if there is no event-level tracking information available.
993 REGISTER_VARIABLE("nExtraCDCSegments", nExtraCDCSegments, R
"DOC(
994[Eventbased] Returns the number of CDC segments not assigned to any track.
996Returns NaN if there is no event-level tracking information available.
1004 REGISTER_VARIABLE(
"trackFindingFailureFlag", trackFindingFailureFlag, R
"DOC(
1005[Eventbased] Returns a flag set by the tracking if there is reason to assume
1006there was a track in the event missed by the tracking, or the track finding was
1007(partly) aborted for this event.
1009Returns NaN if there is no event-level tracking information available.
1012 REGISTER_VARIABLE("isTrackFlippedAndRefitted", isTrackFlippedAndRefitted, R
"DOC(
1013Returns 1 if the charged final state particle comes from a track that has been flipped and refitted
1014at the end of the reconstruction chain, in particular after the outer detector reconstruction.
1017 REGISTER_VARIABLE("trackTime", getTrackTime, R
"DOC(
1018Returns the time at which the track is produced relative to the time of the collision (given by SVD EventT0).
1019Both the time of the collision and the track time are computed using only SVD hits.
1020Returns NaN if SVD EventT0 is NaN, or if no SVD Hits are attached to the track.
1021For more details, see :ref:`Time Extraction <tracking_eventTimeExtraction>` page.
1025 REGISTER_VARIABLE(
"trackLength", getTrackLength, R
"DOC(
1026Returns the arc length of the helix for the TrackFitResult associated with the particle.
1027The arc length is measured from the track origin to the radius of the CDC layer in which the Track has a hit.
1028Returns NaN if the particle has no CDC Hits.
static ROOT::Math::XYZVector getFieldInTesla(const ROOT::Math::XYZVector &pos)
return the magnetic field at a given position in Tesla.
EDetector
Enum for identifying the detector components (detector and subdetector).
static const double doubleNaN
quiet_NaN
@ c_nPhotons
CR is split into n photons (N1)
Values of the result of a track fit with a given particle hypothesis.
UncertainHelix getUncertainHelix() const
Conversion to framework Uncertain Helix (i.e., with covariance).
This class represents an ideal helix in perigee parameterization including the covariance matrix of t...
const TMatrixDSym & getCovariance() const
Getter for covariance matrix of perigee parameters in matrix form.
std::function< VarVariant(const Particle *)> FunctionPtr
functions stored take a const Particle* and return VarVariant.
B2Vector3< double > B2Vector3D
typedef for common usage with double
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.
static const std::unordered_map< int, double > cdcWireRadiuses
CDC sense wire radiuses Values are take from cdc/data/CDC.xml.
static const std::unordered_map< std::string, DetSurfCylBoundaries > detToSurfBoundaries
Map that associates to each detector its valid cylindrical surface's boundaries.
static const std::unordered_map< std::string, DetSurfCylBoundaries > detLayerToSurfBoundaries
Map that associates to each detector layer its valid cylindrical surface's boundaries.