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 auto helix = trackFit->getHelix();
164 helix.passiveMoveBy(ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
165 return helix.getD0();
168 double trackZ0FromIP(
const Particle* part)
170 auto trackFit = part->getTrackFitResult();
172 static DBObjPtr<BeamSpot> beamSpotDB;
173 auto helix = trackFit->getHelix();
174 helix.passiveMoveBy(ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
175 return helix.getZ0();
178 double trackPhi0FromIP(
const Particle* part)
180 auto trackFit = part->getTrackFitResult();
182 static DBObjPtr<BeamSpot> beamSpotDB;
183 auto helix = trackFit->getHelix();
184 helix.passiveMoveBy(ROOT::Math::XYZVector(beamSpotDB->getIPPosition()));
185 return helix.getPhi0();
188 double trackD0Error(
const Particle* part)
190 auto trackFit = part->getTrackFitResult();
193 double errorSquared = trackFit->getCovariance5()[0][0];
195 return sqrt(errorSquared);
198 double trackPhi0Error(
const Particle* part)
200 auto trackFit = part->getTrackFitResult();
203 double errorSquared = trackFit->getCovariance5()[1][1];
205 return sqrt(errorSquared);
208 double trackOmegaError(
const Particle* part)
210 auto trackFit = part->getTrackFitResult();
213 double errorSquared = trackFit->getCovariance5()[2][2];
215 return sqrt(errorSquared);
218 double trackZ0Error(
const Particle* part)
220 auto trackFit = part->getTrackFitResult();
223 double errorSquared = trackFit->getCovariance5()[3][3];
225 return sqrt(errorSquared);
228 double trackTanLambdaError(
const Particle* part)
230 auto trackFit = part->getTrackFitResult();
233 double errorSquared = trackFit->getCovariance5()[4][4];
235 return sqrt(errorSquared);
238 double trackFitCovariance(
const Particle* particle,
const std::vector<double>& indices)
240 if (indices.size() != 2) {
241 B2FATAL(
"Exactly two indices must be provided to the variable trackFitCovariance!");
243 if (*(std::min_element(indices.begin(), indices.end())) < 0 or *(std::max_element(indices.begin(), indices.end())) > 4) {
244 B2FATAL(
"The indices provided to the variable trackFitCovariance must be in the range 0 - 4!");
246 auto trackFit = particle->getTrackFitResult();
248 return trackFit->getCovariance5()[indices[0]][indices[1]];
251 double trackPValue(
const Particle* part)
253 auto trackFit = part->getTrackFitResult();
255 return trackFit->getPValue();
258 double trackFitHypothesisPDG(
const Particle* part)
260 auto trackFit = part->getTrackFitResult();
262 return trackFit->getParticleType().getPDGCode();
265 double trackNECLClusters(
const Particle* part)
267 const Track* track = part->getTrack();
272 for (
const ECLCluster& cluster : track->getRelationsTo<ECLCluster>())
279 B2Vector3D getPositionOnHelix(
const TrackFitResult* trackFit,
const std::vector<double>& pars)
281 const double r = pars[0];
282 const double zfwd = pars[1];
283 const double zbwd = pars[2];
286 const double z0 = trackFit->getZ0();
287 const double tanlambda = trackFit->getTanLambda();
288 const Helix h = trackFit->getHelix();
291 const double arcLength = h.getArcLength2DAtCylindricalR(r);
292 const double lHelixRadius = arcLength > 0 ? arcLength : std::numeric_limits<double>::max();
295 const double lFWD = (zfwd - z0) / tanlambda > 0 ? (zfwd - z0) / tanlambda : std::numeric_limits<double>::max();
298 const double lBWD = (zbwd - z0) / tanlambda > 0 ? (zbwd - z0) / tanlambda : std::numeric_limits<double>::max();
301 const double l = std::min({lHelixRadius, lFWD, lBWD});
303 return h.getPositionAtArcLength2D(l);
306 B2Vector3D getPositionOnHelix(
const Particle* part,
const std::vector<double>& pars)
308 if (pars.size() == 4 and pars[3]) {
309 const Track* track = part->getTrack();
313 auto highestProbMass = part->getMostLikelyTrackFitResult().first;
314 const TrackFitResult* trackFit = track->getTrackFitResultWithClosestMass(highestProbMass);
315 return getPositionOnHelix(trackFit, pars);
317 const TrackFitResult* trackFit = part->getTrackFitResult();
318 return getPositionOnHelix(trackFit, pars);
323 double trackHelixExtTheta(
const Particle* part,
const std::vector<double>& pars)
325 const auto nParams = pars.size();
326 if (nParams != 3 && nParams != 4) {
327 B2FATAL(
"Exactly three (+1 optional) parameters (r, zfwd, zbwd, [useHighestProbMass]) required for helixExtTheta.");
330 B2Vector3D position = getPositionOnHelix(part, pars);
332 return position.Theta();
336 double trackHelixExtPhi(
const Particle* part,
const std::vector<double>& pars)
338 const auto nParams = pars.size();
339 if (nParams != 3 && nParams != 4) {
340 B2FATAL(
"Exactly three (+1 optional) parameters (r, zfwd, zbwd, [useHighestProbMass]) required for helixExtPhi.");
343 B2Vector3D position = getPositionOnHelix(part, pars);
345 return position.Phi();
350 if (arguments.size() != 1 && arguments.size() != 2)
351 B2FATAL(
"Exactly one (+1 optional) parameter (detector_surface_name, [useHighestProbMass]) is required for helixExtThetaOnDet.");
353 std::vector<double> parameters(3);
354 const std::string det = arguments[0];
364 B2FATAL(
"Given detector surface name is not supported.");
366 if (arguments.size() == 2)
367 parameters.push_back(std::stod(arguments[1]));
369 auto func = [parameters](
const Particle * part) ->
double {
371 B2Vector3D position = getPositionOnHelix(part, parameters);
373 return position.Theta();
380 if (arguments.size() != 1 && arguments.size() != 2)
381 B2FATAL(
"Exactly one (+1 optional) parameter (detector_surface_name, [useHighestProbMass]) is required for helixExtPhiOnDet.");
383 std::vector<double> parameters(3);
384 const std::string det = arguments[0];
394 B2FATAL(
"Given detector surface name is not supported.");
396 if (arguments.size() == 2)
397 parameters.push_back(std::stod(arguments[1]));
399 auto func = [parameters](
const Particle * part) ->
double {
401 B2Vector3D position = getPositionOnHelix(part, parameters);
403 return position.Phi();
414 double nExtraCDCHits(
const Particle*)
416 StoreObjPtr<EventLevelTrackingInfo> elti;
418 return elti->getNCDCHitsNotAssigned();
423 double nExtraCDCHitsPostCleaning(
const Particle*)
425 StoreObjPtr<EventLevelTrackingInfo> elti;
427 return elti->getNCDCHitsNotAssignedPostCleaning();
431 double hasExtraCDCHitsInLayer(
const Particle*,
const std::vector<double>& layer)
433 StoreObjPtr<EventLevelTrackingInfo> elti;
435 int ilayer = std::lround(layer[0]);
436 return elti->hasCDCLayer(ilayer);
440 double hasExtraCDCHitsInSuperLayer(
const Particle*,
const std::vector<double>& layer)
442 StoreObjPtr<EventLevelTrackingInfo> elti;
444 int ilayer = std::lround(layer[0]);
445 return elti->hasCDCSLayer(ilayer);
449 double nExtraCDCSegments(
const Particle*)
451 StoreObjPtr<EventLevelTrackingInfo> elti;
453 return elti->getNCDCSegments();
457 double nExtraVXDHitsInLayer(
const Particle*,
const std::vector<double>& layer)
459 StoreObjPtr<EventLevelTrackingInfo> elti;
461 int ilayer = std::lround(layer[0]);
462 return elti->getNVXDClustersInLayer(ilayer);
466 double nExtraVXDHits(
const Particle*)
468 StoreObjPtr<EventLevelTrackingInfo> elti;
471 for (uint16_t ilayer = 1; ilayer < 7; ++ilayer)
472 out += elti->getNVXDClustersInLayer(ilayer);
477 double svdFirstSampleTime(
const Particle*)
479 StoreObjPtr<EventLevelTrackingInfo> elti;
481 return elti->getSVDFirstSampleTime();
488 double trackFindingFailureFlag(
const Particle*)
490 StoreObjPtr<EventLevelTrackingInfo> elti;
492 return elti->hasAnErrorFlag();
498 const ROOT::Math::XYZVector mcProdVertex = mcparticle->getVertex();
499 const ROOT::Math::XYZVector mcMomentum = mcparticle->getMomentum();
501 const double mcParticleCharge = mcparticle->getCharge();
502 return Belle2::Helix(mcProdVertex, mcMomentum, mcParticleCharge, BzAtProdVertex);
505 double getMCHelixParameterAtIndex(
const Particle* particle,
const int index)
509 const MCParticle* mcparticle = particle->getMCParticle();
513 const std::vector<double> mcHelixPars{mcHelix.getD0(), mcHelix.getPhi0(), mcHelix.getOmega(), mcHelix.getZ0(), mcHelix.getTanLambda()};
514 return mcHelixPars.at(index);
517 double getHelixParameterPullAtIndex(
const Particle* particle,
const int index)
521 const MCParticle* mcparticle = particle->getMCParticle();
528 const TMatrixDSym& measCovariance = measHelix.
getCovariance();
531 const std::vector<double> mcHelixPars = {mcHelix.getD0(), mcHelix.getPhi0(), mcHelix.getOmega(), mcHelix.getZ0(), mcHelix.getTanLambda()};
532 const std::vector<double> measHelixPars = {measHelix.getD0(), measHelix.getPhi0(), measHelix.getOmega(), measHelix.getZ0(), measHelix.getTanLambda()};
534 return (mcHelixPars.at(index) - measHelixPars.at(index)) / std::sqrt(measCovariance(index, index));
537 double getHelixMCD0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 0); }
538 double getHelixMCPhi0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 1); }
539 double getHelixMCOmega(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 2); }
540 double getHelixMCZ0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 3); }
541 double getHelixMCTanLambda(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 4); }
543 double getHelixD0Pull(
const Particle* part)
545 return getHelixParameterPullAtIndex(part, 0);
548 double getHelixPhi0Pull(
const Particle* part)
550 return getHelixParameterPullAtIndex(part, 1);
553 double getHelixOmegaPull(
const Particle* part)
555 return getHelixParameterPullAtIndex(part, 2);
558 double getHelixZ0Pull(
const Particle* part)
560 return getHelixParameterPullAtIndex(part, 3);
563 double getHelixTanLambdaPull(
const Particle* part)
565 return getHelixParameterPullAtIndex(part, 4);
568 double getTrackTime(
const Particle* part)
570 const Track* track = part->getTrack();
572 return track->getTrackTime();
575 double isTrackFlippedAndRefitted(
const Particle* part)
577 auto track = part->getTrack();
579 return track->isFlippedAndRefitted() ? 1 : 0;
582 double getTrackLength(
const Particle* part)
584 auto trackFit = part->getTrackFitResult();
587 const double lastCDCLayer = trackLastCDCLayer(part);
588 if (std::isnan(lastCDCLayer) or lastCDCLayer < 0)
593 return trackFit->getHelix().getArcLength2DAtCylindricalR(r);
597 VARIABLE_GROUP(
"Tracking");
599 REGISTER_VARIABLE(
"mcD0", getHelixMCD0, R
"DOC(
600Returns the MC value of :math:`d_0`, the signed distance to the
601point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
603.. seealso:: :b2:var:`d0`
605Returns NaN if the particle is not related to any MCParticle.
608 REGISTER_VARIABLE(
"mcPhi0", getHelixMCPhi0, R
"DOC(
609Returns the MC value of :math:`\phi_0`, the angle of the transverse momentum
610in the :math:`r-\phi` plane.
612.. seealso:: :b2:var:`phi0`
614Returns NaN if the particle is not related to any MCParticle.
617 REGISTER_VARIABLE(
"mcOmega", getHelixMCOmega, R
"DOC(
618Returns the MC value of :math:`\omega`, the curvature of the track.
620.. seealso:: :b2:var:`omega`
622Returns NaN if the particle is not related to any MCParticle.
624)DOC", ":math:`\\text{cm}^{-1}`");
625 REGISTER_VARIABLE(
"mcZ0", getHelixMCZ0, R
"DOC(
626Returns the MC value of :math:`z_0`, the z-coordinate of the
627point-of-closest-approach (POCA).
629.. seealso:: :b2:var:`z0`
631Returns NaN if the particle is not related to any MCParticle.
634 REGISTER_VARIABLE(
"mcTanLambda", getHelixMCTanLambda, R
"DOC(
635Returns the MC value of :math:`\tan\lambda`, the slope of the track in the
638.. seealso:: :b2:var:`tanLambda`
640Returns NaN if the particle is not related to any MCParticle.
643 REGISTER_VARIABLE("d0Pull", getHelixD0Pull, R
"DOC(
644The pull of the tracking parameter :math:`d_0` for the reconstructed
645pattern-recognition track, with respect to the MC track. That is:
649 \frac{d_0^\textrm{MC} - d_0^\textrm{PR}}{\sigma_{d_0; \textrm{PR}}}
651.. seealso:: :b2:var:`d0`, :b2:var:`d0Err`
653Returns NaN if no MC particle is related or if called on something other than a
656 REGISTER_VARIABLE("phi0Pull", getHelixPhi0Pull, R
"DOC(
657The pull of the tracking parameter :math:`\phi_0` for the reconstructed
658pattern-recognition track, with respect to the MC track. That is:
662 \frac{\phi_0^\textrm{MC} - \phi_0^\textrm{PR}}{\sigma_{\phi_0; \textrm{PR}}}
664.. seealso:: :b2:var:`phi0`, :b2:var:`phi0Err`
666Returns NaN if no MC particle is related or if called on something other than a
669 REGISTER_VARIABLE("omegaPull", getHelixOmegaPull, R
"DOC(
670The pull of the tracking parameter :math:`\omega` for the reconstructed
671pattern-recognition track, with respect to the MC track. That is:
675 \frac{\omega^\textrm{MC} - \omega^\textrm{PR}}{\sigma_{\omega; \textrm{PR}}}
677.. seealso:: :b2:var:`omega`, :b2:var:`omegaErr`
679Returns NaN if no MC particle is related or if called on something other than a
682 REGISTER_VARIABLE("z0Pull", getHelixZ0Pull, R
"DOC(
683The pull of the tracking parameter :math:`z_0` for the reconstructed
684pattern-recognition track, with respect to the MC track. That is:
688 \frac{z_0^\textrm{MC} - z_0^\textrm{PR}}{\sigma_{z_0; \textrm{PR}}}
690.. seealso:: :b2:var:`z0`, :b2:var:`z0Err`
692Returns NaN if no MC particle is related or if called on something other than a
695 REGISTER_VARIABLE("tanLambdaPull", getHelixTanLambdaPull, R
"DOC(
696The pull of the tracking parameter :math:`\tan\lambda` for the reconstructed
697pattern-recognition track, with respect to the MC track. That is:
701 \frac{(\tan\lambda)^\textrm{MC} - (\tan\lambda)^\textrm{PR}}{\sigma_{\tan\lambda; \textrm{PR}}}
703.. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaErr`
705Returns NaN if no MC particle is related or if called on something other than a
708 REGISTER_VARIABLE("nCDCHits", trackNCDCHits,
709 "The number of CDC hits associated to the track. Returns NaN if called for something other than a track-based particle.");
710 REGISTER_VARIABLE(
"nSVDHits", trackNSVDHits,
711 "The number of SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
712 REGISTER_VARIABLE(
"nPXDHits", trackNPXDHits,
713 "The number of PXD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
714 REGISTER_VARIABLE(
"nVXDHits", trackNVXDHits,
715 "The number of PXD and SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
716 REGISTER_VARIABLE(
"ndf", trackNDF, R
"DOC(
717Returns the number of degrees of freedom of the track fit.
721 Note that this is not simply the number of hits -5 due to outlier hit
724Returns NaN if called for something other than a track-based particle, or for
725mdst files processed with basf2 versions older than ``release-05-01``.
727 REGISTER_VARIABLE("chi2", trackChi2, R
"DOC(
728Returns the :math:`\chi^2` of the track fit. This is actually computed based on
729:b2:var:`pValue` and :b2:var:`ndf`.
731.. note:: Note that for :b2:var:`pValue` exactly equal to 0 it returns infinity.
733Returns NaN if called for something other than a track-based particle, or for
734mdst files processed with basf2 versions older than ``release-05-01``.
736 REGISTER_VARIABLE("firstSVDLayer", trackFirstSVDLayer,
737 "The first activated SVD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
738 REGISTER_VARIABLE(
"firstPXDLayer", trackFirstPXDLayer,
739 "The first activated PXD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
740 REGISTER_VARIABLE(
"firstCDCLayer", trackFirstCDCLayer,
741 "The first activated CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
742 REGISTER_VARIABLE(
"lastCDCLayer", trackLastCDCLayer,
743 "The last CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
744 REGISTER_VARIABLE(
"d0", trackD0, R
"DOC(
745Returns the tracking parameter :math:`d_0`, the signed distance to the
746point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
750 Tracking parameters are with respect to the origin (0,0,0). For the
751 POCA with respect to the measured beam interaction point, see
752 :b2:var:`dr` (you probably want this unless you're doing a tracking
753 study or some debugging) and :b2:var:`d0FromIP`.
755Returns NaN if called for something other than a track-based particle.
758 REGISTER_VARIABLE(
"phi0", trackPhi0, R
"DOC(
759Returns the tracking parameter :math:`\phi_0`, the angle of the transverse
760momentum in the :math:`r-\phi` plane.
764 Tracking parameters are with respect to the origin (0,0,0). For the
765 POCA with respect to the measured beam interaction point, see
766 :b2:var:`phi0FromIP`.
768Returns NaN if called for something other than a track-based particle.
771 REGISTER_VARIABLE(
"omega", trackOmega, R
"DOC(
772Returns the tracking parameter :math:`\omega`, the curvature of the track.
774Returns NaN if called for something other than a track-based particle.
776)DOC", ":math:`\\text{cm}^{-1}`");
777 REGISTER_VARIABLE(
"z0", trackZ0, R
"DOC(
778Returns the tracking parameter :math:`z_0`, the z-coordinate of the
779point-of-closest-approach (POCA).
783 Tracking parameters are with respect to the origin (0,0,0). For the
784 POCA with respect to the measured beam interaction point, see
785 :b2:var:`dz` (you probably want this unless you're doing a tracking
786 study or some debugging) and :b2:var:`z0FromIP`.
788Returns NaN if called for something other than a track-based particle.
791 REGISTER_VARIABLE(
"tanLambda", trackTanLambda, R
"DOC(
792Returns :math:`\tan\lambda`, the slope of the track in the :math:`r-z` plane.
794Returns NaN if called for something other than a track-based particle.
796 REGISTER_VARIABLE("d0FromIP", trackD0FromIP, R
"DOC(
797Returns the tracking parameter :math:`d_0`, the signed distance to the
798point-of-closest-approach (POCA) in the :math:`r-\phi` plane, with respect to the measured beam interaction point.
800Returns NaN if called for something other than a track-based particle.
803 REGISTER_VARIABLE(
"z0FromIP", trackZ0FromIP, R
"DOC(
804Returns the tracking parameter :math:`z_0`, the z-coordinate of the
805point-of-closest-approach (POCA), with respect to the measured beam interaction point.
807Returns NaN if called for something other than a track-based particle.
810 REGISTER_VARIABLE(
"phi0FromIP", trackPhi0FromIP, R
"DOC(
811Returns the tracking parameter :math:`\phi_0`, the angle of the transverse
812momentum in the :math:`r-\phi` plane, with respect to the measured beam interaction point.
814Returns NaN if called for something other than a track-based particle.
817 REGISTER_VARIABLE(
"d0Err", trackD0Error, R
"DOC(
818Returns the uncertainty on :math:`d_0`, the signed distance to the
819point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
821.. seealso:: :b2:var:`d0`, :b2:var:`d0Pull`
823Returns NaN if called for something other than a track-based particle.
826 REGISTER_VARIABLE(
"phi0Err", trackPhi0Error, R
"DOC(
827Returns the uncertainty on :math:`\phi_0`, the angle of the transverse momentum
828in the :math:`r-\phi` plane.
830.. seealso:: :b2:var:`phi0`, :b2:var:`phi0Pull`
832Returns NaN if called for something other than a track-based particle.
835 REGISTER_VARIABLE(
"omegaErr", trackOmegaError, R
"DOC(
836Returns the uncertainty on :math:`\omega`, the curvature of the track.
838.. seealso:: :b2:var:`omega`, :b2:var:`omegaPull`
840Returns NaN if called for something other than a track-based particle.
842)DOC", ":math:`\\text{cm}^{-1}`");
843 REGISTER_VARIABLE(
"z0Err", trackZ0Error, R
"DOC(
844Returns the uncertainty on :math:`z_0`, the z-coordinate of the
845point-of-closest-approach (POCA).
847.. seealso:: :b2:var:`z0`, :b2:var:`z0Pull`
849Returns NaN if called for something other than a track-based particle."
852 REGISTER_VARIABLE(
"tanLambdaErr", trackTanLambdaError, R
"DOC(
853Returns the uncertainty on :math:`\tan\lambda`, the slope of the track in the
856.. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaPull`
858Returns NaN if called for something other than a track-based particle.
860 REGISTER_VARIABLE("trackFitCovariance(i, j)", trackFitCovariance, R
"DOC(
861 The track fit covariance matrix element corresponding to the two indices is returned.
862 This is the association between integers and parameters:
868 * 4: :math:`\tan\lambda`
872 The covariance is returned. This means that the return value can be negative.
873 Furthermore, it's the squared value of the track fit error variables :b2:var:`d0Err`, etc.
874 when selecting the diagonal entries.
877 REGISTER_VARIABLE("pValue", trackPValue, R
"DOC(
878The :math:`\chi^2` probability of the **track** fit.
882 This is the p-value of the track-fit. It does not get updated after
883 vertex fitting or kinematic fitting, and is meaningless for composite
886 See :b2:var:`chiProb` (you probably want this for high-level analysis).
888Returns NaN if called for something other than a track-based particle.
890 REGISTER_VARIABLE("trackFitHypothesisPDG", trackFitHypothesisPDG, R
"DOC(
891Returns the PDG code of the track hypothesis actually used for the fit.
892Returns NaN if called for something other than a track-based particle.
894 REGISTER_VARIABLE("trackNECLClusters", trackNECLClusters, R
"DOC(
895Returns a count of the number of ECLClusters matched to the track. This is
896always 0 or 1 with newer versions of ECL reconstruction.
900 For high-level analysis it is recommended to require the presence of a
901 matched ECL cluster along with a minimum energy requirement. A
902 track-based particle will have a clusterE if it is matched (NaN if
903 there is no cluster match for the track.
905 .. code-block:: python
907 import modularAnalysis as ma
908 # minimum energy of 200 MeV
909 ma.fillParticleList("e+:clusters", "clusterE > 0.2", path)
911 # these two are equivalent
912 ma.fillParticleList("e+:unmatched", "isNAN(clusterE) == 1", path)
913 ma.fillParticleList("e+:unmatched2", "trackNECLClusters == 0", path)
915Returns NaN if called for something other than a track-based particle.
917 REGISTER_VARIABLE("helixExtTheta(radius [cm], z fwd [cm], z bwd [cm], useHighestProbMass=0)", trackHelixExtTheta,
918 R
"DOC(Returns theta of extrapolated helix parameters. If ``useHighestProbMass=1`` is set, the extrapolation will
919 use the track fit result for the mass hypothesis with the highest pValue.
922 REGISTER_VARIABLE(
"helixExtPhi(radius, z fwd, z bwd, useHighestProbMass=0)", trackHelixExtPhi,
923 "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",
926 REGISTER_METAVARIABLE(
"helixExtThetaOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtThetaOnDet,
927 R
"DOC(Returns theta of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
928 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
929 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
930 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
932 ..note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
933 )DOC", Manager::VariableDataType::c_double);
934 REGISTER_METAVARIABLE("helixExtPhiOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtPhiOnDet,
935 R
"DOC(Returns phi of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
936 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
937 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
938 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
940 ..note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
941 )DOC", Manager::VariableDataType::c_double);
944 REGISTER_VARIABLE("nExtraCDCHits", nExtraCDCHits, R
"DOC(
945[Eventbased] The number of CDC hits in the event not assigned to any track.
947Returns NaN if there is no event-level tracking information available.
949 REGISTER_VARIABLE("nExtraCDCHitsPostCleaning", nExtraCDCHitsPostCleaning, R
"DOC(
950[Eventbased] Returns a count of the number of CDC hits in the event not assigned
951to any track nor very likely beam background (i.e. hits that survive a cleanup
954Returns NaN if there is no event-level tracking information available.
956 REGISTER_VARIABLE("hasExtraCDCHitsInLayer(i)", hasExtraCDCHitsInLayer, R
"DOC(
957[Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC layer,
960Returns NaN if there is no event-level tracking information available.
962 REGISTER_VARIABLE("hasExtraCDCHitsInSuperLayer(i)", hasExtraCDCHitsInSuperLayer, R
"DOC(
963[Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC
964SuperLayer, 0 otherwise.
966Returns NaN if there is no event-level tracking information available.
968 REGISTER_VARIABLE("nExtraCDCSegments", nExtraCDCSegments, R
"DOC(
969[Eventbased] Returns the number of CDC segments not assigned to any track.
971Returns NaN if there is no event-level tracking information available.
979 REGISTER_VARIABLE(
"trackFindingFailureFlag", trackFindingFailureFlag, R
"DOC(
980[Eventbased] Returns a flag set by the tracking if there is reason to assume
981there was a track in the event missed by the tracking, or the track finding was
982(partly) aborted for this event.
984Returns NaN if there is no event-level tracking information available.
987 REGISTER_VARIABLE("isTrackFlippedAndRefitted", isTrackFlippedAndRefitted, R
"DOC(
988Returns 1 if the charged final state particle comes from a track that has been flipped and refitted
989at the end of the reconstruction chain, in particular after the outer detector reconstruction.
992 REGISTER_VARIABLE("trackTime", getTrackTime, R
"DOC(
993Returns the time at which the track is produced relative to the time of the collision (given by SVD EventT0).
994Both the time of the collision and the track time are computed using only SVD hits.
995Returns NaN if SVD EventT0 is NaN, or if no SVD Hits are attached to the track.
996For more details, see :ref:`Time Extraction <tracking_eventTimeExtraction>` page.
1000 REGISTER_VARIABLE(
"trackLength", getTrackLength, R
"DOC(
1001Returns the arc length of the helix for the TrackFitResult associated with the particle.
1002The arc length is measured from the track origin to the radius of the CDC layer in which the Track has a hit.
1003Returns 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.