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>())
283 double trackQualityIndicator(
const Particle* part)
285 const Track* track = part->getTrack();
288 return track->getQualityIndicator();
292 ROOT::Math::XYZVector getPositionOnHelix(
const TrackFitResult* trackFit,
const std::vector<double>& pars)
294 const double r = pars[0];
295 const double zfwd = pars[1];
296 const double zbwd = pars[2];
299 const double z0 = trackFit->getZ0();
300 const double tanlambda = trackFit->getTanLambda();
301 const Helix h = trackFit->getHelix();
304 const double arcLength = h.getArcLength2DAtCylindricalR(r);
305 const double lHelixRadius = arcLength > 0 ? arcLength : std::numeric_limits<double>::max();
308 const double lFWD = (zfwd - z0) / tanlambda > 0 ? (zfwd - z0) / tanlambda : std::numeric_limits<double>::max();
311 const double lBWD = (zbwd - z0) / tanlambda > 0 ? (zbwd - z0) / tanlambda : std::numeric_limits<double>::max();
314 const double l = std::min({lHelixRadius, lFWD, lBWD});
316 return h.getPositionAtArcLength2D(l);
319 ROOT::Math::XYZVector getPositionOnHelix(
const Particle* part,
const std::vector<double>& pars)
321 if (pars.size() == 4 and pars[3]) {
322 const Track* track = part->getTrack();
326 auto highestProbMass = part->getMostLikelyTrackFitResult().first;
327 const TrackFitResult* trackFit = track->getTrackFitResultWithClosestMass(highestProbMass);
328 if (!trackFit)
return vecNaN;
329 else return getPositionOnHelix(trackFit, pars);
331 const TrackFitResult* trackFit = part->getTrackFitResult();
332 if (!trackFit)
return vecNaN;
333 else return getPositionOnHelix(trackFit, pars);
338 double trackHelixExtTheta(
const Particle* part,
const std::vector<double>& pars)
340 const auto nParams = pars.size();
341 if (nParams != 3 && nParams != 4) {
342 B2FATAL(
"Exactly three (+1 optional) parameters (r, zfwd, zbwd, [useHighestProbMass]) required for helixExtTheta.");
345 ROOT::Math::XYZVector position = getPositionOnHelix(part, pars);
347 return position.Theta();
351 double trackHelixExtPhi(
const Particle* part,
const std::vector<double>& pars)
353 const auto nParams = pars.size();
354 if (nParams != 3 && nParams != 4) {
355 B2FATAL(
"Exactly three (+1 optional) parameters (r, zfwd, zbwd, [useHighestProbMass]) required for helixExtPhi.");
358 ROOT::Math::XYZVector position = getPositionOnHelix(part, pars);
360 return position.Phi();
365 if (arguments.size() != 1 && arguments.size() != 2)
366 B2FATAL(
"Exactly one (+1 optional) parameter (detector_surface_name, [useHighestProbMass]) is required for helixExtThetaOnDet.");
368 std::vector<double> parameters(3);
369 const std::string det = arguments[0];
379 B2FATAL(
"Given detector surface name is not supported.");
381 if (arguments.size() == 2)
382 parameters.push_back(std::stod(arguments[1]));
384 auto func = [parameters](
const Particle * part) ->
double {
386 ROOT::Math::XYZVector position = getPositionOnHelix(part, parameters);
388 return position.Theta();
395 if (arguments.size() != 1 && arguments.size() != 2)
396 B2FATAL(
"Exactly one (+1 optional) parameter (detector_surface_name, [useHighestProbMass]) is required for helixExtPhiOnDet.");
398 std::vector<double> parameters(3);
399 const std::string det = arguments[0];
409 B2FATAL(
"Given detector surface name is not supported.");
411 if (arguments.size() == 2)
412 parameters.push_back(std::stod(arguments[1]));
414 auto func = [parameters](
const Particle * part) ->
double {
416 ROOT::Math::XYZVector position = getPositionOnHelix(part, parameters);
418 return position.Phi();
429 double nExtraCDCHits(
const Particle*)
431 StoreObjPtr<EventLevelTrackingInfo> elti;
433 return elti->getNCDCHitsNotAssigned();
438 double nExtraCDCHitsPostCleaning(
const Particle*)
440 StoreObjPtr<EventLevelTrackingInfo> elti;
442 return elti->getNCDCHitsNotAssignedPostCleaning();
446 double hasExtraCDCHitsInLayer(
const Particle*,
const std::vector<double>& layer)
448 StoreObjPtr<EventLevelTrackingInfo> elti;
450 int ilayer = std::lround(layer[0]);
451 return elti->hasCDCLayer(ilayer);
455 double hasExtraCDCHitsInSuperLayer(
const Particle*,
const std::vector<double>& layer)
457 StoreObjPtr<EventLevelTrackingInfo> elti;
459 int ilayer = std::lround(layer[0]);
460 return elti->hasCDCSLayer(ilayer);
464 double nExtraCDCSegments(
const Particle*)
466 StoreObjPtr<EventLevelTrackingInfo> elti;
468 return elti->getNCDCSegments();
472 double nExtraVXDHitsInLayer(
const Particle*,
const std::vector<double>& layer)
474 StoreObjPtr<EventLevelTrackingInfo> elti;
476 int ilayer = std::lround(layer[0]);
477 return elti->getNVXDClustersInLayer(ilayer);
481 double nExtraVXDHits(
const Particle*)
483 StoreObjPtr<EventLevelTrackingInfo> elti;
486 for (uint16_t ilayer = 1; ilayer < 7; ++ilayer)
487 out += elti->getNVXDClustersInLayer(ilayer);
492 double nExtraPXDHits(
const Particle*)
494 StoreObjPtr<EventLevelTrackingInfo> elti;
497 for (uint16_t ilayer = 1; ilayer < 3; ++ilayer)
498 out += elti->getNVXDClustersInLayer(ilayer);
503 double svdFirstSampleTime(
const Particle*)
505 StoreObjPtr<EventLevelTrackingInfo> elti;
507 return elti->getSVDFirstSampleTime();
514 double trackFindingFailureFlag(
const Particle*)
516 StoreObjPtr<EventLevelTrackingInfo> elti;
518 return elti->hasAnErrorFlag();
522 Helix getMCHelix(
const MCParticle* mcparticle)
524 const ROOT::Math::XYZVector mcProdVertex = mcparticle->getVertex();
525 const ROOT::Math::XYZVector mcMomentum = mcparticle->getMomentum();
527 const double mcParticleCharge = mcparticle->getCharge();
528 return Helix(mcProdVertex, mcMomentum, mcParticleCharge, BzAtProdVertex);
531 double getMCHelixParameterAtIndex(
const Particle* particle,
const int index)
535 const MCParticle* mcparticle = particle->getMCParticle();
538 const Helix mcHelix(getMCHelix(mcparticle));
539 const std::vector<double> mcHelixPars{mcHelix.getD0(), mcHelix.getPhi0(), mcHelix.getOmega(), mcHelix.getZ0(), mcHelix.getTanLambda()};
540 return mcHelixPars.at(index);
543 double getHelixParameterPullAtIndex(
const Particle* particle,
const int index)
547 const MCParticle* mcparticle = particle->getMCParticle();
550 const TrackFitResult* trackfit = particle->getTrackFitResult();
553 const UncertainHelix measHelix = trackfit->getUncertainHelix();
554 const TMatrixDSym& measCovariance = measHelix.getCovariance();
555 const Helix mcHelix(getMCHelix(mcparticle));
557 const std::vector<double> mcHelixPars = {mcHelix.getD0(), mcHelix.getPhi0(), mcHelix.getOmega(), mcHelix.getZ0(), mcHelix.getTanLambda()};
558 const std::vector<double> measHelixPars = {measHelix.getD0(), measHelix.getPhi0(), measHelix.getOmega(), measHelix.getZ0(), measHelix.getTanLambda()};
560 return (mcHelixPars.at(index) - measHelixPars.at(index)) / std::sqrt(measCovariance(index, index));
563 double getHelixMCD0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 0); }
564 double getHelixMCPhi0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 1); }
565 double getHelixMCOmega(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 2); }
566 double getHelixMCZ0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 3); }
567 double getHelixMCTanLambda(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 4); }
569 double getHelixD0Pull(
const Particle* part)
571 return getHelixParameterPullAtIndex(part, 0);
574 double getHelixPhi0Pull(
const Particle* part)
576 return getHelixParameterPullAtIndex(part, 1);
579 double getHelixOmegaPull(
const Particle* part)
581 return getHelixParameterPullAtIndex(part, 2);
584 double getHelixZ0Pull(
const Particle* part)
586 return getHelixParameterPullAtIndex(part, 3);
589 double getHelixTanLambdaPull(
const Particle* part)
591 return getHelixParameterPullAtIndex(part, 4);
594 double getTrackTime(
const Particle* part)
596 const Track* track = part->getTrack();
598 return track->getTrackTime();
601 double isTrackFlippedAndRefitted(
const Particle* part)
603 auto track = part->getTrack();
605 return track->isFlippedAndRefitted() ? 1 : 0;
608 double getTrackLength(
const Particle* part)
610 auto trackFit = part->getTrackFitResult();
613 const double lastCDCLayer = trackLastCDCLayer(part);
614 if (std::isnan(lastCDCLayer) or lastCDCLayer < 0)
619 return trackFit->getHelix().getArcLength2DAtCylindricalR(r);
623 VARIABLE_GROUP(
"Tracking");
625 REGISTER_VARIABLE(
"mcD0", getHelixMCD0, R
"DOC(
626Returns the MC value of :math:`d_0`, the signed distance to the
627point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
629.. seealso:: :b2:var:`d0`
631Returns NaN if the particle is not related to any MCParticle.
634 REGISTER_VARIABLE(
"mcPhi0", getHelixMCPhi0, R
"DOC(
635Returns the MC value of :math:`\phi_0`, the angle of the transverse momentum
636in the :math:`r-\phi` plane.
638.. seealso:: :b2:var:`phi0`
640Returns NaN if the particle is not related to any MCParticle.
643 REGISTER_VARIABLE(
"mcOmega", getHelixMCOmega, R
"DOC(
644Returns the MC value of :math:`\omega`, the curvature of the track.
646.. seealso:: :b2:var:`omega`
648Returns NaN if the particle is not related to any MCParticle.
650)DOC", ":math:`\\text{cm}^{-1}`");
651 REGISTER_VARIABLE(
"mcZ0", getHelixMCZ0, R
"DOC(
652Returns the MC value of :math:`z_0`, the z-coordinate of the
653point-of-closest-approach (POCA).
655.. seealso:: :b2:var:`z0`
657Returns NaN if the particle is not related to any MCParticle.
660 REGISTER_VARIABLE(
"mcTanLambda", getHelixMCTanLambda, R
"DOC(
661Returns the MC value of :math:`\tan\lambda`, the slope of the track in the
664.. seealso:: :b2:var:`tanLambda`
666Returns NaN if the particle is not related to any MCParticle.
669 REGISTER_VARIABLE("d0Pull", getHelixD0Pull, R
"DOC(
670The pull of the tracking parameter :math:`d_0` for the reconstructed
671pattern-recognition track, with respect to the MC track. That is:
675 \frac{d_0^\textrm{MC} - d_0^\textrm{PR}}{\sigma_{d_0; \textrm{PR}}}
677.. seealso:: :b2:var:`d0`, :b2:var:`d0Err`
679Returns NaN if no MC particle is related or if called on something other than a
682 REGISTER_VARIABLE("phi0Pull", getHelixPhi0Pull, R
"DOC(
683The pull of the tracking parameter :math:`\phi_0` for the reconstructed
684pattern-recognition track, with respect to the MC track. That is:
688 \frac{\phi_0^\textrm{MC} - \phi_0^\textrm{PR}}{\sigma_{\phi_0; \textrm{PR}}}
690.. seealso:: :b2:var:`phi0`, :b2:var:`phi0Err`
692Returns NaN if no MC particle is related or if called on something other than a
695 REGISTER_VARIABLE("omegaPull", getHelixOmegaPull, R
"DOC(
696The pull of the tracking parameter :math:`\omega` for the reconstructed
697pattern-recognition track, with respect to the MC track. That is:
701 \frac{\omega^\textrm{MC} - \omega^\textrm{PR}}{\sigma_{\omega; \textrm{PR}}}
703.. seealso:: :b2:var:`omega`, :b2:var:`omegaErr`
705Returns NaN if no MC particle is related or if called on something other than a
708 REGISTER_VARIABLE("z0Pull", getHelixZ0Pull, R
"DOC(
709The pull of the tracking parameter :math:`z_0` for the reconstructed
710pattern-recognition track, with respect to the MC track. That is:
714 \frac{z_0^\textrm{MC} - z_0^\textrm{PR}}{\sigma_{z_0; \textrm{PR}}}
716.. seealso:: :b2:var:`z0`, :b2:var:`z0Err`
718Returns NaN if no MC particle is related or if called on something other than a
721 REGISTER_VARIABLE("tanLambdaPull", getHelixTanLambdaPull, R
"DOC(
722The pull of the tracking parameter :math:`\tan\lambda` for the reconstructed
723pattern-recognition track, with respect to the MC track. That is:
727 \frac{(\tan\lambda)^\textrm{MC} - (\tan\lambda)^\textrm{PR}}{\sigma_{\tan\lambda; \textrm{PR}}}
729.. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaErr`
731Returns NaN if no MC particle is related or if called on something other than a
734 REGISTER_VARIABLE("nCDCHits", trackNCDCHits,
735 "The number of CDC hits associated to the track. Returns NaN if called for something other than a track-based particle.");
736 REGISTER_VARIABLE(
"nSVDHits", trackNSVDHits,
737 "The number of SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
738 REGISTER_VARIABLE(
"nPXDHits", trackNPXDHits,
739 "The number of PXD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
740 REGISTER_VARIABLE(
"nVXDHits", trackNVXDHits,
741 "The number of PXD and SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
742 REGISTER_VARIABLE(
"ndf", trackNDF, R
"DOC(
743Returns the number of degrees of freedom of the track fit.
747 Note that this is not simply the number of hits -5 due to outlier hit
750Returns NaN if called for something other than a track-based particle, or for
751mdst files processed with basf2 versions older than ``release-05-01``.
753 REGISTER_VARIABLE("chi2", trackChi2, R
"DOC(
754Returns the :math:`\chi^2` of the track fit. This is actually computed based on
755:b2:var:`pValue` and :b2:var:`ndf`.
757.. note:: Note that for :b2:var:`pValue` exactly equal to 0 it returns infinity.
759Returns NaN if called for something other than a track-based particle, or for
760mdst files processed with basf2 versions older than ``release-05-01``.
762 REGISTER_VARIABLE("firstSVDLayer", trackFirstSVDLayer,
763 "The first activated SVD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
764 REGISTER_VARIABLE(
"firstPXDLayer", trackFirstPXDLayer,
765 "The first activated PXD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
766 REGISTER_VARIABLE(
"firstCDCLayer", trackFirstCDCLayer,
767 "The first activated CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
768 REGISTER_VARIABLE(
"lastCDCLayer", trackLastCDCLayer,
769 "The last CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
770 REGISTER_VARIABLE(
"d0", trackD0, R
"DOC(
771Returns the tracking parameter :math:`d_0`, the signed distance to the
772point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
776 Tracking parameters are with respect to the origin (0,0,0). For the
777 POCA with respect to the measured beam interaction point, see
778 :b2:var:`dr` (you probably want this unless you're doing a tracking
779 study or some debugging) and :b2:var:`d0FromIP`.
781Returns NaN if called for something other than a track-based particle.
784 REGISTER_VARIABLE(
"phi0", trackPhi0, R
"DOC(
785Returns the tracking parameter :math:`\phi_0`, the angle of the transverse
786momentum in the :math:`r-\phi` plane.
790 Tracking parameters are with respect to the origin (0,0,0). For the
791 POCA with respect to the measured beam interaction point, see
792 :b2:var:`phi0FromIP`.
794Returns NaN if called for something other than a track-based particle.
797 REGISTER_VARIABLE(
"omega", trackOmega, R
"DOC(
798Returns the tracking parameter :math:`\omega`, the curvature of the track.
800Returns NaN if called for something other than a track-based particle.
802)DOC", ":math:`\\text{cm}^{-1}`");
803 REGISTER_VARIABLE(
"z0", trackZ0, R
"DOC(
804Returns the tracking parameter :math:`z_0`, the z-coordinate of the
805point-of-closest-approach (POCA).
809 Tracking parameters are with respect to the origin (0,0,0). For the
810 POCA with respect to the measured beam interaction point, see
811 :b2:var:`dz` (you probably want this unless you're doing a tracking
812 study or some debugging) and :b2:var:`z0FromIP`.
814Returns NaN if called for something other than a track-based particle.
817 REGISTER_VARIABLE(
"tanLambda", trackTanLambda, R
"DOC(
818Returns :math:`\tan\lambda`, the slope of the track in the :math:`r-z` plane.
820Returns NaN if called for something other than a track-based particle.
822 REGISTER_VARIABLE("d0FromIP", trackD0FromIP, R
"DOC(
823Returns the tracking parameter :math:`d_0`, the signed distance to the
824point-of-closest-approach (POCA) in the :math:`r-\phi` plane, with respect to the measured beam interaction point.
826Returns NaN if called for something other than a track-based particle.
829 REGISTER_VARIABLE(
"z0FromIP", trackZ0FromIP, R
"DOC(
830Returns the tracking parameter :math:`z_0`, the z-coordinate of the
831point-of-closest-approach (POCA), with respect to the measured beam interaction point.
833Returns NaN if called for something other than a track-based particle.
836 REGISTER_VARIABLE(
"phi0FromIP", trackPhi0FromIP, R
"DOC(
837Returns the tracking parameter :math:`\phi_0`, the angle of the transverse
838momentum in the :math:`r-\phi` plane, with respect to the measured beam interaction point.
840Returns NaN if called for something other than a track-based particle.
843 REGISTER_VARIABLE(
"d0Err", trackD0Error, R
"DOC(
844Returns the uncertainty on :math:`d_0`, the signed distance to the
845point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
847.. seealso:: :b2:var:`d0`, :b2:var:`d0Pull`
849Returns NaN if called for something other than a track-based particle.
852 REGISTER_VARIABLE(
"phi0Err", trackPhi0Error, R
"DOC(
853Returns the uncertainty on :math:`\phi_0`, the angle of the transverse momentum
854in the :math:`r-\phi` plane.
856.. seealso:: :b2:var:`phi0`, :b2:var:`phi0Pull`
858Returns NaN if called for something other than a track-based particle.
861 REGISTER_VARIABLE(
"omegaErr", trackOmegaError, R
"DOC(
862Returns the uncertainty on :math:`\omega`, the curvature of the track.
864.. seealso:: :b2:var:`omega`, :b2:var:`omegaPull`
866Returns NaN if called for something other than a track-based particle.
868)DOC", ":math:`\\text{cm}^{-1}`");
869 REGISTER_VARIABLE(
"z0Err", trackZ0Error, R
"DOC(
870Returns the uncertainty on :math:`z_0`, the z-coordinate of the
871point-of-closest-approach (POCA).
873.. seealso:: :b2:var:`z0`, :b2:var:`z0Pull`
875Returns NaN if called for something other than a track-based particle."
878 REGISTER_VARIABLE(
"tanLambdaErr", trackTanLambdaError, R
"DOC(
879Returns the uncertainty on :math:`\tan\lambda`, the slope of the track in the
882.. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaPull`
884Returns NaN if called for something other than a track-based particle.
886 REGISTER_VARIABLE("trackFitCovariance(i, j)", trackFitCovariance, R
"DOC(
887 The track fit covariance matrix element corresponding to the two indices is returned.
888 This is the association between integers and parameters:
894 * 4: :math:`\tan\lambda`
898 The covariance is returned. This means that the return value can be negative.
899 Furthermore, it's the squared value of the track fit error variables :b2:var:`d0Err`, etc.
900 when selecting the diagonal entries.
903 REGISTER_VARIABLE("pValue", trackPValue, R
"DOC(
904The :math:`\chi^2` probability of the **track** fit.
908 This is the p-value of the track-fit. It does not get updated after
909 vertex fitting or kinematic fitting, and is meaningless for composite
912 See :b2:var:`chiProb` (you probably want this for high-level analysis).
914Returns NaN if called for something other than a track-based particle.
916 REGISTER_VARIABLE("trackFitHypothesisPDG", trackFitHypothesisPDG, R
"DOC(
917Returns the PDG code of the track hypothesis actually used for the fit.
918Returns NaN if called for something other than a track-based particle.
920 REGISTER_VARIABLE("trackNECLClusters", trackNECLClusters, R
"DOC(
921Returns a count of the number of ECLClusters matched to the track. This is
922always 0 or 1 with newer versions of ECL reconstruction.
926 For high-level analysis it is recommended to require the presence of a
927 matched ECL cluster along with a minimum energy requirement. A
928 track-based particle will have a clusterE if it is matched (NaN if
929 there is no cluster match for the track.
931 .. code-block:: python
933 import modularAnalysis as ma
934 # minimum energy of 200 MeV
935 ma.fillParticleList("e+:clusters", "clusterE > 0.2", path)
937 # these two are equivalent
938 ma.fillParticleList("e+:unmatched", "isNAN(clusterE) == 1", path)
939 ma.fillParticleList("e+:unmatched2", "trackNECLClusters == 0", path)
941Returns NaN if called for something other than a track-based particle.
943 REGISTER_VARIABLE("trackQualityIndicator", trackQualityIndicator, R
"DOC(
944Returns the quality indicator of the track, a classification of fake vs. real track.
945A value near zero means the track has a greater chance to be fake.
949 During reconstruction, the probability (given a certain sample composition) of a track
950 to originate from a charged particle rather than e.g. a random combination of hits from
951 different charged particles and background contributions is estimated. This estimate
952 includes information, that isn't used for the calculation of the p-value of the fit, e.g.
953 energy-deposition, timing, and cluster-shape information.
955Returns NaN if called for something other than a track-based particle.
957 REGISTER_VARIABLE("helixExtTheta(radius [cm], z fwd [cm], z bwd [cm], useHighestProbMass=0)", trackHelixExtTheta, R
"DOC(
958 Returns theta of extrapolated helix parameters. If ``useHighestProbMass=1`` is set, the extrapolation will
959 use the track fit result for the mass hypothesis with the highest pValue.
962 REGISTER_VARIABLE(
"helixExtPhi(radius, z fwd, z bwd, useHighestProbMass=0)", trackHelixExtPhi,
963 "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",
966 REGISTER_METAVARIABLE(
"helixExtThetaOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtThetaOnDet, R
"DOC(
967 Returns theta of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
968 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
969 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
970 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
972 .. note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
973 )DOC", Manager::VariableDataType::c_double);
974 REGISTER_METAVARIABLE("helixExtPhiOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtPhiOnDet, R
"DOC(
975 Returns phi of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
976 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
977 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
978 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
980 .. note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
981 )DOC", Manager::VariableDataType::c_double);
984 REGISTER_VARIABLE("nExtraCDCHits", nExtraCDCHits, R
"DOC(
985[Eventbased] The number of CDC hits in the event not assigned to any track.
987Returns NaN if there is no event-level tracking information available.
989 REGISTER_VARIABLE("nExtraCDCHitsPostCleaning", nExtraCDCHitsPostCleaning, R
"DOC(
990[Eventbased] Returns a count of the number of CDC hits in the event not assigned
991to any track nor very likely beam background (i.e. hits that survive a cleanup
994Returns NaN if there is no event-level tracking information available.
996 REGISTER_VARIABLE("hasExtraCDCHitsInLayer(i)", hasExtraCDCHitsInLayer, R
"DOC(
997[Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC layer,
1000Returns NaN if there is no event-level tracking information available.
1002 REGISTER_VARIABLE("hasExtraCDCHitsInSuperLayer(i)", hasExtraCDCHitsInSuperLayer, R
"DOC(
1003[Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC
1004SuperLayer, 0 otherwise.
1006Returns NaN if there is no event-level tracking information available.
1008 REGISTER_VARIABLE("nExtraCDCSegments", nExtraCDCSegments, R
"DOC(
1009[Eventbased] Returns the number of CDC segments not assigned to any track.
1011Returns NaN if there is no event-level tracking information available.
1018 REGISTER_VARIABLE(
"nExtraPXDHits", nExtraPXDHits,
"[Eventbased] The number of PXD hits not assigned to any track");
1020 REGISTER_VARIABLE(
"trackFindingFailureFlag", trackFindingFailureFlag, R
"DOC(
1021[Eventbased] Returns a flag set by the tracking if there is reason to assume
1022there was a track in the event missed by the tracking, or the track finding was
1023(partly) aborted for this event.
1025Returns NaN if there is no event-level tracking information available.
1028 REGISTER_VARIABLE("isTrackFlippedAndRefitted", isTrackFlippedAndRefitted, R
"DOC(
1029Returns 1 if the charged final state particle comes from a track that has been flipped and refitted
1030at the end of the tracking chain, in particular before the outer detector reconstruction.
1033 REGISTER_VARIABLE("trackTime", getTrackTime, R
"DOC(
1034Returns the time at which the track is produced relative to the time of the collision (given by SVD EventT0).
1035Both the time of the collision and the track time are computed using only SVD hits.
1036Returns NaN if SVD EventT0 is NaN, or if no SVD Hits are attached to the track.
1037For more details, see :ref:`Time Extraction <tracking_eventTimeExtraction>` page.
1041 REGISTER_VARIABLE(
"trackLength", getTrackLength, R
"DOC(
1042Returns the arc length of the helix for the TrackFitResult associated with the particle.
1043The arc length is measured from the track origin to the radius of the CDC layer in which the Track has a hit.
1044Returns 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.