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 <set>
0025 #include <numeric>
0026 #include <sstream>
0027
0028 namespace trackerTFP {
0029
0030
0031
0032
0033
0034
0035 class AnalyzerGP : public edm::one::EDAnalyzer<edm::one::WatchRuns, edm::one::SharedResources> {
0036 public:
0037 AnalyzerGP(const edm::ParameterSet& iConfig);
0038 void beginJob() override {}
0039 void beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override;
0040 void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override;
0041 void endRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) override {}
0042 void endJob() override;
0043
0044 private:
0045
0046 edm::EDGetTokenT<tt::StreamsStub> edGetToken_;
0047
0048 edm::EDGetTokenT<tt::StubAssociation> edGetTokenAss_;
0049
0050 edm::ESGetToken<tt::Setup, tt::SetupRcd> esGetTokenSetup_;
0051
0052 edm::ESGetToken<DataFormats, DataFormatsRcd> esGetTokenDataFormats_;
0053
0054 const tt::Setup* setup_ = nullptr;
0055
0056 const DataFormats* dataFormats_ = nullptr;
0057
0058 bool useMCTruth_;
0059
0060 int nEvents_ = 0;
0061
0062
0063
0064 TProfile* prof_;
0065 TProfile* profChannel_;
0066 TH1F* hisChannel_;
0067 TH1F* hisEffEta_;
0068 TH1F* hisEffEtaTotal_;
0069 TEfficiency* effEta_;
0070 TH1F* hisEffZT_;
0071 TH1F* hisEffZTTotal_;
0072 TEfficiency* effZT_;
0073 TH1F* hisEffInv2R_;
0074 TH1F* hisEffInv2RTotal_;
0075 TEfficiency* effInv2R_;
0076 TH1F* hisEffPT_;
0077 TH1F* hisEffPTTotal_;
0078 TEfficiency* effPT_;
0079
0080
0081 std::stringstream log_;
0082 };
0083
0084 AnalyzerGP::AnalyzerGP(const edm::ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter<bool>("UseMCTruth")) {
0085 usesResource("TFileService");
0086
0087 const std::string& label = iConfig.getParameter<std::string>("OutputLabelGP");
0088 const std::string& branch = iConfig.getParameter<std::string>("BranchStubs");
0089 edGetToken_ = consumes<tt::StreamsStub>(edm::InputTag(label, branch));
0090 if (useMCTruth_) {
0091 const auto& inputTagAss = iConfig.getParameter<edm::InputTag>("InputTagSelection");
0092 edGetTokenAss_ = consumes<tt::StubAssociation>(inputTagAss);
0093 }
0094
0095 esGetTokenSetup_ = esConsumes<edm::Transition::BeginRun>();
0096 esGetTokenDataFormats_ = esConsumes<edm::Transition::BeginRun>();
0097
0098 log_.setf(std::ios::fixed, std::ios::floatfield);
0099 log_.precision(4);
0100 }
0101
0102 void AnalyzerGP::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) {
0103
0104 setup_ = &iSetup.getData(esGetTokenSetup_);
0105
0106 dataFormats_ = &iSetup.getData(esGetTokenDataFormats_);
0107
0108 edm::Service<TFileService> fs;
0109 TFileDirectory dir;
0110 dir = fs->mkdir("GP");
0111 prof_ = dir.make<TProfile>("Counts", ";", 4, 0.5, 4.5);
0112 prof_->GetXaxis()->SetBinLabel(1, "Accepted Stubs");
0113 prof_->GetXaxis()->SetBinLabel(2, "Truncated Stubs");
0114 prof_->GetXaxis()->SetBinLabel(3, "Found TPs");
0115 prof_->GetXaxis()->SetBinLabel(4, "Selected TPs");
0116
0117 hisEffEtaTotal_ = dir.make<TH1F>("HisTPEtaTotal", ";", 48, -2.4, 2.4);
0118 hisEffEta_ = dir.make<TH1F>("HisTPEta", ";", 48, -2.4, 2.4);
0119 effEta_ = dir.make<TEfficiency>("EffEta", ";", 48, -2.4, 2.4);
0120 const int zTBins = setup_->gpNumBinsZT();
0121 hisEffZTTotal_ = dir.make<TH1F>("HisTPZTTotal", ";", zTBins, -zTBins / 2, zTBins / 2);
0122 hisEffZT_ = dir.make<TH1F>("HisTPZT", ";", zTBins, -zTBins / 2, zTBins / 2);
0123 effZT_ = dir.make<TEfficiency>("EffZT", ";", zTBins, -zTBins / 2, zTBins / 2);
0124 const double rangeInv2R = dataFormats_->format(Variable::inv2R, Process::dr).range();
0125 hisEffInv2R_ = dir.make<TH1F>("HisTPInv2R", ";", 32, -rangeInv2R / 2., rangeInv2R / 2.);
0126 hisEffInv2RTotal_ = dir.make<TH1F>("HisTPInv2RTotal", ";", 32, -rangeInv2R / 2., rangeInv2R / 2.);
0127 effInv2R_ = dir.make<TEfficiency>("EffInv2R", ";", 32, -rangeInv2R / 2., rangeInv2R / 2.);
0128 hisEffPT_ = dir.make<TH1F>("HisTPPT", ";", 100, 0, 100);
0129 hisEffPTTotal_ = dir.make<TH1F>("HisTPPTTotal", ";", 100, 0, 100);
0130 effPT_ = dir.make<TEfficiency>("EffPT", ";", 100, 0, 100);
0131
0132 constexpr int maxOcc = 180;
0133 const int numChannels = setup_->numSectors();
0134 hisChannel_ = dir.make<TH1F>("His Channel Occupancy", ";", maxOcc, -.5, maxOcc - .5);
0135 profChannel_ = dir.make<TProfile>("Prof Channel Occupancy", ";", numChannels, -.5, numChannels - .5);
0136 }
0137
0138 void AnalyzerGP::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0139 auto fill = [this](const TPPtr& tpPtr, TH1F* hisEta, TH1F* hisZT, TH1F* hisInv2R, TH1F* hisPT) {
0140 const double tpPhi0 = tpPtr->phi();
0141 const double tpCot = sinh(tpPtr->eta());
0142 const math::XYZPointD& v = tpPtr->vertex();
0143 const double tpZ0 = v.z() - tpCot * (v.x() * cos(tpPhi0) + v.y() * sin(tpPhi0));
0144 const double tpZT = tpZ0 + tpCot * setup_->chosenRofZ();
0145 hisEta->Fill(tpPtr->eta());
0146 hisZT->Fill(dataFormats_->format(Variable::zT, Process::gp).integer(tpZT));
0147 hisInv2R->Fill(tpPtr->charge() / tpPtr->pt() * setup_->invPtToDphi());
0148 hisPT->Fill(tpPtr->pt());
0149 };
0150
0151 edm::Handle<tt::StreamsStub> handleStubs;
0152 iEvent.getByToken<tt::StreamsStub>(edGetToken_, handleStubs);
0153
0154 const tt::StubAssociation* stubAssociation = nullptr;
0155 if (useMCTruth_) {
0156 edm::Handle<tt::StubAssociation> handleAss;
0157 iEvent.getByToken<tt::StubAssociation>(edGetTokenAss_, handleAss);
0158 stubAssociation = handleAss.product();
0159 prof_->Fill(4, stubAssociation->numTPs());
0160 for (const auto& p : stubAssociation->getTrackingParticleToTTStubsMap())
0161 fill(p.first, hisEffEtaTotal_, hisEffZTTotal_, hisEffInv2RTotal_, hisEffPTTotal_);
0162 }
0163
0164 std::set<TPPtr> setTPPtr;
0165 for (int region = 0; region < setup_->numRegions(); region++) {
0166 int nStubs(0);
0167 std::map<TPPtr, std::vector<TTStubRef>> mapTPsTTStubs;
0168 for (int channel = 0; channel < setup_->numSectors(); channel++) {
0169 const int index = region * setup_->numSectors() + channel;
0170 const tt::StreamStub& accepted = handleStubs->at(index);
0171 hisChannel_->Fill(accepted.size());
0172 profChannel_->Fill(channel, accepted.size());
0173 for (const tt::FrameStub& frame : accepted) {
0174 if (frame.first.isNull())
0175 continue;
0176 nStubs++;
0177 if (!useMCTruth_)
0178 continue;
0179 const std::vector<TPPtr>& tpPtrs = stubAssociation->findTrackingParticlePtrs(frame.first);
0180 for (const TPPtr& tpPtr : tpPtrs) {
0181 auto it = mapTPsTTStubs.find(tpPtr);
0182 if (it == mapTPsTTStubs.end()) {
0183 it = mapTPsTTStubs.emplace(tpPtr, std::vector<TTStubRef>()).first;
0184 it->second.reserve(stubAssociation->findTTStubRefs(tpPtr).size());
0185 }
0186 it->second.push_back(frame.first);
0187 }
0188 }
0189 }
0190 for (const auto& p : mapTPsTTStubs)
0191 if (setup_->reconstructable(p.second))
0192 setTPPtr.insert(p.first);
0193 prof_->Fill(1, nStubs);
0194 }
0195 for (const TPPtr& tpPtr : setTPPtr)
0196 fill(tpPtr, hisEffEta_, hisEffZT_, hisEffInv2R_, hisEffPT_);
0197 prof_->Fill(3, setTPPtr.size());
0198 nEvents_++;
0199 }
0200
0201 void AnalyzerGP::endJob() {
0202 if (nEvents_ == 0)
0203 return;
0204
0205 effEta_->SetPassedHistogram(*hisEffEta_, "f");
0206 effEta_->SetTotalHistogram(*hisEffEtaTotal_, "f");
0207 effZT_->SetPassedHistogram(*hisEffZT_, "f");
0208 effZT_->SetTotalHistogram(*hisEffZTTotal_, "f");
0209 effInv2R_->SetPassedHistogram(*hisEffInv2R_, "f");
0210 effInv2R_->SetTotalHistogram(*hisEffInv2RTotal_, "f");
0211 effPT_->SetPassedHistogram(*hisEffPT_, "f");
0212 effPT_->SetTotalHistogram(*hisEffPTTotal_, "f");
0213
0214 const double numStubs = prof_->GetBinContent(1);
0215 const double errStubs = prof_->GetBinError(1);
0216 const double numTPs = prof_->GetBinContent(3);
0217 const double totalTPs = prof_->GetBinContent(4);
0218 const double eff = numTPs / totalTPs;
0219 const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_);
0220 const std::vector<double> nums = {numStubs};
0221 const std::vector<double> errs = {errStubs};
0222 const int wNums = std::ceil(std::log10(*std::max_element(nums.begin(), nums.end()))) + 5;
0223 const int wErrs = std::ceil(std::log10(*std::max_element(errs.begin(), errs.end()))) + 5;
0224 log_ << " GP SUMMARY " << std::endl;
0225 log_ << "number of stubs per TFP = " << std::setw(wNums) << numStubs << " +- " << std::setw(wErrs) << errStubs
0226 << std::endl;
0227 log_ << " max tracking efficiency = " << std::setw(wNums) << eff << " +- " << std::setw(wErrs) << errEff
0228 << std::endl;
0229 log_ << "=============================================================";
0230 edm::LogPrint(moduleDescription().moduleName()) << log_.str();
0231 }
0232
0233 }
0234
0235 DEFINE_FWK_MODULE(trackerTFP::AnalyzerGP);