File indexing completed on 2025-06-03 00:12:18
0001 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0002 #include "FWCore/Framework/interface/Run.h"
0003 #include "FWCore/Framework/interface/Event.h"
0004 #include "FWCore/Framework/interface/EventSetup.h"
0005 #include "FWCore/Framework/interface/MakerMacros.h"
0006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0007 #include "FWCore/ServiceRegistry/interface/Service.h"
0008 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0009 #include "FWCore/Utilities/interface/EDGetToken.h"
0010 #include "FWCore/Utilities/interface/InputTag.h"
0011 #include "FWCore/Utilities/interface/Exception.h"
0012 #include "CommonTools/UtilAlgos/interface/TFileService.h"
0013 #include "DataFormats/Common/interface/Handle.h"
0014
0015 #include "SimTracker/TrackTriggerAssociation/interface/StubAssociation.h"
0016 #include "L1Trigger/TrackTrigger/interface/Setup.h"
0017 #include "L1Trigger/TrackerTFP/interface/DataFormats.h"
0018
0019 #include <TProfile.h>
0020 #include <TH1F.h>
0021 #include <TEfficiency.h>
0022
0023 #include <vector>
0024 #include <deque>
0025 #include <set>
0026 #include <cmath>
0027 #include <numeric>
0028 #include <sstream>
0029
0030 namespace trackerTFP {
0031
0032
0033
0034
0035
0036
0037 class AnalyzerCTB : public edm::one::EDAnalyzer<edm::one::WatchRuns, edm::one::SharedResources> {
0038 public:
0039 AnalyzerCTB(const edm::ParameterSet& iConfig);
0040 void beginJob() override {}
0041 void beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override;
0042 void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override;
0043 void endRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override {}
0044 void endJob() override;
0045
0046 private:
0047
0048 void formTracks(const tt::StreamsTrack& streamsTrack,
0049 const tt::StreamsStub& streamsStubs,
0050 std::vector<std::vector<TTStubRef>>& tracks,
0051 int channel) const;
0052
0053 void associate(const std::vector<std::vector<TTStubRef>>& tracks,
0054 const tt::StubAssociation* ass,
0055 std::set<TPPtr>& tps,
0056 int& sum) const;
0057
0058 edm::EDGetTokenT<tt::StreamsStub> edGetTokenStubs_;
0059
0060 edm::EDGetTokenT<tt::StreamsTrack> edGetTokenTracks_;
0061
0062 edm::EDGetTokenT<tt::StubAssociation> edGetTokenSelection_;
0063
0064 edm::EDGetTokenT<tt::StubAssociation> edGetTokenReconstructable_;
0065
0066 edm::ESGetToken<tt::Setup, tt::SetupRcd> esGetTokenSetup_;
0067
0068 edm::ESGetToken<DataFormats, DataFormatsRcd> esGetTokenDataFormats_;
0069
0070 const tt::Setup* setup_ = nullptr;
0071
0072 const DataFormats* dataFormats_ = nullptr;
0073
0074 bool useMCTruth_;
0075
0076 int nEvents_ = 0;
0077
0078
0079
0080 TProfile* prof_;
0081 TProfile* profChan_;
0082 TProfile* profStubs_;
0083 TProfile* profTracks_;
0084 TH1F* hisChan_;
0085 TH1F* hisStubs_;
0086 TH1F* hisTracks_;
0087 TH1F* hisLayers_;
0088 TH1F* hisNumLayers_;
0089 TProfile* profNumLayers_;
0090 TH1F* hisEffZT_;
0091 TH1F* hisEffZTTotal_;
0092 TEfficiency* effZT_;
0093 TH1F* hisEffInv2R_;
0094 TH1F* hisEffInv2RTotal_;
0095 TEfficiency* effInv2R_;
0096
0097
0098 std::stringstream log_;
0099 };
0100
0101 AnalyzerCTB::AnalyzerCTB(const edm::ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter<bool>("UseMCTruth")) {
0102 usesResource("TFileService");
0103
0104 const std::string& label = iConfig.getParameter<std::string>("OutputLabelCTB");
0105 const std::string& branchStubs = iConfig.getParameter<std::string>("BranchStubs");
0106 const std::string& branchTracks = iConfig.getParameter<std::string>("BranchTracks");
0107 edGetTokenStubs_ = consumes<tt::StreamsStub>(edm::InputTag(label, branchStubs));
0108 edGetTokenTracks_ = consumes<tt::StreamsTrack>(edm::InputTag(label, branchTracks));
0109 if (useMCTruth_) {
0110 const auto& inputTagSelecttion = iConfig.getParameter<edm::InputTag>("InputTagSelection");
0111 const auto& inputTagReconstructable = iConfig.getParameter<edm::InputTag>("InputTagReconstructable");
0112 edGetTokenSelection_ = consumes<tt::StubAssociation>(inputTagSelecttion);
0113 edGetTokenReconstructable_ = consumes<tt::StubAssociation>(inputTagReconstructable);
0114 }
0115
0116 esGetTokenSetup_ = esConsumes<edm::Transition::BeginRun>();
0117 esGetTokenDataFormats_ = esConsumes<edm::Transition::BeginRun>();
0118
0119 log_.setf(std::ios::fixed, std::ios::floatfield);
0120 log_.precision(4);
0121 }
0122
0123 void AnalyzerCTB::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) {
0124
0125 setup_ = &iSetup.getData(esGetTokenSetup_);
0126
0127 dataFormats_ = &iSetup.getData(esGetTokenDataFormats_);
0128
0129 edm::Service<TFileService> fs;
0130 TFileDirectory dir;
0131 dir = fs->mkdir("CTB");
0132 prof_ = dir.make<TProfile>("Counts", ";", 9, 0.5, 9.5);
0133 prof_->GetXaxis()->SetBinLabel(1, "Stubs");
0134 prof_->GetXaxis()->SetBinLabel(2, "Tracks");
0135 prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks");
0136 prof_->GetXaxis()->SetBinLabel(5, "All Tracks");
0137 prof_->GetXaxis()->SetBinLabel(6, "Found TPs");
0138 prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs");
0139 prof_->GetXaxis()->SetBinLabel(9, "All TPs");
0140
0141 constexpr int maxOcc = 180;
0142 const int numChannelsTracks = dataFormats_->numChannel(Process::ctb);
0143 const int numChannelsStubs = numChannelsTracks * setup_->numLayers();
0144 hisChan_ = dir.make<TH1F>("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5);
0145 profChan_ = dir.make<TProfile>("Prof Channel Occupancy", ";", numChannelsTracks, -.5, numChannelsTracks - .5);
0146
0147 hisStubs_ = dir.make<TH1F>("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5);
0148 profStubs_ = dir.make<TProfile>("Prof Channel Occupancy", ";", numChannelsStubs, -.5, numChannelsStubs - .5);
0149
0150 hisTracks_ = dir.make<TH1F>("His Track Occupancy", ";", maxOcc, -.5, maxOcc - .5);
0151 profTracks_ = dir.make<TProfile>("Prof Track Occupancy", ";", numChannelsTracks, -.5, numChannelsTracks - .5);
0152
0153 hisLayers_ = dir.make<TH1F>("HisLayers", ";", 8, 0, 8);
0154 hisNumLayers_ = dir.make<TH1F>("HisNumLayers", ";", 9, 0, 9);
0155 profNumLayers_ = dir.make<TProfile>("Prof NumLayers", ";", 32, 0, 2.4);
0156
0157 const double rangeZT = dataFormats_->format(Variable::zT, Process::dr).range();
0158 const int zTBins = setup_->gpNumBinsZT();
0159 hisEffZTTotal_ = dir.make<TH1F>("HisTPZTTotal", ";", zTBins, -rangeZT / 2, rangeZT / 2);
0160 hisEffZT_ = dir.make<TH1F>("HisTPZT", ";", zTBins, -rangeZT / 2, rangeZT / 2);
0161 effZT_ = dir.make<TEfficiency>("EffZT", ";", zTBins, -rangeZT / 2, rangeZT / 2);
0162 const double rangeInv2R = dataFormats_->format(Variable::inv2R, Process::dr).range();
0163 const int inv2RBins = (setup_->htNumBinsInv2R() + 2) * 2;
0164 hisEffInv2R_ = dir.make<TH1F>("HisTPInv2R", ";", inv2RBins, -rangeInv2R / 2., rangeInv2R / 2.);
0165 hisEffInv2RTotal_ = dir.make<TH1F>("HisTPInv2RTotal", ";", inv2RBins, -rangeInv2R / 2., rangeInv2R / 2.);
0166 effInv2R_ = dir.make<TEfficiency>("EffInv2R", ";", inv2RBins, -rangeInv2R / 2., rangeInv2R / 2.);
0167 }
0168
0169 void AnalyzerCTB::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0170 auto fill = [this](const TPPtr& tpPtr, TH1F* hisZT, TH1F* hisInv2R) {
0171 const double tpPhi0 = tpPtr->phi();
0172 const double tpCot = sinh(tpPtr->eta());
0173 const math::XYZPointD& v = tpPtr->vertex();
0174 const double tpZ0 = v.z() - tpCot * (v.x() * cos(tpPhi0) + v.y() * sin(tpPhi0));
0175 const double tpZT = tpZ0 + tpCot * setup_->chosenRofZ();
0176 const double tpInv2R = tpPtr->charge() / tpPtr->pt() * setup_->invPtToDphi();
0177 hisZT->Fill(tpZT);
0178 hisInv2R->Fill(tpInv2R);
0179 };
0180
0181 edm::Handle<tt::StreamsStub> handleStubs;
0182 iEvent.getByToken<tt::StreamsStub>(edGetTokenStubs_, handleStubs);
0183 const tt::StreamsStub& acceptedStubs = *handleStubs;
0184 edm::Handle<tt::StreamsTrack> handleTracks;
0185 iEvent.getByToken<tt::StreamsTrack>(edGetTokenTracks_, handleTracks);
0186 const tt::StreamsTrack& acceptedTracks = *handleTracks;
0187
0188 const tt::StubAssociation* selection = nullptr;
0189 const tt::StubAssociation* reconstructable = nullptr;
0190 if (useMCTruth_) {
0191 edm::Handle<tt::StubAssociation> handleSelection;
0192 iEvent.getByToken<tt::StubAssociation>(edGetTokenSelection_, handleSelection);
0193 selection = handleSelection.product();
0194 prof_->Fill(9, selection->numTPs());
0195 edm::Handle<tt::StubAssociation> handleReconstructable;
0196 iEvent.getByToken<tt::StubAssociation>(edGetTokenReconstructable_, handleReconstructable);
0197 reconstructable = handleReconstructable.product();
0198 for (const auto& p : selection->getTrackingParticleToTTStubsMap())
0199 fill(p.first, hisEffZTTotal_, hisEffInv2RTotal_);
0200 }
0201
0202 std::set<TPPtr> tpPtrs;
0203 std::set<TPPtr> tpPtrsSelection;
0204 int allMatched(0);
0205 int allTracks(0);
0206 for (int region = 0; region < setup_->numRegions(); region++) {
0207 const int offsetTrack = region * dataFormats_->numChannel(Process::ctb);
0208 int nStubs(0);
0209 int nTracks(0);
0210 for (int channel = 0; channel < dataFormats_->numChannel(Process::ctb); channel++) {
0211 const int indexTrack = offsetTrack + channel;
0212 const int size = acceptedTracks[indexTrack].size();
0213 hisChan_->Fill(size);
0214 profChan_->Fill(channel, size);
0215 const int offsetStub = indexTrack * setup_->numLayers();
0216 for (int layer = 0; layer < setup_->numLayers(); layer++) {
0217 const tt::StreamStub& stream = acceptedStubs[offsetStub + layer];
0218 const int nStubs = std::accumulate(stream.begin(), stream.end(), 0, [](int sum, const tt::FrameStub& frame) {
0219 return sum + (frame.first.isNonnull() ? 1 : 0);
0220 });
0221 hisStubs_->Fill(nStubs);
0222 profStubs_->Fill(channel * setup_->numLayers() + layer, nStubs);
0223 }
0224 std::vector<std::vector<TTStubRef>> tracks;
0225 formTracks(acceptedTracks, acceptedStubs, tracks, indexTrack);
0226 hisTracks_->Fill(tracks.size());
0227 profTracks_->Fill(channel, tracks.size());
0228 nTracks += tracks.size();
0229 nStubs += std::accumulate(tracks.begin(), tracks.end(), 0, [](int sum, const std::vector<TTStubRef>& track) {
0230 return sum + track.size();
0231 });
0232 allTracks += tracks.size();
0233 if (!useMCTruth_)
0234 continue;
0235 int tmp(0);
0236 associate(tracks, selection, tpPtrsSelection, tmp);
0237 associate(tracks, reconstructable, tpPtrs, allMatched);
0238 }
0239 prof_->Fill(1, nStubs);
0240 prof_->Fill(2, nTracks);
0241 }
0242 for (const TPPtr& tpPtr : tpPtrsSelection)
0243 fill(tpPtr, hisEffZT_, hisEffInv2R_);
0244 prof_->Fill(4, allMatched);
0245 prof_->Fill(5, allTracks);
0246 prof_->Fill(6, tpPtrs.size());
0247 prof_->Fill(7, tpPtrsSelection.size());
0248 nEvents_++;
0249 }
0250
0251 void AnalyzerCTB::endJob() {
0252 if (nEvents_ == 0)
0253 return;
0254
0255 effZT_->SetPassedHistogram(*hisEffZT_, "f");
0256 effZT_->SetTotalHistogram(*hisEffZTTotal_, "f");
0257 effInv2R_->SetPassedHistogram(*hisEffInv2R_, "f");
0258 effInv2R_->SetTotalHistogram(*hisEffInv2RTotal_, "f");
0259
0260 const double totalTPs = prof_->GetBinContent(9);
0261 const double numStubs = prof_->GetBinContent(1);
0262 const double numTracks = prof_->GetBinContent(2);
0263 const double totalTracks = prof_->GetBinContent(5);
0264 const double numTracksMatched = prof_->GetBinContent(4);
0265 const double numTPsAll = prof_->GetBinContent(6);
0266 const double numTPsEff = prof_->GetBinContent(7);
0267 const double errStubs = prof_->GetBinError(1);
0268 const double errTracks = prof_->GetBinError(2);
0269 const double fracFake = (totalTracks - numTracksMatched) / totalTracks;
0270 const double fracDup = (numTracksMatched - numTPsAll) / totalTracks;
0271 const double eff = numTPsEff / totalTPs;
0272 const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_);
0273 const std::vector<double> nums = {numStubs, numTracks};
0274 const std::vector<double> errs = {errStubs, errTracks};
0275 const int wNums = std::ceil(std::log10(*std::max_element(nums.begin(), nums.end()))) + 5;
0276 const int wErrs = std::ceil(std::log10(*std::max_element(errs.begin(), errs.end()))) + 5;
0277 log_ << " CTB SUMMARY " << std::endl;
0278 log_ << "number of stubs per TFP = " << std::setw(wNums) << numStubs << " +- " << std::setw(wErrs) << errStubs
0279 << std::endl;
0280 log_ << "number of tracks per TFP = " << std::setw(wNums) << numTracks << " +- " << std::setw(wErrs)
0281 << errTracks << std::endl;
0282 log_ << " max tracking efficiency = " << std::setw(wNums) << eff << " +- " << std::setw(wErrs) << errEff
0283 << std::endl;
0284 log_ << " fake rate = " << std::setw(wNums) << fracFake << std::endl;
0285 log_ << " duplicate rate = " << std::setw(wNums) << fracDup << std::endl;
0286 log_ << "=============================================================";
0287 edm::LogPrint(moduleDescription().moduleName()) << log_.str();
0288 }
0289
0290
0291 void AnalyzerCTB::formTracks(const tt::StreamsTrack& streamsTrack,
0292 const tt::StreamsStub& streamsStubs,
0293 std::vector<std::vector<TTStubRef>>& tracks,
0294 int channel) const {
0295 const int offset = channel * setup_->numLayers();
0296 const tt::StreamTrack& streamTrack = streamsTrack[channel];
0297 const int numTracks =
0298 std::accumulate(streamTrack.begin(), streamTrack.end(), 0, [](int sum, const tt::FrameTrack& frame) {
0299 return sum + (frame.first.isNonnull() ? 1 : 0);
0300 });
0301 tracks.reserve(numTracks);
0302 for (int frame = 0; frame < static_cast<int>(streamTrack.size()); frame++) {
0303 const tt::FrameTrack& frameTrack = streamTrack[frame];
0304 if (frameTrack.first.isNull())
0305 continue;
0306 const auto end = std::find_if(std::next(streamTrack.begin(), frame + 1),
0307 streamTrack.end(),
0308 [](const tt::FrameTrack& frame) { return frame.first.isNonnull(); });
0309 const int size = std::distance(std::next(streamTrack.begin(), frame), end);
0310 int numStubs(0);
0311 for (int layer = 0; layer < setup_->numLayers(); layer++) {
0312 const tt::StreamStub& stream = streamsStubs[offset + layer];
0313 numStubs += std::accumulate(
0314 stream.begin() + frame, stream.begin() + frame + size, 0, [](int sum, const tt::FrameStub& frame) {
0315 return sum + (frame.first.isNonnull() ? 1 : 0);
0316 });
0317 }
0318 std::vector<TTStubRef> stubs;
0319 stubs.reserve(numStubs);
0320 int numLayers(0);
0321 for (int layer = 0; layer < setup_->numLayers(); layer++) {
0322 bool any(false);
0323 for (int f = frame; f < frame + size; f++) {
0324 const tt::FrameStub& stub = streamsStubs[offset + layer][f];
0325 if (stub.first.isNonnull()) {
0326 any = true;
0327 stubs.push_back(stub.first);
0328 }
0329 }
0330 if (any) {
0331 hisLayers_->Fill(layer);
0332 numLayers++;
0333 }
0334 }
0335 const double cot = TrackCTB(frameTrack, dataFormats_).zT() / setup_->chosenRofZ();
0336 hisNumLayers_->Fill(numLayers);
0337 profNumLayers_->Fill(abs(sinh(cot)), numLayers);
0338 tracks.push_back(stubs);
0339 }
0340 }
0341
0342
0343 void AnalyzerCTB::associate(const std::vector<std::vector<TTStubRef>>& tracks,
0344 const tt::StubAssociation* ass,
0345 std::set<TPPtr>& tps,
0346 int& sum) const {
0347 for (const std::vector<TTStubRef>& ttStubRefs : tracks) {
0348 const std::vector<TPPtr>& tpPtrs = ass->associate(ttStubRefs);
0349 if (tpPtrs.empty())
0350 continue;
0351 sum++;
0352 std::copy(tpPtrs.begin(), tpPtrs.end(), std::inserter(tps, tps.begin()));
0353 }
0354 }
0355
0356 }
0357
0358 DEFINE_FWK_MODULE(trackerTFP::AnalyzerCTB);