From dba16bf5c2bd94826e1cedd6de49c7b131351340 Mon Sep 17 00:00:00 2001 From: Thomas Schuh Date: Wed, 3 Nov 2021 16:48:18 +0000 Subject: [PATCH 1/4] Reviewed. --- .../plugins/L1FPGATrackProducer.cc | 10 +- .../python/Analyzer_cff.py | 11 +- .../python/Customize_cff.py | 1 + .../python/Producer_cff.py | 2 +- .../python/Producer_cfi.py | 1 + .../test/AnalyzerTBout.cc | 432 ++++++++++++++++++ .../test/HybridTracksNewKF_cfg.py | 3 +- .../test/ProducerTBout.cc | 2 +- L1Trigger/TrackTrigger/interface/Setup.h | 4 +- L1Trigger/TrackTrigger/src/Setup.cc | 22 +- L1Trigger/TrackerDTC/test/Analyzer.cc | 2 +- 11 files changed, 465 insertions(+), 25 deletions(-) create mode 100644 L1Trigger/TrackFindingTracklet/test/AnalyzerTBout.cc diff --git a/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc b/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc index fcc72215d09d5..b2d0660ce1979 100644 --- a/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc +++ b/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc @@ -252,7 +252,11 @@ L1FPGATrackProducer::L1FPGATrackProducer(edm::ParameterSet const& iConfig) tableTREFile = iConfig.getParameter("tableTREFile"); } - // book ES product to assign tracks and stubs to InputRouter input channel and TrackBuilder output channel + // book ED output token for clock and bit accurate tracks + edPutTokenTracks_ = produces("Level1TTTracks"); + // book ED output token for clock and bit accurate stubs + edPutTokenStubs_ = produces("Level1TTTracks"); + // book ES product esGetTokenChannelAssignment_ = esConsumes(); esGetToken_ = esConsumes(); // initial ES products @@ -310,9 +314,9 @@ L1FPGATrackProducer::L1FPGATrackProducer(edm::ParameterSet const& iConfig) cms::Exception exception("ConfigurationNotSupported."); exception.addContext("L1FPGATrackProducer::produce"); if (settings.doMultipleMatches()) - exception << "Stroing of TrackBuilder output does not support doMultipleMatches."; + exception << "Storing of TrackBuilder output does not support doMultipleMatches."; if (settings.removalType() != "") - exception << "Stroing of TrackBuilder output does not support duplicate removal."; + exception << "Storing of TrackBuilder output does not support duplicate removal."; throw exception; } } diff --git a/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py b/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py index 258815abccba9..a46c58947d04b 100644 --- a/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py +++ b/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py @@ -3,8 +3,9 @@ from L1Trigger.TrackFindingTracklet.Analyzer_cfi import TrackFindingTrackletAnalyzer_params from L1Trigger.TrackFindingTracklet.Producer_cfi import TrackFindingTrackletProducer_params -TrackFindingTrackletAnalyzerTracklet = cms.EDAnalyzer( 'trklet::AnalyzerTracklet', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) -TrackFindingTrackletAnalyzerKFin = cms.EDAnalyzer( 'trklet::AnalyzerKFin', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) -TrackFindingTrackletAnalyzerKF = cms.EDAnalyzer( 'trackerTFP::AnalyzerKF', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) -TrackFindingTrackletAnalyzerKFout = cms.EDAnalyzer( 'trklet::AnalyzerKFout', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) -TrackFindingTrackletAnalyzerTT = cms.EDAnalyzer( 'trklet::AnalyzerTT', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) \ No newline at end of file +TrackFindingTrackletAnalyzerTBout = cms.EDAnalyzer( 'trklet::AnalyzerTBout', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducerKF_params ) +TrackFindingTrackletAnalyzerTracklet = cms.EDAnalyzer( 'trklet::AnalyzerTracklet', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducerKF_params ) +TrackFindingTrackletAnalyzerKFin = cms.EDAnalyzer( 'trklet::AnalyzerKFin', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducerKF_params ) +TrackFindingTrackletAnalyzerKF = cms.EDAnalyzer( 'trackerTFP::AnalyzerKF', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducerKF_params ) +TrackFindingTrackletAnalyzerKFout = cms.EDAnalyzer( 'trklet::AnalyzerKFout', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducerKF_params ) +TrackFindingTrackletAnalyzerTT = cms.EDAnalyzer( 'trklet::AnalyzerTT', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducerKF_params ) diff --git a/L1Trigger/TrackFindingTracklet/python/Customize_cff.py b/L1Trigger/TrackFindingTracklet/python/Customize_cff.py index 342544297f601..f6b7ca42c67ea 100644 --- a/L1Trigger/TrackFindingTracklet/python/Customize_cff.py +++ b/L1Trigger/TrackFindingTracklet/python/Customize_cff.py @@ -12,6 +12,7 @@ def fwConfig(process): process.TTTracksFromTrackletEmulation.DoMultipleMatches = False process.TTTracksFromTrackletEmulation.StoreTrackBuilderOutput = True process.ChannelAssignment.UseDuplicateRemoval = False + process.TrackTriggerSetup.KalmanFilter.NumWorker = 8 # configures track finding s/w to behave as a subchain of processing steps def reducedConfig(process): diff --git a/L1Trigger/TrackFindingTracklet/python/Producer_cff.py b/L1Trigger/TrackFindingTracklet/python/Producer_cff.py index a2b4a4548fd27..a3f354b8489ab 100644 --- a/L1Trigger/TrackFindingTracklet/python/Producer_cff.py +++ b/L1Trigger/TrackFindingTracklet/python/Producer_cff.py @@ -14,4 +14,4 @@ TrackFindingTrackletProducerKF = cms.EDProducer( 'trackerTFP::ProducerKF', TrackFindingTrackletProducer_params ) TrackFindingTrackletProducerTT = cms.EDProducer( 'trklet::ProducerTT', TrackFindingTrackletProducer_params ) TrackFindingTrackletProducerAS = cms.EDProducer( 'trklet::ProducerAS', TrackFindingTrackletProducer_params ) -TrackFindingTrackletProducerKFout = cms.EDProducer( 'trklet::ProducerKFout', TrackFindingTrackletProducer_params ) \ No newline at end of file +TrackFindingTrackletProducerKFout = cms.EDProducer( 'trklet::ProducerKFout', TrackFindingTrackletProducer_params ) diff --git a/L1Trigger/TrackFindingTracklet/python/Producer_cfi.py b/L1Trigger/TrackFindingTracklet/python/Producer_cfi.py index ee4be979a3e61..0dc87dd772cbf 100644 --- a/L1Trigger/TrackFindingTracklet/python/Producer_cfi.py +++ b/L1Trigger/TrackFindingTracklet/python/Producer_cfi.py @@ -4,6 +4,7 @@ InputTag = cms.InputTag( "TTTracksFromTrackletEmulation", "Level1TTTracks"), # InputTagDTC = cms.InputTag( "TrackerDTCProducer", "StubAccepted"), # + LabelTBout = cms.string ( "TrackFindingTrackletProducerTBout" ), # LabelKFin = cms.string ( "TrackFindingTrackletProducerKFin" ), # LabelKF = cms.string ( "TrackFindingTrackletProducerKF" ), # LabelTT = cms.string ( "TrackFindingTrackletProducerTT" ), # diff --git a/L1Trigger/TrackFindingTracklet/test/AnalyzerTBout.cc b/L1Trigger/TrackFindingTracklet/test/AnalyzerTBout.cc new file mode 100644 index 0000000000000..d26fd5a1664e8 --- /dev/null +++ b/L1Trigger/TrackFindingTracklet/test/AnalyzerTBout.cc @@ -0,0 +1,432 @@ +#include "FWCore/Framework/interface/one/EDAnalyzer.h" +#include "FWCore/Framework/interface/Run.h" +#include "FWCore/Framework/interface/Event.h" +#include "FWCore/Framework/interface/EventSetup.h" +#include "FWCore/Framework/interface/MakerMacros.h" +#include "FWCore/ParameterSet/interface/ParameterSet.h" +#include "FWCore/ServiceRegistry/interface/Service.h" +#include "FWCore/MessageLogger/interface/MessageLogger.h" +#include "FWCore/Utilities/interface/EDGetToken.h" +#include "FWCore/Utilities/interface/InputTag.h" +#include "FWCore/Utilities/interface/Exception.h" +#include "CommonTools/UtilAlgos/interface/TFileService.h" +#include "DataFormats/Common/interface/Handle.h" + +#include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h" +#include "L1Trigger/TrackTrigger/interface/Setup.h" +#include "L1Trigger/TrackerTFP/interface/DataFormats.h" +#include "L1Trigger/TrackFindingTracklet/interface/ChannelAssignment.h" +#include "L1Trigger/TrackFindingTracklet/interface/Settings.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace edm; +using namespace trackerTFP; +using namespace tt; + +namespace trklet { + + // stub resolution plots helper + enum Resolution { Phi, Z, NumResolution }; + constexpr initializer_list AllResolution = {Phi, Z}; + constexpr auto NameResolution = {"Phi", "Z"}; + inline string name(Resolution r) { return string(*(NameResolution.begin() + r)); } + + /*! \class trklet::AnalyzerTBout + * \brief Class to analyze hardware like structured TTStub Collection generated by Tracklet + * \author Thomas Schuh + * \date 2021, Nov + */ + class AnalyzerTBout : public one::EDAnalyzer { + public: + AnalyzerTBout(const ParameterSet& iConfig); + void beginJob() override {} + void beginRun(const Run& iEvent, const EventSetup& iSetup) override; + void analyze(const Event& iEvent, const EventSetup& iSetup) override; + void endRun(const Run& iEvent, const EventSetup& iSetup) override {} + void endJob() override; + + private: + // + void formTracks(const StreamsTrack& streamsTrack, + const StreamsStub& streamsStubs, + vector>& tracks, + int channel); + // + void associate(const vector>& tracks, const StubAssociation* ass, set& tps, int& sum) const; + // + void fill(const FrameTrack& frameTrack, const FrameStub& frameStub); + + // ED input token of dtc stubs + EDGetTokenT edGetTokenTTDTC_; + // ED input token of stubs + EDGetTokenT edGetTokenAcceptedStubs_; + // ED input token of tracks + EDGetTokenT edGetTokenAcceptedTracks_; + // ED input token of lost stubs + EDGetTokenT edGetTokenLostStubs_; + // ED input token of lost tracks + EDGetTokenT edGetTokenLostTracks_; + // ED input token of TTStubRef to TPPtr association for tracking efficiency + EDGetTokenT edGetTokenSelection_; + // ED input token of TTStubRef to recontructable TPPtr association + EDGetTokenT edGetTokenReconstructable_; + // Setup token + ESGetToken esGetTokenSetup_; + // DataFormats token + ESGetToken esGetTokenDataFormats_; + // ChannelAssignment token + ESGetToken esGetTokenChannelAssignment_; + // stores, calculates and provides run-time constants + const Setup* setup_; + // + const Settings settings_; + // helper class to extract structured data from tt::Frames + const DataFormats* dataFormats_; + // helper class to assign tracklet track to channel + const ChannelAssignment* channelAssignment_; + // enables analyze of TPs + bool useMCTruth_; + // + int nEvents_; + // + vector> regionStubs_; + // + int region_; + // + vector nOverflows_; + + // Histograms + + TProfile* prof_; + TProfile* profChannel_; + TH1F* hisChannel_; + vector hisResolution_; + vector profResolution_; + vector hisResolutionMe_; + vector hisResolutionThey_; + vector his2Resolution_; + + // printout + stringstream log_; + }; + + AnalyzerTBout::AnalyzerTBout(const ParameterSet& iConfig) + : settings_(), useMCTruth_(iConfig.getParameter("UseMCTruth")), nEvents_(0) { + usesResource("TFileService"); + // book in- and output ED products + const InputTag& inputTag = iConfig.getParameter("InputTagDTC"); + const string& label = iConfig.getParameter("LabelTBout"); + const string& branchAcceptedStubs = iConfig.getParameter("BranchAcceptedStubs"); + const string& branchAcceptedTracks = iConfig.getParameter("BranchAcceptedTracks"); + const string& branchLostStubs = iConfig.getParameter("BranchLostStubs"); + const string& branchLostTracks = iConfig.getParameter("BranchLostTracks"); + edGetTokenTTDTC_ = consumes(inputTag); + edGetTokenAcceptedStubs_ = consumes(InputTag(label, branchAcceptedStubs)); + edGetTokenAcceptedTracks_ = consumes(InputTag(label, branchAcceptedTracks)); + edGetTokenLostStubs_ = consumes(InputTag(label, branchLostStubs)); + edGetTokenLostTracks_ = consumes(InputTag(label, branchLostTracks)); + if (useMCTruth_) { + const auto& inputTagSelecttion = iConfig.getParameter("InputTagSelection"); + const auto& inputTagReconstructable = iConfig.getParameter("InputTagReconstructable"); + edGetTokenSelection_ = consumes(inputTagSelecttion); + edGetTokenReconstructable_ = consumes(inputTagReconstructable); + } + // book ES products + esGetTokenSetup_ = esConsumes(); + esGetTokenDataFormats_ = esConsumes(); + esGetTokenChannelAssignment_ = esConsumes(); + // initial ES products + setup_ = nullptr; + dataFormats_ = nullptr; + channelAssignment_ = nullptr; + // + nOverflows_ = vector(2, 0); + // log config + log_.setf(ios::fixed, ios::floatfield); + log_.precision(4); + } + + void AnalyzerTBout::beginRun(const Run& iEvent, const EventSetup& iSetup) { + // helper class to store configurations + setup_ = &iSetup.getData(esGetTokenSetup_); + // helper class to extract structured data from tt::Frames + dataFormats_ = &iSetup.getData(esGetTokenDataFormats_); + // helper class to assign tracklet track to channel + channelAssignment_ = &iSetup.getData(esGetTokenChannelAssignment_); + // book histograms + Service fs; + TFileDirectory dir; + dir = fs->mkdir("TBout"); + prof_ = dir.make("Counts", ";", 9, 0.5, 9.5); + prof_->GetXaxis()->SetBinLabel(1, "Stubs"); + prof_->GetXaxis()->SetBinLabel(2, "Tracks"); + prof_->GetXaxis()->SetBinLabel(3, "Lost Tracks"); + prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks"); + prof_->GetXaxis()->SetBinLabel(5, "All Tracks"); + prof_->GetXaxis()->SetBinLabel(6, "Found TPs"); + prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs"); + prof_->GetXaxis()->SetBinLabel(8, "Lost TPs"); + prof_->GetXaxis()->SetBinLabel(9, "All TPs"); + // channel occupancy + constexpr int maxOcc = 180; + const int numChannels = channelAssignment_->numChannels() * setup_->numLayers() * setup_->numRegions(); + hisChannel_ = dir.make("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5); + profChannel_ = dir.make("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5); + // stub parameter resolutions + constexpr int bins = 400; + constexpr int binsHis = 100; + constexpr double maxZ = 300.; + constexpr double maxR = 120.; + constexpr array ranges{{.01, 5.}}; + hisResolution_.reserve(NumResolution); + profResolution_.reserve(NumResolution); + for (Resolution r : AllResolution) { + hisResolution_.emplace_back(dir.make(("HisRes" + name(r)).c_str(), ";", binsHis, -ranges[r], ranges[r])); + profResolution_.emplace_back( + dir.make(("ProfRes" + name(r)).c_str(), ";;", bins, -maxZ, maxZ, bins, 0., maxR)); + hisResolutionMe_.emplace_back(dir.make(("HisResMe" + name(r)).c_str(), ";", binsHis, -ranges[r], ranges[r])); + hisResolutionThey_.emplace_back(dir.make(("HisResThey" + name(r)).c_str(), ";", binsHis, -ranges[r], ranges[r])); + his2Resolution_.emplace_back(dir.make(("His2" + name(r)).c_str(), ";;", bins, -ranges[r], ranges[r], bins, -ranges[r], ranges[r])); + } + regionStubs_ = vector>(setup_->numRegions()); + } + + void AnalyzerTBout::analyze(const Event& iEvent, const EventSetup& iSetup) { + // read in TTDTC + Handle handleTTDTC; + iEvent.getByToken(edGetTokenTTDTC_, handleTTDTC); + const TTDTC& ttDTC = *handleTTDTC; + for (deque& region : regionStubs_) + region.clear(); + for (int r : ttDTC.tfpRegions()) { + for (int c : ttDTC.tfpChannels()) { + const StreamStub& s = ttDTC.stream(r, c); + copy_if(s.begin(), s.end(), back_inserter(regionStubs_[r]), [](const FrameStub& f){ return f.first.isNonnull(); }); + } + } + // read in TBout products + Handle handleAcceptedStubs; + iEvent.getByToken(edGetTokenAcceptedStubs_, handleAcceptedStubs); + const StreamsStub& acceptedStubs = *handleAcceptedStubs; + Handle handleAcceptedTracks; + iEvent.getByToken(edGetTokenAcceptedTracks_, handleAcceptedTracks); + const StreamsTrack& acceptedTracks = *handleAcceptedTracks; + Handle handleLostStubs; + iEvent.getByToken(edGetTokenLostStubs_, handleLostStubs); + const StreamsStub& lostStubs = *handleLostStubs; + Handle handleLostTracks; + iEvent.getByToken(edGetTokenLostTracks_, handleLostTracks); + const StreamsTrack& lostTracks = *handleLostTracks; + // read in MCTruth + const StubAssociation* selection = nullptr; + const StubAssociation* reconstructable = nullptr; + if (useMCTruth_) { + Handle handleSelection; + iEvent.getByToken(edGetTokenSelection_, handleSelection); + selection = handleSelection.product(); + prof_->Fill(9, selection->numTPs()); + Handle handleReconstructable; + iEvent.getByToken(edGetTokenReconstructable_, handleReconstructable); + reconstructable = handleReconstructable.product(); + } + // analyze ht products and associate found tracks with reconstrucable TrackingParticles + set tpPtrs; + set tpPtrsSelection; + set tpPtrsLost; + int allMatched(0); + int allTracks(0); + for (region_ = 0; region_ < setup_->numRegions(); region_++) { + const int offset = region_ * channelAssignment_->numChannels(); + int nStubs(0); + int nTracks(0); + int nLost(0); + for (int channel = 0; channel < channelAssignment_->numChannels(); channel++) { + vector> tracks; + formTracks(acceptedTracks, acceptedStubs, tracks, offset + channel); + vector> lost; + formTracks(lostTracks, lostStubs, lost, offset + channel); + nTracks += tracks.size(); + nStubs += accumulate(tracks.begin(), tracks.end(), 0, [](int& sum, const auto& v){ return sum += (int)v.size(); }); + nLost += lost.size(); + allTracks += tracks.size(); + if (!useMCTruth_) + continue; + int tmp(0); + associate(tracks, selection, tpPtrsSelection, tmp); + associate(lost, selection, tpPtrsLost, tmp); + associate(tracks, reconstructable, tpPtrs, allMatched); + } + prof_->Fill(1, nStubs); + prof_->Fill(2, nTracks); + prof_->Fill(3, nLost); + } + vector recovered; + recovered.reserve(tpPtrsLost.size()); + set_intersection(tpPtrsLost.begin(), tpPtrsLost.end(), tpPtrs.begin(), tpPtrs.end(), back_inserter(recovered)); + for (const TPPtr& tpPtr : recovered) + tpPtrsLost.erase(tpPtr); + prof_->Fill(4, allMatched); + prof_->Fill(5, allTracks); + prof_->Fill(6, tpPtrs.size()); + prof_->Fill(7, tpPtrsSelection.size()); + prof_->Fill(8, tpPtrsLost.size()); + nEvents_++; + } + + void AnalyzerTBout::endJob() { + if (nEvents_ == 0) + return; + // printout SF summary + const double totalTPs = prof_->GetBinContent(9); + const double numStubs = prof_->GetBinContent(1); + const double numTracks = prof_->GetBinContent(2); + const double numTracksLost = prof_->GetBinContent(3); + const double totalTracks = prof_->GetBinContent(5); + const double numTracksMatched = prof_->GetBinContent(4); + const double numTPsAll = prof_->GetBinContent(6); + const double numTPsEff = prof_->GetBinContent(7); + const double numTPsLost = prof_->GetBinContent(8); + const double errStubs = prof_->GetBinError(1); + const double errTracks = prof_->GetBinError(2); + const double errTracksLost = prof_->GetBinError(3); + const double fracFake = (totalTracks - numTracksMatched) / totalTracks; + const double fracDup = (numTracksMatched - numTPsAll) / totalTracks; + const double eff = numTPsEff / totalTPs; + const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_); + const double effLoss = numTPsLost / totalTPs; + const double errEffLoss = sqrt(effLoss * (1. - effLoss) / totalTPs / nEvents_); + const vector nums = {numStubs, numTracks, numTracksLost}; + const vector errs = {errStubs, errTracks, errTracksLost}; + const int wNums = ceil(log10(*max_element(nums.begin(), nums.end()))) + 5; + const int wErrs = ceil(log10(*max_element(errs.begin(), errs.end()))) + 5; + log_ << " TBout SUMMARY " << endl; + log_ << "number of stubs per TFP = " << setw(wNums) << numStubs << " +- " << setw(wErrs) << errStubs << endl; + log_ << "number of tracks per TFP = " << setw(wNums) << numTracks << " +- " << setw(wErrs) << errTracks + << endl; + log_ << "number of lost tracks per TFP = " << setw(wNums) << numTracksLost << " +- " << setw(wErrs) << errTracksLost + << endl; + log_ << " max tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl; + log_ << " lost tracking efficiency = " << setw(wNums) << effLoss << " +- " << setw(wErrs) << errEffLoss << endl; + log_ << " fake rate = " << setw(wNums) << fracFake << endl; + log_ << " duplicate rate = " << setw(wNums) << fracDup << endl; + log_ << "number of overflowed rz residuals: " << nOverflows_[0] << " and phi: " << nOverflows_[1] << endl; + log_ << "============================================================="; + LogPrint("L1Trigger/TrackerTFP") << log_.str(); + } + + // + void AnalyzerTBout::formTracks(const StreamsTrack& streamsTrack, + const StreamsStub& streamsStubs, + vector>& tracks, + int channel) { + const int offset = channel * channelAssignment_->maxNumProjectionLayers(); + const StreamTrack& streamTrack = streamsTrack[channel]; + const int numTracks = accumulate(streamTrack.begin(), streamTrack.end(), 0, [](int& sum, const FrameTrack& frame) { + return sum += (frame.first.isNonnull() ? 1 : 0); + }); + tracks.reserve(numTracks); + for (int frame = 0; frame < (int)streamTrack.size(); frame++) { + const FrameTrack& frameTrack = streamTrack[frame]; + if (frameTrack.first.isNull()) + continue; + for (int layer = 0; layer < channelAssignment_->maxNumProjectionLayers(); layer++) { + const FrameStub& stub = streamsStubs[offset + layer][frame]; + if (stub.first.isNonnull()) + this->fill(frameTrack, stub); + } + tracks.push_back(frameTrack.first->getStubRefs()); + } + } + + // + void AnalyzerTBout::associate(const vector>& tracks, + const StubAssociation* ass, + set& tps, + int& sum) const { + for (const vector& ttStubRefs : tracks) { + const vector& tpPtrs = ass->associate(ttStubRefs); + if (tpPtrs.empty()) + continue; + sum++; + copy(tpPtrs.begin(), tpPtrs.end(), inserter(tps, tps.begin())); + } + } + + // + void AnalyzerTBout::fill(const FrameTrack& frameTrack, const FrameStub& frameStub) { + // get dtc stub frame + const deque& region = regionStubs_[region_]; + const auto it = find_if(region.begin(), region.end(), [&frameStub](const FrameStub& f){ return f.first == frameStub.first; }); + if (it == region.end()) + throw cms::Exception("LgociError.") << "Stub on track was not in DTC collection."; + const GlobalPoint ttPos = setup_->stubPos(frameStub.first); + const GlobalPoint pos = setup_->stubPos(true, *it, region_); + static constexpr int widthPhi = 12; + static constexpr int widthZ = 9; + static constexpr int widthR = 7; + const bool barrel = setup_->barrel(frameStub.first); + const int layerIdTracklet = channelAssignment_->trackletLayerId(frameStub.first); + static const double baseR = settings_.kz(); + const double basePhi = barrel ? settings_.kphi1() : settings_.kphi(layerIdTracklet); + const double baseZ = settings_.kz(layerIdTracklet); + static const double baseInvR = settings_.kphi1() / settings_.kr() * pow(2, settings_.rinv_shift()); + static const double basePhi0 = settings_.kphi1() * pow(2, settings_.phi0_shift()); + static const double baseZ0 = settings_.kz() * pow(2, settings_.z0_shift()); + static const double baseTanL = settings_.kz() / settings_.kr() * pow(2, settings_.t_shift()); + const int widthRZ = barrel ? widthZ : widthR; + const double baseRZ = barrel ? baseZ : baseR; + // calc residuals + const double rInv = (frameTrack.first->rInv() / baseInvR + .5) * baseInvR; + const double phi0 = (frameTrack.first->phi() / basePhi0 + .5) * basePhi0; + const double z0 = (frameTrack.first->z0() / baseZ0 + .5) * baseZ0; + const double tanL = (frameTrack.first->tanL() / baseTanL + .5) * baseTanL; + const double phi = deltaPhi(pos.phi() - (phi0 - rInv * pos.perp() / 2.)); + const double r = pos.perp() - (pos.z() - z0) / tanL; + const double z = pos.z() - (z0 + tanL * pos.perp()); + const double rz = barrel ? z : r; + const int phii = floor(phi / basePhi); + const int rzi = floor(rz / baseRZ); + const double phid = (phii + .5) * basePhi; + const double rzd = (rzi + .5) * baseRZ; + // parse residuals + TTBV hw(frameStub.second); + const TTBV hwRZ(hw, widthRZ, 0, true); + hw >>= widthRZ; + const TTBV hwPhi(hw, widthPhi, 0, true); + bool overflowPhi = abs(phii - hwPhi.val()) > pow(2, widthPhi) * 7. / 8.; + bool overflowZ = abs(rzi - hwRZ.val()) > pow(2, widthRZ) * 7. / 8.; + const double hwPhid = hwPhi.val(basePhi); + const double hwRZd = hwRZ.val(baseRZ); + const vector resolutions = {phid - hwPhid, rzd - hwRZd}; + const vector overflows = {overflowPhi, overflowZ}; + for (Resolution r : AllResolution) { + if (overflows[r]) { + nOverflows_[r]++; + continue; + } + hisResolution_[r]->Fill(resolutions[r]); + profResolution_[r]->Fill(ttPos.z(), ttPos.perp(), abs(resolutions[r])); + } + hisResolutionMe_[0]->Fill(phid); + hisResolutionMe_[1]->Fill(rzd); + hisResolutionThey_[0]->Fill(hwPhid); + hisResolutionThey_[1]->Fill(hwRZd); + his2Resolution_[0]->Fill(phid, hwPhid); + his2Resolution_[1]->Fill(rzd, hwRZd); + } + +} // namespace trklet + +DEFINE_FWK_MODULE(trklet::AnalyzerTBout); \ No newline at end of file diff --git a/L1Trigger/TrackFindingTracklet/test/HybridTracksNewKF_cfg.py b/L1Trigger/TrackFindingTracklet/test/HybridTracksNewKF_cfg.py index fb17bddfda786..ce7ee30ba8102 100644 --- a/L1Trigger/TrackFindingTracklet/test/HybridTracksNewKF_cfg.py +++ b/L1Trigger/TrackFindingTracklet/test/HybridTracksNewKF_cfg.py @@ -51,7 +51,8 @@ process.kf = cms.Sequence( process.TrackFindingTrackletProducerKF + process.TrackFindingTrackletAnalyzerKF ) process.TTTracks = cms.Sequence( process.TrackFindingTrackletProducerTT + process.TrackFindingTrackletProducerAS + process.TrackTriggerAssociatorTracks ) process.interOut = cms.Sequence( process.TrackFindingTrackletProducerKFout + process.TrackFindingTrackletAnalyzerKFout ) -process.tt = cms.Path( process.mc + process.dtc + process.tracklet + process.interIn + process.kf + process.TTTracks + process.interOut ) +process.TBout = cms.Sequence( process.TrackFindingTrackletProducerTBout + process.TrackFindingTrackletAnalyzerTBout ) +process.tt = cms.Path( process.mc + process.dtc + process.tracklet + process.TBout + process.interIn + process.kf + process.TTTracks + process.interOut ) process.schedule = cms.Schedule( process.tt ) # create options diff --git a/L1Trigger/TrackFindingTracklet/test/ProducerTBout.cc b/L1Trigger/TrackFindingTracklet/test/ProducerTBout.cc index 3ab9a2b660225..39bbbc2c0d777 100644 --- a/L1Trigger/TrackFindingTracklet/test/ProducerTBout.cc +++ b/L1Trigger/TrackFindingTracklet/test/ProducerTBout.cc @@ -194,4 +194,4 @@ namespace trklet { } // namespace trklet -DEFINE_FWK_MODULE(trklet::ProducerTBout); \ No newline at end of file +DEFINE_FWK_MODULE(trklet::ProducerTBout); diff --git a/L1Trigger/TrackTrigger/interface/Setup.h b/L1Trigger/TrackTrigger/interface/Setup.h index 1ac6ae9917cf2..00acf9fc705ce 100644 --- a/L1Trigger/TrackTrigger/interface/Setup.h +++ b/L1Trigger/TrackTrigger/interface/Setup.h @@ -79,10 +79,10 @@ namespace tt { const TrackerGeometry* trackerGeometry() const { return trackerGeometry_; } // TrackerTopology const TrackerTopology* trackerTopology() const { return trackerTopology_; } - // returns bit accurate position of a stub from a given tfp identifier region [0-8] channel [0-47] - GlobalPoint stubPos(bool hybrid, const tt::FrameStub& frame, int tfpRegion, int tfpChannel) const; // returns global TTStub position GlobalPoint stubPos(const TTStubRef& ttStubRef) const; + // returns bit accurate position of a stub from a given tfp region [0-8] + GlobalPoint stubPos(bool hybrid, const tt::FrameStub& frame, int region) const; // empty trackerDTC EDProduct TTDTC ttDTC() const { return TTDTC(numRegions_, numOverlappingRegions_, numDTCsPerRegion_); } // checks if stub collection is considered forming a reconstructable track diff --git a/L1Trigger/TrackTrigger/src/Setup.cc b/L1Trigger/TrackTrigger/src/Setup.cc index d50151c149ac1..5187adc7285c8 100644 --- a/L1Trigger/TrackTrigger/src/Setup.cc +++ b/L1Trigger/TrackTrigger/src/Setup.cc @@ -714,20 +714,20 @@ namespace tt { kfWidthLayerCount_ = ceil(log2(zhtMaxStubsPerLayer_)); } - // returns bit accurate position of a stub from a given tfp identifier region [0-8] channel [0-47] - GlobalPoint Setup::stubPos(bool hybrid, const FrameStub& frame, int tfpRegion, int tfpChannel) const { + // returns bit accurate position of a stub from a given tfp region [0-8] + GlobalPoint Setup::stubPos(bool hybrid, const FrameStub& frame, int region) const { GlobalPoint p; if (frame.first.isNull()) return p; TTBV bv(frame.second); if (hybrid) { const DetId& detId = frame.first->getDetId(); - const int dtcId = Setup::dtcId(tfpRegion, tfpChannel); - const bool barrel = detId.subdetId() == StripSubdetector::TOB; - const bool psModule = Setup::psModule(dtcId); + const bool barrel = this->barrel(frame.first); const int layerId = (barrel ? trackerTopology_->layer(detId) : trackerTopology_->tidWheel(detId)) - offsetLayerId_; - const bool side = Setup::side(dtcId); + const bool psModule = this->psModule(frame.first); + const GlobalPoint gp = this->stubPos(frame.first); + const bool side = gp.z() > 0.; SensorModule::Type type; if (barrel && psModule) type = SensorModule::BarrelPS; @@ -747,17 +747,17 @@ namespace tt { const double baseR = hybridBasesR_.at(type); // parse bit vector bv >>= 1 + hybridWidthLayerId_ + widthBend + widthAlpha; - double phi = (bv.val(widthPhi) + .5) * basePhi - hybridRangePhi_ / 2.; + double phi = bv.val(basePhi, widthPhi) - hybridRangePhi_ / 2.; bv >>= widthPhi; - double z = (bv.val(widthZ, 0, true) + .5) * baseZ; + double z = bv.val(baseZ, widthZ, 0, true); bv >>= widthZ; - double r = (bv.val(widthR, 0, barrel) + .5) * baseR; + double r = bv.val(baseR, widthR, 0, barrel); if (barrel) { r += hybridLayerRs_.at(layerId); } else { z += hybridDiskZs_.at(layerId) * (side ? 1. : -1.); } - phi = deltaPhi(phi + tfpRegion * baseRegion_); + phi = deltaPhi(phi + region * baseRegion_); if (type == SensorModule::Disk2S) { r = bv.val(widthR); r = disk2SRs_.at(layerId).at((int)r); @@ -772,7 +772,7 @@ namespace tt { double r = (bv.val(tmttWidthR_, 0, true) + .5) * tmttBaseR_; bv >>= tmttWidthR_; r = r + chosenRofPhi_; - phi = deltaPhi(phi + tfpRegion * baseRegion_); + phi = deltaPhi(phi + region * baseRegion_); p = GlobalPoint(GlobalPoint::Cylindrical(r, phi, z)); } return p; diff --git a/L1Trigger/TrackerDTC/test/Analyzer.cc b/L1Trigger/TrackerDTC/test/Analyzer.cc index 494ea1948058b..59251f4819114 100644 --- a/L1Trigger/TrackerDTC/test/Analyzer.cc +++ b/L1Trigger/TrackerDTC/test/Analyzer.cc @@ -371,7 +371,7 @@ namespace trackerDTC { if (frame.first.isNull()) continue; sum++; - const GlobalPoint& pos = setup_->stubPos(hybrid_, frame, region, channel); + const GlobalPoint& pos = setup_->stubPos(hybrid_, frame, region); const GlobalPoint& ttPos = setup_->stubPos(frame.first); const vector resolutions = { ttPos.perp() - pos.perp(), deltaPhi(ttPos.phi() - pos.phi()), ttPos.z() - pos.z()}; From 9d42132fa6531142a7b749707a625eaf58274be4 Mon Sep 17 00:00:00 2001 From: Thomas Schuh Date: Wed, 23 Feb 2022 16:04:27 +0000 Subject: [PATCH 2/4] one merge error fixed, but a problem remains --- .../TrackFindingTracklet/python/Analyzer_cff.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py b/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py index a46c58947d04b..5fd6ea8441bbe 100644 --- a/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py +++ b/L1Trigger/TrackFindingTracklet/python/Analyzer_cff.py @@ -3,9 +3,9 @@ from L1Trigger.TrackFindingTracklet.Analyzer_cfi import TrackFindingTrackletAnalyzer_params from L1Trigger.TrackFindingTracklet.Producer_cfi import TrackFindingTrackletProducer_params -TrackFindingTrackletAnalyzerTBout = cms.EDAnalyzer( 'trklet::AnalyzerTBout', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducerKF_params ) -TrackFindingTrackletAnalyzerTracklet = cms.EDAnalyzer( 'trklet::AnalyzerTracklet', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducerKF_params ) -TrackFindingTrackletAnalyzerKFin = cms.EDAnalyzer( 'trklet::AnalyzerKFin', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducerKF_params ) -TrackFindingTrackletAnalyzerKF = cms.EDAnalyzer( 'trackerTFP::AnalyzerKF', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducerKF_params ) -TrackFindingTrackletAnalyzerKFout = cms.EDAnalyzer( 'trklet::AnalyzerKFout', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducerKF_params ) -TrackFindingTrackletAnalyzerTT = cms.EDAnalyzer( 'trklet::AnalyzerTT', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducerKF_params ) +TrackFindingTrackletAnalyzerTBout = cms.EDAnalyzer( 'trklet::AnalyzerTBout', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) +TrackFindingTrackletAnalyzerTracklet = cms.EDAnalyzer( 'trklet::AnalyzerTracklet', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) +TrackFindingTrackletAnalyzerKFin = cms.EDAnalyzer( 'trklet::AnalyzerKFin', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) +TrackFindingTrackletAnalyzerKF = cms.EDAnalyzer( 'trackerTFP::AnalyzerKF', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) +TrackFindingTrackletAnalyzerKFout = cms.EDAnalyzer( 'trklet::AnalyzerKFout', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) +TrackFindingTrackletAnalyzerTT = cms.EDAnalyzer( 'trklet::AnalyzerTT', TrackFindingTrackletAnalyzer_params, TrackFindingTrackletProducer_params ) From 883a479d8361fd1de0cd6a86a98a45c8de582e7d Mon Sep 17 00:00:00 2001 From: Thomas Schuh Date: Wed, 23 Feb 2022 16:13:07 +0000 Subject: [PATCH 3/4] fixed second error. --- L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc b/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc index b2d0660ce1979..f998ba0616b9b 100644 --- a/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc +++ b/L1Trigger/TrackFindingTracklet/plugins/L1FPGATrackProducer.cc @@ -231,10 +231,6 @@ L1FPGATrackProducer::L1FPGATrackProducer(edm::ParameterSet const& iConfig) } produces>>("Level1TTTracks").setBranchAlias("Level1TTTracks"); - // book ED output token for clock and bit accurate TrackBuilder tracks - edPutTokenTracks_ = produces("Level1TTTracks"); - // book ED output token for clock and bit accurate TrackBuilder stubs - edPutTokenStubs_ = produces("Level1TTTracks"); asciiEventOutName_ = iConfig.getUntrackedParameter("asciiFileName", ""); From db4dc5599ae7558e5864c10561a09dbe63fc6d68 Mon Sep 17 00:00:00 2001 From: Ian Tomalin Date: Thu, 24 Feb 2022 00:24:21 +0000 Subject: [PATCH 4/4] Update AnalyzerTBout.cc --- L1Trigger/TrackFindingTracklet/test/AnalyzerTBout.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/L1Trigger/TrackFindingTracklet/test/AnalyzerTBout.cc b/L1Trigger/TrackFindingTracklet/test/AnalyzerTBout.cc index d26fd5a1664e8..182d27714c96a 100644 --- a/L1Trigger/TrackFindingTracklet/test/AnalyzerTBout.cc +++ b/L1Trigger/TrackFindingTracklet/test/AnalyzerTBout.cc @@ -44,7 +44,7 @@ namespace trklet { inline string name(Resolution r) { return string(*(NameResolution.begin() + r)); } /*! \class trklet::AnalyzerTBout - * \brief Class to analyze hardware like structured TTStub Collection generated by Tracklet + * \brief Class to analyze the hardware-like-structured TTStub Collection generated by Tracklet's TrackBuilder stage. * \author Thomas Schuh * \date 2021, Nov */ @@ -429,4 +429,4 @@ namespace trklet { } // namespace trklet -DEFINE_FWK_MODULE(trklet::AnalyzerTBout); \ No newline at end of file +DEFINE_FWK_MODULE(trklet::AnalyzerTBout);