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>
46 auto trackFit = part->getTrackFitResult();
51 if (trackFit->getHitPatternCDC().getNHits() + trackFit->getHitPatternVXD().getNdf() < 1) {
52 trackFit = part->getTrack()->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(part->getPDGCode())));
54 if (det == Const::EDetector::CDC) {
55 return trackFit->getHitPatternCDC().getNHits();
56 }
else if (det == Const::EDetector::SVD) {
57 return trackFit->getHitPatternVXD().getNSVDHits();
58 }
else if (det == Const::EDetector::PXD) {
59 return trackFit->getHitPatternVXD().getNPXDHits();
65 double trackNCDCHits(
const Particle* part)
67 return trackNHits(part, Const::EDetector::CDC);
70 double trackNSVDHits(
const Particle* part)
72 return trackNHits(part, Const::EDetector::SVD);
75 double trackNPXDHits(
const Particle* part)
77 return trackNHits(part, Const::EDetector::PXD);
80 double trackNVXDHits(
const Particle* part)
82 return trackNPXDHits(part) + trackNSVDHits(part);
85 double trackNDF(
const Particle* part)
87 auto trackFit = part->getTrackFitResult();
89 return trackFit->getNDF();
92 double trackChi2(
const Particle* part)
94 auto trackFit = part->getTrackFitResult();
96 return trackFit->getChi2();
99 double trackFirstSVDLayer(
const Particle* part)
101 auto trackFit = part->getTrackFitResult();
105 if (trackFit->getHitPatternCDC().getNHits() + trackFit->getHitPatternVXD().getNdf() < 1) {
106 trackFit = part->getTrack()->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(part->getPDGCode())));
108 return trackFit->getHitPatternVXD().getFirstSVDLayer();
111 double trackFirstPXDLayer(
const Particle* part)
113 auto trackFit = part->getTrackFitResult();
117 if (trackFit->getHitPatternCDC().getNHits() + trackFit->getHitPatternVXD().getNdf() < 1) {
118 trackFit = part->getTrack()->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(part->getPDGCode())));
120 return trackFit->getHitPatternVXD().getFirstPXDLayer(HitPatternVXD::PXDMode::normal);
123 double trackFirstCDCLayer(
const Particle* part)
125 auto trackFit = part->getTrackFitResult();
129 if (trackFit->getHitPatternCDC().getNHits() + trackFit->getHitPatternVXD().getNdf() < 1) {
130 trackFit = part->getTrack()->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(part->getPDGCode())));
132 return trackFit->getHitPatternCDC().getFirstLayer();
135 double trackLastCDCLayer(
const Particle* part)
137 auto trackFit = part->getTrackFitResult();
141 if (trackFit->getHitPatternCDC().getNHits() + trackFit->getHitPatternVXD().getNdf() < 1) {
142 trackFit = part->getTrack()->getTrackFitResultWithClosestMass(Const::ChargedStable(std::abs(part->getPDGCode())));
144 return trackFit->getHitPatternCDC().getLastLayer();
147 double trackD0(
const Particle* part)
149 auto trackFit = part->getTrackFitResult();
151 return trackFit->getD0();
154 double trackPhi0(
const Particle* part)
156 auto trackFit = part->getTrackFitResult();
158 return trackFit->getPhi0();
161 double trackOmega(
const Particle* part)
163 auto trackFit = part->getTrackFitResult();
165 return trackFit->getOmega();
168 double trackZ0(
const Particle* part)
170 auto trackFit = part->getTrackFitResult();
172 return trackFit->getZ0();
175 double trackTanLambda(
const Particle* part)
177 auto trackFit = part->getTrackFitResult();
179 return trackFit->getTanLambda();
182 double trackD0Error(
const Particle* part)
184 auto trackFit = part->getTrackFitResult();
187 double errorSquared = trackFit->getCovariance5()[0][0];
189 return sqrt(errorSquared);
192 double trackPhi0Error(
const Particle* part)
194 auto trackFit = part->getTrackFitResult();
197 double errorSquared = trackFit->getCovariance5()[1][1];
199 return sqrt(errorSquared);
202 double trackOmegaError(
const Particle* part)
204 auto trackFit = part->getTrackFitResult();
207 double errorSquared = trackFit->getCovariance5()[2][2];
209 return sqrt(errorSquared);
212 double trackZ0Error(
const Particle* part)
214 auto trackFit = part->getTrackFitResult();
217 double errorSquared = trackFit->getCovariance5()[3][3];
219 return sqrt(errorSquared);
222 double trackTanLambdaError(
const Particle* part)
224 auto trackFit = part->getTrackFitResult();
227 double errorSquared = trackFit->getCovariance5()[4][4];
229 return sqrt(errorSquared);
232 double trackFitCovariance(
const Particle* particle,
const std::vector<double>& indices)
234 if (indices.size() != 2) {
235 B2FATAL(
"Exactly two indices must be provided to the variable trackFitCovariance!");
237 if (*(std::min_element(indices.begin(), indices.end())) < 0 or *(std::max_element(indices.begin(), indices.end())) > 4) {
238 B2FATAL(
"The indices provided to the variable trackFitCovariance must be in the range 0 - 4!");
240 auto trackFit = particle->getTrackFitResult();
242 return trackFit->getCovariance5()[indices[0]][indices[1]];
245 double trackPValue(
const Particle* part)
247 auto trackFit = part->getTrackFitResult();
249 return trackFit->getPValue();
252 double trackFitHypothesisPDG(
const Particle* part)
254 auto trackFit = part->getTrackFitResult();
256 return trackFit->getParticleType().getPDGCode();
259 double trackNECLClusters(
const Particle* part)
261 const Track* track = part->getTrack();
266 for (
const ECLCluster& cluster : track->getRelationsTo<ECLCluster>())
273 B2Vector3D getPositionOnHelix(
const TrackFitResult* trackFit,
const std::vector<double>& pars)
275 const double r = pars[0];
276 const double zfwd = pars[1];
277 const double zbwd = pars[2];
280 const double z0 = trackFit->getZ0();
281 const double tanlambda = trackFit->getTanLambda();
282 const Helix h = trackFit->getHelix();
285 const double arcLength = h.getArcLength2DAtCylindricalR(r);
286 const double lHelixRadius = arcLength > 0 ? arcLength : std::numeric_limits<double>::max();
289 const double lFWD = (zfwd - z0) / tanlambda > 0 ? (zfwd - z0) / tanlambda : std::numeric_limits<double>::max();
292 const double lBWD = (zbwd - z0) / tanlambda > 0 ? (zbwd - z0) / tanlambda : std::numeric_limits<double>::max();
295 const double l = std::min({lHelixRadius, lFWD, lBWD});
297 return h.getPositionAtArcLength2D(l);
300 B2Vector3D getPositionOnHelix(
const Particle* part,
const std::vector<double>& pars)
302 if (pars.size() == 4 and pars[3]) {
303 const Track* track = part->getTrack();
307 auto highestProbMass = part->getMostLikelyTrackFitResult().first;
308 const TrackFitResult* trackFit = track->getTrackFitResultWithClosestMass(highestProbMass);
309 return getPositionOnHelix(trackFit, pars);
311 const TrackFitResult* trackFit = part->getTrackFitResult();
312 return getPositionOnHelix(trackFit, pars);
317 double trackHelixExtTheta(
const Particle* part,
const std::vector<double>& pars)
319 const auto nParams = pars.size();
320 if (nParams != 3 && nParams != 4) {
321 B2FATAL(
"Exactly three (+1 optional) parameters (r, zfwd, zbwd, [useHighestProbMass]) required for helixExtTheta.");
324 B2Vector3D position = getPositionOnHelix(part, pars);
326 return position.Theta();
330 double trackHelixExtPhi(
const Particle* part,
const std::vector<double>& pars)
332 const auto nParams = pars.size();
333 if (nParams != 3 && nParams != 4) {
334 B2FATAL(
"Exactly three (+1 optional) parameters (r, zfwd, zbwd, [useHighestProbMass]) required for helixExtPhi.");
337 B2Vector3D position = getPositionOnHelix(part, pars);
339 return position.Phi();
344 if (arguments.size() != 1 && arguments.size() != 2)
345 B2FATAL(
"Exactly one (+1 optional) parameter (detector_surface_name, [useHighestProbMass]) is required for helixExtThetaOnDet.");
347 std::vector<double> parameters(3);
348 const std::string det = arguments[0];
358 B2FATAL(
"Given detector surface name is not supported.");
360 if (arguments.size() == 2)
361 parameters.push_back(std::stod(arguments[1]));
363 auto func = [parameters](
const Particle * part) ->
double {
365 B2Vector3D position = getPositionOnHelix(part, parameters);
367 return position.Theta();
374 if (arguments.size() != 1 && arguments.size() != 2)
375 B2FATAL(
"Exactly one (+1 optional) parameter (detector_surface_name, [useHighestProbMass]) is required for helixExtPhiOnDet.");
377 std::vector<double> parameters(3);
378 const std::string det = arguments[0];
388 B2FATAL(
"Given detector surface name is not supported.");
390 if (arguments.size() == 2)
391 parameters.push_back(std::stod(arguments[1]));
393 auto func = [parameters](
const Particle * part) ->
double {
395 B2Vector3D position = getPositionOnHelix(part, parameters);
397 return position.Phi();
408 double nExtraCDCHits(
const Particle*)
410 StoreObjPtr<EventLevelTrackingInfo> elti;
412 return elti->getNCDCHitsNotAssigned();
417 double nExtraCDCHitsPostCleaning(
const Particle*)
419 StoreObjPtr<EventLevelTrackingInfo> elti;
421 return elti->getNCDCHitsNotAssignedPostCleaning();
425 double hasExtraCDCHitsInLayer(
const Particle*,
const std::vector<double>& layer)
427 StoreObjPtr<EventLevelTrackingInfo> elti;
429 int ilayer = std::lround(layer[0]);
430 return elti->hasCDCLayer(ilayer);
434 double hasExtraCDCHitsInSuperLayer(
const Particle*,
const std::vector<double>& layer)
436 StoreObjPtr<EventLevelTrackingInfo> elti;
438 int ilayer = std::lround(layer[0]);
439 return elti->hasCDCSLayer(ilayer);
443 double nExtraCDCSegments(
const Particle*)
445 StoreObjPtr<EventLevelTrackingInfo> elti;
447 return elti->getNCDCSegments();
451 double nExtraVXDHitsInLayer(
const Particle*,
const std::vector<double>& layer)
453 StoreObjPtr<EventLevelTrackingInfo> elti;
455 int ilayer = std::lround(layer[0]);
456 return elti->getNVXDClustersInLayer(ilayer);
460 double nExtraVXDHits(
const Particle*)
462 StoreObjPtr<EventLevelTrackingInfo> elti;
465 for (uint16_t ilayer = 1; ilayer < 7; ++ilayer)
466 out += elti->getNVXDClustersInLayer(ilayer);
471 double svdFirstSampleTime(
const Particle*)
473 StoreObjPtr<EventLevelTrackingInfo> elti;
475 return elti->getSVDFirstSampleTime();
482 double trackFindingFailureFlag(
const Particle*)
484 StoreObjPtr<EventLevelTrackingInfo> elti;
486 return elti->hasAnErrorFlag();
489 double getHelixParameterPullAtIndex(
const Particle* particle,
const int index)
493 const MCParticle* mcparticle = particle->getMCParticle();
500 const TMatrixDSym measCovariance = measHelix.
getCovariance();
501 const ROOT::Math::XYZVector mcProdVertex = mcparticle->getVertex();
502 const ROOT::Math::XYZVector mcMomentum = mcparticle->getMomentum();
505 const double mcParticleCharge = mcparticle->getCharge();
508 const std::vector<double> mcHelixPars = {mcHelix.getD0(), mcHelix.getPhi0(), mcHelix.getOmega(), mcHelix.getZ0(), mcHelix.getTanLambda()};
509 const std::vector<double> measHelixPars = {measHelix.getD0(), measHelix.getPhi0(), measHelix.getOmega(), measHelix.getZ0(), measHelix.getTanLambda()};
510 const std::vector<double> measErrSquare = {measCovariance[0][0], measCovariance[1][1], measCovariance[2][2], measCovariance[3][3], measCovariance[4][4]};
512 return (mcHelixPars.at(index) - measHelixPars.at(index)) /
std::sqrt(measErrSquare.at(index));
515 double getHelixD0Pull(
const Particle* part)
517 return getHelixParameterPullAtIndex(part, 0);
520 double getHelixPhi0Pull(
const Particle* part)
522 return getHelixParameterPullAtIndex(part, 1);
525 double getHelixOmegaPull(
const Particle* part)
527 return getHelixParameterPullAtIndex(part, 2);
530 double getHelixZ0Pull(
const Particle* part)
532 return getHelixParameterPullAtIndex(part, 3);
534 double getHelixTanLambdaPull(
const Particle* part)
536 return getHelixParameterPullAtIndex(part, 4);
538 double getTrackTime(
const Particle* part)
540 const Track* track = part->getTrack();
542 return track->getTrackTime();
545 double isTrackFlippedAndRefitted(
const Particle* part)
547 auto track = part->getTrack();
549 return track->isFlippedAndRefitted() ? 1 : 0;
552 double getTrackLength(
const Particle* part)
554 auto trackFit = part->getTrackFitResult();
557 const double lastCDCLayer = trackLastCDCLayer(part);
558 if (std::isnan(lastCDCLayer) or lastCDCLayer < 0)
563 return trackFit->getHelix().getArcLength2DAtCylindricalR(r);
567 VARIABLE_GROUP(
"Tracking");
568 REGISTER_VARIABLE(
"d0Pull", getHelixD0Pull, R
"DOC(
569 The pull of the tracking parameter :math:`d_0` for the reconstructed
570 pattern-recognition track, with respect to the MC track. That is:
574 \frac{d_0^\textrm{MC} - d_0^\textrm{PR}}{\sigma_{d_0; \textrm{PR}}}
576 .. seealso:: :b2:var:`d0`, :b2:var:`d0Err`
578 Returns NaN if no MC particle is related or if called on something other than a
579 track-based particle.
581 REGISTER_VARIABLE("phi0Pull", getHelixPhi0Pull, R
"DOC(
582 The pull of the tracking parameter :math:`\phi_0` for the reconstructed
583 pattern-recognition track, with respect to the MC track. That is:
587 \frac{\phi_0^\textrm{MC} - \phi_0^\textrm{PR}}{\sigma_{\phi_0; \textrm{PR}}}
589 .. seealso:: :b2:var:`phi0`, :b2:var:`phi0Err`
591 Returns NaN if no MC particle is related or if called on something other than a
592 track-based particle.
594 REGISTER_VARIABLE("omegaPull", getHelixOmegaPull, R
"DOC(
595 The pull of the tracking parameter :math:`\omega` for the reconstructed
596 pattern-recognition track, with respect to the MC track. That is:
600 \frac{\omega^\textrm{MC} - \omega^\textrm{PR}}{\sigma_{\omega; \textrm{PR}}}
602 .. seealso:: :b2:var:`omega`, :b2:var:`omegaErr`
604 Returns NaN if no MC particle is related or if called on something other than a
605 track-based particle.
607 REGISTER_VARIABLE("z0Pull", getHelixZ0Pull, R
"DOC(
608 The pull of the tracking parameter :math:`z_0` for the reconstructed
609 pattern-recognition track, with respect to the MC track. That is:
613 \frac{z_0^\textrm{MC} - z_0^\textrm{PR}}{\sigma_{z_0; \textrm{PR}}}
615 .. seealso:: :b2:var:`z0`, :b2:var:`z0Err`
617 Returns NaN if no MC particle is related or if called on something other than a
618 track-based particle.
620 REGISTER_VARIABLE("tanLambdaPull", getHelixTanLambdaPull, R
"DOC(
621 The pull of the tracking parameter :math:`\tan\lambda` for the reconstructed
622 pattern-recognition track, with respect to the MC track. That is:
626 \frac{(\tan\lambda)^\textrm{MC} - (\tan\lambda)^\textrm{PR}}{\sigma_{\tan\lambda; \textrm{PR}}}
628 .. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaErr`
630 Returns NaN if no MC particle is related or if called on something other than a
631 track-based particle.
633 REGISTER_VARIABLE("nCDCHits", trackNCDCHits,
634 "The number of CDC hits associated to the track. Returns NaN if called for something other than a track-based particle.");
635 REGISTER_VARIABLE(
"nSVDHits", trackNSVDHits,
636 "The number of SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
637 REGISTER_VARIABLE(
"nPXDHits", trackNPXDHits,
638 "The number of PXD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
639 REGISTER_VARIABLE(
"nVXDHits", trackNVXDHits,
640 "The number of PXD and SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
641 REGISTER_VARIABLE(
"ndf", trackNDF, R
"DOC(
642 Returns the number of degrees of freedom of the track fit.
646 Note that this is not simply the number of hits -5 due to outlier hit
649 Returns NaN if called for something other than a track-based particle, or for
650 mdst files processed with basf2 versions older than ``release-05-01``.
652 REGISTER_VARIABLE("chi2", trackChi2, R
"DOC(
653 Returns the :math:`\chi^2` of the track fit. This is actually computed based on
654 :b2:var:`pValue` and :b2:var:`ndf`.
656 .. note:: Note that for :b2:var:`pValue` exactly equal to 0 it returns infinity.
658 Returns NaN if called for something other than a track-based particle, or for
659 mdst files processed with basf2 versions older than ``release-05-01``.
661 REGISTER_VARIABLE("firstSVDLayer", trackFirstSVDLayer,
662 "The first activated SVD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
663 REGISTER_VARIABLE(
"firstPXDLayer", trackFirstPXDLayer,
664 "The first activated PXD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
665 REGISTER_VARIABLE(
"firstCDCLayer", trackFirstCDCLayer,
666 "The first activated CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
667 REGISTER_VARIABLE(
"lastCDCLayer", trackLastCDCLayer,
668 "The last CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
669 REGISTER_VARIABLE(
"d0", trackD0, R
"DOC(
670 Returns the tracking parameter :math:`d_0`, the signed distance to the
671 point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
675 Tracking parameters are with respect to the origin (0,0,0). For the
676 POCA with respect to the measured beam interaction point, see
677 :b2:var:`dr` (you probably want this unless you're doing a tracking
678 study or some debugging).
680 Returns NaN if called for something other than a track-based particle.
683 REGISTER_VARIABLE(
"phi0", trackPhi0, R
"DOC(
684 Returns the tracking parameter :math:`\phi_0`, the angle of the transverse
685 momentum in the :math:`r-\phi` plane.
687 Returns NaN if called for something other than a track-based particle.
690 REGISTER_VARIABLE(
"omega", trackOmega, R
"DOC(
691 Returns the tracking parameter :math:`\omega`, the curvature of the track.
693 Returns NaN if called for something other than a track-based particle.
695 )DOC", ":math:`\\text{cm}^{-1}`");
696 REGISTER_VARIABLE(
"z0", trackZ0, R
"DOC(
697 Returns the tracking parameter :math:`z_0`, the z-coordinate of the
698 point-of-closest-approach (POCA).
702 Tracking parameters are with respect to the origin (0,0,0). For the
703 POCA with respect to the measured beam interaction point, see
704 :b2:var:`dz` (you probably want this unless you're doing a tracking
705 study or some debugging).
707 Returns NaN if called for something other than a track-based particle.
710 REGISTER_VARIABLE(
"tanLambda", trackTanLambda, R
"DOC(
711 Returns :math:`\tan\lambda`, the slope of the track in the :math:`r-z` plane.
713 Returns NaN if called for something other than a track-based particle.
715 REGISTER_VARIABLE("d0Err", trackD0Error, R
"DOC(
716 Returns the uncertainty on :math:`d_0`, the signed distance to the
717 point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
719 .. seealso:: :b2:var:`d0`, :b2:var:`d0Pull`
721 Returns NaN if called for something other than a track-based particle.
724 REGISTER_VARIABLE(
"phi0Err", trackPhi0Error, R
"DOC(
725 Returns the uncertainty on :math:`\phi_0`, the angle of the transverse momentum
726 in the :math:`r-\phi` plane.
728 .. seealso:: :b2:var:`phi0`, :b2:var:`phi0Pull`
730 Returns NaN if called for something other than a track-based particle.
733 REGISTER_VARIABLE(
"omegaErr", trackOmegaError, R
"DOC(
734 Returns the uncertainty on :math:`\omega`, the curvature of the track.
736 .. seealso:: :b2:var:`omega`, :b2:var:`omegaPull`
738 Returns NaN if called for something other than a track-based particle.
740 )DOC", ":math:`\\text{cm}^{-1}`");
741 REGISTER_VARIABLE(
"z0Err", trackZ0Error, R
"DOC(
742 Returns the uncertainty on :math:`z_0`, the z-coordinate of the
743 point-of-closest-approach (POCA).
745 .. seealso:: :b2:var:`z0`, :b2:var:`z0Pull`
747 Returns NaN if called for something other than a track-based particle."
750 REGISTER_VARIABLE(
"tanLambdaErr", trackTanLambdaError, R
"DOC(
751 Returns the uncertainty on :math:`\tan\lambda`, the slope of the track in the
754 .. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaPull`
756 Returns NaN if called for something other than a track-based particle.
758 REGISTER_VARIABLE("trackFitCovariance(i, j)", trackFitCovariance, R
"DOC(
759 The track fit covariance matrix element corresponding to the two indices is returned.
760 This is the association between integers and parameters:
766 * 4: :math:`\tan\lambda`
770 The covariance is returned. This means that the return value can be negative.
771 Furthermore, it's the squared value of the track fit error variables :b2:var:`d0Err`, etc.
772 when selecting the diagonal entries.
775 REGISTER_VARIABLE("pValue", trackPValue, R
"DOC(
776 The :math:`\chi^2` probability of the **track** fit.
780 This is the p-value of the track-fit. It does not get updated after
781 vertex fitting or kinematic fitting, and is meaningless for composite
784 See :b2:var:`chiProb` (you probably want this for high-level analysis).
786 Returns NaN if called for something other than a track-based particle.
788 REGISTER_VARIABLE("trackFitHypothesisPDG", trackFitHypothesisPDG, R
"DOC(
789 Returns the PDG code of the track hypothesis actually used for the fit.
790 Returns NaN if called for something other than a track-based particle.
792 REGISTER_VARIABLE("trackNECLClusters", trackNECLClusters, R
"DOC(
793 Returns a count of the number of ECLClusters matched to the track. This is
794 always 0 or 1 with newer versions of ECL reconstruction.
798 For high-level analysis it is recommended to require the presence of a
799 matched ECL cluster along with a minimum energy requirement. A
800 track-based particle will have a clusterE if it is matched (NaN if
801 there is no cluster match for the track.
803 .. code-block:: python
805 import modularAnalysis as ma
806 # minimum energy of 200 MeV
807 ma.fillParticleList("e+:clusters", "clusterE > 0.2", path)
809 # these two are equivalent
810 ma.fillParticleList("e+:unmatched", "isNAN(clusterE) == 1", path)
811 ma.fillParticleList("e+:unmatched2", "trackNECLClusters == 0", path)
813 Returns NaN if called for something other than a track-based particle.
815 REGISTER_VARIABLE("helixExtTheta(radius [cm], z fwd [cm], z bwd [cm], useHighestProbMass=0)", trackHelixExtTheta,
816 R
"DOC(Returns theta of extrapolated helix parameters. If ``useHighestProbMass=1`` is set, the extrapolation will
817 use the track fit result for the mass hypothesis with the highest pValue.
820 REGISTER_VARIABLE(
"helixExtPhi(radius, z fwd, z bwd, useHighestProbMass=0)", trackHelixExtPhi,
821 "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",
824 REGISTER_METAVARIABLE(
"helixExtThetaOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtThetaOnDet,
825 R
"DOC(Returns theta of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
826 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
827 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
828 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
830 ..note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
831 )DOC", Manager::VariableDataType::c_double);
832 REGISTER_METAVARIABLE("helixExtPhiOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtPhiOnDet,
833 R
"DOC(Returns phi of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
834 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
835 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
836 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
838 ..note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
839 )DOC", Manager::VariableDataType::c_double);
842 REGISTER_VARIABLE("nExtraCDCHits", nExtraCDCHits, R
"DOC(
843 [Eventbased] The number of CDC hits in the event not assigned to any track.
845 Returns NaN if there is no event-level tracking information available.
847 REGISTER_VARIABLE("nExtraCDCHitsPostCleaning", nExtraCDCHitsPostCleaning, R
"DOC(
848 [Eventbased] Returns a count of the number of CDC hits in the event not assigned
849 to any track nor very likely beam background (i.e. hits that survive a cleanup
852 Returns NaN if there is no event-level tracking information available.
854 REGISTER_VARIABLE("hasExtraCDCHitsInLayer(i)", hasExtraCDCHitsInLayer, R
"DOC(
855 [Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC layer,
858 Returns NaN if there is no event-level tracking information available.
860 REGISTER_VARIABLE("hasExtraCDCHitsInSuperLayer(i)", hasExtraCDCHitsInSuperLayer, R
"DOC(
861 [Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC
862 SuperLayer, 0 otherwise.
864 Returns NaN if there is no event-level tracking information available.
866 REGISTER_VARIABLE("nExtraCDCSegments", nExtraCDCSegments, R
"DOC(
867 [Eventbased] Returns the number of CDC segments not assigned to any track.
869 Returns NaN if there is no event-level tracking information available.
877 REGISTER_VARIABLE(
"trackFindingFailureFlag", trackFindingFailureFlag, R
"DOC(
878 [Eventbased] Returns a flag set by the tracking if there is reason to assume
879 there was a track in the event missed by the tracking, or the track finding was
880 (partly) aborted for this event.
882 Returns NaN if there is no event-level tracking information available.
885 REGISTER_VARIABLE("isTrackFlippedAndRefitted", isTrackFlippedAndRefitted, R
"DOC(
886 Returns 1 if the charged final state particle comes from a track that has been flipped and refitted
887 at the end of the reconstruction chain, in particular after the outer detector reconstruction.
890 REGISTER_VARIABLE("trackTime", getTrackTime, R
"DOC(
891 Returns the time at which the track is produced relative to the time of the collision (given by SVD EventT0).
892 Both the time of the collision and the track time are computed using only SVD hits.
893 Returns NaN if SVD EventT0 is NaN, or if no SVD Hits are attached to the track.
894 For more details, see :ref:`Time Extraction <tracking_eventTimeExtraction>` page.
898 REGISTER_VARIABLE(
"trackLength", getTrackLength, R
"DOC(
899 Returns the arc length of the helix for the TrackFitResult associated with the particle.
900 The arc length is measured from the track origin to the radius of the CDC layer in which the Track has a hit.
901 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.