Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:32:50

0001 //
0002 //
0003 
0004 /**
0005   \class    pat::CandidateSummaryTable CandidateSummaryTable.h "PhysicsTools/PatAlgos/interface/CandidateSummaryTable.h"
0006   \brief    Produce a summary table of some candidate collections
0007 
0008   FIXME FIXME Move to CandAlgos
0009 
0010   \author   Giovanni Petrucciani
0011   \version  $Id: CandidateSummaryTable.cc,v 1.4 2010/02/20 21:00:15 wmtan Exp $
0012 */
0013 
0014 #include "FWCore/Framework/interface/stream/EDAnalyzer.h"
0015 #include "FWCore/Framework/interface/Event.h"
0016 #include "FWCore/Framework/interface/ConsumesCollector.h"
0017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0018 #include "FWCore/Utilities/interface/InputTag.h"
0019 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0020 #include <iomanip>
0021 #include <atomic>
0022 
0023 #include "DataFormats/Common/interface/View.h"
0024 #include "DataFormats/Candidate/interface/Candidate.h"
0025 
0026 namespace pathelpers {
0027   struct Record {
0028     const edm::InputTag src;
0029     mutable std::atomic<size_t> present, empty, min, max, total;
0030     Record(const edm::InputTag& tag) : src(tag), present(0), empty(0), min(0), max(0), total(0) {}
0031     Record(const Record& other)
0032         : src(other.src),
0033           present(other.present.load()),
0034           empty(other.empty.load()),
0035           min(other.min.load()),
0036           max(other.max.load()),
0037           total(other.total.load()) {}
0038     void update(const edm::View<reco::Candidate>& items) const {
0039       present++;
0040       const size_t size = items.size();
0041       if (size == 0) {
0042         empty++;
0043       } else {
0044         auto previousMin = min.load();
0045         while (previousMin > size and not min.compare_exchange_weak(previousMin, size)) {
0046         }
0047         auto previousMax = max.load();
0048         while (previousMax < size and not max.compare_exchange_weak(previousMax, size)) {
0049         }
0050       }
0051       total += size;
0052     }
0053   };
0054 
0055   struct RecordCache {
0056     RecordCache(const edm::ParameterSet& iConfig)
0057         : perEvent_(iConfig.getUntrackedParameter<bool>("perEvent", false)),
0058           perJob_(iConfig.getUntrackedParameter<bool>("perJob", true)),
0059           self_(iConfig.getParameter<std::string>("@module_label")),
0060           logName_(iConfig.getUntrackedParameter<std::string>("logName")),
0061           dumpItems_(iConfig.getUntrackedParameter<bool>("dumpItems", false)),
0062           totalEvents_(0) {
0063       const std::vector<edm::InputTag>& tags = iConfig.getParameter<std::vector<edm::InputTag> >("candidates");
0064       for (const auto& tag : tags) {
0065         collections_.emplace_back(tag);
0066       }
0067     }
0068     const bool perEvent_, perJob_;
0069     const std::string self_, logName_;
0070     const bool dumpItems_;
0071     mutable std::atomic<size_t> totalEvents_;
0072     std::vector<Record> collections_;  // size of vector is never altered later! (atomics are in the class below)
0073   };
0074 
0075 }  // namespace pathelpers
0076 
0077 namespace pat {
0078   class CandidateSummaryTable : public edm::stream::EDAnalyzer<edm::GlobalCache<pathelpers::RecordCache> > {
0079   public:
0080     explicit CandidateSummaryTable(const edm::ParameterSet& iConfig, const pathelpers::RecordCache*);
0081     ~CandidateSummaryTable() override;
0082 
0083     static std::unique_ptr<pathelpers::RecordCache> initializeGlobalCache(edm::ParameterSet const& conf) {
0084       return std::make_unique<pathelpers::RecordCache>(conf);
0085     }
0086 
0087     void analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) override;
0088 
0089     static void globalEndJob(const pathelpers::RecordCache*);
0090 
0091   private:
0092     std::vector<std::pair<edm::InputTag, edm::EDGetTokenT<edm::View<reco::Candidate> > > > srcTokens;
0093   };
0094 }  // namespace pat
0095 
0096 pat::CandidateSummaryTable::CandidateSummaryTable(const edm::ParameterSet& iConfig, const pathelpers::RecordCache*) {
0097   const std::vector<edm::InputTag>& inputs = iConfig.getParameter<std::vector<edm::InputTag> >("candidates");
0098   for (std::vector<edm::InputTag>::const_iterator it = inputs.begin(); it != inputs.end(); ++it) {
0099     srcTokens.emplace_back(*it, consumes<edm::View<reco::Candidate> >(*it));
0100   }
0101 }
0102 
0103 pat::CandidateSummaryTable::~CandidateSummaryTable() {}
0104 
0105 void pat::CandidateSummaryTable::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0106   using namespace edm;
0107   using std::left;
0108   using std::right;
0109   using std::setprecision;
0110   using std::setw;
0111 
0112   Handle<View<reco::Candidate> > candidates;
0113   if (globalCache()->perEvent_) {
0114     LogInfo(globalCache()->logName_) << "Per Event Table " << globalCache()->logName_ << " (" << globalCache()->self_
0115                                      << ", run:event " << iEvent.id().run() << ":" << iEvent.id().event() << ")";
0116   }
0117   ++(globalCache()->totalEvents_);
0118   auto& collections = globalCache()->collections_;
0119   auto tags = srcTokens.cbegin();
0120   for (auto it = collections.begin(), ed = collections.end(); it != ed; ++it, ++tags) {
0121     iEvent.getByToken(tags->second, candidates);
0122     if (!candidates.failedToGet())
0123       it->update(*candidates);
0124     if (globalCache()->perEvent_) {
0125       LogVerbatim(globalCache()->logName_) << "    " << setw(30) << left << it->src.encode() << right;
0126       if (globalCache()->dumpItems_) {
0127         size_t i = 0;
0128         std::ostringstream oss;
0129         for (View<reco::Candidate>::const_iterator cand = candidates->begin(), endc = candidates->end(); cand != endc;
0130              ++cand, ++i) {
0131           oss << "      [" << setw(3) << i << "]"
0132               << "  pt " << setw(7) << setprecision(5) << cand->pt() << "  eta " << setw(7) << setprecision(5)
0133               << cand->eta() << "  phi " << setw(7) << setprecision(5) << cand->phi() << "  et " << setw(7)
0134               << setprecision(5) << cand->et() << "  phi " << setw(7) << setprecision(5) << cand->phi() << "  charge "
0135               << setw(2) << cand->charge() << "  id " << setw(7) << cand->pdgId() << "  st " << setw(7)
0136               << cand->status() << "\n";
0137         }
0138         LogVerbatim(globalCache()->logName_) << oss.str();
0139       }
0140     }
0141   }
0142   if (globalCache()->perEvent_)
0143     LogInfo(globalCache()->logName_) << "";  // add an empty line
0144 }
0145 
0146 void pat::CandidateSummaryTable::globalEndJob(const pathelpers::RecordCache* rcd) {
0147   using std::left;
0148   using std::right;
0149   using std::setprecision;
0150   using std::setw;
0151   if (rcd->perJob_) {
0152     std::ostringstream oss;
0153     oss << "Summary Table " << rcd->logName_ << " (" << rcd->self_ << ", events total " << rcd->totalEvents_ << ")\n";
0154     for (auto it = rcd->collections_.cbegin(), ed = rcd->collections_.cend(); it != ed; ++it) {
0155       oss << "    " << setw(30) << left << it->src.encode() << right << "  present " << setw(7) << it->present << " ("
0156           << setw(4) << setprecision(3) << (it->present * 100.0 / rcd->totalEvents_) << "%)"
0157           << "  empty " << setw(7) << it->empty << " (" << setw(4) << setprecision(3)
0158           << (it->empty * 100.0 / rcd->totalEvents_) << "%)"
0159           << "  min " << setw(7) << it->min << "  max " << setw(7) << it->max << "  total " << setw(7) << it->total
0160           << "  avg " << setw(5) << setprecision(3) << (it->total / double(rcd->totalEvents_)) << "\n";
0161     }
0162     oss << "\n";
0163     edm::LogVerbatim(rcd->logName_) << oss.str();
0164   }
0165 }
0166 
0167 #include "FWCore/Framework/interface/MakerMacros.h"
0168 using pat::CandidateSummaryTable;
0169 DEFINE_FWK_MODULE(CandidateSummaryTable);