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/dataobjects/Track.h>
24 #include <mdst/dataobjects/MCParticle.h>
25 #include <mdst/dataobjects/TrackFitResult.h>
26 #include <mdst/dataobjects/EventLevelTrackingInfo.h>
27 #include <mdst/dataobjects/HitPatternVXD.h>
28 #include <mdst/dataobjects/ECLCluster.h>
31 #include <framework/logging/Logger.h>
42 static const double realNaN = std::numeric_limits<double>::quiet_NaN();
43 static const B2Vector3D vecNaN(realNaN, realNaN, realNaN);
47 auto trackFit = part->getTrackFitResult();
48 if (!trackFit)
return realNaN;
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();
89 if (!trackFit)
return realNaN;
90 return trackFit->getNDF();
93 double trackChi2(
const Particle* part)
95 auto trackFit = part->getTrackFitResult();
96 if (!trackFit)
return realNaN;
97 return trackFit->getChi2();
100 double trackFirstSVDLayer(
const Particle* part)
102 auto trackFit = part->getTrackFitResult();
103 if (!trackFit)
return realNaN;
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();
115 if (!trackFit)
return realNaN;
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();
127 if (!trackFit)
return realNaN;
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();
139 if (!trackFit)
return realNaN;
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();
151 if (!trackFit)
return realNaN;
152 return trackFit->getD0();
155 double trackPhi0(
const Particle* part)
157 auto trackFit = part->getTrackFitResult();
158 if (!trackFit)
return realNaN;
159 return trackFit->getPhi0();
162 double trackOmega(
const Particle* part)
164 auto trackFit = part->getTrackFitResult();
165 if (!trackFit)
return realNaN;
166 return trackFit->getOmega();
169 double trackZ0(
const Particle* part)
171 auto trackFit = part->getTrackFitResult();
172 if (!trackFit)
return realNaN;
173 return trackFit->getZ0();
176 double trackTanLambda(
const Particle* part)
178 auto trackFit = part->getTrackFitResult();
179 if (!trackFit)
return realNaN;
180 return trackFit->getTanLambda();
183 double trackD0Error(
const Particle* part)
185 auto trackFit = part->getTrackFitResult();
186 if (!trackFit)
return realNaN;
188 double errorSquared = trackFit->getCovariance5()[0][0];
189 if (errorSquared <= 0)
return realNaN;
190 return sqrt(errorSquared);
193 double trackPhi0Error(
const Particle* part)
195 auto trackFit = part->getTrackFitResult();
196 if (!trackFit)
return realNaN;
198 double errorSquared = trackFit->getCovariance5()[1][1];
199 if (errorSquared <= 0)
return realNaN;
200 return sqrt(errorSquared);
203 double trackOmegaError(
const Particle* part)
205 auto trackFit = part->getTrackFitResult();
206 if (!trackFit)
return realNaN;
208 double errorSquared = trackFit->getCovariance5()[2][2];
209 if (errorSquared <= 0)
return realNaN;
210 return sqrt(errorSquared);
213 double trackZ0Error(
const Particle* part)
215 auto trackFit = part->getTrackFitResult();
216 if (!trackFit)
return realNaN;
218 double errorSquared = trackFit->getCovariance5()[3][3];
219 if (errorSquared <= 0)
return realNaN;
220 return sqrt(errorSquared);
223 double trackTanLambdaError(
const Particle* part)
225 auto trackFit = part->getTrackFitResult();
226 if (!trackFit)
return realNaN;
228 double errorSquared = trackFit->getCovariance5()[4][4];
229 if (errorSquared <= 0)
return realNaN;
230 return sqrt(errorSquared);
233 double trackFitCovariance(
const Particle* particle,
const std::vector<double>& indices)
235 if (indices.size() != 2) {
236 B2FATAL(
"Exactly two indices must be provided to the variable trackFitCovariance!");
238 if (*(std::min_element(indices.begin(), indices.end())) < 0 or *(std::max_element(indices.begin(), indices.end())) > 4) {
239 B2FATAL(
"The indices provided to the variable trackFitCovariance must be in the range 0 - 4!");
241 auto trackFit = particle->getTrackFitResult();
242 if (!trackFit)
return realNaN;
243 return trackFit->getCovariance5()[indices[0]][indices[1]];
246 double trackPValue(
const Particle* part)
248 auto trackFit = part->getTrackFitResult();
249 if (!trackFit)
return realNaN;
250 return trackFit->getPValue();
253 double trackFitHypothesisPDG(
const Particle* part)
255 auto trackFit = part->getTrackFitResult();
256 if (!trackFit)
return realNaN;
257 return trackFit->getParticleType().getPDGCode();
260 double trackNECLClusters(
const Particle* part)
262 const Track* track = part->getTrack();
263 if (!track)
return realNaN;
267 for (
const ECLCluster& cluster : track->getRelationsTo<ECLCluster>())
274 B2Vector3D getPositionOnHelix(
const TrackFitResult* trackFit,
const std::vector<double>& pars)
276 const double r = pars[0];
277 const double zfwd = pars[1];
278 const double zbwd = pars[2];
281 const double z0 = trackFit->getZ0();
282 const double tanlambda = trackFit->getTanLambda();
283 const Helix h = trackFit->getHelix();
286 const double arcLength = h.getArcLength2DAtCylindricalR(r);
287 const double lHelixRadius = arcLength > 0 ? arcLength : std::numeric_limits<double>::max();
290 const double lFWD = (zfwd - z0) / tanlambda > 0 ? (zfwd - z0) / tanlambda : std::numeric_limits<double>::max();
293 const double lBWD = (zbwd - z0) / tanlambda > 0 ? (zbwd - z0) / tanlambda : std::numeric_limits<double>::max();
296 const double l = std::min({lHelixRadius, lFWD, lBWD});
298 return h.getPositionAtArcLength2D(l);
301 B2Vector3D getPositionOnHelix(
const Particle* part,
const std::vector<double>& pars)
303 if (pars.size() == 4 and pars[3]) {
304 const Track* track = part->getTrack();
308 auto highestProbMass = part->getMostLikelyTrackFitResult().first;
309 const TrackFitResult* trackFit = track->getTrackFitResultWithClosestMass(highestProbMass);
310 return getPositionOnHelix(trackFit, pars);
312 const TrackFitResult* trackFit = part->getTrackFitResult();
313 return getPositionOnHelix(trackFit, pars);
318 double trackHelixExtTheta(
const Particle* part,
const std::vector<double>& pars)
320 const auto nParams = pars.size();
321 if (nParams != 3 && nParams != 4) {
322 B2FATAL(
"Exactly three (+1 optional) parameters (r, zfwd, zbwd, [useHighestProbMass]) required for helixExtTheta.");
325 B2Vector3D position = getPositionOnHelix(part, pars);
326 if (position == vecNaN)
return realNaN;
327 return position.Theta();
331 double trackHelixExtPhi(
const Particle* part,
const std::vector<double>& pars)
333 const auto nParams = pars.size();
334 if (nParams != 3 && nParams != 4) {
335 B2FATAL(
"Exactly three (+1 optional) parameters (r, zfwd, zbwd, [useHighestProbMass]) required for helixExtPhi.");
338 B2Vector3D position = getPositionOnHelix(part, pars);
339 if (position == vecNaN)
return realNaN;
340 return position.Phi();
345 if (arguments.size() != 1 && arguments.size() != 2)
346 B2FATAL(
"Exactly one (+1 optional) parameter (detector_surface_name, [useHighestProbMass]) is required for helixExtThetaOnDet.");
348 std::vector<double> parameters(3);
349 const std::string det = arguments[0];
359 B2FATAL(
"Given detector surface name is not supported.");
361 if (arguments.size() == 2)
362 parameters.push_back(std::stod(arguments[1]));
364 auto func = [parameters](
const Particle * part) ->
double {
366 B2Vector3D position = getPositionOnHelix(part, parameters);
367 if (position == vecNaN)
return realNaN;
368 return position.Theta();
375 if (arguments.size() != 1 && arguments.size() != 2)
376 B2FATAL(
"Exactly one (+1 optional) parameter (detector_surface_name, [useHighestProbMass]) is required for helixExtPhiOnDet.");
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);
397 if (position == vecNaN)
return realNaN;
398 return position.Phi();
409 double nExtraCDCHits(
const Particle*)
411 StoreObjPtr<EventLevelTrackingInfo> elti;
412 if (!elti)
return realNaN;
413 return elti->getNCDCHitsNotAssigned();
418 double nExtraCDCHitsPostCleaning(
const Particle*)
420 StoreObjPtr<EventLevelTrackingInfo> elti;
421 if (!elti)
return realNaN;
422 return elti->getNCDCHitsNotAssignedPostCleaning();
426 double hasExtraCDCHitsInLayer(
const Particle*,
const std::vector<double>& layer)
428 StoreObjPtr<EventLevelTrackingInfo> elti;
429 if (!elti)
return realNaN;
430 int ilayer = std::lround(layer[0]);
431 return elti->hasCDCLayer(ilayer);
435 double hasExtraCDCHitsInSuperLayer(
const Particle*,
const std::vector<double>& layer)
437 StoreObjPtr<EventLevelTrackingInfo> elti;
438 if (!elti)
return realNaN;
439 int ilayer = std::lround(layer[0]);
440 return elti->hasCDCSLayer(ilayer);
444 double nExtraCDCSegments(
const Particle*)
446 StoreObjPtr<EventLevelTrackingInfo> elti;
447 if (!elti)
return realNaN;
448 return elti->getNCDCSegments();
452 double nExtraVXDHitsInLayer(
const Particle*,
const std::vector<double>& layer)
454 StoreObjPtr<EventLevelTrackingInfo> elti;
455 if (!elti)
return realNaN;
456 int ilayer = std::lround(layer[0]);
457 return elti->getNVXDClustersInLayer(ilayer);
461 double nExtraVXDHits(
const Particle*)
463 StoreObjPtr<EventLevelTrackingInfo> elti;
464 if (!elti)
return realNaN;
466 for (uint16_t ilayer = 1; ilayer < 7; ++ilayer)
467 out += elti->getNVXDClustersInLayer(ilayer);
472 double svdFirstSampleTime(
const Particle*)
474 StoreObjPtr<EventLevelTrackingInfo> elti;
475 if (!elti)
return realNaN;
476 return elti->getSVDFirstSampleTime();
483 double trackFindingFailureFlag(
const Particle*)
485 StoreObjPtr<EventLevelTrackingInfo> elti;
486 if (!elti)
return realNaN;
487 return elti->hasAnErrorFlag();
490 double getHelixParameterPullAtIndex(
const Particle* particle,
const int index)
492 if (!particle)
return realNaN;
495 if (!mcparticle)
return realNaN;
498 if (!trackfit)
return realNaN;
501 const TMatrixDSym measCovariance = measHelix.
getCovariance();
502 const ROOT::Math::XYZVector mcProdVertex = mcparticle->getVertex();
503 const ROOT::Math::XYZVector mcMomentum = mcparticle->getMomentum();
506 const double mcParticleCharge = mcparticle->getCharge();
511 const std::vector<double> measErrSquare = {measCovariance[0][0], measCovariance[1][1], measCovariance[2][2], measCovariance[3][3], measCovariance[4][4]};
513 return (mcHelixPars.at(index) - measHelixPars.at(index)) / std::sqrt(measErrSquare.at(index));
516 double getHelixD0Pull(
const Particle* part)
518 return getHelixParameterPullAtIndex(part, 0);
521 double getHelixPhi0Pull(
const Particle* part)
523 return getHelixParameterPullAtIndex(part, 1);
526 double getHelixOmegaPull(
const Particle* part)
528 return getHelixParameterPullAtIndex(part, 2);
531 double getHelixZ0Pull(
const Particle* part)
533 return getHelixParameterPullAtIndex(part, 3);
535 double getHelixTanLambdaPull(
const Particle* part)
537 return getHelixParameterPullAtIndex(part, 4);
539 double getTrackTime(
const Particle* part)
541 const Track* track = part->getTrack();
542 if (!track)
return realNaN;
543 return track->getTrackTime();
546 double isTrackFlippedAndRefitted(
const Particle* part)
548 auto track = part->getTrack();
549 if (!track)
return realNaN;
550 return track->isFlippedAndRefitted() ? 1 : 0;
553 VARIABLE_GROUP(
"Tracking");
554 REGISTER_VARIABLE(
"d0Pull", getHelixD0Pull, R
"DOC(
555 The pull of the tracking parameter :math:`d_0` for the reconstructed
556 pattern-recognition track, with respect to the MC track. That is:
560 \frac{d_0^\textrm{MC} - d_0^\textrm{PR}}{\sigma_{d_0; \textrm{PR}}}
562 .. seealso:: :b2:var:`d0`, :b2:var:`d0Err`
564 Returns NaN if no MC particle is related or if called on something other than a
565 track-based particle.
567 REGISTER_VARIABLE("phi0Pull", getHelixPhi0Pull, R
"DOC(
568 The pull of the tracking parameter :math:`\phi_0` for the reconstructed
569 pattern-recognition track, with respect to the MC track. That is:
573 \frac{\phi_0^\textrm{MC} - \phi_0^\textrm{PR}}{\sigma_{\phi_0; \textrm{PR}}}
575 .. seealso:: :b2:var:`phi0`, :b2:var:`phi0Err`
577 Returns NaN if no MC particle is related or if called on something other than a
578 track-based particle.
580 REGISTER_VARIABLE("omegaPull", getHelixOmegaPull, R
"DOC(
581 The pull of the tracking parameter :math:`\omega` for the reconstructed
582 pattern-recognition track, with respect to the MC track. That is:
586 \frac{\omega^\textrm{MC} - \omega^\textrm{PR}}{\sigma_{\omega; \textrm{PR}}}
588 .. seealso:: :b2:var:`omega`, :b2:var:`omegaErr`
590 Returns NaN if no MC particle is related or if called on something other than a
591 track-based particle.
593 REGISTER_VARIABLE("z0Pull", getHelixZ0Pull, R
"DOC(
594 The pull of the tracking parameter :math:`z_0` for the reconstructed
595 pattern-recognition track, with respect to the MC track. That is:
599 \frac{z_0^\textrm{MC} - z_0^\textrm{PR}}{\sigma_{z_0; \textrm{PR}}}
601 .. seealso:: :b2:var:`z0`, :b2:var:`z0Err`
603 Returns NaN if no MC particle is related or if called on something other than a
604 track-based particle.
606 REGISTER_VARIABLE("tanLambdaPull", getHelixTanLambdaPull, R
"DOC(
607 The pull of the tracking parameter :math:`\tan\lambda` for the reconstructed
608 pattern-recognition track, with respect to the MC track. That is:
612 \frac{(\tan\lambda)^\textrm{MC} - (\tan\lambda)^\textrm{PR}}{\sigma_{\tan\lambda; \textrm{PR}}}
614 .. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaErr`
616 Returns NaN if no MC particle is related or if called on something other than a
617 track-based particle.
619 REGISTER_VARIABLE("nCDCHits", trackNCDCHits,
620 "The number of CDC hits associated to the track. Returns NaN if called for something other than a track-based particle.");
621 REGISTER_VARIABLE(
"nSVDHits", trackNSVDHits,
622 "The number of SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
623 REGISTER_VARIABLE(
"nPXDHits", trackNPXDHits,
624 "The number of PXD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
625 REGISTER_VARIABLE(
"nVXDHits", trackNVXDHits,
626 "The number of PXD and SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
627 REGISTER_VARIABLE(
"ndf", trackNDF, R
"DOC(
628 Returns the number of degrees of freedom of the track fit.
632 Note that this is not simply the number of hits -5 due to outlier hit
635 Returns NaN if called for something other than a track-based particle, or for
636 mdst files processed with basf2 versions older than ``release-05-01``.
638 REGISTER_VARIABLE("chi2", trackChi2, R
"DOC(
639 Returns the :math:`\chi^2` of the track fit. This is actually computed based on
640 :b2:var:`pValue` and :b2:var:`ndf`.
642 .. note:: Note that for :b2:var:`pValue` exactly equal to 0 it returns infinity.
644 Returns NaN if called for something other than a track-based particle, or for
645 mdst files processed with basf2 versions older than ``release-05-01``.
647 REGISTER_VARIABLE("firstSVDLayer", trackFirstSVDLayer,
648 "The first activated SVD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
649 REGISTER_VARIABLE(
"firstPXDLayer", trackFirstPXDLayer,
650 "The first activated PXD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
651 REGISTER_VARIABLE(
"firstCDCLayer", trackFirstCDCLayer,
652 "The first activated CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
653 REGISTER_VARIABLE(
"lastCDCLayer", trackLastCDCLayer,
654 "The last CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
655 REGISTER_VARIABLE(
"d0", trackD0, R
"DOC(
656 Returns the tracking parameter :math:`d_0`, the signed distance to the
657 point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
661 Tracking parameters are with respect to the origin (0,0,0). For the
662 POCA with respect to the measured beam interaction point, see
663 :b2:var:`dr` (you probably want this unless you're doing a tracking
664 study or some debugging).
666 Returns NaN if called for something other than a track-based particle.
669 REGISTER_VARIABLE(
"phi0", trackPhi0, R
"DOC(
670 Returns the tracking parameter :math:`\phi_0`, the angle of the transverse
671 momentum in the :math:`r-\phi` plane.
673 Returns NaN if called for something other than a track-based particle.
676 REGISTER_VARIABLE(
"omega", trackOmega, R
"DOC(
677 Returns the tracking parameter :math:`\omega`, the curvature of the track.
679 Returns NaN if called for something other than a track-based particle.
681 )DOC", ":math:`\\text{cm}^{-1}`");
682 REGISTER_VARIABLE(
"z0", trackZ0, R
"DOC(
683 Returns the tracking parameter :math:`z_0`, the z-coordinate of the
684 point-of-closest-approach (POCA).
688 Tracking parameters are with respect to the origin (0,0,0). For the
689 POCA with respect to the measured beam interaction point, see
690 :b2:var:`dz` (you probably want this unless you're doing a tracking
691 study or some debugging).
693 Returns NaN if called for something other than a track-based particle.
696 REGISTER_VARIABLE(
"tanLambda", trackTanLambda, R
"DOC(
697 Returns :math:`\tan\lambda`, the slope of the track in the :math:`r-z` plane.
699 Returns NaN if called for something other than a track-based particle.
701 REGISTER_VARIABLE("d0Err", trackD0Error, R
"DOC(
702 Returns the uncertainty on :math:`d_0`, the signed distance to the
703 point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
705 .. seealso:: :b2:var:`d0`, :b2:var:`d0Pull`
707 Returns NaN if called for something other than a track-based particle.
710 REGISTER_VARIABLE(
"phi0Err", trackPhi0Error, R
"DOC(
711 Returns the uncertainty on :math:`\phi_0`, the angle of the transverse momentum
712 in the :math:`r-\phi` plane.
714 .. seealso:: :b2:var:`phi0`, :b2:var:`phi0Pull`
716 Returns NaN if called for something other than a track-based particle.
719 REGISTER_VARIABLE(
"omegaErr", trackOmegaError, R
"DOC(
720 Returns the uncertainty on :math:`\omega`, the curvature of the track.
722 .. seealso:: :b2:var:`omega`, :b2:var:`omegaPull`
724 Returns NaN if called for something other than a track-based particle.
726 )DOC", ":math:`\\text{cm}^{-1}`");
727 REGISTER_VARIABLE(
"z0Err", trackZ0Error, R
"DOC(
728 Returns the uncertainty on :math:`z_0`, the z-coordinate of the
729 point-of-closest-approach (POCA).
731 .. seealso:: :b2:var:`z0`, :b2:var:`z0Pull`
733 Returns NaN if called for something other than a track-based particle."
736 REGISTER_VARIABLE(
"tanLambdaErr", trackTanLambdaError, R
"DOC(
737 Returns the uncertainty on :math:`\tan\lambda`, the slope of the track in the
740 .. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaPull`
742 Returns NaN if called for something other than a track-based particle.
744 REGISTER_VARIABLE("trackFitCovariance(i, j)", trackFitCovariance, R
"DOC(
745 The track fit covariance matrix element corresponding to the two indices is returned.
746 This is the association between integers and parameters:
752 * 4: :math:`\tan\lambda`
756 The covariance is returned. This means that the return value can be negative.
757 Furthermore, it's the squared value of the track fit error variables :b2:var:`d0Err`, etc.
758 when selecting the diagonal entries.
761 REGISTER_VARIABLE("pValue", trackPValue, R
"DOC(
762 The :math:`\chi^2` probability of the **track** fit.
766 This is the p-value of the track-fit. It does not get updated after
767 vertex fitting or kinematic fitting, and is meaningless for composite
770 See :b2:var:`chiProb` (you probably want this for high-level analysis).
772 Returns NaN if called for something other than a track-based particle.
774 REGISTER_VARIABLE("trackFitHypothesisPDG", trackFitHypothesisPDG, R
"DOC(
775 Returns the PDG code of the track hypothesis actually used for the fit.
776 Returns NaN if called for something other than a track-based particle.
778 REGISTER_VARIABLE("trackNECLClusters", trackNECLClusters, R
"DOC(
779 Returns a count of the number of ECLClusters matched to the track. This is
780 always 0 or 1 with newer versions of ECL reconstruction.
784 For high-level analysis it is recommended to require the presence of a
785 matched ECL cluster along with a minimum energy requirement. A
786 track-based particle will have a clusterE if it is matched (NaN if
787 there is no cluster match for the track.
789 .. code-block:: python
791 import modularAnalysis as ma
792 # minimum energy of 200 MeV
793 ma.fillParticleList("e+:clusters", "clusterE > 0.2", path)
795 # these two are equivalent
796 ma.fillParticleList("e+:unmatched", "isNAN(clusterE) == 1", path)
797 ma.fillParticleList("e+:unmatched2", "trackNECLClusters == 0", path)
799 Returns NaN if called for something other than a track-based particle.
801 REGISTER_VARIABLE("helixExtTheta(radius [cm], z fwd [cm], z bwd [cm], useHighestProbMass=0)", trackHelixExtTheta,
802 R
"DOC(Returns theta of extrapolated helix parameters. If ``useHighestProbMass=1`` is set, the extrapolation will
803 use the track fit result for the mass hypothesis with the highest pValue.
806 REGISTER_VARIABLE(
"helixExtPhi(radius, z fwd, z bwd, useHighestProbMass=0)", trackHelixExtPhi,
807 "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",
810 REGISTER_METAVARIABLE(
"helixExtThetaOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtThetaOnDet,
811 R
"DOC(Returns theta of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
812 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
813 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
814 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
816 ..note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
817 )DOC", Manager::VariableDataType::c_double);
818 REGISTER_METAVARIABLE("helixExtPhiOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtPhiOnDet,
819 R
"DOC(Returns phi of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
820 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
821 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
822 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
824 ..note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
825 )DOC", Manager::VariableDataType::c_double);
828 REGISTER_VARIABLE("nExtraCDCHits", nExtraCDCHits, R
"DOC(
829 [Eventbased] The number of CDC hits in the event not assigned to any track.
831 Returns NaN if there is no event-level tracking information available.
833 REGISTER_VARIABLE("nExtraCDCHitsPostCleaning", nExtraCDCHitsPostCleaning, R
"DOC(
834 [Eventbased] Returns a count of the number of CDC hits in the event not assigned
835 to any track nor very likely beam background (i.e. hits that survive a cleanup
838 Returns NaN if there is no event-level tracking information available.
840 REGISTER_VARIABLE("hasExtraCDCHitsInLayer(i)", hasExtraCDCHitsInLayer, R
"DOC(
841 [Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC layer,
844 Returns NaN if there is no event-level tracking information available.
846 REGISTER_VARIABLE("hasExtraCDCHitsInSuperLayer(i)", hasExtraCDCHitsInSuperLayer, R
"DOC(
847 [Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC
848 SuperLayer, 0 otherwise.
850 Returns NaN if there is no event-level tracking information available.
852 REGISTER_VARIABLE("nExtraCDCSegments", nExtraCDCSegments, R
"DOC(
853 [Eventbased] Returns the number of CDC segments not assigned to any track.
855 Returns NaN if there is no event-level tracking information available.
863 REGISTER_VARIABLE(
"trackFindingFailureFlag", trackFindingFailureFlag, R
"DOC(
864 [Eventbased] Returns a flag set by the tracking if there is reason to assume
865 there was a track in the event missed by the tracking, or the track finding was
866 (partly) aborted for this event.
868 Returns NaN if there is no event-level tracking information available.
871 REGISTER_VARIABLE("isTrackFlippedAndRefitted", isTrackFlippedAndRefitted, R
"DOC(
872 Returns 1 if the charged final state particle comes from a track that has been flipped and refitted
873 at the end of the reconstruction chain, in particular after the outer detector reconstruction.
876 REGISTER_VARIABLE("trackTime", getTrackTime, R
"DOC(
877 Returns the time at which the track is produced relative to the time of the collision (given by SVD EventT0).
878 Both the time of the collision and the track time are computed using only SVD hits.
879 Returns NaN if SVD EventT0 is NaN, or if no SVD Hits are attached to the track.
880 For more details, see :ref:`Time Extraction <tracking_eventTimeExtraction>` page.
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).
@ c_nPhotons
CR is split into n photons (N1)
This class represents an ideal helix in perigee parameterization.
double getOmega() const
Getter for omega, which is a signed curvature measure of the track.
double getD0() const
Getter for d0, which is the signed distance to the perigee in the r-phi plane.
double getTanLambda() const
Getter for tan lambda, which is the z over two dimensional arc length slope of the track.
double getZ0() const
Getter for z0, which is the z coordinate of the perigee.
double getPhi0() const
Getter for phi0, which is the azimuth angle of the transverse momentum at the perigee.
const MCParticle * getMCParticle() const
Returns the pointer to the MCParticle object that was used to create this Particle (ParticleType == c...
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
Abstract base class for different kinds of events.
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.