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();
520 double getHelixParameterPullAtIndex(
const Particle* particle,
const int index)
524 const MCParticle* mcparticle = particle->getMCParticle();
531 const TMatrixDSym measCovariance = measHelix.
getCovariance();
532 const ROOT::Math::XYZVector mcProdVertex = mcparticle->getVertex();
533 const ROOT::Math::XYZVector mcMomentum = mcparticle->getMomentum();
536 const double mcParticleCharge = mcparticle->getCharge();
539 const std::vector<double> mcHelixPars = {mcHelix.getD0(), mcHelix.getPhi0(), mcHelix.getOmega(), mcHelix.getZ0(), mcHelix.getTanLambda()};
540 const std::vector<double> measHelixPars = {measHelix.getD0(), measHelix.getPhi0(), measHelix.getOmega(), measHelix.getZ0(), measHelix.getTanLambda()};
541 const std::vector<double> measErrSquare = {measCovariance[0][0], measCovariance[1][1], measCovariance[2][2], measCovariance[3][3], measCovariance[4][4]};
543 return (mcHelixPars.at(index) - measHelixPars.at(index)) /
std::sqrt(measErrSquare.at(index));
546 double getHelixD0Pull(
const Particle* part)
548 return getHelixParameterPullAtIndex(part, 0);
551 double getHelixPhi0Pull(
const Particle* part)
553 return getHelixParameterPullAtIndex(part, 1);
556 double getHelixOmegaPull(
const Particle* part)
558 return getHelixParameterPullAtIndex(part, 2);
561 double getHelixZ0Pull(
const Particle* part)
563 return getHelixParameterPullAtIndex(part, 3);
565 double getHelixTanLambdaPull(
const Particle* part)
567 return getHelixParameterPullAtIndex(part, 4);
569 double getTrackTime(
const Particle* part)
571 const Track* track = part->getTrack();
573 return track->getTrackTime();
576 double isTrackFlippedAndRefitted(
const Particle* part)
578 auto track = part->getTrack();
580 return track->isFlippedAndRefitted() ? 1 : 0;
583 double getTrackLength(
const Particle* part)
585 auto trackFit = part->getTrackFitResult();
588 const double lastCDCLayer = trackLastCDCLayer(part);
589 if (std::isnan(lastCDCLayer) or lastCDCLayer < 0)
594 return trackFit->getHelix().getArcLength2DAtCylindricalR(r);
598 VARIABLE_GROUP(
"Tracking");
599 REGISTER_VARIABLE(
"d0Pull", getHelixD0Pull, R
"DOC(
600 The pull of the tracking parameter :math:`d_0` for the reconstructed
601 pattern-recognition track, with respect to the MC track. That is:
605 \frac{d_0^\textrm{MC} - d_0^\textrm{PR}}{\sigma_{d_0; \textrm{PR}}}
607 .. seealso:: :b2:var:`d0`, :b2:var:`d0Err`
609 Returns NaN if no MC particle is related or if called on something other than a
610 track-based particle.
612 REGISTER_VARIABLE("phi0Pull", getHelixPhi0Pull, R
"DOC(
613 The pull of the tracking parameter :math:`\phi_0` for the reconstructed
614 pattern-recognition track, with respect to the MC track. That is:
618 \frac{\phi_0^\textrm{MC} - \phi_0^\textrm{PR}}{\sigma_{\phi_0; \textrm{PR}}}
620 .. seealso:: :b2:var:`phi0`, :b2:var:`phi0Err`
622 Returns NaN if no MC particle is related or if called on something other than a
623 track-based particle.
625 REGISTER_VARIABLE("omegaPull", getHelixOmegaPull, R
"DOC(
626 The pull of the tracking parameter :math:`\omega` for the reconstructed
627 pattern-recognition track, with respect to the MC track. That is:
631 \frac{\omega^\textrm{MC} - \omega^\textrm{PR}}{\sigma_{\omega; \textrm{PR}}}
633 .. seealso:: :b2:var:`omega`, :b2:var:`omegaErr`
635 Returns NaN if no MC particle is related or if called on something other than a
636 track-based particle.
638 REGISTER_VARIABLE("z0Pull", getHelixZ0Pull, R
"DOC(
639 The pull of the tracking parameter :math:`z_0` for the reconstructed
640 pattern-recognition track, with respect to the MC track. That is:
644 \frac{z_0^\textrm{MC} - z_0^\textrm{PR}}{\sigma_{z_0; \textrm{PR}}}
646 .. seealso:: :b2:var:`z0`, :b2:var:`z0Err`
648 Returns NaN if no MC particle is related or if called on something other than a
649 track-based particle.
651 REGISTER_VARIABLE("tanLambdaPull", getHelixTanLambdaPull, R
"DOC(
652 The pull of the tracking parameter :math:`\tan\lambda` for the reconstructed
653 pattern-recognition track, with respect to the MC track. That is:
657 \frac{(\tan\lambda)^\textrm{MC} - (\tan\lambda)^\textrm{PR}}{\sigma_{\tan\lambda; \textrm{PR}}}
659 .. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaErr`
661 Returns NaN if no MC particle is related or if called on something other than a
662 track-based particle.
664 REGISTER_VARIABLE("nCDCHits", trackNCDCHits,
665 "The number of CDC hits associated to the track. Returns NaN if called for something other than a track-based particle.");
666 REGISTER_VARIABLE(
"nSVDHits", trackNSVDHits,
667 "The number of SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
668 REGISTER_VARIABLE(
"nPXDHits", trackNPXDHits,
669 "The number of PXD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
670 REGISTER_VARIABLE(
"nVXDHits", trackNVXDHits,
671 "The number of PXD and SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
672 REGISTER_VARIABLE(
"ndf", trackNDF, R
"DOC(
673 Returns the number of degrees of freedom of the track fit.
677 Note that this is not simply the number of hits -5 due to outlier hit
680 Returns NaN if called for something other than a track-based particle, or for
681 mdst files processed with basf2 versions older than ``release-05-01``.
683 REGISTER_VARIABLE("chi2", trackChi2, R
"DOC(
684 Returns the :math:`\chi^2` of the track fit. This is actually computed based on
685 :b2:var:`pValue` and :b2:var:`ndf`.
687 .. note:: Note that for :b2:var:`pValue` exactly equal to 0 it returns infinity.
689 Returns NaN if called for something other than a track-based particle, or for
690 mdst files processed with basf2 versions older than ``release-05-01``.
692 REGISTER_VARIABLE("firstSVDLayer", trackFirstSVDLayer,
693 "The first activated SVD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
694 REGISTER_VARIABLE(
"firstPXDLayer", trackFirstPXDLayer,
695 "The first activated PXD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
696 REGISTER_VARIABLE(
"firstCDCLayer", trackFirstCDCLayer,
697 "The first activated CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
698 REGISTER_VARIABLE(
"lastCDCLayer", trackLastCDCLayer,
699 "The last CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
700 REGISTER_VARIABLE(
"d0", trackD0, R
"DOC(
701 Returns the tracking parameter :math:`d_0`, the signed distance to the
702 point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
706 Tracking parameters are with respect to the origin (0,0,0). For the
707 POCA with respect to the measured beam interaction point, see
708 :b2:var:`dr` (you probably want this unless you're doing a tracking
709 study or some debugging) and :b2:var:`d0FromIP`.
711 Returns NaN if called for something other than a track-based particle.
714 REGISTER_VARIABLE(
"phi0", trackPhi0, R
"DOC(
715 Returns the tracking parameter :math:`\phi_0`, the angle of the transverse
716 momentum in the :math:`r-\phi` plane.
720 Tracking parameters are with respect to the origin (0,0,0). For the
721 POCA with respect to the measured beam interaction point, see
722 :b2:var:`phi0FromIP`.
724 Returns NaN if called for something other than a track-based particle.
727 REGISTER_VARIABLE(
"omega", trackOmega, R
"DOC(
728 Returns the tracking parameter :math:`\omega`, the curvature of the track.
730 Returns NaN if called for something other than a track-based particle.
732 )DOC", ":math:`\\text{cm}^{-1}`");
733 REGISTER_VARIABLE(
"z0", trackZ0, R
"DOC(
734 Returns the tracking parameter :math:`z_0`, the z-coordinate of the
735 point-of-closest-approach (POCA).
739 Tracking parameters are with respect to the origin (0,0,0). For the
740 POCA with respect to the measured beam interaction point, see
741 :b2:var:`dz` (you probably want this unless you're doing a tracking
742 study or some debugging) and :b2:var:`z0FromIP`.
744 Returns NaN if called for something other than a track-based particle.
747 REGISTER_VARIABLE(
"tanLambda", trackTanLambda, R
"DOC(
748 Returns :math:`\tan\lambda`, the slope of the track in the :math:`r-z` plane.
750 Returns NaN if called for something other than a track-based particle.
752 REGISTER_VARIABLE("d0FromIP", trackD0FromIP, R
"DOC(
753 Returns the tracking parameter :math:`d_0`, the signed distance to the
754 point-of-closest-approach (POCA) in the :math:`r-\phi` plane, with respect to the measured beam interaction point.
756 Returns NaN if called for something other than a track-based particle.
759 REGISTER_VARIABLE(
"z0FromIP", trackZ0FromIP, R
"DOC(
760 Returns the tracking parameter :math:`z_0`, the z-coordinate of the
761 point-of-closest-approach (POCA), with respect to the measured beam interaction point.
763 Returns NaN if called for something other than a track-based particle.
766 REGISTER_VARIABLE(
"phi0FromIP", trackPhi0FromIP, R
"DOC(
767 Returns the tracking parameter :math:`\phi_0`, the angle of the transverse
768 momentum in the :math:`r-\phi` plane, with respect to the measured beam interaction point.
770 Returns NaN if called for something other than a track-based particle.
773 REGISTER_VARIABLE(
"d0Err", trackD0Error, R
"DOC(
774 Returns the uncertainty on :math:`d_0`, the signed distance to the
775 point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
777 .. seealso:: :b2:var:`d0`, :b2:var:`d0Pull`
779 Returns NaN if called for something other than a track-based particle.
782 REGISTER_VARIABLE(
"phi0Err", trackPhi0Error, R
"DOC(
783 Returns the uncertainty on :math:`\phi_0`, the angle of the transverse momentum
784 in the :math:`r-\phi` plane.
786 .. seealso:: :b2:var:`phi0`, :b2:var:`phi0Pull`
788 Returns NaN if called for something other than a track-based particle.
791 REGISTER_VARIABLE(
"omegaErr", trackOmegaError, R
"DOC(
792 Returns the uncertainty on :math:`\omega`, the curvature of the track.
794 .. seealso:: :b2:var:`omega`, :b2:var:`omegaPull`
796 Returns NaN if called for something other than a track-based particle.
798 )DOC", ":math:`\\text{cm}^{-1}`");
799 REGISTER_VARIABLE(
"z0Err", trackZ0Error, R
"DOC(
800 Returns the uncertainty on :math:`z_0`, the z-coordinate of the
801 point-of-closest-approach (POCA).
803 .. seealso:: :b2:var:`z0`, :b2:var:`z0Pull`
805 Returns NaN if called for something other than a track-based particle."
808 REGISTER_VARIABLE(
"tanLambdaErr", trackTanLambdaError, R
"DOC(
809 Returns the uncertainty on :math:`\tan\lambda`, the slope of the track in the
812 .. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaPull`
814 Returns NaN if called for something other than a track-based particle.
816 REGISTER_VARIABLE("trackFitCovariance(i, j)", trackFitCovariance, R
"DOC(
817 The track fit covariance matrix element corresponding to the two indices is returned.
818 This is the association between integers and parameters:
824 * 4: :math:`\tan\lambda`
828 The covariance is returned. This means that the return value can be negative.
829 Furthermore, it's the squared value of the track fit error variables :b2:var:`d0Err`, etc.
830 when selecting the diagonal entries.
833 REGISTER_VARIABLE("pValue", trackPValue, R
"DOC(
834 The :math:`\chi^2` probability of the **track** fit.
838 This is the p-value of the track-fit. It does not get updated after
839 vertex fitting or kinematic fitting, and is meaningless for composite
842 See :b2:var:`chiProb` (you probably want this for high-level analysis).
844 Returns NaN if called for something other than a track-based particle.
846 REGISTER_VARIABLE("trackFitHypothesisPDG", trackFitHypothesisPDG, R
"DOC(
847 Returns the PDG code of the track hypothesis actually used for the fit.
848 Returns NaN if called for something other than a track-based particle.
850 REGISTER_VARIABLE("trackNECLClusters", trackNECLClusters, R
"DOC(
851 Returns a count of the number of ECLClusters matched to the track. This is
852 always 0 or 1 with newer versions of ECL reconstruction.
856 For high-level analysis it is recommended to require the presence of a
857 matched ECL cluster along with a minimum energy requirement. A
858 track-based particle will have a clusterE if it is matched (NaN if
859 there is no cluster match for the track.
861 .. code-block:: python
863 import modularAnalysis as ma
864 # minimum energy of 200 MeV
865 ma.fillParticleList("e+:clusters", "clusterE > 0.2", path)
867 # these two are equivalent
868 ma.fillParticleList("e+:unmatched", "isNAN(clusterE) == 1", path)
869 ma.fillParticleList("e+:unmatched2", "trackNECLClusters == 0", path)
871 Returns NaN if called for something other than a track-based particle.
873 REGISTER_VARIABLE("helixExtTheta(radius [cm], z fwd [cm], z bwd [cm], useHighestProbMass=0)", trackHelixExtTheta,
874 R
"DOC(Returns theta of extrapolated helix parameters. If ``useHighestProbMass=1`` is set, the extrapolation will
875 use the track fit result for the mass hypothesis with the highest pValue.
878 REGISTER_VARIABLE(
"helixExtPhi(radius, z fwd, z bwd, useHighestProbMass=0)", trackHelixExtPhi,
879 "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",
882 REGISTER_METAVARIABLE(
"helixExtThetaOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtThetaOnDet,
883 R
"DOC(Returns theta of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
884 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
885 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
886 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
888 ..note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
889 )DOC", Manager::VariableDataType::c_double);
890 REGISTER_METAVARIABLE("helixExtPhiOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtPhiOnDet,
891 R
"DOC(Returns phi of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
892 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
893 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
894 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
896 ..note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
897 )DOC", Manager::VariableDataType::c_double);
900 REGISTER_VARIABLE("nExtraCDCHits", nExtraCDCHits, R
"DOC(
901 [Eventbased] The number of CDC hits in the event not assigned to any track.
903 Returns NaN if there is no event-level tracking information available.
905 REGISTER_VARIABLE("nExtraCDCHitsPostCleaning", nExtraCDCHitsPostCleaning, R
"DOC(
906 [Eventbased] Returns a count of the number of CDC hits in the event not assigned
907 to any track nor very likely beam background (i.e. hits that survive a cleanup
910 Returns NaN if there is no event-level tracking information available.
912 REGISTER_VARIABLE("hasExtraCDCHitsInLayer(i)", hasExtraCDCHitsInLayer, R
"DOC(
913 [Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC layer,
916 Returns NaN if there is no event-level tracking information available.
918 REGISTER_VARIABLE("hasExtraCDCHitsInSuperLayer(i)", hasExtraCDCHitsInSuperLayer, R
"DOC(
919 [Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC
920 SuperLayer, 0 otherwise.
922 Returns NaN if there is no event-level tracking information available.
924 REGISTER_VARIABLE("nExtraCDCSegments", nExtraCDCSegments, R
"DOC(
925 [Eventbased] Returns the number of CDC segments not assigned to any track.
927 Returns NaN if there is no event-level tracking information available.
935 REGISTER_VARIABLE(
"trackFindingFailureFlag", trackFindingFailureFlag, R
"DOC(
936 [Eventbased] Returns a flag set by the tracking if there is reason to assume
937 there was a track in the event missed by the tracking, or the track finding was
938 (partly) aborted for this event.
940 Returns NaN if there is no event-level tracking information available.
943 REGISTER_VARIABLE("isTrackFlippedAndRefitted", isTrackFlippedAndRefitted, R
"DOC(
944 Returns 1 if the charged final state particle comes from a track that has been flipped and refitted
945 at the end of the reconstruction chain, in particular after the outer detector reconstruction.
948 REGISTER_VARIABLE("trackTime", getTrackTime, R
"DOC(
949 Returns the time at which the track is produced relative to the time of the collision (given by SVD EventT0).
950 Both the time of the collision and the track time are computed using only SVD hits.
951 Returns NaN if SVD EventT0 is NaN, or if no SVD Hits are attached to the track.
952 For more details, see :ref:`Time Extraction <tracking_eventTimeExtraction>` page.
956 REGISTER_VARIABLE(
"trackLength", getTrackLength, R
"DOC(
957 Returns the arc length of the helix for the TrackFitResult associated with the particle.
958 The arc length is measured from the track origin to the radius of the CDC layer in which the Track has a hit.
959 Returns 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.