File indexing completed on 2024-04-06 12:21:47
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 using namespace std;
0031 using namespace edm;
0032 using namespace tt;
0033
0034 namespace trackerTFP {
0035
0036
0037
0038
0039
0040
0041 class AnalyzerMHT : public one::EDAnalyzer<one::WatchRuns, one::SharedResources> {
0042 public:
0043 AnalyzerMHT(const ParameterSet& iConfig);
0044 void beginJob() override {}
0045 void beginRun(const Run& iEvent, const EventSetup& iSetup) override;
0046 void analyze(const Event& iEvent, const EventSetup& iSetup) override;
0047 void endRun(const Run& iEvent, const EventSetup& iSetup) override {}
0048 void endJob() override;
0049
0050 private:
0051
0052 void formTracks(const StreamStub& stream, vector<vector<TTStubRef>>& tracks) const;
0053
0054 void associate(const vector<vector<TTStubRef>>& tracks, const StubAssociation* ass, set<TPPtr>& tps, int& sum) const;
0055
0056
0057 EDGetTokenT<StreamsStub> edGetTokenAccepted_;
0058
0059 EDGetTokenT<StreamsStub> edGetTokenLost_;
0060
0061 EDGetTokenT<StubAssociation> edGetTokenSelection_;
0062
0063 EDGetTokenT<StubAssociation> edGetTokenReconstructable_;
0064
0065 ESGetToken<Setup, SetupRcd> esGetTokenSetup_;
0066
0067 ESGetToken<DataFormats, DataFormatsRcd> esGetTokenDataFormats_;
0068
0069 const Setup* setup_ = nullptr;
0070
0071 const DataFormats* dataFormats_ = nullptr;
0072
0073 bool useMCTruth_;
0074
0075 int nEvents_ = 0;
0076
0077
0078
0079 TProfile* prof_;
0080 TProfile* profChannel_;
0081 TH1F* hisChannel_;
0082 TH1F* hisEff_;
0083 TH1F* hisEffTotal_;
0084 TEfficiency* eff_;
0085
0086
0087 stringstream log_;
0088 };
0089
0090 AnalyzerMHT::AnalyzerMHT(const ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter<bool>("UseMCTruth")) {
0091 usesResource("TFileService");
0092
0093 const string& label = iConfig.getParameter<string>("LabelMHT");
0094 const string& branchAccepted = iConfig.getParameter<string>("BranchAcceptedStubs");
0095 const string& branchLost = iConfig.getParameter<string>("BranchLostStubs");
0096 edGetTokenAccepted_ = consumes<StreamsStub>(InputTag(label, branchAccepted));
0097 edGetTokenLost_ = consumes<StreamsStub>(InputTag(label, branchLost));
0098 if (useMCTruth_) {
0099 const auto& inputTagSelecttion = iConfig.getParameter<InputTag>("InputTagSelection");
0100 const auto& inputTagReconstructable = iConfig.getParameter<InputTag>("InputTagReconstructable");
0101 edGetTokenSelection_ = consumes<StubAssociation>(inputTagSelecttion);
0102 edGetTokenReconstructable_ = consumes<StubAssociation>(inputTagReconstructable);
0103 }
0104
0105 esGetTokenSetup_ = esConsumes<Setup, SetupRcd, Transition::BeginRun>();
0106 esGetTokenDataFormats_ = esConsumes<DataFormats, DataFormatsRcd, Transition::BeginRun>();
0107
0108 log_.setf(ios::fixed, ios::floatfield);
0109 log_.precision(4);
0110 }
0111
0112 void AnalyzerMHT::beginRun(const Run& iEvent, const EventSetup& iSetup) {
0113
0114 setup_ = &iSetup.getData(esGetTokenSetup_);
0115
0116 dataFormats_ = &iSetup.getData(esGetTokenDataFormats_);
0117
0118 Service<TFileService> fs;
0119 TFileDirectory dir;
0120 dir = fs->mkdir("MHT");
0121 prof_ = dir.make<TProfile>("Counts", ";", 9, 0.5, 9.5);
0122 prof_->GetXaxis()->SetBinLabel(1, "Stubs");
0123 prof_->GetXaxis()->SetBinLabel(2, "Tracks");
0124 prof_->GetXaxis()->SetBinLabel(3, "Lost Tracks");
0125 prof_->GetXaxis()->SetBinLabel(4, "Matched Tracks");
0126 prof_->GetXaxis()->SetBinLabel(5, "All Tracks");
0127 prof_->GetXaxis()->SetBinLabel(6, "Found TPs");
0128 prof_->GetXaxis()->SetBinLabel(7, "Found selected TPs");
0129 prof_->GetXaxis()->SetBinLabel(8, "Lost TPs");
0130 prof_->GetXaxis()->SetBinLabel(9, "All TPs");
0131
0132 constexpr int maxOcc = 180;
0133 const int numChannels = dataFormats_->numChannel(Process::mht);
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 hisEffTotal_ = dir.make<TH1F>("HisTPEtaTotal", ";", 128, -2.5, 2.5);
0138 hisEff_ = dir.make<TH1F>("HisTPEta", ";", 128, -2.5, 2.5);
0139 eff_ = dir.make<TEfficiency>("EffEta", ";", 128, -2.5, 2.5);
0140 }
0141
0142 void AnalyzerMHT::analyze(const Event& iEvent, const EventSetup& iSetup) {
0143 auto fill = [](const TPPtr& tpPtr, TH1F* his) { his->Fill(tpPtr->eta()); };
0144
0145 Handle<StreamsStub> handleAccepted;
0146 iEvent.getByToken<StreamsStub>(edGetTokenAccepted_, handleAccepted);
0147 Handle<StreamsStub> handleLost;
0148 iEvent.getByToken<StreamsStub>(edGetTokenLost_, handleLost);
0149
0150 const StubAssociation* selection = nullptr;
0151 const StubAssociation* reconstructable = nullptr;
0152 if (useMCTruth_) {
0153 Handle<StubAssociation> handleSelection;
0154 iEvent.getByToken<StubAssociation>(edGetTokenSelection_, handleSelection);
0155 selection = handleSelection.product();
0156 prof_->Fill(9, selection->numTPs());
0157 Handle<StubAssociation> handleReconstructable;
0158 iEvent.getByToken<StubAssociation>(edGetTokenReconstructable_, handleReconstructable);
0159 reconstructable = handleReconstructable.product();
0160 for (const auto& p : selection->getTrackingParticleToTTStubsMap())
0161 fill(p.first, hisEffTotal_);
0162 }
0163
0164 set<TPPtr> tpPtrs;
0165 set<TPPtr> tpPtrsSelection;
0166 set<TPPtr> tpPtrsLost;
0167 int allMatched(0);
0168 int allTracks(0);
0169 for (int region = 0; region < setup_->numRegions(); region++) {
0170 int nStubs(0);
0171 int nTracks(0);
0172 int nLost(0);
0173 for (int channel = 0; channel < dataFormats_->numChannel(Process::mht); channel++) {
0174 const int index = region * dataFormats_->numChannel(Process::mht) + channel;
0175 const StreamStub& accepted = handleAccepted->at(index);
0176 hisChannel_->Fill(accepted.size());
0177 profChannel_->Fill(channel, accepted.size());
0178 nStubs += accumulate(accepted.begin(), accepted.end(), 0, [](int sum, const FrameStub& frame) {
0179 return sum + (frame.first.isNonnull() ? 1 : 0);
0180 });
0181 vector<vector<TTStubRef>> tracks;
0182 vector<vector<TTStubRef>> lost;
0183 formTracks(accepted, tracks);
0184 formTracks(handleLost->at(index), lost);
0185 nTracks += tracks.size();
0186 allTracks += tracks.size();
0187 nLost += lost.size();
0188 if (!useMCTruth_)
0189 continue;
0190 int tmp(0);
0191 associate(tracks, selection, tpPtrsSelection, tmp);
0192 associate(lost, selection, tpPtrsLost, tmp);
0193 associate(tracks, reconstructable, tpPtrs, allMatched);
0194 }
0195 prof_->Fill(1, nStubs);
0196 prof_->Fill(2, nTracks);
0197 prof_->Fill(3, nLost);
0198 }
0199 for (const TPPtr& tpPtr : tpPtrsSelection)
0200 fill(tpPtr, hisEff_);
0201 vector<TPPtr> recovered;
0202 recovered.reserve(tpPtrsLost.size());
0203 set_intersection(tpPtrsLost.begin(), tpPtrsLost.end(), tpPtrs.begin(), tpPtrs.end(), back_inserter(recovered));
0204 for (const TPPtr& tpPtr : recovered)
0205 tpPtrsLost.erase(tpPtr);
0206 prof_->Fill(4, allMatched);
0207 prof_->Fill(5, allTracks);
0208 prof_->Fill(6, tpPtrs.size());
0209 prof_->Fill(7, tpPtrsSelection.size());
0210 prof_->Fill(8, tpPtrsLost.size());
0211 nEvents_++;
0212 }
0213
0214 void AnalyzerMHT::endJob() {
0215 if (nEvents_ == 0)
0216 return;
0217
0218 eff_->SetPassedHistogram(*hisEff_, "f");
0219 eff_->SetTotalHistogram(*hisEffTotal_, "f");
0220
0221 const double totalTPs = prof_->GetBinContent(9);
0222 const double numStubs = prof_->GetBinContent(1);
0223 const double numTracks = prof_->GetBinContent(2);
0224 const double numTracksLost = prof_->GetBinContent(3);
0225 const double totalTracks = prof_->GetBinContent(5);
0226 const double numTracksMatched = prof_->GetBinContent(4);
0227 const double numTPsAll = prof_->GetBinContent(6);
0228 const double numTPsEff = prof_->GetBinContent(7);
0229 const double numTPsLost = prof_->GetBinContent(8);
0230 const double errStubs = prof_->GetBinError(1);
0231 const double errTracks = prof_->GetBinError(2);
0232 const double errTracksLost = prof_->GetBinError(3);
0233 const double fracFake = (totalTracks - numTracksMatched) / totalTracks;
0234 const double fracDup = (numTracksMatched - numTPsAll) / totalTracks;
0235 const double eff = numTPsEff / totalTPs;
0236 const double errEff = sqrt(eff * (1. - eff) / totalTPs / nEvents_);
0237 const double effLoss = numTPsLost / totalTPs;
0238 const double errEffLoss = sqrt(effLoss * (1. - effLoss) / totalTPs / nEvents_);
0239 const vector<double> nums = {numStubs, numTracks, numTracksLost};
0240 const vector<double> errs = {errStubs, errTracks, errTracksLost};
0241 const int wNums = ceil(log10(*max_element(nums.begin(), nums.end()))) + 5;
0242 const int wErrs = ceil(log10(*max_element(errs.begin(), errs.end()))) + 5;
0243 log_ << " MHT SUMMARY " << endl;
0244 log_ << "number of stubs per TFP = " << setw(wNums) << numStubs << " +- " << setw(wErrs) << errStubs << endl;
0245 log_ << "number of tracks per TFP = " << setw(wNums) << numTracks << " +- " << setw(wErrs) << errTracks
0246 << endl;
0247 log_ << "number of lost tracks per TFP = " << setw(wNums) << numTracksLost << " +- " << setw(wErrs) << errTracksLost
0248 << endl;
0249 log_ << " max tracking efficiency = " << setw(wNums) << eff << " +- " << setw(wErrs) << errEff << endl;
0250 log_ << " lost tracking efficiency = " << setw(wNums) << effLoss << " +- " << setw(wErrs) << errEffLoss << endl;
0251 log_ << " fake rate = " << setw(wNums) << fracFake << endl;
0252 log_ << " duplicate rate = " << setw(wNums) << fracDup << endl;
0253 log_ << "=============================================================";
0254 LogPrint("L1Trigger/TrackerTFP") << log_.str();
0255 }
0256
0257
0258 void AnalyzerMHT::formTracks(const StreamStub& stream, vector<vector<TTStubRef>>& tracks) const {
0259 vector<StubMHT> stubs;
0260 stubs.reserve(stream.size());
0261 for (const FrameStub& frame : stream)
0262 if (frame.first.isNonnull())
0263 stubs.emplace_back(frame, dataFormats_);
0264 for (auto it = stubs.begin(); it != stubs.end();) {
0265 const auto start = it;
0266 const int id = it->trackId();
0267 auto different = [id](const StubMHT& stub) { return id != stub.trackId(); };
0268 it = find_if(it, stubs.end(), different);
0269 vector<TTStubRef> ttStubRefs;
0270 ttStubRefs.reserve(distance(start, it));
0271 transform(start, it, back_inserter(ttStubRefs), [](const StubMHT& stub) { return stub.ttStubRef(); });
0272 tracks.push_back(ttStubRefs);
0273 }
0274 }
0275
0276
0277 void AnalyzerMHT::associate(const vector<vector<TTStubRef>>& tracks,
0278 const StubAssociation* ass,
0279 set<TPPtr>& tps,
0280 int& sum) const {
0281 for (const vector<TTStubRef>& ttStubRefs : tracks) {
0282 const vector<TPPtr>& tpPtrs = ass->associate(ttStubRefs);
0283 if (tpPtrs.empty())
0284 continue;
0285 sum++;
0286 copy(tpPtrs.begin(), tpPtrs.end(), inserter(tps, tps.begin()));
0287 }
0288 }
0289
0290 }
0291
0292 DEFINE_FWK_MODULE(trackerTFP::AnalyzerMHT);