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();
50 if (det == Const::EDetector::CDC) {
51 return trackFit->getHitPatternCDC().getNHits();
52 }
else if (det == Const::EDetector::SVD) {
53 return trackFit->getHitPatternVXD().getNSVDHits();
54 }
else if (det == Const::EDetector::PXD) {
55 return trackFit->getHitPatternVXD().getNPXDHits();
61 double trackNCDCHits(
const Particle* part)
63 return trackNHits(part, Const::EDetector::CDC);
66 double trackNSVDHits(
const Particle* part)
68 return trackNHits(part, Const::EDetector::SVD);
71 double trackNPXDHits(
const Particle* part)
73 return trackNHits(part, Const::EDetector::PXD);
76 double trackNVXDHits(
const Particle* part)
78 return trackNPXDHits(part) + trackNSVDHits(part);
81 double trackNDF(
const Particle* part)
83 auto trackFit = part->getTrackFitResult();
85 return trackFit->getNDF();
88 double trackChi2(
const Particle* part)
90 auto trackFit = part->getTrackFitResult();
92 return trackFit->getChi2();
95 double trackFirstSVDLayer(
const Particle* part)
97 auto trackFit = part->getTrackFitResult();
99 return trackFit->getHitPatternVXD().getFirstSVDLayer();
102 double trackFirstPXDLayer(
const Particle* part)
104 auto trackFit = part->getTrackFitResult();
106 return trackFit->getHitPatternVXD().getFirstPXDLayer(HitPatternVXD::PXDMode::normal);
109 double trackFirstCDCLayer(
const Particle* part)
111 auto trackFit = part->getTrackFitResult();
113 return trackFit->getHitPatternCDC().getFirstLayer();
116 double trackLastCDCLayer(
const Particle* part)
118 auto trackFit = part->getTrackFitResult();
120 return trackFit->getHitPatternCDC().getLastLayer();
123 double trackD0(
const Particle* part)
125 auto trackFit = part->getTrackFitResult();
127 return trackFit->getD0();
130 double trackPhi0(
const Particle* part)
132 auto trackFit = part->getTrackFitResult();
134 return trackFit->getPhi0();
137 double trackOmega(
const Particle* part)
139 auto trackFit = part->getTrackFitResult();
141 return trackFit->getOmega();
144 double trackZ0(
const Particle* part)
146 auto trackFit = part->getTrackFitResult();
148 return trackFit->getZ0();
151 double trackTanLambda(
const Particle* part)
153 auto trackFit = part->getTrackFitResult();
155 return trackFit->getTanLambda();
158 double trackD0FromIP(
const Particle* part)
160 auto trackFit = part->getTrackFitResult();
162 static DBObjPtr<BeamSpot> beamSpotDB;
163 if (!beamSpotDB.isValid())
165 auto helix = trackFit->getHelix();
166 helix.passiveMoveBy(beamSpotDB->getIPPosition());
167 return helix.getD0();
170 double trackZ0FromIP(
const Particle* part)
172 auto trackFit = part->getTrackFitResult();
174 static DBObjPtr<BeamSpot> beamSpotDB;
175 if (!beamSpotDB.isValid())
177 auto helix = trackFit->getHelix();
178 helix.passiveMoveBy(beamSpotDB->getIPPosition());
179 return helix.getZ0();
182 double trackPhi0FromIP(
const Particle* part)
184 auto trackFit = part->getTrackFitResult();
186 static DBObjPtr<BeamSpot> beamSpotDB;
187 if (!beamSpotDB.isValid())
189 auto helix = trackFit->getHelix();
190 helix.passiveMoveBy(beamSpotDB->getIPPosition());
191 return helix.getPhi0();
194 double trackD0Error(
const Particle* part)
196 auto trackFit = part->getTrackFitResult();
198 double errorSquared = trackFit->getCovariance5()[0][0];
200 return sqrt(errorSquared);
203 double trackPhi0Error(
const Particle* part)
205 auto trackFit = part->getTrackFitResult();
208 double errorSquared = trackFit->getCovariance5()[1][1];
210 return sqrt(errorSquared);
213 double trackOmegaError(
const Particle* part)
215 auto trackFit = part->getTrackFitResult();
218 double errorSquared = trackFit->getCovariance5()[2][2];
220 return sqrt(errorSquared);
223 double trackZ0Error(
const Particle* part)
225 auto trackFit = part->getTrackFitResult();
228 double errorSquared = trackFit->getCovariance5()[3][3];
230 return sqrt(errorSquared);
233 double trackTanLambdaError(
const Particle* part)
235 auto trackFit = part->getTrackFitResult();
238 double errorSquared = trackFit->getCovariance5()[4][4];
240 return sqrt(errorSquared);
243 double trackFitCovariance(
const Particle* particle,
const std::vector<double>& indices)
245 if (indices.size() != 2) {
246 B2FATAL(
"Exactly two indices must be provided to the variable trackFitCovariance!");
248 if (*(std::min_element(indices.begin(), indices.end())) < 0 or *(std::max_element(indices.begin(), indices.end())) > 4) {
249 B2FATAL(
"The indices provided to the variable trackFitCovariance must be in the range 0 - 4!");
251 auto trackFit = particle->getTrackFitResult();
253 return trackFit->getCovariance5()[indices[0]][indices[1]];
256 double trackPValue(
const Particle* part)
258 auto trackFit = part->getTrackFitResult();
260 return trackFit->getPValue();
263 double trackFitHypothesisPDG(
const Particle* part)
265 auto trackFit = part->getTrackFitResult();
267 return trackFit->getParticleType().getPDGCode();
270 double trackNECLClusters(
const Particle* part)
272 const Track* track = part->getTrack();
277 for (
const ECLCluster& cluster : track->getRelationsTo<ECLCluster>())
284 ROOT::Math::XYZVector getPositionOnHelix(
const TrackFitResult* trackFit,
const std::vector<double>& pars)
286 const double r = pars[0];
287 const double zfwd = pars[1];
288 const double zbwd = pars[2];
291 const double z0 = trackFit->getZ0();
292 const double tanlambda = trackFit->getTanLambda();
293 const Helix h = trackFit->getHelix();
296 const double arcLength = h.getArcLength2DAtCylindricalR(r);
297 const double lHelixRadius = arcLength > 0 ? arcLength : std::numeric_limits<double>::max();
300 const double lFWD = (zfwd - z0) / tanlambda > 0 ? (zfwd - z0) / tanlambda : std::numeric_limits<double>::max();
303 const double lBWD = (zbwd - z0) / tanlambda > 0 ? (zbwd - z0) / tanlambda : std::numeric_limits<double>::max();
306 const double l = std::min({lHelixRadius, lFWD, lBWD});
308 return h.getPositionAtArcLength2D(l);
311 ROOT::Math::XYZVector getPositionOnHelix(
const Particle* part,
const std::vector<double>& pars)
313 if (pars.size() == 4 and pars[3]) {
314 const Track* track = part->getTrack();
318 auto highestProbMass = part->getMostLikelyTrackFitResult().first;
319 const TrackFitResult* trackFit = track->getTrackFitResultWithClosestMass(highestProbMass);
320 if (!trackFit)
return vecNaN;
321 else return getPositionOnHelix(trackFit, pars);
323 const TrackFitResult* trackFit = part->getTrackFitResult();
324 if (!trackFit)
return vecNaN;
325 else return getPositionOnHelix(trackFit, pars);
330 double trackHelixExtTheta(
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 helixExtTheta.");
337 ROOT::Math::XYZVector position = getPositionOnHelix(part, pars);
339 return position.Theta();
343 double trackHelixExtPhi(
const Particle* part,
const std::vector<double>& pars)
345 const auto nParams = pars.size();
346 if (nParams != 3 && nParams != 4) {
347 B2FATAL(
"Exactly three (+1 optional) parameters (r, zfwd, zbwd, [useHighestProbMass]) required for helixExtPhi.");
350 ROOT::Math::XYZVector position = getPositionOnHelix(part, pars);
352 return position.Phi();
357 if (arguments.size() != 1 && arguments.size() != 2)
358 B2FATAL(
"Exactly one (+1 optional) parameter (detector_surface_name, [useHighestProbMass]) is required for helixExtThetaOnDet.");
360 std::vector<double> parameters(3);
361 const std::string det = arguments[0];
371 B2FATAL(
"Given detector surface name is not supported.");
373 if (arguments.size() == 2)
374 parameters.push_back(std::stod(arguments[1]));
376 auto func = [parameters](
const Particle * part) ->
double {
378 ROOT::Math::XYZVector position = getPositionOnHelix(part, parameters);
380 return position.Theta();
387 if (arguments.size() != 1 && arguments.size() != 2)
388 B2FATAL(
"Exactly one (+1 optional) parameter (detector_surface_name, [useHighestProbMass]) is required for helixExtPhiOnDet.");
390 std::vector<double> parameters(3);
391 const std::string det = arguments[0];
401 B2FATAL(
"Given detector surface name is not supported.");
403 if (arguments.size() == 2)
404 parameters.push_back(std::stod(arguments[1]));
406 auto func = [parameters](
const Particle * part) ->
double {
408 ROOT::Math::XYZVector position = getPositionOnHelix(part, parameters);
410 return position.Phi();
421 double nExtraCDCHits(
const Particle*)
423 StoreObjPtr<EventLevelTrackingInfo> elti;
425 return elti->getNCDCHitsNotAssigned();
430 double nExtraCDCHitsPostCleaning(
const Particle*)
432 StoreObjPtr<EventLevelTrackingInfo> elti;
434 return elti->getNCDCHitsNotAssignedPostCleaning();
438 double hasExtraCDCHitsInLayer(
const Particle*,
const std::vector<double>& layer)
440 StoreObjPtr<EventLevelTrackingInfo> elti;
442 int ilayer = std::lround(layer[0]);
443 return elti->hasCDCLayer(ilayer);
447 double hasExtraCDCHitsInSuperLayer(
const Particle*,
const std::vector<double>& layer)
449 StoreObjPtr<EventLevelTrackingInfo> elti;
451 int ilayer = std::lround(layer[0]);
452 return elti->hasCDCSLayer(ilayer);
456 double nExtraCDCSegments(
const Particle*)
458 StoreObjPtr<EventLevelTrackingInfo> elti;
460 return elti->getNCDCSegments();
464 double nExtraVXDHitsInLayer(
const Particle*,
const std::vector<double>& layer)
466 StoreObjPtr<EventLevelTrackingInfo> elti;
468 int ilayer = std::lround(layer[0]);
469 return elti->getNVXDClustersInLayer(ilayer);
473 double nExtraVXDHits(
const Particle*)
475 StoreObjPtr<EventLevelTrackingInfo> elti;
478 for (uint16_t ilayer = 1; ilayer < 7; ++ilayer)
479 out += elti->getNVXDClustersInLayer(ilayer);
484 double nExtraPXDHits(
const Particle*)
486 StoreObjPtr<EventLevelTrackingInfo> elti;
489 for (uint16_t ilayer = 1; ilayer < 3; ++ilayer)
490 out += elti->getNVXDClustersInLayer(ilayer);
495 double svdFirstSampleTime(
const Particle*)
497 StoreObjPtr<EventLevelTrackingInfo> elti;
499 return elti->getSVDFirstSampleTime();
506 double trackFindingFailureFlag(
const Particle*)
508 StoreObjPtr<EventLevelTrackingInfo> elti;
510 return elti->hasAnErrorFlag();
514 Helix getMCHelix(
const MCParticle* mcparticle)
516 const ROOT::Math::XYZVector mcProdVertex = mcparticle->getVertex();
517 const ROOT::Math::XYZVector mcMomentum = mcparticle->getMomentum();
519 const double mcParticleCharge = mcparticle->getCharge();
520 return Helix(mcProdVertex, mcMomentum, mcParticleCharge, BzAtProdVertex);
523 double getMCHelixParameterAtIndex(
const Particle* particle,
const int index)
527 const MCParticle* mcparticle = particle->getMCParticle();
530 const Helix mcHelix(getMCHelix(mcparticle));
531 const std::vector<double> mcHelixPars{mcHelix.getD0(), mcHelix.getPhi0(), mcHelix.getOmega(), mcHelix.getZ0(), mcHelix.getTanLambda()};
532 return mcHelixPars.at(index);
535 double getHelixParameterPullAtIndex(
const Particle* particle,
const int index)
539 const MCParticle* mcparticle = particle->getMCParticle();
542 const TrackFitResult* trackfit = particle->getTrackFitResult();
545 const UncertainHelix measHelix = trackfit->getUncertainHelix();
546 const TMatrixDSym& measCovariance = measHelix.getCovariance();
547 const Helix mcHelix(getMCHelix(mcparticle));
549 const std::vector<double> mcHelixPars = {mcHelix.getD0(), mcHelix.getPhi0(), mcHelix.getOmega(), mcHelix.getZ0(), mcHelix.getTanLambda()};
550 const std::vector<double> measHelixPars = {measHelix.getD0(), measHelix.getPhi0(), measHelix.getOmega(), measHelix.getZ0(), measHelix.getTanLambda()};
552 return (mcHelixPars.at(index) - measHelixPars.at(index)) / std::sqrt(measCovariance(index, index));
555 double getHelixMCD0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 0); }
556 double getHelixMCPhi0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 1); }
557 double getHelixMCOmega(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 2); }
558 double getHelixMCZ0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 3); }
559 double getHelixMCTanLambda(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 4); }
561 double getHelixD0Pull(
const Particle* part)
563 return getHelixParameterPullAtIndex(part, 0);
566 double getHelixPhi0Pull(
const Particle* part)
568 return getHelixParameterPullAtIndex(part, 1);
571 double getHelixOmegaPull(
const Particle* part)
573 return getHelixParameterPullAtIndex(part, 2);
576 double getHelixZ0Pull(
const Particle* part)
578 return getHelixParameterPullAtIndex(part, 3);
581 double getHelixTanLambdaPull(
const Particle* part)
583 return getHelixParameterPullAtIndex(part, 4);
586 double getTrackTime(
const Particle* part)
588 const Track* track = part->getTrack();
590 return track->getTrackTime();
593 double isTrackFlippedAndRefitted(
const Particle* part)
595 auto track = part->getTrack();
597 return track->isFlippedAndRefitted() ? 1 : 0;
600 double getTrackLength(
const Particle* part)
602 auto trackFit = part->getTrackFitResult();
605 const double lastCDCLayer = trackLastCDCLayer(part);
606 if (std::isnan(lastCDCLayer) or lastCDCLayer < 0)
611 return trackFit->getHelix().getArcLength2DAtCylindricalR(r);
615 VARIABLE_GROUP(
"Tracking");
617 REGISTER_VARIABLE(
"mcD0", getHelixMCD0, R
"DOC(
618Returns the MC value of :math:`d_0`, the signed distance to the
619point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
621.. seealso:: :b2:var:`d0`
623Returns NaN if the particle is not related to any MCParticle.
626 REGISTER_VARIABLE(
"mcPhi0", getHelixMCPhi0, R
"DOC(
627Returns the MC value of :math:`\phi_0`, the angle of the transverse momentum
628in the :math:`r-\phi` plane.
630.. seealso:: :b2:var:`phi0`
632Returns NaN if the particle is not related to any MCParticle.
635 REGISTER_VARIABLE(
"mcOmega", getHelixMCOmega, R
"DOC(
636Returns the MC value of :math:`\omega`, the curvature of the track.
638.. seealso:: :b2:var:`omega`
640Returns NaN if the particle is not related to any MCParticle.
642)DOC", ":math:`\\text{cm}^{-1}`");
643 REGISTER_VARIABLE(
"mcZ0", getHelixMCZ0, R
"DOC(
644Returns the MC value of :math:`z_0`, the z-coordinate of the
645point-of-closest-approach (POCA).
647.. seealso:: :b2:var:`z0`
649Returns NaN if the particle is not related to any MCParticle.
652 REGISTER_VARIABLE(
"mcTanLambda", getHelixMCTanLambda, R
"DOC(
653Returns the MC value of :math:`\tan\lambda`, the slope of the track in the
656.. seealso:: :b2:var:`tanLambda`
658Returns NaN if the particle is not related to any MCParticle.
661 REGISTER_VARIABLE("d0Pull", getHelixD0Pull, R
"DOC(
662The pull of the tracking parameter :math:`d_0` for the reconstructed
663pattern-recognition track, with respect to the MC track. That is:
667 \frac{d_0^\textrm{MC} - d_0^\textrm{PR}}{\sigma_{d_0; \textrm{PR}}}
669.. seealso:: :b2:var:`d0`, :b2:var:`d0Err`
671Returns NaN if no MC particle is related or if called on something other than a
674 REGISTER_VARIABLE("phi0Pull", getHelixPhi0Pull, R
"DOC(
675The pull of the tracking parameter :math:`\phi_0` for the reconstructed
676pattern-recognition track, with respect to the MC track. That is:
680 \frac{\phi_0^\textrm{MC} - \phi_0^\textrm{PR}}{\sigma_{\phi_0; \textrm{PR}}}
682.. seealso:: :b2:var:`phi0`, :b2:var:`phi0Err`
684Returns NaN if no MC particle is related or if called on something other than a
687 REGISTER_VARIABLE("omegaPull", getHelixOmegaPull, R
"DOC(
688The pull of the tracking parameter :math:`\omega` for the reconstructed
689pattern-recognition track, with respect to the MC track. That is:
693 \frac{\omega^\textrm{MC} - \omega^\textrm{PR}}{\sigma_{\omega; \textrm{PR}}}
695.. seealso:: :b2:var:`omega`, :b2:var:`omegaErr`
697Returns NaN if no MC particle is related or if called on something other than a
700 REGISTER_VARIABLE("z0Pull", getHelixZ0Pull, R
"DOC(
701The pull of the tracking parameter :math:`z_0` for the reconstructed
702pattern-recognition track, with respect to the MC track. That is:
706 \frac{z_0^\textrm{MC} - z_0^\textrm{PR}}{\sigma_{z_0; \textrm{PR}}}
708.. seealso:: :b2:var:`z0`, :b2:var:`z0Err`
710Returns NaN if no MC particle is related or if called on something other than a
713 REGISTER_VARIABLE("tanLambdaPull", getHelixTanLambdaPull, R
"DOC(
714The pull of the tracking parameter :math:`\tan\lambda` for the reconstructed
715pattern-recognition track, with respect to the MC track. That is:
719 \frac{(\tan\lambda)^\textrm{MC} - (\tan\lambda)^\textrm{PR}}{\sigma_{\tan\lambda; \textrm{PR}}}
721.. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaErr`
723Returns NaN if no MC particle is related or if called on something other than a
726 REGISTER_VARIABLE("nCDCHits", trackNCDCHits,
727 "The number of CDC hits associated to the track. Returns NaN if called for something other than a track-based particle.");
728 REGISTER_VARIABLE(
"nSVDHits", trackNSVDHits,
729 "The number of SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
730 REGISTER_VARIABLE(
"nPXDHits", trackNPXDHits,
731 "The number of PXD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
732 REGISTER_VARIABLE(
"nVXDHits", trackNVXDHits,
733 "The number of PXD and SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
734 REGISTER_VARIABLE(
"ndf", trackNDF, R
"DOC(
735Returns the number of degrees of freedom of the track fit.
739 Note that this is not simply the number of hits -5 due to outlier hit
742Returns NaN if called for something other than a track-based particle, or for
743mdst files processed with basf2 versions older than ``release-05-01``.
745 REGISTER_VARIABLE("chi2", trackChi2, R
"DOC(
746Returns the :math:`\chi^2` of the track fit. This is actually computed based on
747:b2:var:`pValue` and :b2:var:`ndf`.
749.. note:: Note that for :b2:var:`pValue` exactly equal to 0 it returns infinity.
751Returns NaN if called for something other than a track-based particle, or for
752mdst files processed with basf2 versions older than ``release-05-01``.
754 REGISTER_VARIABLE("firstSVDLayer", trackFirstSVDLayer,
755 "The first activated SVD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
756 REGISTER_VARIABLE(
"firstPXDLayer", trackFirstPXDLayer,
757 "The first activated PXD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
758 REGISTER_VARIABLE(
"firstCDCLayer", trackFirstCDCLayer,
759 "The first activated CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
760 REGISTER_VARIABLE(
"lastCDCLayer", trackLastCDCLayer,
761 "The last CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
762 REGISTER_VARIABLE(
"d0", trackD0, R
"DOC(
763Returns the tracking parameter :math:`d_0`, the signed distance to the
764point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
768 Tracking parameters are with respect to the origin (0,0,0). For the
769 POCA with respect to the measured beam interaction point, see
770 :b2:var:`dr` (you probably want this unless you're doing a tracking
771 study or some debugging) and :b2:var:`d0FromIP`.
773Returns NaN if called for something other than a track-based particle.
776 REGISTER_VARIABLE(
"phi0", trackPhi0, R
"DOC(
777Returns the tracking parameter :math:`\phi_0`, the angle of the transverse
778momentum in the :math:`r-\phi` plane.
782 Tracking parameters are with respect to the origin (0,0,0). For the
783 POCA with respect to the measured beam interaction point, see
784 :b2:var:`phi0FromIP`.
786Returns NaN if called for something other than a track-based particle.
789 REGISTER_VARIABLE(
"omega", trackOmega, R
"DOC(
790Returns the tracking parameter :math:`\omega`, the curvature of the track.
792Returns NaN if called for something other than a track-based particle.
794)DOC", ":math:`\\text{cm}^{-1}`");
795 REGISTER_VARIABLE(
"z0", trackZ0, R
"DOC(
796Returns the tracking parameter :math:`z_0`, the z-coordinate of the
797point-of-closest-approach (POCA).
801 Tracking parameters are with respect to the origin (0,0,0). For the
802 POCA with respect to the measured beam interaction point, see
803 :b2:var:`dz` (you probably want this unless you're doing a tracking
804 study or some debugging) and :b2:var:`z0FromIP`.
806Returns NaN if called for something other than a track-based particle.
809 REGISTER_VARIABLE(
"tanLambda", trackTanLambda, R
"DOC(
810Returns :math:`\tan\lambda`, the slope of the track in the :math:`r-z` plane.
812Returns NaN if called for something other than a track-based particle.
814 REGISTER_VARIABLE("d0FromIP", trackD0FromIP, R
"DOC(
815Returns the tracking parameter :math:`d_0`, the signed distance to the
816point-of-closest-approach (POCA) in the :math:`r-\phi` plane, with respect to the measured beam interaction point.
818Returns NaN if called for something other than a track-based particle.
821 REGISTER_VARIABLE(
"z0FromIP", trackZ0FromIP, R
"DOC(
822Returns the tracking parameter :math:`z_0`, the z-coordinate of the
823point-of-closest-approach (POCA), with respect to the measured beam interaction point.
825Returns NaN if called for something other than a track-based particle.
828 REGISTER_VARIABLE(
"phi0FromIP", trackPhi0FromIP, R
"DOC(
829Returns the tracking parameter :math:`\phi_0`, the angle of the transverse
830momentum in the :math:`r-\phi` plane, with respect to the measured beam interaction point.
832Returns NaN if called for something other than a track-based particle.
835 REGISTER_VARIABLE(
"d0Err", trackD0Error, R
"DOC(
836Returns the uncertainty on :math:`d_0`, the signed distance to the
837point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
839.. seealso:: :b2:var:`d0`, :b2:var:`d0Pull`
841Returns NaN if called for something other than a track-based particle.
844 REGISTER_VARIABLE(
"phi0Err", trackPhi0Error, R
"DOC(
845Returns the uncertainty on :math:`\phi_0`, the angle of the transverse momentum
846in the :math:`r-\phi` plane.
848.. seealso:: :b2:var:`phi0`, :b2:var:`phi0Pull`
850Returns NaN if called for something other than a track-based particle.
853 REGISTER_VARIABLE(
"omegaErr", trackOmegaError, R
"DOC(
854Returns the uncertainty on :math:`\omega`, the curvature of the track.
856.. seealso:: :b2:var:`omega`, :b2:var:`omegaPull`
858Returns NaN if called for something other than a track-based particle.
860)DOC", ":math:`\\text{cm}^{-1}`");
861 REGISTER_VARIABLE(
"z0Err", trackZ0Error, R
"DOC(
862Returns the uncertainty on :math:`z_0`, the z-coordinate of the
863point-of-closest-approach (POCA).
865.. seealso:: :b2:var:`z0`, :b2:var:`z0Pull`
867Returns NaN if called for something other than a track-based particle."
870 REGISTER_VARIABLE(
"tanLambdaErr", trackTanLambdaError, R
"DOC(
871Returns the uncertainty on :math:`\tan\lambda`, the slope of the track in the
874.. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaPull`
876Returns NaN if called for something other than a track-based particle.
878 REGISTER_VARIABLE("trackFitCovariance(i, j)", trackFitCovariance, R
"DOC(
879 The track fit covariance matrix element corresponding to the two indices is returned.
880 This is the association between integers and parameters:
886 * 4: :math:`\tan\lambda`
890 The covariance is returned. This means that the return value can be negative.
891 Furthermore, it's the squared value of the track fit error variables :b2:var:`d0Err`, etc.
892 when selecting the diagonal entries.
895 REGISTER_VARIABLE("pValue", trackPValue, R
"DOC(
896The :math:`\chi^2` probability of the **track** fit.
900 This is the p-value of the track-fit. It does not get updated after
901 vertex fitting or kinematic fitting, and is meaningless for composite
904 See :b2:var:`chiProb` (you probably want this for high-level analysis).
906Returns NaN if called for something other than a track-based particle.
908 REGISTER_VARIABLE("trackFitHypothesisPDG", trackFitHypothesisPDG, R
"DOC(
909Returns the PDG code of the track hypothesis actually used for the fit.
910Returns NaN if called for something other than a track-based particle.
912 REGISTER_VARIABLE("trackNECLClusters", trackNECLClusters, R
"DOC(
913Returns a count of the number of ECLClusters matched to the track. This is
914always 0 or 1 with newer versions of ECL reconstruction.
918 For high-level analysis it is recommended to require the presence of a
919 matched ECL cluster along with a minimum energy requirement. A
920 track-based particle will have a clusterE if it is matched (NaN if
921 there is no cluster match for the track.
923 .. code-block:: python
925 import modularAnalysis as ma
926 # minimum energy of 200 MeV
927 ma.fillParticleList("e+:clusters", "clusterE > 0.2", path)
929 # these two are equivalent
930 ma.fillParticleList("e+:unmatched", "isNAN(clusterE) == 1", path)
931 ma.fillParticleList("e+:unmatched2", "trackNECLClusters == 0", path)
933Returns NaN if called for something other than a track-based particle.
935 REGISTER_VARIABLE("helixExtTheta(radius [cm], z fwd [cm], z bwd [cm], useHighestProbMass=0)", trackHelixExtTheta, R
"DOC(
936 Returns theta of extrapolated helix parameters. If ``useHighestProbMass=1`` is set, the extrapolation will
937 use the track fit result for the mass hypothesis with the highest pValue.
940 REGISTER_VARIABLE(
"helixExtPhi(radius, z fwd, z bwd, useHighestProbMass=0)", trackHelixExtPhi,
941 "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",
944 REGISTER_METAVARIABLE(
"helixExtThetaOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtThetaOnDet, R
"DOC(
945 Returns theta of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
946 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
947 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
948 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
950 .. note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
951 )DOC", Manager::VariableDataType::c_double);
952 REGISTER_METAVARIABLE("helixExtPhiOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtPhiOnDet, R
"DOC(
953 Returns phi of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
954 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
955 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
956 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
958 .. note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
959 )DOC", Manager::VariableDataType::c_double);
962 REGISTER_VARIABLE("nExtraCDCHits", nExtraCDCHits, R
"DOC(
963[Eventbased] The number of CDC hits in the event not assigned to any track.
965Returns NaN if there is no event-level tracking information available.
967 REGISTER_VARIABLE("nExtraCDCHitsPostCleaning", nExtraCDCHitsPostCleaning, R
"DOC(
968[Eventbased] Returns a count of the number of CDC hits in the event not assigned
969to any track nor very likely beam background (i.e. hits that survive a cleanup
972Returns NaN if there is no event-level tracking information available.
974 REGISTER_VARIABLE("hasExtraCDCHitsInLayer(i)", hasExtraCDCHitsInLayer, R
"DOC(
975[Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC layer,
978Returns NaN if there is no event-level tracking information available.
980 REGISTER_VARIABLE("hasExtraCDCHitsInSuperLayer(i)", hasExtraCDCHitsInSuperLayer, R
"DOC(
981[Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC
982SuperLayer, 0 otherwise.
984Returns NaN if there is no event-level tracking information available.
986 REGISTER_VARIABLE("nExtraCDCSegments", nExtraCDCSegments, R
"DOC(
987[Eventbased] Returns the number of CDC segments not assigned to any track.
989Returns NaN if there is no event-level tracking information available.
996 REGISTER_VARIABLE(
"nExtraPXDHits", nExtraPXDHits,
"[Eventbased] The number of PXD hits not assigned to any track");
998 REGISTER_VARIABLE(
"trackFindingFailureFlag", trackFindingFailureFlag, R
"DOC(
999[Eventbased] Returns a flag set by the tracking if there is reason to assume
1000there was a track in the event missed by the tracking, or the track finding was
1001(partly) aborted for this event.
1003Returns NaN if there is no event-level tracking information available.
1006 REGISTER_VARIABLE("isTrackFlippedAndRefitted", isTrackFlippedAndRefitted, R
"DOC(
1007Returns 1 if the charged final state particle comes from a track that has been flipped and refitted
1008at the end of the tracking chain, in particular before the outer detector reconstruction.
1011 REGISTER_VARIABLE("trackTime", getTrackTime, R
"DOC(
1012Returns the time at which the track is produced relative to the time of the collision (given by SVD EventT0).
1013Both the time of the collision and the track time are computed using only SVD hits.
1014Returns NaN if SVD EventT0 is NaN, or if no SVD Hits are attached to the track.
1015For more details, see :ref:`Time Extraction <tracking_eventTimeExtraction>` page.
1019 REGISTER_VARIABLE(
"trackLength", getTrackLength, R
"DOC(
1020Returns the arc length of the helix for the TrackFitResult associated with the particle.
1021The arc length is measured from the track origin to the radius of the CDC layer in which the Track has a hit.
1022Returns 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)
std::function< VarVariant(const Particle *)> FunctionPtr
functions stored take a const Particle* and return VarVariant.
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.