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 AnalyzerHT : public edm::one::EDAnalyzer<edm::one::WatchRuns, edm::one::SharedResources> {
0038 public:
0039 AnalyzerHT(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::StreamStub& stream, std::vector<std::vector<TTStubRef>>& tracks) const;
0049
0050 void associate(const std::vector<std::vector<TTStubRef>>& tracks,
0051 const tt::StubAssociation* ass,
0052 std::set<TPPtr>& tps,
0053 int& sum) const;
0054
0055
0056 edm::EDGetTokenT<tt::StreamsStub> edGetToken_;
0057
0058 edm::EDGetTokenT<tt::StubAssociation> edGetTokenSelection_;
0059
0060 edm::EDGetTokenT<tt::StubAssociation> edGetTokenReconstructable_;
0061
0062 edm::ESGetToken<tt::Setup, tt::SetupRcd> esGetTokenSetup_;
0063
0064 edm::ESGetToken<DataFormats, DataFormatsRcd> esGetTokenDataFormats_;
0065
0066 const tt::Setup* setup_ = nullptr;
0067
0068 const DataFormats* dataFormats_ = nullptr;
0069
0070 bool useMCTruth_;
0071
0072 int nEvents_ = 0;
0073
0074
0075
0076 TProfile* prof_;
0077 TProfile* profChannel_;
0078 TH1F* hisChannel_;
0079 TH1F* hisLayers_;
0080 TH1F* hisNumLayers_;
0081 TProfile* profNumLayers_;
0082 TH1F* hisEffEta_;
0083 TH1F* hisEffEtaTotal_;
0084 TEfficiency* effEta_;
0085 TH1F* hisEffZT_;
0086 TH1F* hisEffZTTotal_;
0087 TEfficiency* effZT_;
0088 TH1F* hisEffInv2R_;
0089 TH1F* hisEffInv2RTotal_;
0090 TEfficiency* effInv2R_;
0091 TH1F* hisEffPT_;
0092 TH1F* hisEffPTTotal_;
0093 TEfficiency* effPT_;
0094
0095
0096 std::stringstream log_;
0097 };
0098
0099 AnalyzerHT::AnalyzerHT(const edm::ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter<bool>("UseMCTruth")) {
0100 usesResource("TFileService");
0101
0102 const std::string& label = iConfig.getParameter<std::string>("OutputLabelHT");
0103 const std::string& branch = iConfig.getParameter<std::string>("BranchStubs");
0104 edGetToken_ = consumes<tt::StreamsStub>(edm::InputTag(label, branch));
0105 if (useMCTruth_) {
0106 const auto& inputTagSelecttion = iConfig.getParameter<edm::InputTag>("InputTagSelection");
0107 const auto& inputTagReconstructable = iConfig.getParameter<edm::InputTag>("InputTagReconstructable");
0108 edGetTokenSelection_ = consumes<tt::StubAssociation>(inputTagSelecttion);
0109 edGetTokenReconstructable_ = consumes<tt::StubAssociation>(inputTagReconstructable);
0110 }
0111
0112 esGetTokenSetup_ = esConsumes<edm::Transition::BeginRun>();
0113 esGetTokenDataFormats_ = esConsumes<edm::Transition::BeginRun>();
0114
0115 log_.setf(std::ios::fixed, std::ios::floatfield);
0116 log_.precision(4);
0117 }
0118
0119 void AnalyzerHT::beginRun(const edm::Run& iEvent, const edm::EventSetup& iSetup) {
0120
0121 setup_ = &iSetup.getData(esGetTokenSetup_);
0122
0123 dataFormats_ = &iSetup.getData(esGetTokenDataFormats_);
0124
0125 edm::Service<TFileService> fs;
0126 TFileDirectory dir;
0127 dir = fs->mkdir("HT");
0128 prof_ = dir.make<TProfile>("Counts", ";", 9, 0.5, 9.5);
0129 prof_->GetXaxis()->SetBinLabel(1, "Stubs");
0130 prof_->GetXaxis()->SetBinLabel(2, "Tracks");
0131 prof_->GetXaxis()->SetBinLabel(3, "Truncated Tracks");
0132 prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks");
0133 prof_->GetXaxis()->SetBinLabel(5, "All Tracks");
0134 prof_->GetXaxis()->SetBinLabel(6, "Found TPs");
0135 prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs");
0136 prof_->GetXaxis()->SetBinLabel(8, "Truncated TPs");
0137 prof_->GetXaxis()->SetBinLabel(9, "All TPs");
0138
0139 hisEffEtaTotal_ = dir.make<TH1F>("HisTPEtaTotal", ";", 48, -2.4, 2.4);
0140 hisEffEta_ = dir.make<TH1F>("HisTPEta", ";", 48, -2.4, 2.4);
0141 effEta_ = dir.make<TEfficiency>("EffEta", ";", 48, -2.4, 2.4);
0142 const double rangeZT = dataFormats_->format(Variable::zT, Process::dr).range();
0143 const int zTBins = setup_->gpNumBinsZT();
0144 hisEffZTTotal_ = dir.make<TH1F>("HisTPZTTotal", ";", zTBins, -rangeZT / 2, rangeZT / 2);
0145 hisEffZT_ = dir.make<TH1F>("HisTPZT", ";", zTBins, -rangeZT / 2, rangeZT / 2);
0146 effZT_ = dir.make<TEfficiency>("EffZT", ";", zTBins, -rangeZT / 2, rangeZT / 2);
0147 const double rangeInv2R = dataFormats_->format(Variable::inv2R, Process::dr).range();
0148 const int inv2RBins = (setup_->htNumBinsInv2R() + 2) * 2;
0149 hisEffInv2R_ = dir.make<TH1F>("HisTPInv2R", ";", inv2RBins, -rangeInv2R / 2., rangeInv2R / 2.);
0150 hisEffInv2RTotal_ = dir.make<TH1F>("HisTPInv2RTotal", ";", inv2RBins, -rangeInv2R / 2., rangeInv2R / 2.);
0151 effInv2R_ = dir.make<TEfficiency>("EffInv2R", ";", inv2RBins, -rangeInv2R / 2., rangeInv2R / 2.);
0152 hisEffPT_ = dir.make<TH1F>("HisTPPT", ";", 100, 0, 100);
0153 hisEffPTTotal_ = dir.make<TH1F>("HisTPPTTotal", ";", 100, 0, 100);
0154 effPT_ = dir.make<TEfficiency>("EffPT", ";", 100, 0, 100);
0155
0156 constexpr int maxOcc = 180;
0157 const int numChannel = dataFormats_->numChannel(Process::ht);
0158 hisChannel_ = dir.make<TH1F>("His binInv2R Occupancy", ";", maxOcc, -.5, maxOcc - .5);
0159 profChannel_ = dir.make<TProfile>("Prof binInv2R Occupancy", ";", numChannel, -.5, numChannel - .5);
0160
0161 hisLayers_ = dir.make<TH1F>("HisLayers", ";", 8, 0, 8);
0162 hisNumLayers_ = dir.make<TH1F>("HisNumLayers", ";", 9, 0, 9);
0163 profNumLayers_ = dir.make<TProfile>("Prof NumLayers", ";", 32, 0, 2.4);
0164 }
0165
0166 void AnalyzerHT::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0167 auto fill = [this](const TPPtr& tpPtr, TH1F* hisEta, TH1F* hisZT, TH1F* hisInv2R, TH1F* hisPT) {
0168 const double tpPhi0 = tpPtr->phi();
0169 const double tpCot = sinh(tpPtr->eta());
0170 const math::XYZPointD& v = tpPtr->vertex();
0171 const double tpZ0 = v.z() - tpCot * (v.x() * cos(tpPhi0) + v.y() * sin(tpPhi0));
0172 const double tpZT = tpZ0 + tpCot * setup_->chosenRofZ();
0173 hisEta->Fill(tpPtr->eta());
0174 hisZT->Fill(tpZT);
0175 hisInv2R->Fill(tpPtr->charge() / tpPtr->pt() * setup_->invPtToDphi());
0176 hisPT->Fill(tpPtr->pt());
0177 };
0178
0179 edm::Handle<tt::StreamsStub> handleStubs;
0180 iEvent.getByToken<tt::StreamsStub>(edGetToken_, handleStubs);
0181
0182 const tt::StubAssociation* selection = nullptr;
0183 const tt::StubAssociation* reconstructable = nullptr;
0184 if (useMCTruth_) {
0185 edm::Handle<tt::StubAssociation> handleSelection;
0186 iEvent.getByToken<tt::StubAssociation>(edGetTokenSelection_, handleSelection);
0187 selection = handleSelection.product();
0188 prof_->Fill(9, selection->numTPs());
0189 edm::Handle<tt::StubAssociation> handleReconstructable;
0190 iEvent.getByToken<tt::StubAssociation>(edGetTokenReconstructable_, handleReconstructable);
0191 reconstructable = handleReconstructable.product();
0192 for (const auto& p : selection->getTrackingParticleToTTStubsMap())
0193 fill(p.first, hisEffEtaTotal_, hisEffZTTotal_, hisEffInv2RTotal_, hisEffPTTotal_);
0194 }
0195
0196 std::set<TPPtr> tpPtrs;
0197 std::set<TPPtr> tpPtrsSelection;
0198 int allMatched(0);
0199 int allTracks(0);
0200 for (int region = 0; region < setup_->numRegions(); region++) {
0201 int nStubs(0);
0202 int nTracks(0);
0203 for (int channel = 0; channel < dataFormats_->numChannel(Process::ht); channel++) {
0204 const int index = region * dataFormats_->numChannel(Process::ht) + channel;
0205 const tt::StreamStub& accepted = handleStubs->at(index);
0206 hisChannel_->Fill(accepted.size());
0207 profChannel_->Fill(channel, accepted.size());
0208 nStubs += accepted.size();
0209 std::vector<std::vector<TTStubRef>> tracks;
0210 formTracks(accepted, tracks);
0211 nTracks += tracks.size();
0212 allTracks += tracks.size();
0213 if (!useMCTruth_)
0214 continue;
0215 int tmp(0);
0216 associate(tracks, selection, tpPtrsSelection, tmp);
0217 associate(tracks, reconstructable, tpPtrs, allMatched);
0218 }
0219 prof_->Fill(1, nStubs);
0220 prof_->Fill(2, nTracks);
0221 }
0222 for (const TPPtr& tpPtr : tpPtrsSelection)
0223 fill(tpPtr, hisEffEta_, hisEffZT_, hisEffInv2R_, hisEffPT_);
0224 prof_->Fill(4, allMatched);
0225 prof_->Fill(5, allTracks);
0226 prof_->Fill(6, tpPtrs.size());
0227 prof_->Fill(7, tpPtrsSelection.size());
0228 nEvents_++;
0229 }
0230
0231 void AnalyzerHT::endJob() {
0232 if (nEvents_ == 0)
0233 return;
0234
0235 effEta_->SetPassedHistogram(*hisEffEta_, "f");
0236 effEta_->SetTotalHistogram(*hisEffEtaTotal_, "f");
0237 effZT_->SetPassedHistogram(*hisEffZT_, "f");
0238 effZT_->SetTotalHistogram(*hisEffZTTotal_, "f");
0239 effInv2R_->SetPassedHistogram(*hisEffInv2R_, "f");
0240 effInv2R_->SetTotalHistogram(*hisEffInv2RTotal_, "f");
0241 effPT_->SetPassedHistogram(*hisEffPT_, "f");
0242 effPT_->SetTotalHistogram(*hisEffPTTotal_, "f");
0243
0244 const double totalTPs = prof_->GetBinContent(9);
0245 const double numStubs = prof_->GetBinContent(1);
0246 const double numTracks = prof_->GetBinContent(2);
0247 const double totalTracks = prof_->GetBinContent(5);
0248 const double numTracksMatched = prof_->GetBinContent(4);
0249 const double numTPsAll = prof_->GetBinContent(6);
0250 const double numTPsEff = prof_->GetBinContent(7);
0251 const double errStubs = prof_->GetBinError(1);
0252 const double errTracks = prof_->GetBinError(2);
0253 const double fracFake = (totalTracks - numTracksMatched) / totalTracks;
0254 const double fracDup = (numTracksMatched - numTPsAll) / totalTracks;
0255 const double eff = numTPsEff / totalTPs;
0256 const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_);
0257 const std::vector<double> nums = {numStubs, numTracks};
0258 const std::vector<double> errs = {errStubs, errTracks};
0259 const int wNums = std::ceil(std::log10(*std::max_element(nums.begin(), nums.end()))) + 5;
0260 const int wErrs = std::ceil(std::log10(*std::max_element(errs.begin(), errs.end()))) + 5;
0261 log_ << " HT SUMMARY " << std::endl;
0262 log_ << "number of stubs per TFP = " << std::setw(wNums) << numStubs << " +- " << std::setw(wErrs) << errStubs
0263 << std::endl;
0264 log_ << "number of tracks per TFP = " << std::setw(wNums) << numTracks << " +- " << std::setw(wErrs)
0265 << errTracks << std::endl;
0266 log_ << " max tracking efficiency = " << std::setw(wNums) << eff << " +- " << std::setw(wErrs) << errEff
0267 << std::endl;
0268 log_ << " fake rate = " << std::setw(wNums) << fracFake << std::endl;
0269 log_ << " duplicate rate = " << std::setw(wNums) << fracDup << std::endl;
0270 log_ << "=============================================================";
0271 edm::LogPrint(moduleDescription().moduleName()) << log_.str();
0272 }
0273
0274
0275 void AnalyzerHT::formTracks(const tt::StreamStub& stream, std::vector<std::vector<TTStubRef>>& tracks) const {
0276 static const DataFormat& layer = dataFormats_->format(Variable::layer, Process::ctb);
0277 auto toTrkId = [this](const StubHT& stub) {
0278 static const DataFormat& phiT = dataFormats_->format(Variable::phiT, Process::ht);
0279 static const DataFormat& zT = dataFormats_->format(Variable::zT, Process::ht);
0280 return (phiT.ttBV(stub.phiT()) + zT.ttBV(stub.zT())).val();
0281 };
0282 std::vector<StubHT> stubs;
0283 stubs.reserve(stream.size());
0284 for (const tt::FrameStub& frame : stream)
0285 stubs.emplace_back(frame, dataFormats_);
0286 for (auto it = stubs.begin(); it != stubs.end();) {
0287 const auto start = it;
0288 const int id = toTrkId(*it);
0289 auto different = [id, toTrkId](const StubHT& stub) { return id != toTrkId(stub); };
0290 it = std::find_if(it, stubs.end(), different);
0291 std::vector<TTStubRef> ttStubRefs;
0292 ttStubRefs.reserve(std::distance(start, it));
0293 std::transform(start, it, std::back_inserter(ttStubRefs), [](const StubHT& stub) { return stub.frame().first; });
0294 tracks.push_back(ttStubRefs);
0295 TTBV hitPattern(0, setup_->numLayers());
0296 for (auto iter = start; iter != it; iter++)
0297 hitPattern.set(iter->layer().val(layer.width()));
0298 const double cot = dataFormats_->format(Variable::zT, Process::ht).floating(start->zT()) / setup_->chosenRofZ();
0299 hisNumLayers_->Fill(hitPattern.count());
0300 profNumLayers_->Fill(abs(sinh(cot)), hitPattern.count());
0301 for (int layer : hitPattern.ids())
0302 hisLayers_->Fill(layer);
0303 }
0304 }
0305
0306
0307 void AnalyzerHT::associate(const std::vector<std::vector<TTStubRef>>& tracks,
0308 const tt::StubAssociation* ass,
0309 std::set<TPPtr>& tps,
0310 int& sum) const {
0311 for (const std::vector<TTStubRef>& ttStubRefs : tracks) {
0312 const std::vector<TPPtr>& tpPtrs = ass->associate(ttStubRefs);
0313 if (tpPtrs.empty())
0314 continue;
0315 sum++;
0316 std::copy(tpPtrs.begin(), tpPtrs.end(), std::inserter(tps, tps.begin()));
0317 }
0318 }
0319
0320 }
0321
0322 DEFINE_FWK_MODULE(trackerTFP::AnalyzerHT);