diff --git a/L1Trigger/TrackFindingTracklet/interface/PurgeDuplicate.h b/L1Trigger/TrackFindingTracklet/interface/PurgeDuplicate.h index 6600a3de15d98..4d7a27fde6baf 100644 --- a/L1Trigger/TrackFindingTracklet/interface/PurgeDuplicate.h +++ b/L1Trigger/TrackFindingTracklet/interface/PurgeDuplicate.h @@ -7,6 +7,13 @@ #include +// Run algorithm to remove duplicate tracks. +// Returns Track object that represent output at end of L1 track chain, +// (and are later converted to TTTrack). Duplicate Track objects are flagged, +// but only deleted if using the Hybrid algo. +// Also writes to memory the same tracks in more detailed Tracklet format, +// where duplicates are all deleted. + namespace trklet { class Settings; diff --git a/L1Trigger/TrackFindingTracklet/interface/Settings.h b/L1Trigger/TrackFindingTracklet/interface/Settings.h index d82eaa9bf91fe..5e5d3e7bbd4c8 100644 --- a/L1Trigger/TrackFindingTracklet/interface/Settings.h +++ b/L1Trigger/TrackFindingTracklet/interface/Settings.h @@ -298,6 +298,7 @@ namespace trklet { double phicritminmc() const { return phicritmin() - dphicritmc_; } double phicritmaxmc() const { return phicritmax() + dphicritmc_; } + // Stub digitization granularities double kphi() const { return dphisectorHG() / (1 << nphibitsstub(0)); } double kphi1() const { return dphisectorHG() / (1 << nphibitsstub(N_LAYER - 1)); } double kphi(unsigned int layerdisk) const { return dphisectorHG() / (1 << nphibitsstub(layerdisk)); } @@ -383,6 +384,7 @@ namespace trklet { int chisqphifactbits() const { return chisqphifactbits_; } int chisqzfactbits() const { return chisqzfactbits_; } + // Helix param digisation granularities //0.02 here is the maximum range in rinv values that can be represented double krinvpars() const { int shift = ceil(-log2(0.02 * rmaxdisk_ / ((1 << nbitsrinv_) * dphisectorHG()))); @@ -775,6 +777,7 @@ namespace trklet { {"PR", 108}, {"ME", 108}, {"MC", 105}, + {"TB", 108}, {"MP", 108}, {"TP", 108}, {"TRE", 108}}; diff --git a/L1Trigger/TrackFindingTracklet/interface/Track.h b/L1Trigger/TrackFindingTracklet/interface/Track.h index 0e014083b70fc..087e47416b531 100644 --- a/L1Trigger/TrackFindingTracklet/interface/Track.h +++ b/L1Trigger/TrackFindingTracklet/interface/Track.h @@ -17,8 +17,9 @@ namespace trklet { class Track { public: - Track(TrackPars ipars, - int ichisqrphi, + // Create track from digitized helix params & stubs + Track(TrackPars ipars, // digi helix + int ichisqrphi, // digi chi2 int ichisqrz, double chisqrphi, double chisqrz, @@ -54,6 +55,7 @@ namespace trklet { return (settings.c() * settings.bfield() * 0.01) / (ipars_.rinv() * settings.krinvpars()); } + // Get floating point helix params by undigitized digi helix params double phi0(Settings const& settings) const; double eta(Settings const& settings) const { return asinh(ipars_.t() * settings.ktpars()); } diff --git a/L1Trigger/TrackFindingTracklet/interface/Tracklet.h b/L1Trigger/TrackFindingTracklet/interface/Tracklet.h index 30e1ae3900ec3..2e31286e775fe 100644 --- a/L1Trigger/TrackFindingTracklet/interface/Tracklet.h +++ b/L1Trigger/TrackFindingTracklet/interface/Tracklet.h @@ -157,6 +157,7 @@ namespace trklet { return FPGAWord(ichisqrphifit_.value() + ichisqrzfit_.value(), ichisqrphifit_.nbits()); } + // Note floating & digitized helix params after track fit. void setFitPars(double rinvfit, double phi0fit, double d0fit, @@ -185,6 +186,7 @@ namespace trklet { const std::string diskstubstr(const unsigned disk) const; std::string trackfitstr() const; + // Create a Track object from stubs & digitized track helix params Track makeTrack(const std::vector& l1stubs); Track* getTrack() { diff --git a/L1Trigger/TrackFindingTracklet/src/FitTrack.cc b/L1Trigger/TrackFindingTracklet/src/FitTrack.cc index 7b1a9eca7a504..46cf0eb980fb2 100644 --- a/L1Trigger/TrackFindingTracklet/src/FitTrack.cc +++ b/L1Trigger/TrackFindingTracklet/src/FitTrack.cc @@ -124,13 +124,15 @@ void FitTrack::trackFitKF(Tracklet* tracklet, stubidslist.push_back(std::make_pair(layer, it->phiregionaddress())); } - // And that's all we need! The rest is just for fitting (in PurgeDuplicate) - return; - } + // And that's all we need! The rest is just for track fit (done in PurgeDuplicate) - HybridFit hybridFitter(iSector_, settings_, globals_); - hybridFitter.Fit(tracklet, trackstublist); - return; + } else { + + // Track fit only called here if not running duplicate removal + // before fit. (e.g. If skipping duplicate removal). + HybridFit hybridFitter(iSector_, settings_, globals_); + hybridFitter.Fit(tracklet, trackstublist); + } } } #endif @@ -889,8 +891,8 @@ void FitTrack::execute(unsigned int iSector) { indexArray[i] = 0; } - int countAll = 0; - int countFit = 0; + unsigned int countAll = 0; + unsigned int countFit = 0; Tracklet* bestTracklet = nullptr; do { @@ -989,6 +991,7 @@ void FitTrack::execute(unsigned int iSector) { std::vector trackstublist; std::vector> stubidslist; + // Track Builder cut of >= 4 layers with stubs. if ((bestTracklet->getISeed() >= (int)N_SEED_PROMPT && nMatchesUniq >= 1) || nMatchesUniq >= 2) { //For seeds index >=8 (triplet seeds), there are three stubs associated from start. countFit++; @@ -1021,7 +1024,7 @@ void FitTrack::execute(unsigned int iSector) { } } - } while (bestTracklet != nullptr); + } while (bestTracklet != nullptr && countAll < settings_.maxStep("TB")); if (settings_.writeMonitorData("FT")) { globals_->ofstream("fittrack.txt") << getName() << " " << countAll << " " << countFit << endl; diff --git a/L1Trigger/TrackFindingTracklet/src/PurgeDuplicate.cc b/L1Trigger/TrackFindingTracklet/src/PurgeDuplicate.cc index 2e9f644671582..a70afb75b3715 100644 --- a/L1Trigger/TrackFindingTracklet/src/PurgeDuplicate.cc +++ b/L1Trigger/TrackFindingTracklet/src/PurgeDuplicate.cc @@ -323,26 +323,29 @@ void PurgeDuplicate::execute(std::vector& outputtracks_, unsigned int iSe // Make the final track objects, fit with KF, and send to output for (unsigned int itrk = 0; itrk < numStublists; itrk++) { - Tracklet* tracklet = inputtracklets_[itrk]; - std::vector trackstublist = inputstublists_[itrk]; - - HybridFit hybridFitter(iSector, settings_, globals_); - hybridFitter.Fit(tracklet, trackstublist); - - // If the track was accepted (and thus fit), add to output - if (tracklet->fit()) { - // Add track to output if it wasn't merged into another - Track* outtrack = tracklet->getTrack(); - outtrack->setSector(iSector); - if (trackInfo[itrk].second == true) - outtrack->setDuplicate(true); - else + bool duplicateTrack = trackInfo[itrk].second; + if (not duplicateTrack) { // Don't waste CPU by calling KF for duplicates + + Tracklet* tracklet = inputtracklets_[itrk]; + std::vector trackstublist = inputstublists_[itrk]; + + // Run KF track fit + HybridFit hybridFitter(iSector, settings_, globals_); + hybridFitter.Fit(tracklet, trackstublist); + + // If the track was accepted (and thus fit), add to output + if (tracklet->fit()) { + // Add fitted Track to output (later converted to TTTrack) + Track* outtrack = tracklet->getTrack(); + outtrack->setSector(iSector); + // Also store fitted track as more detailed Tracklet object. outputtracklets_[trackInfo[itrk].first]->addTrack(tracklet); - // Add all tracks to standalone root file output - outtrack->setStubIDpremerge(inputstubidslists_[itrk]); - outtrack->setStubIDprefit(mergedstubidslists_[itrk]); - outputtracks_.push_back(*outtrack); + // Add all tracks to standalone root file output + outtrack->setStubIDpremerge(inputstubidslists_[itrk]); + outtrack->setStubIDprefit(mergedstubidslists_[itrk]); + outputtracks_.push_back(*outtrack); + } } } } diff --git a/L1Trigger/TrackFindingTracklet/src/Sector.cc b/L1Trigger/TrackFindingTracklet/src/Sector.cc index 0cce2f1508dc9..f4ddd63a21f8a 100644 --- a/L1Trigger/TrackFindingTracklet/src/Sector.cc +++ b/L1Trigger/TrackFindingTracklet/src/Sector.cc @@ -410,12 +410,17 @@ void Sector::executeMP() { } } +// Order here reflects Tracklet algo that calls FitTrack before PurgeDuplicates. +// If using Hybrid, then PurgeDuplicates runs both duplicate removal & KF steps. +// (unless duplicate removal disabled, in which case FitTrack runs KF). + void Sector::executeFT() { for (auto& i : FT_) { i->execute(isector_); } } +// Returns tracks reconstructed by L1 track chain. void Sector::executePD(std::vector& tracks) { for (auto& i : PD_) { i->execute(tracks, isector_); diff --git a/L1Trigger/TrackFindingTracklet/src/Tracklet.cc b/L1Trigger/TrackFindingTracklet/src/Tracklet.cc index 0861aaec04f49..0b271e05d1ad1 100644 --- a/L1Trigger/TrackFindingTracklet/src/Tracklet.cc +++ b/L1Trigger/TrackFindingTracklet/src/Tracklet.cc @@ -735,9 +735,12 @@ std::string Tracklet::trackfitstr() const { return oss; } +// Create a Track object from stubs & digitized track helix params + Track Tracklet::makeTrack(const vector& l1stubs) { assert(fit()); + // Digitized track helix params TrackPars ipars(fpgafitpars_.rinv().value(), fpgafitpars_.phi0().value(), fpgafitpars_.d0().value(),