Skip to content

Commit 5fce31f

Browse files
authored
Merge pull request cms-sw#31433 from dpiparo/TrackBaseOptimisation
TrackBase: Reduce number of operations such as divisions, sqrts and multiplications
2 parents 592bcce + 68210c2 commit 5fce31f

File tree

1 file changed

+60
-17
lines changed

1 file changed

+60
-17
lines changed

DataFormats/TrackReco/interface/TrackBase.h

Lines changed: 60 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,15 @@ namespace reco {
220220
/// dz parameter (= dsz/cos(lambda)). This is the track z0 w.r.t (0,0,0) only if the refPoint is close to (0,0,0). See also function dz(myBeamSpot)
221221
double dz() const;
222222

223+
/// momentum vector magnitude square
224+
double p2() const;
225+
223226
/// momentum vector magnitude
224227
double p() const;
225228

229+
/// track transverse momentum square
230+
double pt2() const;
231+
226232
/// track transverse momentum
227233
double pt() const;
228234

@@ -302,6 +308,9 @@ namespace reco {
302308
/// error on signed transverse curvature
303309
double qoverpError() const;
304310

311+
/// error on Pt (set to 1000**2 TeV**2 if charge==0 for safety)
312+
double ptError2() const;
313+
305314
/// error on Pt (set to 1000 TeV if charge==0 for safety)
306315
double ptError() const;
307316

@@ -602,16 +611,30 @@ namespace reco {
602611
inline double TrackBase::d0() const { return -dxy(); }
603612

604613
// dsz parameter (THIS IS NOT the SZ impact parameter to (0,0,0) if refPoint is far from (0,0,0): see parametrization definition above for details)
605-
inline double TrackBase::dsz() const { return vz() * pt() / p() - (vx() * px() + vy() * py()) / pt() * pz() / p(); }
614+
inline double TrackBase::dsz() const {
615+
const auto thept = pt();
616+
const auto thepinv = 1 / p();
617+
const auto theptoverp = thept * thepinv;
618+
return vz() * theptoverp - (vx() * px() + vy() * py()) / thept * pz() * thepinv;
619+
}
606620

607621
// dz parameter (= dsz/cos(lambda)). This is the track z0 w.r.t (0,0,0) only if the refPoint is close to (0,0,0). See also function dz(myBeamSpot) below.
608-
inline double TrackBase::dz() const { return vz() - (vx() * px() + vy() * py()) / pt() * (pz() / pt()); }
622+
inline double TrackBase::dz() const {
623+
const auto thept2inv = 1 / pt2();
624+
return vz() - (vx() * px() + vy() * py()) * pz() * thept2inv;
625+
}
626+
627+
// momentum vector magnitude square
628+
inline double TrackBase::p2() const { return momentum_.Mag2(); }
609629

610630
// momentum vector magnitude
611-
inline double TrackBase::p() const { return momentum_.R(); }
631+
inline double TrackBase::p() const { return sqrt(p2()); }
632+
633+
// track transverse momentum square
634+
inline double TrackBase::pt2() const { return momentum_.Perp2(); }
612635

613636
// track transverse momentum
614-
inline double TrackBase::pt() const { return sqrt(momentum_.Perp2()); }
637+
inline double TrackBase::pt() const { return sqrt(pt2()); }
615638

616639
// x coordinate of momentum vector
617640
inline double TrackBase::px() const { return momentum_.x(); }
@@ -668,16 +691,20 @@ namespace reco {
668691
// (WARNING: this quantity can only be interpreted as the distance in the S-Z plane to the beamSpot, if the beam spot is reasonably close to the refPoint, since linear approximations are involved).
669692
// This is a good approximation for Tracker tracks.
670693
inline double TrackBase::dsz(const Point &myBeamSpot) const {
671-
return (vz() - myBeamSpot.z()) * pt() / p() -
672-
((vx() - myBeamSpot.x()) * px() + (vy() - myBeamSpot.y()) * py()) / pt() * pz() / p();
694+
const auto thept = pt();
695+
const auto thepinv = 1 / p();
696+
const auto theptoverp = thept * thepinv;
697+
return (vz() - myBeamSpot.z()) * theptoverp -
698+
((vx() - myBeamSpot.x()) * px() + (vy() - myBeamSpot.y()) * py()) / thept * pz() * thepinv;
673699
}
674700

675701
// dz parameter with respect to a user-given beamSpot
676702
// (WARNING: this quantity can only be interpreted as the track z0, if the beamSpot is reasonably close to the refPoint, since linear approximations are involved).
677703
// This is a good approximation for Tracker tracks.
678704
inline double TrackBase::dz(const Point &myBeamSpot) const {
705+
const auto theptinv2 = 1 / pt2();
679706
return (vz() - myBeamSpot.z()) -
680-
((vx() - myBeamSpot.x()) * px() + (vy() - myBeamSpot.y()) * py()) / pt() * pz() / pt();
707+
((vx() - myBeamSpot.x()) * px() + (vy() - myBeamSpot.y()) * py()) * pz() * theptinv2;
681708
}
682709

683710
// Track parameters with one-to-one correspondence to the covariance matrix
@@ -704,22 +731,36 @@ namespace reco {
704731
// error on signed transverse curvature
705732
inline double TrackBase::qoverpError() const { return error(i_qoverp); }
706733

707-
// error on Pt (set to 1000 TeV if charge==0 for safety)
708-
inline double TrackBase::ptError() const {
709-
return (charge() != 0) ? sqrt(pt() * pt() * p() * p() / charge() / charge() * covariance(i_qoverp, i_qoverp) +
710-
2 * pt() * p() / charge() * pz() * covariance(i_qoverp, i_lambda) +
711-
pz() * pz() * covariance(i_lambda, i_lambda))
712-
: 1.e6;
734+
// error on Pt (set to 1000**2 TeV**2 if charge==0 for safety)
735+
inline double TrackBase::ptError2() const {
736+
const auto thecharge = charge();
737+
738+
if (thecharge != 0) {
739+
const auto thept2 = pt2();
740+
const auto thep2 = p2();
741+
const auto thepz = pz();
742+
const auto ptimespt = sqrt(thep2 * thept2);
743+
const auto oneovercharge = 1 / thecharge;
744+
745+
return thept2 * thep2 * oneovercharge * oneovercharge * covariance(i_qoverp, i_qoverp) +
746+
2 * ptimespt * oneovercharge * thepz * covariance(i_qoverp, i_lambda) +
747+
thepz * thepz * covariance(i_lambda, i_lambda);
748+
}
749+
750+
return 1.e12;
713751
}
714752

753+
// error on Pt (set to 1000 TeV if charge==0 for safety)
754+
inline double TrackBase::ptError() const { return sqrt(ptError2()); }
755+
715756
// error on theta
716757
inline double TrackBase::thetaError() const { return error(i_lambda); }
717758

718759
// error on lambda
719760
inline double TrackBase::lambdaError() const { return error(i_lambda); }
720761

721762
// error on eta
722-
inline double TrackBase::etaError() const { return error(i_lambda) * p() / pt(); }
763+
inline double TrackBase::etaError() const { return error(i_lambda) * sqrt(p2() / pt2()); }
723764

724765
// error on phi
725766
inline double TrackBase::phiError() const { return error(i_phi); }
@@ -734,7 +775,7 @@ namespace reco {
734775
inline double TrackBase::dszError() const { return error(i_dsz); }
735776

736777
// error on dz
737-
inline double TrackBase::dzError() const { return error(i_dsz) * p() / pt(); }
778+
inline double TrackBase::dzError() const { return error(i_dsz) * sqrt(p2() / pt2()); }
738779

739780
// covariance of t0
740781
inline double TrackBase::covt0t0() const { return covt0t0_; }
@@ -778,11 +819,13 @@ namespace reco {
778819
int lostIn = hitPattern_.numberOfLostTrackerHits(HitPattern::MISSING_INNER_HITS);
779820
int lostOut = hitPattern_.numberOfLostTrackerHits(HitPattern::MISSING_OUTER_HITS);
780821

781-
if ((valid + lost + lostIn + lostOut) == 0) {
822+
const auto tot = valid + lost + lostIn + lostOut;
823+
824+
if (tot == 0) {
782825
return -1;
783826
}
784827

785-
return valid / (double)(valid + lost + lostIn + lostOut);
828+
return valid / (double)(tot);
786829
}
787830

788831
//Track algorithm

0 commit comments

Comments
 (0)