/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
DQMServices/Components/plugins/DQMStoreStats.cc
1 124 строки
41 KB
Shahzad Malik Muzaffar
[DQM] [GCC16] cleanup for unused variables
20 май 2026, 13:08
20 май 2026, 13:08
6bb69b0
Код
Авторство
О чём код?
/* * \file DQMStoreStats.cc * \author Andreas Meyer * Last Update: * * Description: Print out statistics of histograms in DQMStore */ /** \class DQMStoreStats * * * DQM Test Client * * \author Andreas Meyer CERN * \author Jan Olzem DESY * */ #include <string> #include <sstream> #include <utility> #include <vector> #include <iostream> #include <iomanip> #include <utility> #include <fstream> #include <sstream> #include "TFile.h" #include "TTree.h" #include "DQMServices/Core/interface/DQMStore.h" #include "FWCore/Framework/interface/one/EDAnalyzer.h" #include "FWCore/MessageLogger/interface/JobReport.h" #include "FWCore/ParameterSet/interface/ParameterSet.h" #include "FWCore/ServiceRegistry/interface/Service.h" // // class declarations // using dqm::legacy::DQMStore; using dqm::legacy::MonitorElement; /// /// DQMStoreStats helper class for /// storing subsystem results /// class DQMStoreStatsSubfolder { public: DQMStoreStatsSubfolder() { totalHistos_ = 0; totalBins_ = 0; totalMemory_ = 0; totalEmptyBins_ = 0; } std::string subfolderName_; unsigned int totalHistos_; unsigned int totalBins_; unsigned int totalEmptyBins_; unsigned int totalMemory_; void AddBinsF(unsigned int nBins, unsigned int nEmptyBins) { ++totalHistos_; totalBins_ += nBins; totalEmptyBins_ += nEmptyBins; totalMemory_ += (nBins * sizeof(float)); } void AddBinsS(unsigned int nBins, unsigned int nEmptyBins) { ++totalHistos_; totalBins_ += nBins; totalEmptyBins_ += nEmptyBins; totalMemory_ += (nBins * sizeof(short)); } void AddBinsD(unsigned int nBins, unsigned int nEmptyBins) { ++totalHistos_; totalBins_ += nBins; totalEmptyBins_ += nEmptyBins; totalMemory_ += (nBins * sizeof(double)); } void AddBinsI(unsigned int nBins, unsigned int nEmptyBins) { ++totalHistos_; totalBins_ += nBins; totalEmptyBins_ += nEmptyBins; totalMemory_ += (nBins * sizeof(int)); } }; /// /// DQMStoreStats helper class for /// storing subsystem results /// class DQMStoreStatsSubsystem : public std::vector<DQMStoreStatsSubfolder> { public: DQMStoreStatsSubsystem() = default; std::string subsystemName_; }; /// /// DQMStoreStats helper class for /// storing subsystem results /// class DQMStoreStatsTopLevel : public std::vector<DQMStoreStatsSubsystem> { public: DQMStoreStatsTopLevel() = default; }; template <class Item> class Iterator { public: virtual ~Iterator() = default; virtual void First() = 0; virtual void Next() = 0; virtual bool IsDone() const = 0; virtual Item CurrentItem() const = 0; protected: Iterator() = default; }; template <class Item> class VIterator : public Iterator<Item> { public: VIterator(const std::vector<Item>* aVector) : vector_(aVector), index(0) {} ~VIterator() override = default; void First() override { index = 0; } void Next() override { ++index; } virtual int size() { return vector_->size(); } virtual int getIndex() { return (int)index; } bool IsDone() const override { if (index < (unsigned int)vector_->size()) return false; return true; } Item CurrentItem() const override { return vector_->operator[](index); } private: const std::vector<Item>* vector_; unsigned int index; }; static unsigned int getId() { static unsigned int id = 10; return ++id; } class Folder { public: Folder(std::string name) : totalHistos_(0), totalBins_(0), totalEmptyBins_(0), totalMemory_(0), id_(10), level_(0), folderName_(std::move(name)), father_(nullptr) {} ~Folder() { for (auto& subfolder : subfolders_) delete subfolder; } void setFather(Folder* e) { father_ = e; } Folder* getFather() { return father_; } const std::string& name() { return folderName_; } Folder* cd(const std::string& name) { for (auto& subfolder : subfolders_) if (subfolder->name() == name) return subfolder; auto* tmp = new Folder(name); this->add(tmp); return tmp; } void setId(unsigned int id) { id_ = id; } unsigned int id() { return id_; } void setLevel(unsigned int value) { level_ = value; } unsigned int level() { return level_; } void add(Folder* f) { f->setFather(this); subfolders_.push_back(f); f->setLevel(level_ + 1); f->setId(getId()); } unsigned int getHistos() { unsigned int result = totalHistos_; for (auto& subfolder : subfolders_) result += subfolder->getHistos(); return result; } unsigned int getBins() { unsigned int result = totalBins_; for (auto& subfolder : subfolders_) result += subfolder->getBins(); return result; } unsigned int getEmptyBins() { unsigned int result = totalEmptyBins_; for (auto& subfolder : subfolders_) result += subfolder->getEmptyBins(); return result; } unsigned int getMemory() { unsigned int result = totalMemory_; for (auto& subfolder : subfolders_) result += subfolder->getMemory(); return result; } void update(unsigned int bins, unsigned int empty, unsigned int memory) { totalHistos_ += 1; totalBins_ += bins; totalEmptyBins_ += empty; totalMemory_ += memory; } void dump(std::string indent) { indent.append(" "); std::cout << indent << "I'm a " << name() << " whose father is " << getFather() << " with ID: " << id_ << " Histo: " << getHistos() << " Bins: " << getBins() << " EmptyBins: " << getEmptyBins() << " Memory: " << getMemory() << " and my children are: " << std::endl; for (auto& subfolder : subfolders_) subfolder->dump(indent); } VIterator<Folder*> CreateIterator() { return VIterator<Folder*>(&subfolders_); } void mainrows(std::string& sql_statement) { std::stringstream s(""); s << "INSERT INTO mainrows(id, symbol_id, self_count, cumulative_count, kids, self_calls, total_calls, self_paths, " "total_paths, pct)" " VALUES(" << id_ << ", " << id_ << ", " << getMemory() << ", " << getMemory() << ", " << subfolders_.size() << ", " << getBins() - getEmptyBins() << ", " << getBins() << ", " << getHistos() << ", " << getHistos() << ", 0.0);\n"; sql_statement.append(s.str()); for (auto& subfolder : subfolders_) subfolder->mainrows(sql_statement); } void symbols(std::string& sql_statement) { unsigned int parentid = this->getFather() ? this->getFather()->id() : id_; std::stringstream s(""); s << "INSERT INTO symbols(id, name, filename_id) VALUES (" << id_ << ",\"" << folderName_ << "\", " << parentid << ");\n"; sql_statement.append(s.str()); for (auto& subfolder : subfolders_) subfolder->symbols(sql_statement); } void parents(std::string& sql_statement) { unsigned int parentid = this->getFather() ? this->getFather()->id() : id_; std::stringstream s(""); s << "INSERT INTO parents(self_id, child_id, to_child_count, to_child_calls, to_child_paths, pct) VALUES(" << parentid << "," << id_ << "," << totalMemory_ << "," << totalBins_ << "," << totalHistos_ << ",0" << ");\n"; sql_statement.append(s.str()); for (auto& subfolder : subfolders_) subfolder->parents(sql_statement); } void children(std::string& sql_statement) { unsigned int parentid = this->getFather() ? this->getFather()->id() : id_; std::stringstream s(""); s << "INSERT INTO children(self_id, parent_id, from_parent_count, from_parent_calls, from_parent_paths, pct) " "VALUES(" << id_ << "," << parentid << "," << getMemory() << "," << getBins() - getEmptyBins() << "," << totalHistos_ << ",0" << ");\n"; sql_statement.append(s.str()); for (auto& subfolder : subfolders_) subfolder->children(sql_statement); } void mainrows_cumulative(std::string& sql_statement) { std::stringstream s(""); s << "INSERT INTO mainrows(id, symbol_id, self_count, cumulative_count, kids, self_calls, total_calls, self_paths, " "total_paths, pct)" << " VALUES(" << id_ << "," << id_ << "," << 0 << "," << getMemory() << ", 0," << getBins() - getEmptyBins() << "," << getBins() << ", 0, " << getHistos() << ", 0);\n"; sql_statement.append(s.str()); } void summary(std::string& sql_statement) { std::stringstream s(""); s << "INSERT INTO summary(counter, total_count, total_freq, tick_period) VALUES (\"BINS_LIVE\"," << getMemory() << "," << getBins() << ", 1);\n"; sql_statement.append(s.str()); } void files(std::string& sql_statement) { std::stringstream s(""); s << "INSERT INTO files(id, name) VALUES(" << id_ << ",\"" << folderName_ << "\");\n"; sql_statement.append(s.str()); } private: unsigned int totalHistos_; unsigned int totalBins_; unsigned int totalEmptyBins_; unsigned int totalMemory_; unsigned int id_; unsigned int level_; std::string folderName_; Folder* father_; std::vector<Folder*> subfolders_; }; /// /// DQMStoreStats itself /// class DQMStoreStats : public edm::one::EDAnalyzer<edm::one::WatchRuns, edm::one::WatchLuminosityBlocks> { public: DQMStoreStats(const edm::ParameterSet&); ~DQMStoreStats() override = default; enum statsMode { considerAllME = 0, considerOnlyLumiProductME = 1 }; protected: // BeginJob void beginJob() override; // BeginRun void beginRun(const edm::Run& r, const edm::EventSetup& c) override; // Fake Analyze void analyze(const edm::Event& e, const edm::EventSetup& c) override; // DQM Client Diagnostic void beginLuminosityBlock(const edm::LuminosityBlock& lumiSeg, const edm::EventSetup& c) override; void endLuminosityBlock(const edm::LuminosityBlock& lumiSeg, const edm::EventSetup& c) override; // EndRun void endRun(const edm::Run& r, const edm::EventSetup& c) override; // Endjob void endJob() override; private: int calcstats(int); std::vector<double> GetTH2PolyArray(TH2Poly* poly); void calcIgProfDump(Folder&); void dumpMemoryProfile(); std::pair<unsigned int, unsigned int> readMemoryEntry() const; void print(); DQMStore* dbe_; edm::ParameterSet parameters_; std::string subsystem_; std::string subfolder_; int nbinsglobal_; int nbinssubsys_; int nmeglobal_; int nmesubsys_; int maxbinsglobal_; int maxbinssubsys_; std::string maxbinsmeglobal_; std::string maxbinsmesubsys_; int statsdepth_; std::string pathnamematch_; int verbose_; std::vector<std::pair<time_t, unsigned int> > memoryHistoryVector_; time_t startingTime_; bool isOpenProcFileSuccessful_; std::stringstream procFileName_; bool runonendrun_; bool runonendjob_; bool runonendlumi_; bool runineventloop_; bool dumpMemHistory_; bool dumpToFWJR_; // ---------- member data ---------- }; using namespace std; using namespace edm; template <class T> static unsigned int getEmptyMetric(T* array, int lenx, int leny, int lenz) { // len{x,y,z} MUST include under/overflow bins. unsigned int len = lenx + leny + lenz; unsigned int result = 0; // start from 1 to exclude underflow bin. The comparison is accurate // since it takes properly into account under/overflow bins, for all // kind of histograms. for (unsigned int i = 1; i < len; ++i) { // get rid of under/overflow bins for x,y,z axis, to have a correct statistics. if (i % (lenx - 1) == 0) continue; if (i % lenx == 0) continue; if (i % (lenx + leny - 1) == 0) continue; if (i % (lenx + leny) == 0) continue; if (i % (lenx + leny + lenz - 1) == 0) continue; if (array[i] == 0) result += 1; } return result; } //==================================================================// //================= Constructor and Destructor =====================// //==================================================================// DQMStoreStats::DQMStoreStats(const edm::ParameterSet& ps) : subsystem_(""), subfolder_(""), nbinsglobal_(0), nbinssubsys_(0), nmeglobal_(0), nmesubsys_(0), maxbinsglobal_(0), maxbinssubsys_(0), maxbinsmeglobal_(""), maxbinsmesubsys_(""), statsdepth_(1), pathnamematch_(""), verbose_(0) { parameters_ = ps; pathnamematch_ = ps.getUntrackedParameter<std::string>("pathNameMatch", pathnamematch_); statsdepth_ = ps.getUntrackedParameter<int>("statsDepth", statsdepth_); verbose_ = ps.getUntrackedParameter<int>("verbose", verbose_); dumpMemHistory_ = ps.getUntrackedParameter<bool>("dumpMemoryHistory", false); runonendrun_ = ps.getUntrackedParameter<bool>("runOnEndRun", true); runonendjob_ = ps.getUntrackedParameter<bool>("runOnEndJob", false); runonendlumi_ = ps.getUntrackedParameter<bool>("runOnEndLumi", false); runineventloop_ = ps.getUntrackedParameter<bool>("runInEventLoop", false); dumpToFWJR_ = ps.getUntrackedParameter<bool>("dumpToFWJR", false); startingTime_ = time(nullptr); } void DQMStoreStats::calcIgProfDump(Folder& root) { std::ofstream stream("dqm-bin-stats.sql"); stream << "" " PRAGMA journal_mode=OFF;" " PRAGMA count_changes=OFF;" " DROP TABLE IF EXISTS files;" " DROP TABLE IF EXISTS symbols;" " DROP TABLE IF EXISTS mainrows;" " DROP TABLE IF EXISTS children;" " DROP TABLE IF EXISTS parents;" " DROP TABLE IF EXISTS summary;" " CREATE TABLE children (" " self_id INTEGER CONSTRAINT self_exists REFERENCES mainrows(id)," " parent_id INTEGER CONSTRAINT parent_exists REFERENCES mainrows(id)," " from_parent_count INTEGER," " from_parent_calls INTEGER," " from_parent_paths INTEGER," " pct REAL" " );" " CREATE TABLE files (" " id," " name TEXT" " );" " CREATE TABLE mainrows (" " id INTEGER PRIMARY KEY," " symbol_id INTEGER CONSTRAINT symbol_id_exists REFERENCES symbols(id)," " self_count INTEGER," " cumulative_count INTEGER," " kids INTEGER," " self_calls INTEGER," " total_calls INTEGER," " self_paths INTEGER," " total_paths INTEGER," " pct REAL" " );" " CREATE TABLE parents (" " self_id INTEGER CONSTRAINT self_exists REFERENCES mainrows(id)," " child_id INTEGER CONSTRAINT child_exists REFERENCES mainrows(id)," " to_child_count INTEGER," " to_child_calls INTEGER," " to_child_paths INTEGER," " pct REAL" " );" " CREATE TABLE summary (" " counter TEXT," " total_count INTEGER," " total_freq INTEGER," " tick_period REAL" " );" " CREATE TABLE symbols (" " id," " name TEXT," " filename_id INTEGER CONSTRAINT file_id_exists REFERENCES files(id)" " );" " CREATE UNIQUE INDEX fileIndex ON files (id);" " CREATE INDEX selfCountIndex ON mainrows(self_count);" " CREATE UNIQUE INDEX symbolsIndex ON symbols (id);" " CREATE INDEX totalCountIndex ON mainrows(cumulative_count);" << std::endl; std::string sql_statement(""); root.files(sql_statement); root.symbols(sql_statement); root.mainrows_cumulative(sql_statement); root.summary(sql_statement); VIterator<Folder*> subsystems = root.CreateIterator(); for (subsystems.First(); !subsystems.IsDone(); subsystems.Next()) { subsystems.CurrentItem()->mainrows(sql_statement); subsystems.CurrentItem()->parents(sql_statement); subsystems.CurrentItem()->children(sql_statement); } stream << sql_statement << std::endl; } std::vector<double> DQMStoreStats::GetTH2PolyArray(TH2Poly* poly) { int nBins = poly->GetNumberOfBins(); std::vector<double> array(nBins + 1, 0.0); // Initialize with zeros for (int i = 1; i <= nBins; i++) { array[i] = poly->GetBinContent(i); } return array; } /// /// do the stats here and produce output; /// /// mode is coded in DQMStoreStats::statMode enum /// (select subsets of ME, e.g. those with getLumiFlag() == true) /// int DQMStoreStats::calcstats(int mode = DQMStoreStats::considerAllME) { ////---- initialise Event and LS counters nbinsglobal_ = 0; nbinssubsys_ = 0; maxbinsglobal_ = 0; maxbinssubsys_ = 0; std::string path = ""; std::string subsystemname = ""; std::string subfoldername = ""; size_t subsysStringEnd = 0, subfolderStringBegin = 0, subfolderStringEnd = 0; std::vector<MonitorElement*> melist; melist = dbe_->getAllContents(pathnamematch_); Folder dbeFolder("root"); DQMStoreStatsTopLevel dqmStoreStatsTopLevel; // loop all ME for (auto& it : melist) { // consider only ME with getLumiFlag() == true ? if (mode == DQMStoreStats::considerOnlyLumiProductME && !(it->getLumiFlag())) continue; // figure out subsystem/subfolder names const std::string& path = it->getPathname(); subfolderStringBegin = 0; Folder* curr = &dbeFolder; while (true) { subfolderStringEnd = path.find('/', subfolderStringBegin); if (std::string::npos == subfolderStringEnd) { curr = curr->cd(path.substr(subfolderStringBegin, path.size() - subfolderStringBegin)); break; } curr = curr->cd(path.substr(subfolderStringBegin, subfolderStringEnd - subfolderStringBegin)); subfolderStringBegin = ++subfolderStringEnd < path.size() ? subfolderStringEnd : path.size(); } // protection against ghost ME with empty paths if (path.empty()) continue; subsysStringEnd = path.find('/', 0); if (std::string::npos == subsysStringEnd) subsysStringEnd = path.size(); // no subfolder // new subsystem? if (path.substr(0, subsysStringEnd) != subsystemname) { DQMStoreStatsSubsystem aSubsystem; subsystemname = path.substr(0, subsysStringEnd); aSubsystem.subsystemName_ = subsystemname; dqmStoreStatsTopLevel.push_back(aSubsystem); subfoldername = ""; } // get subfolder name (if there is one..) if (path.size() == subsysStringEnd) { // no subfolders in subsystem, make dummy DQMStoreStatsSubfolder aSubfolder; aSubfolder.subfolderName_ = subsystemname; // <-- for tagging this case dqmStoreStatsTopLevel.back().push_back(aSubfolder); } else { // there is a subfolder, get its name subfolderStringEnd = path.find('/', subsysStringEnd + 1); if (std::string::npos == subfolderStringEnd) subfolderStringEnd = path.size(); // new subfolder? if (path.substr(subsysStringEnd + 1, subfolderStringEnd - subsysStringEnd - 1) != subfoldername) { subfoldername = path.substr(subsysStringEnd + 1, subfolderStringEnd - subsysStringEnd - 1); DQMStoreStatsSubfolder aSubfolder; aSubfolder.subfolderName_ = subfoldername; dqmStoreStatsTopLevel.back().push_back(aSubfolder); } } // shortcut DQMStoreStatsSubfolder& currentSubfolder = dqmStoreStatsTopLevel.back().back(); switch (it->kind()) { // one-dim ME case MonitorElement::Kind::TH1F: currentSubfolder.AddBinsF(it->getNbinsX(), getEmptyMetric(it->getTH1F()->GetArray(), it->getTH1F()->fN, 0, 0)); curr->update(it->getNbinsX(), getEmptyMetric(it->getTH1F()->GetArray(), it->getTH1F()->fN, 0, 0), it->getNbinsX() * sizeof(float)); break; case MonitorElement::Kind::TH1S: currentSubfolder.AddBinsS(it->getNbinsX(), getEmptyMetric(it->getTH1S()->GetArray(), it->getTH1S()->fN, 0, 0)); curr->update(it->getNbinsX(), getEmptyMetric(it->getTH1S()->GetArray(), it->getTH1S()->fN, 0, 0), it->getNbinsX() * sizeof(short)); break; case MonitorElement::Kind::TH1D: currentSubfolder.AddBinsD(it->getNbinsX(), getEmptyMetric(it->getTH1D()->GetArray(), it->getTH1D()->fN, 0, 0)); curr->update(it->getNbinsX(), getEmptyMetric(it->getTH1D()->GetArray(), it->getTH1D()->fN, 0, 0), it->getNbinsX() * sizeof(double)); break; case MonitorElement::Kind::TH1I: currentSubfolder.AddBinsI(it->getNbinsX(), getEmptyMetric(it->getTH1I()->GetArray(), it->getTH1I()->fN, 0, 0)); curr->update(it->getNbinsX(), getEmptyMetric(it->getTH1I()->GetArray(), it->getTH1I()->fN, 0, 0), it->getNbinsX() * sizeof(int)); break; case MonitorElement::Kind::TPROFILE: currentSubfolder.AddBinsD(it->getNbinsX(), getEmptyMetric(it->getTProfile()->GetArray(), it->getTProfile()->fN, 0, 0)); curr->update(it->getNbinsX(), getEmptyMetric(it->getTProfile()->GetArray(), it->getTProfile()->fN, 0, 0), it->getNbinsX() * sizeof(double)); break; // two-dim ME case MonitorElement::Kind::TH2F: currentSubfolder.AddBinsF( it->getNbinsX() * it->getNbinsY(), getEmptyMetric(it->getTH2F()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0)); curr->update(it->getNbinsX() * it->getNbinsY(), getEmptyMetric(it->getTH2F()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0), it->getNbinsX() * it->getNbinsY() * sizeof(float)); break; case MonitorElement::Kind::TH2S: currentSubfolder.AddBinsS( it->getNbinsX() * it->getNbinsY(), getEmptyMetric(it->getTH2S()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0)); curr->update(it->getNbinsX() * it->getNbinsY(), getEmptyMetric(it->getTH2S()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0), it->getNbinsX() * it->getNbinsY() * sizeof(short)); break; case MonitorElement::Kind::TH2D: currentSubfolder.AddBinsD( it->getNbinsX() * it->getNbinsY(), getEmptyMetric(it->getTH2D()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0)); curr->update(it->getNbinsX() * it->getNbinsY(), getEmptyMetric(it->getTH2D()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0), it->getNbinsX() * it->getNbinsY() * sizeof(double)); break; case MonitorElement::Kind::TH2I: currentSubfolder.AddBinsI( it->getNbinsX() * it->getNbinsY(), getEmptyMetric(it->getTH2I()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0)); curr->update(it->getNbinsX() * it->getNbinsY(), getEmptyMetric(it->getTH2I()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0), it->getNbinsX() * it->getNbinsY() * sizeof(int)); break; case MonitorElement::Kind::TH2Poly: { std::vector<double> polyArray = GetTH2PolyArray(it->getTH2Poly()); int nBins = polyArray.size() - 1; currentSubfolder.AddBinsD(nBins, getEmptyMetric(polyArray.data(), nBins + 1, 1, 0)); curr->update(nBins, getEmptyMetric(polyArray.data(), nBins + 1, 1, 0), nBins * sizeof(double)); break; } case MonitorElement::Kind::TPROFILE2D: currentSubfolder.AddBinsD( it->getNbinsX() * it->getNbinsY(), getEmptyMetric(it->getTProfile2D()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0)); curr->update(it->getNbinsX() * it->getNbinsY(), getEmptyMetric(it->getTProfile2D()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, 0), it->getNbinsX() * it->getNbinsY() * sizeof(double)); break; // three-dim ME case MonitorElement::Kind::TH3F: currentSubfolder.AddBinsF( it->getNbinsX() * it->getNbinsY() * it->getNbinsZ(), getEmptyMetric(it->getTH3F()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, it->getNbinsZ() + 2)); curr->update( it->getNbinsX() * it->getNbinsY() * it->getNbinsZ(), getEmptyMetric(it->getTH3F()->GetArray(), it->getNbinsX() + 2, it->getNbinsY() + 2, it->getNbinsZ() + 2), it->getNbinsX() * it->getNbinsY() * it->getNbinsZ() * sizeof(float)); break; default: { } // here we have a DQM_KIND_INVALID, DQM_KIND_INT, DQM_KIND_REAL or DQM_KIND_STRING // which we don't care much about. Alternatively: // std::cerr << "[DQMStoreStats::calcstats] ** WARNING: monitor element of kind: " // << (*it)->kind() << ", name: \"" << (*it)->getName() << "\"\n" // << " in path: \"" << path << "\" not considered." << std::endl; } } if (mode == DQMStoreStats::considerAllME) calcIgProfDump(dbeFolder); // OUTPUT std::cout << endl; std::cout << "===========================================================================================" << std::endl; std::cout << "[DQMStoreStats::calcstats] -- Dumping stats results "; if (mode == DQMStoreStats::considerAllME) std::cout << "FOR ALL ME" << std::endl; else if (mode == DQMStoreStats::considerOnlyLumiProductME) std::cout << "FOR LUMI PRODUCTS ONLY" << std::endl; std::cout << "===========================================================================================" << std::endl; std::cout << endl; std::cout << "------------------------------------------------------------------------------------------" << std::endl; std::cout << "Configuration:" << std::endl; std::cout << "------------------------------------------------------------------------------------------" << std::endl; std::cout << " > running "; if (runonendrun_) std::cout << "on run end." << std::endl; if (runonendlumi_) std::cout << "on lumi end." << std::endl; if (runonendjob_) std::cout << "on job end." << std::endl; if (runineventloop_) std::cout << "in event loop." << std::endl; std::cout << " > pathNameMatch = \"" << pathnamematch_ << "\"" << std::endl; std::cout << std::endl; // dump folder structure std::cout << "------------------------------------------------------------------------------------------" << std::endl; std::cout << "Top level folder tree:" << std::endl; std::cout << "------------------------------------------------------------------------------------------" << std::endl; for (auto it0 = dqmStoreStatsTopLevel.begin(); it0 < dqmStoreStatsTopLevel.end(); ++it0) { std::cout << it0->subsystemName_ << " (subsystem)" << std::endl; for (auto it1 = it0->begin(); it1 < it0->end(); ++it1) { std::cout << " |--> " << it1->subfolderName_ << " (subfolder)" << std::endl; } } // dump mem/bin table unsigned int overallNHistograms = 0, overallNBins = 0, overallNBytes = 0; std::cout << std::endl; std::cout << "------------------------------------------------------------------------------------------" << std::endl; std::cout << "Detailed ressource usage information "; if (mode == DQMStoreStats::considerAllME) std::cout << "FOR ALL ME" << std::endl; else if (mode == DQMStoreStats::considerOnlyLumiProductME) std::cout << "FOR LUMI PRODUCTS ONLY" << std::endl; std::cout << "------------------------------------------------------------------------------------------" << std::endl; std::cout << "subsystem/folder histograms bins Empty bins Empty/Total " "bins per MB kB per" << std::endl; std::cout << " (total) (total) (total) " "histogram (total) histogram " << std::endl; std::cout << "------------------------------------------------------------------------------------------" << std::endl; for (auto it0 = dqmStoreStatsTopLevel.begin(); it0 < dqmStoreStatsTopLevel.end(); ++it0) { std::cout << it0->subsystemName_ << std::endl; unsigned int nHistograms = 0, nBins = 0, nEmptyBins = 0, nBytes = 0; for (auto it1 = it0->begin(); it1 < it0->end(); ++it1) { // fixed-size working copy std::string thisSubfolderName(it1->subfolderName_); if (thisSubfolderName.size() > 30) { thisSubfolderName.resize(30); thisSubfolderName.replace(thisSubfolderName.size() - 3, 3, 3, '.'); } std::cout << " -> " << std::setw(30) << std::left << thisSubfolderName; std::cout << std::setw(14) << std::right << it1->totalHistos_; std::cout << std::setw(14) << std::right << it1->totalBins_; std::cout << std::setw(14) << std::right << it1->totalEmptyBins_; std::cout << std::setw(14) << std::right << std::setprecision(3) << (float)it1->totalEmptyBins_ / (float)it1->totalBins_; // bins/histogram, need to catch nan if histos=0 if (it1->totalHistos_) { std::cout << std::setw(14) << std::right << std::setprecision(3) << it1->totalBins_ / float(it1->totalHistos_); } else std::cout << std::setw(14) << std::right << "-"; std::cout << std::setw(14) << std::right << std::setprecision(3) << it1->totalMemory_ / 1024. / 1024.; // mem/histogram, need to catch nan if histos=0 if (it1->totalHistos_) { std::cout << std::setw(14) << std::right << std::setprecision(3) << it1->totalMemory_ / 1024. / it1->totalHistos_; } else std::cout << std::setw(14) << std::right << "-"; std::cout << std::endl; // collect totals nHistograms += it1->totalHistos_; nBins += it1->totalBins_; nEmptyBins += it1->totalEmptyBins_; nBytes += it1->totalMemory_; } overallNHistograms += nHistograms; overallNBins += nBins; overallNBytes += nBytes; // display totals std::cout << " " << std::setw(30) << std::left << "SUBSYSTEM TOTAL"; std::cout << std::setw(14) << std::right << nHistograms; std::cout << std::setw(14) << std::right << nBins; std::cout << std::setw(14) << std::right << nEmptyBins; std::cout << std::setw(14) << std::right << (float)nEmptyBins / (float)nBins; std::cout << std::setw(14) << std::right << std::setprecision(3) << nBins / float(nHistograms); std::cout << std::setw(14) << std::right << std::setprecision(3) << nBytes / 1024. / 1000.; std::cout << std::setw(14) << std::right << std::setprecision(3) << nBytes / 1024. / nHistograms; std::cout << std::endl; std::cout << ".........................................................................................." << std::endl; } // dump total std::cout << std::endl; std::cout << "------------------------------------------------------------------------------------------" << std::endl; std::cout << "Grand total "; if (mode == DQMStoreStats::considerAllME) std::cout << "FOR ALL ME:" << std::endl; else if (mode == DQMStoreStats::considerOnlyLumiProductME) std::cout << "FOR LUMI PRODUCTS ONLY:" << std::endl; std::cout << "------------------------------------------------------------------------------------------" << std::endl; std::cout << "Number of subsystems: " << dqmStoreStatsTopLevel.size() << std::endl; std::cout << "Total number of histograms: " << overallNHistograms << " with: " << overallNBins << " bins alltogether" << std::endl; std::cout << "Total memory occupied by histograms (excl. overhead): " << overallNBytes / 1024. / 1000. << " MB" << std::endl; std::cout << endl; std::cout << "===========================================================================================" << std::endl; std::cout << "[DQMStoreStats::calcstats] -- End of output "; if (mode == DQMStoreStats::considerAllME) std::cout << "FOR ALL ME." << std::endl; else if (mode == DQMStoreStats::considerOnlyLumiProductME) std::cout << "FOR LUMI PRODUCTS ONLY." << std::endl; std::cout << "===========================================================================================" << std::endl; std::cout << endl; // Put together a simplified version of the complete dump that is // sent to std::cout. Just dump the very basic information, // i.e. summary for each folder, both for run and LS products. if (dumpToFWJR_) { edm::Service<edm::JobReport> jr; // Do not even try if the FWJR service is not available. if (!jr.isAvailable()) return 0; // Prepare appropriate map to store FWJR output. std::map<std::string, std::string> jrInfo; jrInfo["Source"] = "DQMServices/Components"; jrInfo["FileClass"] = "DQMStoreStats"; if (runonendrun_) jrInfo["DumpType"] = "EndRun"; if (runonendlumi_) jrInfo["DumpType"] = "EndLumi"; if (runonendjob_) jrInfo["DumpType"] = "EndJob"; if (runineventloop_) jrInfo["DumpType"] = "EventLoop"; if (mode == DQMStoreStats::considerAllME) jrInfo["Type"] = "RunProduct"; else if (mode == DQMStoreStats::considerOnlyLumiProductME) jrInfo["Type"] = "LumiProduct"; jrInfo["pathNameMatch"] = pathnamematch_; for (auto it0 = dqmStoreStatsTopLevel.begin(); it0 < dqmStoreStatsTopLevel.end(); ++it0) { unsigned int nHistograms = 0, nBins = 0, nEmptyBins = 0, nBytes = 0; for (auto it1 = it0->begin(); it1 < it0->end(); ++it1) { // collect totals nHistograms += it1->totalHistos_; nBins += it1->totalBins_; nEmptyBins += it1->totalEmptyBins_; nBytes += it1->totalMemory_; } std::stringstream iss(""); iss << nHistograms; jrInfo[it0->subsystemName_ + std::string("_h")] = iss.str(); iss.str(""); iss << nBins; jrInfo[it0->subsystemName_ + std::string("_b")] = iss.str(); iss.str(""); iss << nEmptyBins; jrInfo[it0->subsystemName_ + std::string("_be")] = iss.str(); iss.str(""); iss << ((float)nEmptyBins / (float)nBins); jrInfo[it0->subsystemName_ + std::string("_fbe")] = iss.str(); iss.str(""); iss << ((float)nBins / (float)nHistograms); jrInfo[it0->subsystemName_ + std::string("_b_h")] = iss.str(); iss.str(""); iss << nBytes / 1024. / 1024.; jrInfo[it0->subsystemName_ + std::string("_MB")] = iss.str(); iss.str(""); iss << nBytes / 1024. / nHistograms; jrInfo[it0->subsystemName_ + std::string("_Kb_h")] = iss.str(); } jr->reportAnalysisFile("DQMStatsReport", jrInfo); } return 0; } /// /// /// void DQMStoreStats::dumpMemoryProfile() { std::cout << std::endl; std::cout << "------------------------------------------------------------------------------------------" << std::endl; std::cout << "Memory profile:" << std::endl; std::cout << "------------------------------------------------------------------------------------------" << std::endl; // determine virtual memory maximum std::pair<time_t, unsigned int> maxItem(0, 0); for (auto it = memoryHistoryVector_.begin(); it < memoryHistoryVector_.end(); ++it) { if (it->second > maxItem.second) { maxItem = *it; } } std::stringstream rootOutputFileName; rootOutputFileName << "dqmStoreStats_memProfile_" << getpid() << ".root"; // dump memory history to root file if (dumpMemHistory_ && isOpenProcFileSuccessful_) { TFile outputFile(rootOutputFileName.str().c_str(), "RECREATE"); int aTime; float aMb; TTree memHistoryTree("dqmstorestats_memhistory", "memory history"); memHistoryTree.Branch("seconds", &aTime, "seconds/I"); memHistoryTree.Branch("megabytes", &aMb, "megabytes/F"); for (auto it = memoryHistoryVector_.begin(); it < memoryHistoryVector_.end(); ++it) { aTime = it->first - startingTime_; aMb = it->second / 1000.; memHistoryTree.Fill(); } outputFile.Write(); outputFile.Close(); } std::cout << "Approx. maximum total virtual memory size of job: "; if (isOpenProcFileSuccessful_ && !memoryHistoryVector_.empty()) { std::cout << maxItem.second / 1000. << " MB (reached " << maxItem.first - startingTime_ << " sec. after constructor called)," << std::endl; std::cout << " memory history written to: " << rootOutputFileName.str() << " (" << memoryHistoryVector_.size() << " samples)" << std::endl; } else { std::cout << "(could not be determined)" << std::endl; } std::cout << std::endl << std::endl; } /// /// /// void DQMStoreStats::print() { // subsystem info printout std::cout << " ---------- " << subsystem_ << " ---------- " << std::endl; std::cout << " " << subfolder_ << ": "; std::cout << nmesubsys_ << " histograms with " << nbinssubsys_ << " bins. "; if (nmesubsys_ > 0) std::cout << nbinssubsys_ / nmesubsys_ << " bins/histogram "; std::cout << std::endl; std::cout << " Largest histogram: " << maxbinsmesubsys_ << " with " << maxbinssubsys_ << " bins." << std::endl; } /// /// read virtual memory size from /proc/<pid>/status file /// std::pair<unsigned int, unsigned int> DQMStoreStats::readMemoryEntry() const { // see if initial test reading was successful if (isOpenProcFileSuccessful_) { std::ifstream procFile(procFileName_.str().c_str(), ios::in); std::string readBuffer(""); unsigned int memSize = 0; // scan procfile while (!procFile.eof()) { procFile >> readBuffer; if (std::string("VmSize:") == readBuffer) { procFile >> memSize; break; } } procFile.close(); return std::pair<time_t, unsigned int>(time(nullptr), memSize); } return std::pair<time_t, unsigned int>(0, 0); } //==================================================================// //========================= beginJob ===============================// //==================================================================// void DQMStoreStats::beginJob() { ////---- get DQM store interface dbe_ = Service<DQMStore>().operator->(); // access the proc/ folder for memory information procFileName_ << "/proc/" << getpid() << "/status"; // open for a test std::ifstream procFile(procFileName_.str().c_str(), ios::in); if (procFile.good()) { isOpenProcFileSuccessful_ = true; } else { std::cerr << " [DQMStoreStats::beginJob] ** WARNING: could not open file: " << procFileName_.str() << std::endl; std::cerr << " Total memory profile will not be available." << std::endl; isOpenProcFileSuccessful_ = false; } procFile.close(); } //==================================================================// //========================= beginRun ===============================// //==================================================================// void DQMStoreStats::beginRun(const edm::Run& r, const EventSetup& context) {} //==================================================================// //==================== analyse (takes each event) ==================// //==================================================================// void DQMStoreStats::analyze(const Event& iEvent, const EventSetup& iSetup) { //now read virtual memory size from proc folder memoryHistoryVector_.emplace_back(readMemoryEntry()); if (runineventloop_) { calcstats(DQMStoreStats::considerAllME); calcstats(DQMStoreStats::considerOnlyLumiProductME); dumpMemoryProfile(); } } //==================================================================// //========================= endLuminosityBlock =====================// //==================================================================// void DQMStoreStats::endLuminosityBlock(const LuminosityBlock& lumiSeg, const EventSetup& context) { if (runonendlumi_) { calcstats(DQMStoreStats::considerAllME); calcstats(DQMStoreStats::considerOnlyLumiProductME); dumpMemoryProfile(); } } //==================================================================// //======================= beginLuminosityBlock =====================// //==================================================================// void DQMStoreStats::beginLuminosityBlock(const edm::LuminosityBlock& lumiSeg, const edm::EventSetup& context) {} //==================================================================// //============================= endRun =============================// //==================================================================// void DQMStoreStats::endRun(const Run& r, const EventSetup& context) { if (runonendrun_) { calcstats(DQMStoreStats::considerAllME); calcstats(DQMStoreStats::considerOnlyLumiProductME); dumpMemoryProfile(); } } //==================================================================// //============================= endJob =============================// //==================================================================// void DQMStoreStats::endJob() { if (runonendjob_) { calcstats(DQMStoreStats::considerAllME); calcstats(DQMStoreStats::considerOnlyLumiProductME); dumpMemoryProfile(); } } #include "FWCore/PluginManager/interface/ModuleDef.h" #include "FWCore/Framework/interface/MakerMacros.h" DEFINE_FWK_MODULE(DQMStoreStats);