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();
492 const ROOT::Math::XYZVector mcProdVertex = mcparticle->getVertex();
493 const ROOT::Math::XYZVector mcMomentum = mcparticle->
getMomentum();
495 const double mcParticleCharge = mcparticle->getCharge();
496 return Belle2::Helix(mcProdVertex, mcMomentum, mcParticleCharge, BzAtProdVertex);
499 double getMCHelixParameterAtIndex(
const Particle* particle,
const int index)
507 const std::vector<double> mcHelixPars{mcHelix.getD0(), mcHelix.getPhi0(), mcHelix.getOmega(), mcHelix.getZ0(), mcHelix.getTanLambda()};
508 return mcHelixPars.at(index);
511 double getHelixParameterPullAtIndex(
const Particle* particle,
const int index)
522 const TMatrixDSym& measCovariance = measHelix.
getCovariance();
525 const std::vector<double> mcHelixPars = {mcHelix.getD0(), mcHelix.getPhi0(), mcHelix.getOmega(), mcHelix.getZ0(), mcHelix.getTanLambda()};
528 return (mcHelixPars.at(index) - measHelixPars.at(index)) / std::sqrt(measCovariance(index, index));
531 double getHelixMCD0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 0); }
532 double getHelixMCPhi0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 1); }
533 double getHelixMCOmega(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 2); }
534 double getHelixMCZ0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 3); }
535 double getHelixMCTanLambda(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 4); }
537 double getHelixD0Pull(
const Particle* part)
539 return getHelixParameterPullAtIndex(part, 0);
542 double getHelixPhi0Pull(
const Particle* part)
544 return getHelixParameterPullAtIndex(part, 1);
547 double getHelixOmegaPull(
const Particle* part)
549 return getHelixParameterPullAtIndex(part, 2);
552 double getHelixZ0Pull(
const Particle* part)
554 return getHelixParameterPullAtIndex(part, 3);
557 double getHelixTanLambdaPull(
const Particle* part)
559 return getHelixParameterPullAtIndex(part, 4);
562 double getTrackTime(
const Particle* part)
564 const Track* track = part->getTrack();
566 return track->getTrackTime();
569 double isTrackFlippedAndRefitted(
const Particle* part)
571 auto track = part->getTrack();
573 return track->isFlippedAndRefitted() ? 1 : 0;
576 double getTrackLength(
const Particle* part)
578 auto trackFit = part->getTrackFitResult();
581 const double lastCDCLayer = trackLastCDCLayer(part);
582 if (std::isnan(lastCDCLayer) or lastCDCLayer < 0)
587 return trackFit->getHelix().getArcLength2DAtCylindricalR(r);
591 VARIABLE_GROUP(
"Tracking");
593 REGISTER_VARIABLE(
"mcD0", getHelixMCD0, R
"DOC(
594Returns the MC value of :math:`d_0`, the signed distance to the
595point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
597.. seealso:: :b2:var:`d0`
599Returns NaN if the particle is not related to any MCParticle.
602 REGISTER_VARIABLE(
"mcPhi0", getHelixMCPhi0, R
"DOC(
603Returns the MC value of :math:`\phi_0`, the angle of the transverse momentum
604in the :math:`r-\phi` plane.
606.. seealso:: :b2:var:`phi0`
608Returns NaN if the particle is not related to any MCParticle.
611 REGISTER_VARIABLE(
"mcOmega", getHelixMCOmega, R
"DOC(
612Returns the MC value of :math:`\omega`, the curvature of the track.
614.. seealso:: :b2:var:`omega`
616Returns NaN if the particle is not related to any MCParticle.
618)DOC", ":math:`\\text{cm}^{-1}`");
619 REGISTER_VARIABLE(
"mcZ0", getHelixMCZ0, R
"DOC(
620Returns the MC value of :math:`z_0`, the z-coordinate of the
621point-of-closest-approach (POCA).
623.. seealso:: :b2:var:`z0`
625Returns NaN if the particle is not related to any MCParticle.
628 REGISTER_VARIABLE(
"mcTanLambda", getHelixMCTanLambda, R
"DOC(
629Returns the MC value of :math:`\tan\lambda`, the slope of the track in the
632.. seealso:: :b2:var:`tanLambda`
634Returns NaN if the particle is not related to any MCParticle.
637 REGISTER_VARIABLE("d0Pull", getHelixD0Pull, R
"DOC(
638The pull of the tracking parameter :math:`d_0` for the reconstructed
639pattern-recognition track, with respect to the MC track. That is:
643 \frac{d_0^\textrm{MC} - d_0^\textrm{PR}}{\sigma_{d_0; \textrm{PR}}}
645.. seealso:: :b2:var:`d0`, :b2:var:`d0Err`
647Returns NaN if no MC particle is related or if called on something other than a
650 REGISTER_VARIABLE("phi0Pull", getHelixPhi0Pull, R
"DOC(
651The pull of the tracking parameter :math:`\phi_0` for the reconstructed
652pattern-recognition track, with respect to the MC track. That is:
656 \frac{\phi_0^\textrm{MC} - \phi_0^\textrm{PR}}{\sigma_{\phi_0; \textrm{PR}}}
658.. seealso:: :b2:var:`phi0`, :b2:var:`phi0Err`
660Returns NaN if no MC particle is related or if called on something other than a
663 REGISTER_VARIABLE("omegaPull", getHelixOmegaPull, R
"DOC(
664The pull of the tracking parameter :math:`\omega` for the reconstructed
665pattern-recognition track, with respect to the MC track. That is:
669 \frac{\omega^\textrm{MC} - \omega^\textrm{PR}}{\sigma_{\omega; \textrm{PR}}}
671.. seealso:: :b2:var:`omega`, :b2:var:`omegaErr`
673Returns NaN if no MC particle is related or if called on something other than a
676 REGISTER_VARIABLE("z0Pull", getHelixZ0Pull, R
"DOC(
677The pull of the tracking parameter :math:`z_0` for the reconstructed
678pattern-recognition track, with respect to the MC track. That is:
682 \frac{z_0^\textrm{MC} - z_0^\textrm{PR}}{\sigma_{z_0; \textrm{PR}}}
684.. seealso:: :b2:var:`z0`, :b2:var:`z0Err`
686Returns NaN if no MC particle is related or if called on something other than a
689 REGISTER_VARIABLE("tanLambdaPull", getHelixTanLambdaPull, R
"DOC(
690The pull of the tracking parameter :math:`\tan\lambda` for the reconstructed
691pattern-recognition track, with respect to the MC track. That is:
695 \frac{(\tan\lambda)^\textrm{MC} - (\tan\lambda)^\textrm{PR}}{\sigma_{\tan\lambda; \textrm{PR}}}
697.. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaErr`
699Returns NaN if no MC particle is related or if called on something other than a
702 REGISTER_VARIABLE("nCDCHits", trackNCDCHits,
703 "The number of CDC hits associated to the track. Returns NaN if called for something other than a track-based particle.");
704 REGISTER_VARIABLE(
"nSVDHits", trackNSVDHits,
705 "The number of SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
706 REGISTER_VARIABLE(
"nPXDHits", trackNPXDHits,
707 "The number of PXD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
708 REGISTER_VARIABLE(
"nVXDHits", trackNVXDHits,
709 "The number of PXD and SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
710 REGISTER_VARIABLE(
"ndf", trackNDF, R
"DOC(
711Returns the number of degrees of freedom of the track fit.
715 Note that this is not simply the number of hits -5 due to outlier hit
718Returns NaN if called for something other than a track-based particle, or for
719mdst files processed with basf2 versions older than ``release-05-01``.
721 REGISTER_VARIABLE("chi2", trackChi2, R
"DOC(
722Returns the :math:`\chi^2` of the track fit. This is actually computed based on
723:b2:var:`pValue` and :b2:var:`ndf`.
725.. note:: Note that for :b2:var:`pValue` exactly equal to 0 it returns infinity.
727Returns NaN if called for something other than a track-based particle, or for
728mdst files processed with basf2 versions older than ``release-05-01``.
730 REGISTER_VARIABLE("firstSVDLayer", trackFirstSVDLayer,
731 "The first activated SVD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
732 REGISTER_VARIABLE(
"firstPXDLayer", trackFirstPXDLayer,
733 "The first activated PXD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
734 REGISTER_VARIABLE(
"firstCDCLayer", trackFirstCDCLayer,
735 "The first activated CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
736 REGISTER_VARIABLE(
"lastCDCLayer", trackLastCDCLayer,
737 "The last CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
738 REGISTER_VARIABLE(
"d0", trackD0, R
"DOC(
739Returns the tracking parameter :math:`d_0`, the signed distance to the
740point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
744 Tracking parameters are with respect to the origin (0,0,0). For the
745 POCA with respect to the measured beam interaction point, see
746 :b2:var:`dr` (you probably want this unless you're doing a tracking
747 study or some debugging).
749Returns NaN if called for something other than a track-based particle.
752 REGISTER_VARIABLE(
"phi0", trackPhi0, R
"DOC(
753Returns the tracking parameter :math:`\phi_0`, the angle of the transverse
754momentum in the :math:`r-\phi` plane.
756Returns NaN if called for something other than a track-based particle.
759 REGISTER_VARIABLE(
"omega", trackOmega, R
"DOC(
760Returns the tracking parameter :math:`\omega`, the curvature of the track.
762Returns NaN if called for something other than a track-based particle.
764)DOC", ":math:`\\text{cm}^{-1}`");
765 REGISTER_VARIABLE(
"z0", trackZ0, R
"DOC(
766Returns the tracking parameter :math:`z_0`, the z-coordinate of the
767point-of-closest-approach (POCA).
771 Tracking parameters are with respect to the origin (0,0,0). For the
772 POCA with respect to the measured beam interaction point, see
773 :b2:var:`dz` (you probably want this unless you're doing a tracking
774 study or some debugging).
776Returns NaN if called for something other than a track-based particle.
779 REGISTER_VARIABLE(
"tanLambda", trackTanLambda, R
"DOC(
780Returns :math:`\tan\lambda`, the slope of the track in the :math:`r-z` plane.
782Returns NaN if called for something other than a track-based particle.
784 REGISTER_VARIABLE("d0Err", trackD0Error, R
"DOC(
785Returns the uncertainty on :math:`d_0`, the signed distance to the
786point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
788.. seealso:: :b2:var:`d0`, :b2:var:`d0Pull`
790Returns NaN if called for something other than a track-based particle.
793 REGISTER_VARIABLE(
"phi0Err", trackPhi0Error, R
"DOC(
794Returns the uncertainty on :math:`\phi_0`, the angle of the transverse momentum
795in the :math:`r-\phi` plane.
797.. seealso:: :b2:var:`phi0`, :b2:var:`phi0Pull`
799Returns NaN if called for something other than a track-based particle.
802 REGISTER_VARIABLE(
"omegaErr", trackOmegaError, R
"DOC(
803Returns the uncertainty on :math:`\omega`, the curvature of the track.
805.. seealso:: :b2:var:`omega`, :b2:var:`omegaPull`
807Returns NaN if called for something other than a track-based particle.
809)DOC", ":math:`\\text{cm}^{-1}`");
810 REGISTER_VARIABLE(
"z0Err", trackZ0Error, R
"DOC(
811Returns the uncertainty on :math:`z_0`, the z-coordinate of the
812point-of-closest-approach (POCA).
814.. seealso:: :b2:var:`z0`, :b2:var:`z0Pull`
816Returns NaN if called for something other than a track-based particle."
819 REGISTER_VARIABLE(
"tanLambdaErr", trackTanLambdaError, R
"DOC(
820Returns the uncertainty on :math:`\tan\lambda`, the slope of the track in the
823.. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaPull`
825Returns NaN if called for something other than a track-based particle.
827 REGISTER_VARIABLE("trackFitCovariance(i, j)", trackFitCovariance, R
"DOC(
828 The track fit covariance matrix element corresponding to the two indices is returned.
829 This is the association between integers and parameters:
835 * 4: :math:`\tan\lambda`
839 The covariance is returned. This means that the return value can be negative.
840 Furthermore, it's the squared value of the track fit error variables :b2:var:`d0Err`, etc.
841 when selecting the diagonal entries.
844 REGISTER_VARIABLE("pValue", trackPValue, R
"DOC(
845The :math:`\chi^2` probability of the **track** fit.
849 This is the p-value of the track-fit. It does not get updated after
850 vertex fitting or kinematic fitting, and is meaningless for composite
853 See :b2:var:`chiProb` (you probably want this for high-level analysis).
855Returns NaN if called for something other than a track-based particle.
857 REGISTER_VARIABLE("trackFitHypothesisPDG", trackFitHypothesisPDG, R
"DOC(
858Returns the PDG code of the track hypothesis actually used for the fit.
859Returns NaN if called for something other than a track-based particle.
861 REGISTER_VARIABLE("trackNECLClusters", trackNECLClusters, R
"DOC(
862Returns a count of the number of ECLClusters matched to the track. This is
863always 0 or 1 with newer versions of ECL reconstruction.
867 For high-level analysis it is recommended to require the presence of a
868 matched ECL cluster along with a minimum energy requirement. A
869 track-based particle will have a clusterE if it is matched (NaN if
870 there is no cluster match for the track.
872 .. code-block:: python
874 import modularAnalysis as ma
875 # minimum energy of 200 MeV
876 ma.fillParticleList("e+:clusters", "clusterE > 0.2", path)
878 # these two are equivalent
879 ma.fillParticleList("e+:unmatched", "isNAN(clusterE) == 1", path)
880 ma.fillParticleList("e+:unmatched2", "trackNECLClusters == 0", path)
882Returns NaN if called for something other than a track-based particle.
884 REGISTER_VARIABLE("helixExtTheta(radius [cm], z fwd [cm], z bwd [cm], useHighestProbMass=0)", trackHelixExtTheta,
885 R
"DOC(Returns theta of extrapolated helix parameters. If ``useHighestProbMass=1`` is set, the extrapolation will
886 use the track fit result for the mass hypothesis with the highest pValue.
889 REGISTER_VARIABLE(
"helixExtPhi(radius, z fwd, z bwd, useHighestProbMass=0)", trackHelixExtPhi,
890 "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",
893 REGISTER_METAVARIABLE(
"helixExtThetaOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtThetaOnDet,
894 R
"DOC(Returns theta of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
895 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
896 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
897 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
899 ..note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
900 )DOC", Manager::VariableDataType::c_double);
901 REGISTER_METAVARIABLE("helixExtPhiOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtPhiOnDet,
902 R
"DOC(Returns phi of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
903 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
904 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
905 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
907 ..note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
908 )DOC", Manager::VariableDataType::c_double);
911 REGISTER_VARIABLE("nExtraCDCHits", nExtraCDCHits, R
"DOC(
912[Eventbased] The number of CDC hits in the event not assigned to any track.
914Returns NaN if there is no event-level tracking information available.
916 REGISTER_VARIABLE("nExtraCDCHitsPostCleaning", nExtraCDCHitsPostCleaning, R
"DOC(
917[Eventbased] Returns a count of the number of CDC hits in the event not assigned
918to any track nor very likely beam background (i.e. hits that survive a cleanup
921Returns NaN if there is no event-level tracking information available.
923 REGISTER_VARIABLE("hasExtraCDCHitsInLayer(i)", hasExtraCDCHitsInLayer, R
"DOC(
924[Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC layer,
927Returns NaN if there is no event-level tracking information available.
929 REGISTER_VARIABLE("hasExtraCDCHitsInSuperLayer(i)", hasExtraCDCHitsInSuperLayer, R
"DOC(
930[Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC
931SuperLayer, 0 otherwise.
933Returns NaN if there is no event-level tracking information available.
935 REGISTER_VARIABLE("nExtraCDCSegments", nExtraCDCSegments, R
"DOC(
936[Eventbased] Returns the number of CDC segments not assigned to any track.
938Returns NaN if there is no event-level tracking information available.
946 REGISTER_VARIABLE(
"trackFindingFailureFlag", trackFindingFailureFlag, R
"DOC(
947[Eventbased] Returns a flag set by the tracking if there is reason to assume
948there was a track in the event missed by the tracking, or the track finding was
949(partly) aborted for this event.
951Returns NaN if there is no event-level tracking information available.
954 REGISTER_VARIABLE("isTrackFlippedAndRefitted", isTrackFlippedAndRefitted, R
"DOC(
955Returns 1 if the charged final state particle comes from a track that has been flipped and refitted
956at the end of the reconstruction chain, in particular after the outer detector reconstruction.
959 REGISTER_VARIABLE("trackTime", getTrackTime, R
"DOC(
960Returns the time at which the track is produced relative to the time of the collision (given by SVD EventT0).
961Both the time of the collision and the track time are computed using only SVD hits.
962Returns NaN if SVD EventT0 is NaN, or if no SVD Hits are attached to the track.
963For more details, see :ref:`Time Extraction <tracking_eventTimeExtraction>` page.
967 REGISTER_VARIABLE(
"trackLength", getTrackLength, R
"DOC(
968Returns the arc length of the helix for the TrackFitResult associated with the particle.
969The arc length is measured from the track origin to the radius of the CDC layer in which the Track has a hit.
970Returns 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)
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.
ROOT::Math::XYZVector getMomentum(const double bZ) const
Getter for vector of momentum at the perigee position.
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< 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.