Back to home page

Project CMSSW displayed by LXR

 
 

    


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   /*! \class  trackerTFP::AnalyzerGP
0031    *  \brief  Class to analyze hardware like structured TTStub Collection generated by Geometric Processor
0032    *  \author Thomas Schuh
0033    *  \date   2020, Apr
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     // ED input token of stubs
0046     edm::EDGetTokenT<tt::StreamsStub> edGetToken_;
0047     // ED input token of TTStubRef to TPPtr association for tracking efficiency
0048     edm::EDGetTokenT<tt::StubAssociation> edGetTokenAss_;
0049     // Setup token
0050     edm::ESGetToken<tt::Setup, tt::SetupRcd> esGetTokenSetup_;
0051     // DataFormats token
0052     edm::ESGetToken<DataFormats, DataFormatsRcd> esGetTokenDataFormats_;
0053     // stores, calculates and provides run-time constants
0054     const tt::Setup* setup_ = nullptr;
0055     // helper class to extract structured data from tt::Frames
0056     const DataFormats* dataFormats_ = nullptr;
0057     // enables analyze of TPs
0058     bool useMCTruth_;
0059     //
0060     int nEvents_ = 0;
0061 
0062     // Histograms
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     // printout
0081     std::stringstream log_;
0082   };
0083 
0084   AnalyzerGP::AnalyzerGP(const edm::ParameterSet& iConfig) : useMCTruth_(iConfig.getParameter<bool>("UseMCTruth")) {
0085     usesResource("TFileService");
0086     // book in- and output ED products
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     // book ES products
0095     esGetTokenSetup_ = esConsumes<edm::Transition::BeginRun>();
0096     esGetTokenDataFormats_ = esConsumes<edm::Transition::BeginRun>();
0097     // log config
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     // helper class to store configurations
0104     setup_ = &iSetup.getData(esGetTokenSetup_);
0105     // helper class to extract structured data from tt::Frames
0106     dataFormats_ = &iSetup.getData(esGetTokenDataFormats_);
0107     // book histograms
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     // Efficiencies
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     // channel occupancy
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     // read in gp products
0151     edm::Handle<tt::StreamsStub> handleStubs;
0152     iEvent.getByToken<tt::StreamsStub>(edGetToken_, handleStubs);
0153     // read in MCTruth
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     // analyze gp products and find still reconstrucable TrackingParticles
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     // effi
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     // printout GP summary
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 }  // namespace trackerTFP
0234 
0235 DEFINE_FWK_MODULE(trackerTFP::AnalyzerGP);