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 if (!trackFit)
return vecNaN;
316 else return getPositionOnHelix(trackFit, pars);
318 const TrackFitResult* trackFit = part->getTrackFitResult();
319 if (!trackFit)
return vecNaN;
320 else return getPositionOnHelix(trackFit, pars);
325 double trackHelixExtTheta(
const Particle* part,
const std::vector<double>& pars)
327 const auto nParams = pars.size();
328 if (nParams != 3 && nParams != 4) {
329 B2FATAL(
"Exactly three (+1 optional) parameters (r, zfwd, zbwd, [useHighestProbMass]) required for helixExtTheta.");
332 B2Vector3D position = getPositionOnHelix(part, pars);
334 return position.Theta();
338 double trackHelixExtPhi(
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 helixExtPhi.");
345 B2Vector3D position = getPositionOnHelix(part, pars);
347 return position.Phi();
352 if (arguments.size() != 1 && arguments.size() != 2)
353 B2FATAL(
"Exactly one (+1 optional) parameter (detector_surface_name, [useHighestProbMass]) is required for helixExtThetaOnDet.");
355 std::vector<double> parameters(3);
356 const std::string det = arguments[0];
366 B2FATAL(
"Given detector surface name is not supported.");
368 if (arguments.size() == 2)
369 parameters.push_back(std::stod(arguments[1]));
371 auto func = [parameters](
const Particle * part) ->
double {
373 B2Vector3D position = getPositionOnHelix(part, parameters);
375 return position.Theta();
382 if (arguments.size() != 1 && arguments.size() != 2)
383 B2FATAL(
"Exactly one (+1 optional) parameter (detector_surface_name, [useHighestProbMass]) is required for helixExtPhiOnDet.");
385 std::vector<double> parameters(3);
386 const std::string det = arguments[0];
396 B2FATAL(
"Given detector surface name is not supported.");
398 if (arguments.size() == 2)
399 parameters.push_back(std::stod(arguments[1]));
401 auto func = [parameters](
const Particle * part) ->
double {
403 B2Vector3D position = getPositionOnHelix(part, parameters);
405 return position.Phi();
416 double nExtraCDCHits(
const Particle*)
418 StoreObjPtr<EventLevelTrackingInfo> elti;
420 return elti->getNCDCHitsNotAssigned();
425 double nExtraCDCHitsPostCleaning(
const Particle*)
427 StoreObjPtr<EventLevelTrackingInfo> elti;
429 return elti->getNCDCHitsNotAssignedPostCleaning();
433 double hasExtraCDCHitsInLayer(
const Particle*,
const std::vector<double>& layer)
435 StoreObjPtr<EventLevelTrackingInfo> elti;
437 int ilayer = std::lround(layer[0]);
438 return elti->hasCDCLayer(ilayer);
442 double hasExtraCDCHitsInSuperLayer(
const Particle*,
const std::vector<double>& layer)
444 StoreObjPtr<EventLevelTrackingInfo> elti;
446 int ilayer = std::lround(layer[0]);
447 return elti->hasCDCSLayer(ilayer);
451 double nExtraCDCSegments(
const Particle*)
453 StoreObjPtr<EventLevelTrackingInfo> elti;
455 return elti->getNCDCSegments();
459 double nExtraVXDHitsInLayer(
const Particle*,
const std::vector<double>& layer)
461 StoreObjPtr<EventLevelTrackingInfo> elti;
463 int ilayer = std::lround(layer[0]);
464 return elti->getNVXDClustersInLayer(ilayer);
468 double nExtraVXDHits(
const Particle*)
470 StoreObjPtr<EventLevelTrackingInfo> elti;
473 for (uint16_t ilayer = 1; ilayer < 7; ++ilayer)
474 out += elti->getNVXDClustersInLayer(ilayer);
479 double svdFirstSampleTime(
const Particle*)
481 StoreObjPtr<EventLevelTrackingInfo> elti;
483 return elti->getSVDFirstSampleTime();
490 double trackFindingFailureFlag(
const Particle*)
492 StoreObjPtr<EventLevelTrackingInfo> elti;
494 return elti->hasAnErrorFlag();
500 const ROOT::Math::XYZVector mcProdVertex = mcparticle->getVertex();
501 const ROOT::Math::XYZVector mcMomentum = mcparticle->getMomentum();
503 const double mcParticleCharge = mcparticle->getCharge();
504 return Belle2::Helix(mcProdVertex, mcMomentum, mcParticleCharge, BzAtProdVertex);
507 double getMCHelixParameterAtIndex(
const Particle* particle,
const int index)
511 const MCParticle* mcparticle = particle->getMCParticle();
515 const std::vector<double> mcHelixPars{mcHelix.getD0(), mcHelix.getPhi0(), mcHelix.getOmega(), mcHelix.getZ0(), mcHelix.getTanLambda()};
516 return mcHelixPars.at(index);
519 double getHelixParameterPullAtIndex(
const Particle* particle,
const int index)
523 const MCParticle* mcparticle = particle->getMCParticle();
530 const TMatrixDSym& measCovariance = measHelix.
getCovariance();
533 const std::vector<double> mcHelixPars = {mcHelix.getD0(), mcHelix.getPhi0(), mcHelix.getOmega(), mcHelix.getZ0(), mcHelix.getTanLambda()};
534 const std::vector<double> measHelixPars = {measHelix.getD0(), measHelix.getPhi0(), measHelix.getOmega(), measHelix.getZ0(), measHelix.getTanLambda()};
536 return (mcHelixPars.at(index) - measHelixPars.at(index)) / std::sqrt(measCovariance(index, index));
539 double getHelixMCD0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 0); }
540 double getHelixMCPhi0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 1); }
541 double getHelixMCOmega(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 2); }
542 double getHelixMCZ0(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 3); }
543 double getHelixMCTanLambda(
const Particle* part) {
return getMCHelixParameterAtIndex(part, 4); }
545 double getHelixD0Pull(
const Particle* part)
547 return getHelixParameterPullAtIndex(part, 0);
550 double getHelixPhi0Pull(
const Particle* part)
552 return getHelixParameterPullAtIndex(part, 1);
555 double getHelixOmegaPull(
const Particle* part)
557 return getHelixParameterPullAtIndex(part, 2);
560 double getHelixZ0Pull(
const Particle* part)
562 return getHelixParameterPullAtIndex(part, 3);
565 double getHelixTanLambdaPull(
const Particle* part)
567 return getHelixParameterPullAtIndex(part, 4);
570 double getTrackTime(
const Particle* part)
572 const Track* track = part->getTrack();
574 return track->getTrackTime();
577 double isTrackFlippedAndRefitted(
const Particle* part)
579 auto track = part->getTrack();
581 return track->isFlippedAndRefitted() ? 1 : 0;
584 double getTrackLength(
const Particle* part)
586 auto trackFit = part->getTrackFitResult();
589 const double lastCDCLayer = trackLastCDCLayer(part);
590 if (std::isnan(lastCDCLayer) or lastCDCLayer < 0)
595 return trackFit->getHelix().getArcLength2DAtCylindricalR(r);
599 VARIABLE_GROUP(
"Tracking");
601 REGISTER_VARIABLE(
"mcD0", getHelixMCD0, R
"DOC(
602Returns the MC value of :math:`d_0`, the signed distance to the
603point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
605.. seealso:: :b2:var:`d0`
607Returns NaN if the particle is not related to any MCParticle.
610 REGISTER_VARIABLE(
"mcPhi0", getHelixMCPhi0, R
"DOC(
611Returns the MC value of :math:`\phi_0`, the angle of the transverse momentum
612in the :math:`r-\phi` plane.
614.. seealso:: :b2:var:`phi0`
616Returns NaN if the particle is not related to any MCParticle.
619 REGISTER_VARIABLE(
"mcOmega", getHelixMCOmega, R
"DOC(
620Returns the MC value of :math:`\omega`, the curvature of the track.
622.. seealso:: :b2:var:`omega`
624Returns NaN if the particle is not related to any MCParticle.
626)DOC", ":math:`\\text{cm}^{-1}`");
627 REGISTER_VARIABLE(
"mcZ0", getHelixMCZ0, R
"DOC(
628Returns the MC value of :math:`z_0`, the z-coordinate of the
629point-of-closest-approach (POCA).
631.. seealso:: :b2:var:`z0`
633Returns NaN if the particle is not related to any MCParticle.
636 REGISTER_VARIABLE(
"mcTanLambda", getHelixMCTanLambda, R
"DOC(
637Returns the MC value of :math:`\tan\lambda`, the slope of the track in the
640.. seealso:: :b2:var:`tanLambda`
642Returns NaN if the particle is not related to any MCParticle.
645 REGISTER_VARIABLE("d0Pull", getHelixD0Pull, R
"DOC(
646The pull of the tracking parameter :math:`d_0` for the reconstructed
647pattern-recognition track, with respect to the MC track. That is:
651 \frac{d_0^\textrm{MC} - d_0^\textrm{PR}}{\sigma_{d_0; \textrm{PR}}}
653.. seealso:: :b2:var:`d0`, :b2:var:`d0Err`
655Returns NaN if no MC particle is related or if called on something other than a
658 REGISTER_VARIABLE("phi0Pull", getHelixPhi0Pull, R
"DOC(
659The pull of the tracking parameter :math:`\phi_0` for the reconstructed
660pattern-recognition track, with respect to the MC track. That is:
664 \frac{\phi_0^\textrm{MC} - \phi_0^\textrm{PR}}{\sigma_{\phi_0; \textrm{PR}}}
666.. seealso:: :b2:var:`phi0`, :b2:var:`phi0Err`
668Returns NaN if no MC particle is related or if called on something other than a
671 REGISTER_VARIABLE("omegaPull", getHelixOmegaPull, R
"DOC(
672The pull of the tracking parameter :math:`\omega` for the reconstructed
673pattern-recognition track, with respect to the MC track. That is:
677 \frac{\omega^\textrm{MC} - \omega^\textrm{PR}}{\sigma_{\omega; \textrm{PR}}}
679.. seealso:: :b2:var:`omega`, :b2:var:`omegaErr`
681Returns NaN if no MC particle is related or if called on something other than a
684 REGISTER_VARIABLE("z0Pull", getHelixZ0Pull, R
"DOC(
685The pull of the tracking parameter :math:`z_0` for the reconstructed
686pattern-recognition track, with respect to the MC track. That is:
690 \frac{z_0^\textrm{MC} - z_0^\textrm{PR}}{\sigma_{z_0; \textrm{PR}}}
692.. seealso:: :b2:var:`z0`, :b2:var:`z0Err`
694Returns NaN if no MC particle is related or if called on something other than a
697 REGISTER_VARIABLE("tanLambdaPull", getHelixTanLambdaPull, R
"DOC(
698The pull of the tracking parameter :math:`\tan\lambda` for the reconstructed
699pattern-recognition track, with respect to the MC track. That is:
703 \frac{(\tan\lambda)^\textrm{MC} - (\tan\lambda)^\textrm{PR}}{\sigma_{\tan\lambda; \textrm{PR}}}
705.. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaErr`
707Returns NaN if no MC particle is related or if called on something other than a
710 REGISTER_VARIABLE("nCDCHits", trackNCDCHits,
711 "The number of CDC hits associated to the track. Returns NaN if called for something other than a track-based particle.");
712 REGISTER_VARIABLE(
"nSVDHits", trackNSVDHits,
713 "The number of SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
714 REGISTER_VARIABLE(
"nPXDHits", trackNPXDHits,
715 "The number of PXD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
716 REGISTER_VARIABLE(
"nVXDHits", trackNVXDHits,
717 "The number of PXD and SVD hits associated to the track. Returns NaN if called for something other than a track-based particle.");
718 REGISTER_VARIABLE(
"ndf", trackNDF, R
"DOC(
719Returns the number of degrees of freedom of the track fit.
723 Note that this is not simply the number of hits -5 due to outlier hit
726Returns NaN if called for something other than a track-based particle, or for
727mdst files processed with basf2 versions older than ``release-05-01``.
729 REGISTER_VARIABLE("chi2", trackChi2, R
"DOC(
730Returns the :math:`\chi^2` of the track fit. This is actually computed based on
731:b2:var:`pValue` and :b2:var:`ndf`.
733.. note:: Note that for :b2:var:`pValue` exactly equal to 0 it returns infinity.
735Returns NaN if called for something other than a track-based particle, or for
736mdst files processed with basf2 versions older than ``release-05-01``.
738 REGISTER_VARIABLE("firstSVDLayer", trackFirstSVDLayer,
739 "The first activated SVD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
740 REGISTER_VARIABLE(
"firstPXDLayer", trackFirstPXDLayer,
741 "The first activated PXD layer associated to the track. Returns NaN if called for something other than a track-based particle.");
742 REGISTER_VARIABLE(
"firstCDCLayer", trackFirstCDCLayer,
743 "The first activated CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
744 REGISTER_VARIABLE(
"lastCDCLayer", trackLastCDCLayer,
745 "The last CDC layer associated to the track. Returns NaN if called for something other than a track-based particle.");
746 REGISTER_VARIABLE(
"d0", trackD0, R
"DOC(
747Returns the tracking parameter :math:`d_0`, the signed distance to the
748point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
752 Tracking parameters are with respect to the origin (0,0,0). For the
753 POCA with respect to the measured beam interaction point, see
754 :b2:var:`dr` (you probably want this unless you're doing a tracking
755 study or some debugging) and :b2:var:`d0FromIP`.
757Returns NaN if called for something other than a track-based particle.
760 REGISTER_VARIABLE(
"phi0", trackPhi0, R
"DOC(
761Returns the tracking parameter :math:`\phi_0`, the angle of the transverse
762momentum in the :math:`r-\phi` plane.
766 Tracking parameters are with respect to the origin (0,0,0). For the
767 POCA with respect to the measured beam interaction point, see
768 :b2:var:`phi0FromIP`.
770Returns NaN if called for something other than a track-based particle.
773 REGISTER_VARIABLE(
"omega", trackOmega, R
"DOC(
774Returns the tracking parameter :math:`\omega`, the curvature of the track.
776Returns NaN if called for something other than a track-based particle.
778)DOC", ":math:`\\text{cm}^{-1}`");
779 REGISTER_VARIABLE(
"z0", trackZ0, R
"DOC(
780Returns the tracking parameter :math:`z_0`, the z-coordinate of the
781point-of-closest-approach (POCA).
785 Tracking parameters are with respect to the origin (0,0,0). For the
786 POCA with respect to the measured beam interaction point, see
787 :b2:var:`dz` (you probably want this unless you're doing a tracking
788 study or some debugging) and :b2:var:`z0FromIP`.
790Returns NaN if called for something other than a track-based particle.
793 REGISTER_VARIABLE(
"tanLambda", trackTanLambda, R
"DOC(
794Returns :math:`\tan\lambda`, the slope of the track in the :math:`r-z` plane.
796Returns NaN if called for something other than a track-based particle.
798 REGISTER_VARIABLE("d0FromIP", trackD0FromIP, R
"DOC(
799Returns the tracking parameter :math:`d_0`, the signed distance to the
800point-of-closest-approach (POCA) in the :math:`r-\phi` plane, with respect to the measured beam interaction point.
802Returns NaN if called for something other than a track-based particle.
805 REGISTER_VARIABLE(
"z0FromIP", trackZ0FromIP, R
"DOC(
806Returns the tracking parameter :math:`z_0`, the z-coordinate of the
807point-of-closest-approach (POCA), with respect to the measured beam interaction point.
809Returns NaN if called for something other than a track-based particle.
812 REGISTER_VARIABLE(
"phi0FromIP", trackPhi0FromIP, R
"DOC(
813Returns the tracking parameter :math:`\phi_0`, the angle of the transverse
814momentum in the :math:`r-\phi` plane, with respect to the measured beam interaction point.
816Returns NaN if called for something other than a track-based particle.
819 REGISTER_VARIABLE(
"d0Err", trackD0Error, R
"DOC(
820Returns the uncertainty on :math:`d_0`, the signed distance to the
821point-of-closest-approach (POCA) in the :math:`r-\phi` plane.
823.. seealso:: :b2:var:`d0`, :b2:var:`d0Pull`
825Returns NaN if called for something other than a track-based particle.
828 REGISTER_VARIABLE(
"phi0Err", trackPhi0Error, R
"DOC(
829Returns the uncertainty on :math:`\phi_0`, the angle of the transverse momentum
830in the :math:`r-\phi` plane.
832.. seealso:: :b2:var:`phi0`, :b2:var:`phi0Pull`
834Returns NaN if called for something other than a track-based particle.
837 REGISTER_VARIABLE(
"omegaErr", trackOmegaError, R
"DOC(
838Returns the uncertainty on :math:`\omega`, the curvature of the track.
840.. seealso:: :b2:var:`omega`, :b2:var:`omegaPull`
842Returns NaN if called for something other than a track-based particle.
844)DOC", ":math:`\\text{cm}^{-1}`");
845 REGISTER_VARIABLE(
"z0Err", trackZ0Error, R
"DOC(
846Returns the uncertainty on :math:`z_0`, the z-coordinate of the
847point-of-closest-approach (POCA).
849.. seealso:: :b2:var:`z0`, :b2:var:`z0Pull`
851Returns NaN if called for something other than a track-based particle."
854 REGISTER_VARIABLE(
"tanLambdaErr", trackTanLambdaError, R
"DOC(
855Returns the uncertainty on :math:`\tan\lambda`, the slope of the track in the
858.. seealso:: :b2:var:`tanLambda`, :b2:var:`tanLambdaPull`
860Returns NaN if called for something other than a track-based particle.
862 REGISTER_VARIABLE("trackFitCovariance(i, j)", trackFitCovariance, R
"DOC(
863 The track fit covariance matrix element corresponding to the two indices is returned.
864 This is the association between integers and parameters:
870 * 4: :math:`\tan\lambda`
874 The covariance is returned. This means that the return value can be negative.
875 Furthermore, it's the squared value of the track fit error variables :b2:var:`d0Err`, etc.
876 when selecting the diagonal entries.
879 REGISTER_VARIABLE("pValue", trackPValue, R
"DOC(
880The :math:`\chi^2` probability of the **track** fit.
884 This is the p-value of the track-fit. It does not get updated after
885 vertex fitting or kinematic fitting, and is meaningless for composite
888 See :b2:var:`chiProb` (you probably want this for high-level analysis).
890Returns NaN if called for something other than a track-based particle.
892 REGISTER_VARIABLE("trackFitHypothesisPDG", trackFitHypothesisPDG, R
"DOC(
893Returns the PDG code of the track hypothesis actually used for the fit.
894Returns NaN if called for something other than a track-based particle.
896 REGISTER_VARIABLE("trackNECLClusters", trackNECLClusters, R
"DOC(
897Returns a count of the number of ECLClusters matched to the track. This is
898always 0 or 1 with newer versions of ECL reconstruction.
902 For high-level analysis it is recommended to require the presence of a
903 matched ECL cluster along with a minimum energy requirement. A
904 track-based particle will have a clusterE if it is matched (NaN if
905 there is no cluster match for the track.
907 .. code-block:: python
909 import modularAnalysis as ma
910 # minimum energy of 200 MeV
911 ma.fillParticleList("e+:clusters", "clusterE > 0.2", path)
913 # these two are equivalent
914 ma.fillParticleList("e+:unmatched", "isNAN(clusterE) == 1", path)
915 ma.fillParticleList("e+:unmatched2", "trackNECLClusters == 0", path)
917Returns NaN if called for something other than a track-based particle.
919 REGISTER_VARIABLE("helixExtTheta(radius [cm], z fwd [cm], z bwd [cm], useHighestProbMass=0)", trackHelixExtTheta,
920 R
"DOC(Returns theta of extrapolated helix parameters. If ``useHighestProbMass=1`` is set, the extrapolation will
921 use the track fit result for the mass hypothesis with the highest pValue.
924 REGISTER_VARIABLE(
"helixExtPhi(radius, z fwd, z bwd, useHighestProbMass=0)", trackHelixExtPhi,
925 "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",
928 REGISTER_METAVARIABLE(
"helixExtThetaOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtThetaOnDet,
929 R
"DOC(Returns theta of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
930 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
931 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
932 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
934 ..note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
935 )DOC", Manager::VariableDataType::c_double);
936 REGISTER_METAVARIABLE("helixExtPhiOnDet(detector_surface_name, useHighestProbMass=0)", trackHelixExtPhiOnDet,
937 R
"DOC(Returns phi of extrapolated helix parameters on the given detector surface. The unit of angle is ``rad``.
938 If ``useHighestProbMass=1`` is set, the extrapolation will use the track fit result for the mass hypothesis with the highest pValue.
939 The supported detector surface names are ``{'CDC', 'TOP', 'ARICH', 'ECL', 'KLM'}``.
940 Also, the detector name with number of meaningful-layer is supported, e.g. ``'CDC8'``: last superlayer of CDC, ``'ECL1'``: mid-point of ECL.
942 ..note:: You can find more information in `modularAnalysis.calculateTrackIsolation`.
943 )DOC", Manager::VariableDataType::c_double);
946 REGISTER_VARIABLE("nExtraCDCHits", nExtraCDCHits, R
"DOC(
947[Eventbased] The number of CDC hits in the event not assigned to any track.
949Returns NaN if there is no event-level tracking information available.
951 REGISTER_VARIABLE("nExtraCDCHitsPostCleaning", nExtraCDCHitsPostCleaning, R
"DOC(
952[Eventbased] Returns a count of the number of CDC hits in the event not assigned
953to any track nor very likely beam background (i.e. hits that survive a cleanup
956Returns NaN if there is no event-level tracking information available.
958 REGISTER_VARIABLE("hasExtraCDCHitsInLayer(i)", hasExtraCDCHitsInLayer, R
"DOC(
959[Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC layer,
962Returns NaN if there is no event-level tracking information available.
964 REGISTER_VARIABLE("hasExtraCDCHitsInSuperLayer(i)", hasExtraCDCHitsInSuperLayer, R
"DOC(
965[Eventbased] Returns 1 if a non-assigned hit exists in the specified CDC
966SuperLayer, 0 otherwise.
968Returns NaN if there is no event-level tracking information available.
970 REGISTER_VARIABLE("nExtraCDCSegments", nExtraCDCSegments, R
"DOC(
971[Eventbased] Returns the number of CDC segments not assigned to any track.
973Returns NaN if there is no event-level tracking information available.
981 REGISTER_VARIABLE(
"trackFindingFailureFlag", trackFindingFailureFlag, R
"DOC(
982[Eventbased] Returns a flag set by the tracking if there is reason to assume
983there was a track in the event missed by the tracking, or the track finding was
984(partly) aborted for this event.
986Returns NaN if there is no event-level tracking information available.
989 REGISTER_VARIABLE("isTrackFlippedAndRefitted", isTrackFlippedAndRefitted, R
"DOC(
990Returns 1 if the charged final state particle comes from a track that has been flipped and refitted
991at the end of the reconstruction chain, in particular after the outer detector reconstruction.
994 REGISTER_VARIABLE("trackTime", getTrackTime, R
"DOC(
995Returns the time at which the track is produced relative to the time of the collision (given by SVD EventT0).
996Both the time of the collision and the track time are computed using only SVD hits.
997Returns NaN if SVD EventT0 is NaN, or if no SVD Hits are attached to the track.
998For more details, see :ref:`Time Extraction <tracking_eventTimeExtraction>` page.
1002 REGISTER_VARIABLE(
"trackLength", getTrackLength, R
"DOC(
1003Returns the arc length of the helix for the TrackFitResult associated with the particle.
1004The arc length is measured from the track origin to the radius of the CDC layer in which the Track has a hit.
1005Returns 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.