File indexing completed on 2024-04-06 12:23:47
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
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_;
0073 };
0074
0075 }
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 }
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_) << "";
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);