File indexing completed on 2025-04-22 06:27:33
0001 #include "DataFormats/Common/interface/setIsMergeable.h"
0002 #include "DataFormats/Provenance/interface/BranchIDListHelper.h"
0003 #include "DataFormats/Provenance/interface/BranchType.h"
0004 #include "DataFormats/Provenance/interface/branchIDToProductID.h"
0005 #include "DataFormats/Provenance/interface/EventSelectionID.h"
0006 #include "DataFormats/Provenance/interface/History.h"
0007 #include "DataFormats/Provenance/interface/ParameterSetBlob.h"
0008 #include "DataFormats/Provenance/interface/ParameterSetID.h"
0009 #include "DataFormats/Provenance/interface/ProcessHistoryRegistry.h"
0010 #include "DataFormats/Provenance/interface/ProductRegistry.h"
0011 #include "DataFormats/Provenance/interface/Parentage.h"
0012 #include "DataFormats/Provenance/interface/ProductProvenance.h"
0013 #include "DataFormats/Provenance/interface/StoredProductProvenance.h"
0014 #include "DataFormats/Provenance/interface/ParentageRegistry.h"
0015 #include "FWCore/Catalog/interface/InputFileCatalog.h"
0016 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0017 #include "FWCore/ParameterSet/interface/Registry.h"
0018 #include "FWCore/Services/interface/setupSiteLocalConfig.h"
0019
0020 #include "FWCore/Utilities/interface/Algorithms.h"
0021 #include "FWCore/Utilities/interface/Exception.h"
0022 #include "FWCore/Utilities/interface/propagate_const.h"
0023
0024 #include "TError.h"
0025 #include "TFile.h"
0026 #include "TTree.h"
0027
0028 #include "boost/program_options.hpp"
0029
0030 #include <cassert>
0031 #include <iostream>
0032 #include <memory>
0033 #include <map>
0034 #include <optional>
0035 #include <set>
0036 #include <sstream>
0037 #include <vector>
0038
0039 typedef std::map<std::string, std::vector<edm::ProductDescription>> IdToBranches;
0040 typedef std::map<std::pair<std::string, std::string>, IdToBranches> ModuleToIdBranches;
0041
0042 static std::ostream& prettyPrint(std::ostream& oStream,
0043 edm::ParameterSet const& iPSet,
0044 std::string const& iIndent,
0045 std::string const& iIndentDelta);
0046
0047 static std::string const triggerResults = std::string("TriggerResults");
0048 static std::string const triggerPaths = std::string("@trigger_paths");
0049 static std::string const source = std::string("source");
0050 static std::string const input = std::string("@main_input");
0051
0052 namespace {
0053 typedef std::map<edm::ParameterSetID, edm::ParameterSetBlob> ParameterSetMap;
0054
0055 class HistoryNode {
0056 public:
0057 HistoryNode() = default;
0058
0059 HistoryNode(edm::ProcessConfiguration const& iConfig,
0060 unsigned int iSimpleId,
0061 bool printHardwareResourcesDescription)
0062 : config_(iConfig),
0063 simpleId_(iSimpleId),
0064 printHardwareResourcesDescription_(printHardwareResourcesDescription) {}
0065
0066 void addChild(HistoryNode const& child) { children_.push_back(child); }
0067
0068 edm::ParameterSetID const& parameterSetID() const { return config_.parameterSetID(); }
0069
0070 std::string const& processName() const { return config_.processName(); }
0071
0072 std::size_t size() const { return children_.size(); }
0073
0074 HistoryNode* lastChildAddress() { return &children_.back(); }
0075
0076 typedef std::vector<HistoryNode>::const_iterator const_iterator;
0077 typedef std::vector<HistoryNode>::iterator iterator;
0078
0079 iterator begin() { return children_.begin(); }
0080 iterator end() { return children_.end(); }
0081
0082 const_iterator begin() const { return children_.begin(); }
0083 const_iterator end() const { return children_.end(); }
0084
0085 void print(std::ostream& os) const {
0086 os << config_.processName() << " '" << config_.releaseVersion() << "' [" << simpleId_ << "] ("
0087 << config_.parameterSetID() << ")";
0088 if (printHardwareResourcesDescription_) {
0089 auto const& hwresources = config_.hardwareResourcesDescription();
0090 os << " (" << hwresources.microarchitecture;
0091 if (not hwresources.selectedAccelerators.empty()) {
0092 os << "; " << hwresources.selectedAccelerators.front();
0093 for (auto it = hwresources.selectedAccelerators.begin() + 1; it != hwresources.selectedAccelerators.end();
0094 ++it) {
0095 os << "," << *it;
0096 }
0097 }
0098 os << ")";
0099 }
0100 os << std::endl;
0101 }
0102
0103 void printHistory(std::string const& iIndent = std::string(" ")) const;
0104 void printEventSetupHistory(ParameterSetMap const& iPSM,
0105 std::vector<std::string> const& iFindMatch,
0106 std::ostream& oErrorLog) const;
0107 void printOtherModulesHistory(ParameterSetMap const& iPSM,
0108 ModuleToIdBranches const&,
0109 std::vector<std::string> const& iFindMatch,
0110 std::ostream& oErrorLog) const;
0111 void printTopLevelPSetsHistory(ParameterSetMap const& iPSM,
0112 std::vector<std::string> const& iFindMatch,
0113 std::ostream& oErrorLog) const;
0114
0115 edm::ProcessConfigurationID configurationID() const { return config_.id(); }
0116
0117 static bool sort_;
0118
0119 private:
0120 edm::ProcessConfiguration config_;
0121 std::vector<HistoryNode> children_;
0122 unsigned int simpleId_ = 0;
0123 bool printHardwareResourcesDescription_ = false;
0124 };
0125
0126 std::ostream& operator<<(std::ostream& os, HistoryNode const& node) {
0127 node.print(os);
0128 return os;
0129 }
0130 bool HistoryNode::sort_ = false;
0131 }
0132
0133 std::ostream& operator<<(std::ostream& os, edm::ProcessHistory& iHist) {
0134 std::string const indentDelta(" ");
0135 std::string indent = indentDelta;
0136 for (auto const& process : iHist) {
0137
0138 os << indent << process.processName() << " '" << process.releaseVersion() << "' (" << process.parameterSetID()
0139 << ")" << std::endl;
0140 indent += indentDelta;
0141 }
0142 return os;
0143 }
0144
0145 void HistoryNode::printHistory(std::string const& iIndent) const {
0146 std::string const indentDelta(" ");
0147 const std::string& indent = iIndent;
0148 for (auto const& item : *this) {
0149 std::cout << indent << item;
0150 item.printHistory(indent + indentDelta);
0151 }
0152 }
0153
0154 std::string eventSetupComponent(char const* iType,
0155 std::string const& iCompName,
0156 edm::ParameterSet const& iProcessConfig,
0157 std::string const& iProcessName) {
0158 std::ostringstream result;
0159 edm::ParameterSet const& pset = iProcessConfig.getParameterSet(iCompName);
0160 std::string name(pset.getParameter<std::string>("@module_label"));
0161 if (name.empty()) {
0162 name = pset.getParameter<std::string>("@module_type");
0163 }
0164
0165 result << iType << ": " << name << " " << iProcessName << "\n"
0166 << " parameters: ";
0167 prettyPrint(result, pset, " ", " ");
0168 return result.str();
0169 }
0170
0171 void HistoryNode::printEventSetupHistory(ParameterSetMap const& iPSM,
0172 std::vector<std::string> const& iFindMatch,
0173 std::ostream& oErrorLog) const {
0174 for (auto const& itH : *this) {
0175
0176 ParameterSetMap::const_iterator itFind = iPSM.find(itH.parameterSetID());
0177 if (itFind == iPSM.end()) {
0178 oErrorLog << "No ParameterSetID for " << itH.parameterSetID() << std::endl;
0179 } else {
0180 edm::ParameterSet processConfig(itFind->second.pset());
0181 std::vector<std::string> sourceStrings, moduleStrings;
0182
0183 std::vector<std::string> sources = processConfig.getParameter<std::vector<std::string>>("@all_essources");
0184 for (auto& itM : sources) {
0185 std::string retValue = eventSetupComponent("ESSource", itM, processConfig, itH.processName());
0186 bool foundMatch = true;
0187 if (!iFindMatch.empty()) {
0188 for (auto const& stringToFind : iFindMatch) {
0189 if (retValue.find(stringToFind) == std::string::npos) {
0190 foundMatch = false;
0191 break;
0192 }
0193 }
0194 }
0195 if (foundMatch) {
0196 sourceStrings.push_back(std::move(retValue));
0197 }
0198 }
0199
0200 std::vector<std::string> modules = processConfig.getParameter<std::vector<std::string>>("@all_esmodules");
0201 for (auto& itM : modules) {
0202 std::string retValue = eventSetupComponent("ESModule", itM, processConfig, itH.processName());
0203 bool foundMatch = true;
0204 if (!iFindMatch.empty()) {
0205 for (auto const& stringToFind : iFindMatch) {
0206 if (retValue.find(stringToFind) == std::string::npos) {
0207 foundMatch = false;
0208 break;
0209 }
0210 }
0211 }
0212 if (foundMatch) {
0213 moduleStrings.push_back(std::move(retValue));
0214 }
0215 }
0216 if (sort_) {
0217 std::sort(sourceStrings.begin(), sourceStrings.end());
0218 std::sort(moduleStrings.begin(), moduleStrings.end());
0219 }
0220 std::copy(sourceStrings.begin(), sourceStrings.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
0221 std::copy(moduleStrings.begin(), moduleStrings.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
0222 }
0223 itH.printEventSetupHistory(iPSM, iFindMatch, oErrorLog);
0224 }
0225 }
0226
0227 std::string nonProducerComponent(std::string const& iCompName,
0228 edm::ParameterSet const& iProcessConfig,
0229 std::string const& iProcessName) {
0230 std::ostringstream result;
0231 edm::ParameterSet const& pset = iProcessConfig.getParameterSet(iCompName);
0232 std::string label(pset.getParameter<std::string>("@module_label"));
0233
0234 result << "Module: " << label << " " << iProcessName << "\n"
0235 << " parameters: ";
0236 prettyPrint(result, pset, " ", " ");
0237 return result.str();
0238 }
0239
0240 void HistoryNode::printOtherModulesHistory(ParameterSetMap const& iPSM,
0241 ModuleToIdBranches const& iModules,
0242 std::vector<std::string> const& iFindMatch,
0243 std::ostream& oErrorLog) const {
0244 for (auto const& itH : *this) {
0245
0246 ParameterSetMap::const_iterator itFind = iPSM.find(itH.parameterSetID());
0247 if (itFind == iPSM.end()) {
0248 oErrorLog << "No ParameterSetID for " << itH.parameterSetID() << std::endl;
0249 } else {
0250 edm::ParameterSet processConfig(itFind->second.pset());
0251 std::vector<std::string> moduleStrings;
0252
0253 std::vector<std::string> modules = processConfig.getParameter<std::vector<std::string>>("@all_modules");
0254 for (auto& itM : modules) {
0255
0256 if (iModules.end() == iModules.find(std::make_pair(itH.processName(), itM))) {
0257 std::string retValue(nonProducerComponent(itM, processConfig, itH.processName()));
0258 bool foundMatch = true;
0259 if (!iFindMatch.empty()) {
0260 for (auto const& stringToFind : iFindMatch) {
0261 if (retValue.find(stringToFind) == std::string::npos) {
0262 foundMatch = false;
0263 break;
0264 }
0265 }
0266 }
0267 if (foundMatch) {
0268 moduleStrings.push_back(std::move(retValue));
0269 }
0270 }
0271 }
0272 if (sort_) {
0273 std::sort(moduleStrings.begin(), moduleStrings.end());
0274 }
0275 std::copy(moduleStrings.begin(), moduleStrings.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
0276 }
0277 itH.printOtherModulesHistory(iPSM, iModules, iFindMatch, oErrorLog);
0278 }
0279 }
0280
0281 static void appendToSet(std::set<std::string>& iSet, std::vector<std::string> const& iFrom) {
0282 for (auto const& n : iFrom) {
0283 iSet.insert(n);
0284 }
0285 }
0286
0287 static std::string topLevelPSet(std::string const& iName,
0288 edm::ParameterSet const& iProcessConfig,
0289 std::string const& iProcessName) {
0290 std::ostringstream result;
0291 edm::ParameterSet const& pset = iProcessConfig.getParameterSet(iName);
0292
0293 result << "PSet: " << iName << " " << iProcessName << "\n"
0294 << " parameters: ";
0295 prettyPrint(result, pset, " ", " ");
0296 return result.str();
0297 }
0298
0299 void HistoryNode::printTopLevelPSetsHistory(ParameterSetMap const& iPSM,
0300 std::vector<std::string> const& iFindMatch,
0301 std::ostream& oErrorLog) const {
0302 for (auto const& itH : *this) {
0303
0304 ParameterSetMap::const_iterator itFind = iPSM.find(itH.parameterSetID());
0305 if (itFind == iPSM.end()) {
0306 oErrorLog << "No ParameterSetID for " << itH.parameterSetID() << std::endl;
0307 } else {
0308 edm::ParameterSet processConfig(itFind->second.pset());
0309
0310 std::set<std::string> namesToExclude;
0311 appendToSet(namesToExclude, processConfig.getParameter<std::vector<std::string>>("@all_modules"));
0312 appendToSet(namesToExclude, processConfig.getParameter<std::vector<std::string>>("@all_sources"));
0313 appendToSet(namesToExclude, processConfig.getParameter<std::vector<std::string>>("@all_loopers"));
0314 appendToSet(namesToExclude, processConfig.getParameter<std::vector<std::string>>("@all_esmodules"));
0315 appendToSet(namesToExclude, processConfig.getParameter<std::vector<std::string>>("@all_essources"));
0316 appendToSet(namesToExclude, processConfig.getParameter<std::vector<std::string>>("@all_esprefers"));
0317 if (processConfig.existsAs<std::vector<std::string>>("all_aliases")) {
0318 appendToSet(namesToExclude, processConfig.getParameter<std::vector<std::string>>("@all_aliases"));
0319 }
0320
0321 std::vector<std::string> allNames{};
0322 processConfig.getParameterSetNames(allNames);
0323
0324 std::vector<std::string> results;
0325 for (auto const& name : allNames) {
0326 if (name.empty() || '@' == name[0] || namesToExclude.find(name) != namesToExclude.end()) {
0327 continue;
0328 }
0329 std::string retValue = topLevelPSet(name, processConfig, itH.processName());
0330
0331 bool foundMatch = true;
0332 if (!iFindMatch.empty()) {
0333 for (auto const& stringToFind : iFindMatch) {
0334 if (retValue.find(stringToFind) == std::string::npos) {
0335 foundMatch = false;
0336 break;
0337 }
0338 }
0339 }
0340 if (foundMatch) {
0341 results.push_back(std::move(retValue));
0342 }
0343 }
0344 if (sort_) {
0345 std::sort(results.begin(), results.end());
0346 }
0347 std::copy(results.begin(), results.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
0348 }
0349 itH.printTopLevelPSetsHistory(iPSM, iFindMatch, oErrorLog);
0350 }
0351 }
0352
0353 namespace {
0354 std::unique_ptr<TFile> makeTFileWithLookup(std::string const& filename) {
0355
0356 auto operate = edm::setupSiteLocalConfig();
0357 std::string override;
0358 std::vector<std::string> fileNames;
0359 fileNames.push_back(filename);
0360 edm::InputFileCatalog catalog(fileNames, override, true);
0361 if (catalog.fileNames(0)[0] == filename) {
0362 throw cms::Exception("FileNotFound", "RootFile::RootFile()")
0363 << "File " << filename << " was not found or could not be opened.\n";
0364 }
0365
0366 std::unique_ptr<TFile> result(TFile::Open(catalog.fileNames(0)[0].c_str()));
0367 if (!result.get()) {
0368 throw cms::Exception("FileNotFound", "RootFile::RootFile()")
0369 << "File " << fileNames[0] << " was not found or could not be opened.\n";
0370 }
0371 return result;
0372 }
0373
0374
0375
0376
0377
0378 std::unique_ptr<TFile> makeTFile(std::string const& filename) {
0379 gErrorIgnoreLevel = kFatal;
0380 std::unique_ptr<TFile> result(TFile::Open(filename.c_str()));
0381 gErrorIgnoreLevel = kError;
0382 if (!result.get()) {
0383
0384 return makeTFileWithLookup(filename);
0385 }
0386 return result;
0387 }
0388 }
0389
0390 static std::ostream& prettyPrint(std::ostream& os,
0391 edm::ParameterSetEntry const& psetEntry,
0392 std::string const& iIndent,
0393 std::string const& iIndentDelta) {
0394 char const* trackiness = (psetEntry.isTracked() ? "tracked" : "untracked");
0395 os << "PSet " << trackiness << " = (";
0396 prettyPrint(os, psetEntry.pset(), iIndent + iIndentDelta, iIndentDelta);
0397 os << ")";
0398 return os;
0399 }
0400
0401 static std::ostream& prettyPrint(std::ostream& os,
0402 edm::VParameterSetEntry const& vpsetEntry,
0403 std::string const& iIndent,
0404 std::string const& iIndentDelta) {
0405 std::vector<edm::ParameterSet> const& vps = vpsetEntry.vpset();
0406 os << "VPSet " << (vpsetEntry.isTracked() ? "tracked" : "untracked") << " = ({" << std::endl;
0407 std::string newIndent = iIndent + iIndentDelta;
0408 std::string start;
0409 std::string const between(",\n");
0410 for (auto const& item : vps) {
0411 os << start << newIndent;
0412 prettyPrint(os, item, newIndent, iIndentDelta);
0413 start = between;
0414 }
0415 if (!vps.empty()) {
0416 os << std::endl;
0417 }
0418 os << iIndent << "})";
0419 return os;
0420 }
0421
0422 static std::ostream& prettyPrint(std::ostream& oStream,
0423 edm::ParameterSet const& iPSet,
0424 std::string const& iIndent,
0425 std::string const& iIndentDelta) {
0426 std::string newIndent = iIndent + iIndentDelta;
0427
0428 oStream << "{" << std::endl;
0429 for (auto const& item : iPSet.tbl()) {
0430
0431 oStream << newIndent << item.first << ": " << item.second << std::endl;
0432 }
0433 for (auto const& item : iPSet.psetTable()) {
0434
0435 edm::ParameterSetEntry const& pe = item.second;
0436 oStream << newIndent << item.first << ": ";
0437 prettyPrint(oStream, pe, iIndent, iIndentDelta);
0438 oStream << std::endl;
0439 }
0440 for (auto const& item : iPSet.vpsetTable()) {
0441
0442 edm::VParameterSetEntry const& pe = item.second;
0443 oStream << newIndent << item.first << ": ";
0444 prettyPrint(oStream, pe, newIndent, iIndentDelta);
0445 oStream << std::endl;
0446 }
0447 oStream << iIndent << "}";
0448
0449 return oStream;
0450 }
0451
0452 class ProvenanceDumper {
0453 public:
0454
0455
0456 ProvenanceDumper(std::string const& filename,
0457 bool showDependencies,
0458 bool extendedAncestors,
0459 bool extendedDescendants,
0460 bool excludeESModules,
0461 bool showAllModules,
0462 bool showTopLevelPSets,
0463 std::vector<std::string> const& findMatch,
0464 bool dontPrintProducts,
0465 std::string const& dumpPSetID,
0466 int productIDEntry,
0467 bool printHardwareResourcesDescription);
0468
0469 ProvenanceDumper(ProvenanceDumper const&) = delete;
0470 ProvenanceDumper& operator=(ProvenanceDumper const&) = delete;
0471
0472
0473 void dump();
0474 void printErrors(std::ostream& os);
0475 int exitCode() const;
0476
0477 private:
0478 void addAncestors(edm::BranchID const& branchID,
0479 std::set<edm::BranchID>& ancestorBranchIDs,
0480 std::ostringstream& sout,
0481 std::map<edm::BranchID, std::set<edm::ParentageID>>& perProductParentage) const;
0482
0483 void addDescendants(edm::BranchID const& branchID,
0484 std::set<edm::BranchID>& descendantBranchIDs,
0485 std::ostringstream& sout,
0486 std::map<edm::BranchID, std::set<edm::BranchID>>& parentToChildren) const;
0487
0488 std::string filename_;
0489 edm::propagate_const<std::unique_ptr<TFile>> inputFile_;
0490 int exitCode_;
0491 std::stringstream errorLog_;
0492 int errorCount_;
0493 edm::ProductRegistry reg_;
0494 edm::ProcessConfigurationVector phc_;
0495 edm::ProcessHistoryVector phv_;
0496 ParameterSetMap psm_;
0497 HistoryNode historyGraph_;
0498 bool showDependencies_;
0499 bool extendedAncestors_;
0500 bool extendedDescendants_;
0501 bool excludeESModules_;
0502 bool showOtherModules_;
0503 bool productRegistryPresent_;
0504 bool showTopLevelPSets_;
0505 std::vector<std::string> findMatch_;
0506 bool dontPrintProducts_;
0507 std::string dumpPSetID_;
0508 int const productIDEntry_;
0509 bool const printHardwareResourcesDescription_;
0510
0511 void work_();
0512 void dumpProcessHistory_();
0513 void dumpEventFilteringParameterSets_(TFile* file);
0514 void dumpEventFilteringParameterSets(edm::EventSelectionIDVector const& ids);
0515 void dumpParameterSetForID_(edm::ParameterSetID const& id);
0516 std::optional<std::tuple<edm::BranchIDListHelper, std::vector<edm::ProcessIndex>>> makeBranchIDListHelper();
0517 };
0518
0519 ProvenanceDumper::ProvenanceDumper(std::string const& filename,
0520 bool showDependencies,
0521 bool extendedAncestors,
0522 bool extendedDescendants,
0523 bool excludeESModules,
0524 bool showOtherModules,
0525 bool showTopLevelPSets,
0526 std::vector<std::string> const& findMatch,
0527 bool dontPrintProducts,
0528 std::string const& dumpPSetID,
0529 int productIDEntry,
0530 bool printHardwareResourcesDescription)
0531 : filename_(filename),
0532 inputFile_(makeTFile(filename)),
0533 exitCode_(0),
0534 errorLog_(),
0535 errorCount_(0),
0536 showDependencies_(showDependencies),
0537 extendedAncestors_(extendedAncestors),
0538 extendedDescendants_(extendedDescendants),
0539 excludeESModules_(excludeESModules),
0540 showOtherModules_(showOtherModules),
0541 productRegistryPresent_(true),
0542 showTopLevelPSets_(showTopLevelPSets),
0543 findMatch_(findMatch),
0544 dontPrintProducts_(dontPrintProducts),
0545 dumpPSetID_(dumpPSetID),
0546 productIDEntry_(productIDEntry),
0547 printHardwareResourcesDescription_(printHardwareResourcesDescription) {}
0548
0549 void ProvenanceDumper::dump() { work_(); }
0550
0551 void ProvenanceDumper::printErrors(std::ostream& os) {
0552 if (errorCount_ > 0)
0553 os << errorLog_.str() << std::endl;
0554 }
0555
0556 int ProvenanceDumper::exitCode() const { return exitCode_; }
0557
0558 void ProvenanceDumper::dumpEventFilteringParameterSets(edm::EventSelectionIDVector const& ids) {
0559 edm::EventSelectionIDVector::size_type num_ids = ids.size();
0560 if (num_ids == 0) {
0561 std::cout << "No event filtering information is available.\n";
0562 std::cout << "------------------------------\n";
0563 } else {
0564 std::cout << "Event filtering information for " << num_ids << " processing steps is available.\n"
0565 << "The ParameterSets will be printed out, "
0566 << "with the oldest printed first.\n";
0567 for (edm::EventSelectionIDVector::size_type i = 0; i != num_ids; ++i) {
0568 dumpParameterSetForID_(ids[i]);
0569 }
0570 }
0571 }
0572
0573 void ProvenanceDumper::dumpEventFilteringParameterSets_(TFile* file) {
0574 TTree* history = dynamic_cast<TTree*>(file->Get(edm::poolNames::eventHistoryTreeName().c_str()));
0575 if (history != nullptr) {
0576 edm::History h;
0577 edm::History* ph = &h;
0578
0579 history->SetBranchAddress(edm::poolNames::eventHistoryBranchName().c_str(), &ph);
0580 if (history->GetEntry(0) <= 0) {
0581 std::cout << "No event filtering information is available; the event history tree has no entries\n";
0582 } else {
0583 dumpEventFilteringParameterSets(h.eventSelectionIDs());
0584 }
0585 } else {
0586 TTree* events = dynamic_cast<TTree*>(file->Get(edm::poolNames::eventTreeName().c_str()));
0587 assert(events != nullptr);
0588 TBranch* eventSelectionsBranch = events->GetBranch(edm::poolNames::eventSelectionsBranchName().c_str());
0589 if (eventSelectionsBranch == nullptr)
0590 return;
0591 edm::EventSelectionIDVector ids;
0592 edm::EventSelectionIDVector* pids = &ids;
0593 eventSelectionsBranch->SetAddress(&pids);
0594 if (eventSelectionsBranch->GetEntry(0) <= 0) {
0595 std::cout << "No event filtering information is available; the event selections branch has no entries\n";
0596 } else {
0597 dumpEventFilteringParameterSets(ids);
0598 }
0599 }
0600 }
0601
0602 void ProvenanceDumper::dumpParameterSetForID_(edm::ParameterSetID const& id) {
0603 std::cout << "ParameterSetID: " << id << '\n';
0604 if (id.isValid()) {
0605 ParameterSetMap::const_iterator i = psm_.find(id);
0606 if (i == psm_.end()) {
0607 std::cout << "We are unable to find the corresponding ParameterSet\n";
0608 edm::ParameterSet empty;
0609 empty.registerIt();
0610 if (id == empty.id()) {
0611 std::cout << "But it would have been empty anyway\n";
0612 }
0613 } else {
0614 edm::ParameterSet ps(i->second.pset());
0615 prettyPrint(std::cout, ps, " ", " ");
0616 std::cout << '\n';
0617 }
0618 } else {
0619 std::cout << "This ID is not valid\n";
0620 }
0621 std::cout << " -------------------------\n";
0622 }
0623
0624 void ProvenanceDumper::dumpProcessHistory_() {
0625 std::cout << "Processing History:" << std::endl;
0626 std::map<edm::ProcessConfigurationID, unsigned int> simpleIDs;
0627 for (auto const& ph : phv_) {
0628
0629 HistoryNode* parent = &historyGraph_;
0630 for (auto const& pc : ph) {
0631 if (parent->size() == 0) {
0632 unsigned int id = simpleIDs[pc.id()];
0633 if (0 == id) {
0634 id = 1;
0635 simpleIDs[pc.id()] = id;
0636 }
0637 parent->addChild(HistoryNode(pc, id, printHardwareResourcesDescription_));
0638 parent = parent->lastChildAddress();
0639 } else {
0640
0641 bool isUnique = true;
0642 for (auto& child : *parent) {
0643 if (child.configurationID() == pc.id()) {
0644 isUnique = false;
0645 parent = &child;
0646 break;
0647 }
0648 }
0649 if (isUnique) {
0650 simpleIDs[pc.id()] = parent->size() + 1;
0651 parent->addChild(HistoryNode(pc, simpleIDs[pc.id()], printHardwareResourcesDescription_));
0652 parent = parent->lastChildAddress();
0653 }
0654 }
0655 }
0656 }
0657 historyGraph_.printHistory();
0658 }
0659
0660 std::optional<std::tuple<edm::BranchIDListHelper, std::vector<edm::ProcessIndex>>>
0661 ProvenanceDumper::makeBranchIDListHelper() {
0662
0663 if (productIDEntry_ < 0) {
0664 return {};
0665 }
0666
0667 TTree* metaTree = dynamic_cast<TTree*>(inputFile_->Get(edm::poolNames::metaDataTreeName().c_str()));
0668 if (nullptr == metaTree) {
0669
0670 return {};
0671 }
0672
0673 TBranch* branchIDListsBranch = metaTree->GetBranch(edm::poolNames::branchIDListBranchName().c_str());
0674 if (nullptr == branchIDListsBranch) {
0675
0676
0677
0678
0679 return {};
0680 }
0681
0682 edm::BranchIDLists branchIDLists;
0683 edm::BranchIDLists* branchIDListsPtr = &branchIDLists;
0684 branchIDListsBranch->SetAddress(&branchIDListsPtr);
0685 if (branchIDListsBranch->GetEntry(0) <= 0) {
0686
0687 return {};
0688 }
0689
0690 edm::BranchIDListHelper branchIDListHelper;
0691 branchIDListHelper.updateFromInput(branchIDLists);
0692
0693 TTree* events = dynamic_cast<TTree*>(inputFile_->Get(edm::poolNames::eventTreeName().c_str()));
0694 assert(events != nullptr);
0695 TBranch* branchListIndexesBranch = events->GetBranch(edm::poolNames::branchListIndexesBranchName().c_str());
0696 if (nullptr == branchListIndexesBranch) {
0697
0698
0699
0700
0701 return {};
0702 }
0703 edm::BranchListIndexes branchListIndexes;
0704 edm::BranchListIndexes* pbranchListIndexes = &branchListIndexes;
0705 branchListIndexesBranch->SetAddress(&pbranchListIndexes);
0706 if (branchListIndexesBranch->GetEntry(productIDEntry_) <= 0 or branchListIndexes.empty()) {
0707
0708
0709
0710
0711 return {};
0712 }
0713
0714 if (not branchIDListHelper.fixBranchListIndexes(branchListIndexes)) {
0715
0716 return {};
0717 }
0718
0719
0720 auto branchListIndexToProcessIndex = edm::makeBranchListIndexToProcessIndex(branchListIndexes);
0721
0722 return std::tuple(std::move(branchIDListHelper), std::move(branchListIndexToProcessIndex));
0723 }
0724
0725 void ProvenanceDumper::work_() {
0726 TTree* meta = dynamic_cast<TTree*>(inputFile_->Get(edm::poolNames::metaDataTreeName().c_str()));
0727 assert(nullptr != meta);
0728
0729 edm::ProductRegistry* pReg = ®_;
0730 if (meta->FindBranch(edm::poolNames::productDescriptionBranchName().c_str()) != nullptr) {
0731 meta->SetBranchAddress(edm::poolNames::productDescriptionBranchName().c_str(), &pReg);
0732 } else {
0733 productRegistryPresent_ = false;
0734 }
0735
0736 ParameterSetMap* pPsm = &psm_;
0737 if (meta->FindBranch(edm::poolNames::parameterSetMapBranchName().c_str()) != nullptr) {
0738 meta->SetBranchAddress(edm::poolNames::parameterSetMapBranchName().c_str(), &pPsm);
0739 } else {
0740 TTree* psetTree = dynamic_cast<TTree*>(inputFile_->Get(edm::poolNames::parameterSetsTreeName().c_str()));
0741 assert(nullptr != psetTree);
0742 typedef std::pair<edm::ParameterSetID, edm::ParameterSetBlob> IdToBlobs;
0743 IdToBlobs idToBlob;
0744 IdToBlobs* pIdToBlob = &idToBlob;
0745 psetTree->SetBranchAddress(edm::poolNames::idToParameterSetBlobsBranchName().c_str(), &pIdToBlob);
0746 for (long long i = 0; i != psetTree->GetEntries(); ++i) {
0747 psetTree->GetEntry(i);
0748 psm_.insert(idToBlob);
0749 }
0750 }
0751
0752 edm::ProcessHistoryVector* pPhv = &phv_;
0753 if (meta->FindBranch(edm::poolNames::processHistoryBranchName().c_str()) != nullptr) {
0754 meta->SetBranchAddress(edm::poolNames::processHistoryBranchName().c_str(), &pPhv);
0755 }
0756
0757 edm::ProcessHistoryMap phm;
0758 edm::ProcessHistoryMap* pPhm = &phm;
0759 if (meta->FindBranch(edm::poolNames::processHistoryMapBranchName().c_str()) != nullptr) {
0760 meta->SetBranchAddress(edm::poolNames::processHistoryMapBranchName().c_str(), &pPhm);
0761 }
0762
0763 if (meta->FindBranch(edm::poolNames::moduleDescriptionMapBranchName().c_str()) != nullptr) {
0764 if (meta->GetBranch(edm::poolNames::moduleDescriptionMapBranchName().c_str())->GetSplitLevel() != 0) {
0765 meta->SetBranchStatus((edm::poolNames::moduleDescriptionMapBranchName() + ".*").c_str(), false);
0766 } else {
0767 meta->SetBranchStatus(edm::poolNames::moduleDescriptionMapBranchName().c_str(), false);
0768 }
0769 }
0770
0771 meta->GetEntry(0);
0772 assert(nullptr != pReg);
0773
0774 edm::pset::Registry& psetRegistry = *edm::pset::Registry::instance();
0775 for (auto const& item : psm_) {
0776 edm::ParameterSet pset(item.second.pset());
0777 pset.setID(item.first);
0778 psetRegistry.insertMapped(pset);
0779 }
0780
0781 if (!phv_.empty()) {
0782 for (auto const& history : phv_) {
0783 for (auto const& process : history) {
0784 phc_.push_back(process);
0785 }
0786 }
0787 edm::sort_all(phc_);
0788 phc_.erase(std::unique(phc_.begin(), phc_.end()), phc_.end());
0789
0790 }
0791
0792 else if (!phm.empty()) {
0793 for (auto const& history : phm) {
0794 phv_.push_back(history.second);
0795 for (auto const& process : history.second) {
0796 phc_.push_back(process);
0797 }
0798 }
0799 edm::sort_all(phc_);
0800 phc_.erase(std::unique(phc_.begin(), phc_.end()), phc_.end());
0801 }
0802
0803 if (!dumpPSetID_.empty()) {
0804 edm::ParameterSetID psetID;
0805 try {
0806 psetID = edm::ParameterSetID(dumpPSetID_);
0807 } catch (cms::Exception const& x) {
0808 throw cms::Exception("Command Line Argument")
0809 << "Illegal ParameterSetID string. It should contain 32 hexadecimal characters";
0810 }
0811 dumpParameterSetForID_(psetID);
0812 return;
0813 }
0814
0815
0816 auto branchIDListHelperAndToProcessIndex = makeBranchIDListHelper();
0817
0818
0819 std::map<edm::BranchID, std::set<edm::ParentageID>> perProductParentage;
0820
0821 if (showDependencies_ || extendedAncestors_ || extendedDescendants_) {
0822 TTree* parentageTree = dynamic_cast<TTree*>(inputFile_->Get(edm::poolNames::parentageTreeName().c_str()));
0823 if (nullptr == parentageTree) {
0824 std::cerr << "ERROR, no Parentage tree available so cannot show dependencies, ancestors, or descendants.\n";
0825 std::cerr << "Possibly this is not a standard EDM format file. For example, dependency, ancestor, and\n";
0826 std::cerr << "descendant options to edmProvDump will not work with nanoAOD format files.\n\n";
0827 showDependencies_ = false;
0828 extendedAncestors_ = false;
0829 extendedDescendants_ = false;
0830 } else {
0831 edm::ParentageRegistry& registry = *edm::ParentageRegistry::instance();
0832
0833 std::vector<edm::ParentageID> orderedParentageIDs;
0834 orderedParentageIDs.reserve(parentageTree->GetEntries());
0835 for (Long64_t i = 0, numEntries = parentageTree->GetEntries(); i < numEntries; ++i) {
0836 edm::Parentage parentageBuffer;
0837 edm::Parentage* pParentageBuffer = &parentageBuffer;
0838 parentageTree->SetBranchAddress(edm::poolNames::parentageBranchName().c_str(), &pParentageBuffer);
0839 parentageTree->GetEntry(i);
0840 registry.insertMapped(parentageBuffer);
0841 orderedParentageIDs.push_back(parentageBuffer.id());
0842 }
0843 parentageTree->SetBranchAddress(edm::poolNames::parentageBranchName().c_str(), nullptr);
0844
0845 TTree* eventMetaTree =
0846 dynamic_cast<TTree*>(inputFile_->Get(edm::BranchTypeToMetaDataTreeName(edm::InEvent).c_str()));
0847 if (nullptr == eventMetaTree) {
0848 eventMetaTree = dynamic_cast<TTree*>(inputFile_->Get(edm::BranchTypeToProductTreeName(edm::InEvent).c_str()));
0849 }
0850 if (nullptr == eventMetaTree) {
0851 std::cerr << "ERROR, no '" << edm::BranchTypeToProductTreeName(edm::InEvent)
0852 << "' Tree in file so can not show dependencies\n";
0853 showDependencies_ = false;
0854 extendedAncestors_ = false;
0855 extendedDescendants_ = false;
0856 } else {
0857 TBranch* storedProvBranch =
0858 eventMetaTree->GetBranch(edm::BranchTypeToProductProvenanceBranchName(edm::InEvent).c_str());
0859
0860 if (nullptr != storedProvBranch) {
0861 std::vector<edm::StoredProductProvenance> info;
0862 std::vector<edm::StoredProductProvenance>* pInfo = &info;
0863 storedProvBranch->SetAddress(&pInfo);
0864 for (Long64_t i = 0, numEntries = eventMetaTree->GetEntries(); i < numEntries; ++i) {
0865 storedProvBranch->GetEntry(i);
0866 for (auto const& item : info) {
0867 edm::BranchID bid(item.branchID_);
0868 perProductParentage[bid].insert(orderedParentageIDs.at(item.parentageIDIndex_));
0869 }
0870 }
0871 } else {
0872
0873 TBranch* productProvBranch =
0874 eventMetaTree->GetBranch(edm::BranchTypeToBranchEntryInfoBranchName(edm::InEvent).c_str());
0875 if (nullptr != productProvBranch) {
0876 std::vector<edm::ProductProvenance> info;
0877 std::vector<edm::ProductProvenance>* pInfo = &info;
0878 productProvBranch->SetAddress(&pInfo);
0879 for (Long64_t i = 0, numEntries = eventMetaTree->GetEntries(); i < numEntries; ++i) {
0880 productProvBranch->GetEntry(i);
0881 for (auto const& item : info) {
0882 perProductParentage[item.branchID()].insert(item.parentageID());
0883 }
0884 }
0885 } else {
0886 std::cerr << " ERROR, could not find provenance information so can not show dependencies\n";
0887 showDependencies_ = false;
0888 extendedAncestors_ = false;
0889 extendedDescendants_ = false;
0890 }
0891 }
0892 }
0893 }
0894 }
0895
0896 std::map<edm::BranchID, std::set<edm::BranchID>> parentToChildren;
0897 edm::ParentageRegistry& registry = *edm::ParentageRegistry::instance();
0898
0899 if (extendedDescendants_) {
0900 for (auto const& itParentageSet : perProductParentage) {
0901 edm::BranchID childBranchID = itParentageSet.first;
0902 for (auto const& itParentageID : itParentageSet.second) {
0903 edm::Parentage const* parentage = registry.getMapped(itParentageID);
0904 if (nullptr != parentage) {
0905 for (auto const& branch : parentage->parents()) {
0906 parentToChildren[branch].insert(childBranchID);
0907 }
0908 } else {
0909 std::cerr << " ERROR:parentage info not in registry ParentageID=" << itParentageID << std::endl;
0910 }
0911 }
0912 }
0913 }
0914
0915 dumpEventFilteringParameterSets_(inputFile_.get());
0916
0917 dumpProcessHistory_();
0918
0919 if (productRegistryPresent_) {
0920 std::cout << "---------Producers with data in file---------" << std::endl;
0921 }
0922
0923
0924
0925 ModuleToIdBranches moduleToIdBranches;
0926
0927
0928 std::map<edm::BranchID, std::string> branchIDToBranchName;
0929
0930 for (auto const& processConfig : phc_) {
0931 edm::ParameterSet const* processParameterSet =
0932 edm::pset::Registry::instance()->getMapped(processConfig.parameterSetID());
0933 if (nullptr == processParameterSet || processParameterSet->empty()) {
0934 continue;
0935 }
0936 for (auto& item : reg_.productListUpdator()) {
0937 auto& product = item.second;
0938 if (product.processName() != processConfig.processName()) {
0939 continue;
0940 }
0941
0942 product.init();
0943 setIsMergeable(product);
0944
0945 if (showDependencies_ || extendedAncestors_ || extendedDescendants_) {
0946 branchIDToBranchName[product.branchID()] = product.branchName();
0947 }
0948
0949
0950
0951
0952 std::string moduleLabel = product.moduleLabel();
0953 if (moduleLabel == source) {
0954 moduleLabel = input;
0955 } else if (moduleLabel == triggerResults) {
0956 moduleLabel = triggerPaths;
0957 }
0958
0959 std::stringstream s;
0960
0961 if (processParameterSet->existsAs<edm::ParameterSet>(moduleLabel)) {
0962 edm::ParameterSet const& moduleParameterSet = processParameterSet->getParameterSet(moduleLabel);
0963 if (!moduleParameterSet.isRegistered()) {
0964 edm::ParameterSet moduleParameterSetCopy = processParameterSet->getParameterSet(moduleLabel);
0965 moduleParameterSetCopy.registerIt();
0966 s << moduleParameterSetCopy.id();
0967 } else {
0968 s << moduleParameterSet.id();
0969 }
0970 moduleToIdBranches[std::make_pair(product.processName(), product.moduleLabel())][s.str()].push_back(product);
0971 }
0972 }
0973 }
0974
0975 for (auto const& item : moduleToIdBranches) {
0976 std::ostringstream sout;
0977 sout << "Module: " << item.first.second << " " << item.first.first << std::endl;
0978 std::set<edm::BranchID> allBranchIDsForLabelAndProcess;
0979 IdToBranches const& idToBranches = item.second;
0980 for (auto const& idBranch : idToBranches) {
0981 sout << " PSet id:" << idBranch.first << std::endl;
0982 if (!dontPrintProducts_) {
0983 sout << " products: {" << std::endl;
0984 }
0985 std::set<edm::BranchID> branchIDs;
0986 for (auto const& branch : idBranch.second) {
0987 if (!dontPrintProducts_) {
0988 sout << " " << branch.branchName();
0989 edm::ProductID id;
0990 if (branchIDListHelperAndToProcessIndex) {
0991 sout << " ProductID "
0992 << edm::branchIDToProductID(branch.branchID(),
0993 std::get<0>(*branchIDListHelperAndToProcessIndex),
0994 std::get<1>(*branchIDListHelperAndToProcessIndex));
0995 } else {
0996 sout << " BranchID " << branch.branchID();
0997 }
0998 sout << std::endl;
0999 }
1000 branchIDs.insert(branch.branchID());
1001 allBranchIDsForLabelAndProcess.insert(branch.branchID());
1002 }
1003 sout << " }" << std::endl;
1004 edm::ParameterSetID psid(idBranch.first);
1005 ParameterSetMap::const_iterator itpsm = psm_.find(psid);
1006 if (psm_.end() == itpsm) {
1007 ++errorCount_;
1008 errorLog_ << "No ParameterSetID for " << psid << std::endl;
1009 exitCode_ = 1;
1010 } else {
1011 sout << " parameters: ";
1012 prettyPrint(sout, edm::ParameterSet((*itpsm).second.pset()), " ", " ");
1013 sout << std::endl;
1014 }
1015 if (showDependencies_) {
1016 sout << " dependencies: {" << std::endl;
1017 std::set<edm::ParentageID> parentageIDs;
1018 for (auto const& branch : branchIDs) {
1019
1020 std::set<edm::ParentageID> const& temp = perProductParentage[branch];
1021 parentageIDs.insert(temp.begin(), temp.end());
1022 }
1023 for (auto const& parentID : parentageIDs) {
1024 edm::Parentage const* parentage = registry.getMapped(parentID);
1025 if (nullptr != parentage) {
1026 for (auto const& branch : parentage->parents()) {
1027 sout << " " << branchIDToBranchName[branch] << std::endl;
1028 }
1029 } else {
1030 sout << " ERROR:parentage info not in registry ParentageID=" << parentID << std::endl;
1031 }
1032 }
1033 if (parentageIDs.empty()) {
1034 sout << " no dependencies recorded (event may not contain data from this module)" << std::endl;
1035 }
1036 sout << " }" << std::endl;
1037 }
1038 }
1039 if (extendedAncestors_) {
1040 sout << " extendedAncestors: {" << std::endl;
1041 std::set<edm::BranchID> ancestorBranchIDs;
1042 for (auto const& branchID : allBranchIDsForLabelAndProcess) {
1043 addAncestors(branchID, ancestorBranchIDs, sout, perProductParentage);
1044 }
1045 for (auto const& ancestorBranchID : ancestorBranchIDs) {
1046 sout << " " << branchIDToBranchName[ancestorBranchID] << "\n";
1047 }
1048 sout << " }" << std::endl;
1049 }
1050
1051 if (extendedDescendants_) {
1052 sout << " extendedDescendants: {" << std::endl;
1053 std::set<edm::BranchID> descendantBranchIDs;
1054 for (auto const& branchID : allBranchIDsForLabelAndProcess) {
1055 addDescendants(branchID, descendantBranchIDs, sout, parentToChildren);
1056 }
1057 for (auto const& descendantBranchID : descendantBranchIDs) {
1058 sout << " " << branchIDToBranchName[descendantBranchID] << "\n";
1059 }
1060 sout << " }" << std::endl;
1061 }
1062 bool foundMatch = true;
1063 if (!findMatch_.empty()) {
1064 for (auto const& stringToFind : findMatch_) {
1065 if (sout.str().find(stringToFind) == std::string::npos) {
1066 foundMatch = false;
1067 break;
1068 }
1069 }
1070 }
1071 if (foundMatch) {
1072 std::cout << sout.str() << std::endl;
1073 }
1074 }
1075
1076 if (productRegistryPresent_ && showOtherModules_) {
1077 std::cout << "---------Other Modules---------" << std::endl;
1078 historyGraph_.printOtherModulesHistory(psm_, moduleToIdBranches, findMatch_, errorLog_);
1079 } else if (!productRegistryPresent_) {
1080 std::cout << "---------All Modules---------" << std::endl;
1081 historyGraph_.printOtherModulesHistory(psm_, moduleToIdBranches, findMatch_, errorLog_);
1082 }
1083
1084 if (!excludeESModules_) {
1085 std::cout << "---------EventSetup---------" << std::endl;
1086 historyGraph_.printEventSetupHistory(psm_, findMatch_, errorLog_);
1087 }
1088
1089 if (showTopLevelPSets_) {
1090 std::cout << "---------Top Level PSets---------" << std::endl;
1091 historyGraph_.printTopLevelPSetsHistory(psm_, findMatch_, errorLog_);
1092 }
1093 if (errorCount_ != 0) {
1094 exitCode_ = 1;
1095 }
1096 }
1097
1098 void ProvenanceDumper::addAncestors(edm::BranchID const& branchID,
1099 std::set<edm::BranchID>& ancestorBranchIDs,
1100 std::ostringstream& sout,
1101 std::map<edm::BranchID, std::set<edm::ParentageID>>& perProductParentage) const {
1102 edm::ParentageRegistry& registry = *edm::ParentageRegistry::instance();
1103
1104 std::set<edm::ParentageID> const& parentIDs = perProductParentage[branchID];
1105 for (auto const& parentageID : parentIDs) {
1106 edm::Parentage const* parentage = registry.getMapped(parentageID);
1107 if (nullptr != parentage) {
1108 for (auto const& branch : parentage->parents()) {
1109 if (ancestorBranchIDs.insert(branch).second) {
1110 addAncestors(branch, ancestorBranchIDs, sout, perProductParentage);
1111 }
1112 }
1113 } else {
1114 sout << " ERROR:parentage info not in registry ParentageID=" << parentageID << std::endl;
1115 }
1116 }
1117 }
1118
1119 void ProvenanceDumper::addDescendants(edm::BranchID const& branchID,
1120 std::set<edm::BranchID>& descendantBranchIDs,
1121 std::ostringstream& sout,
1122 std::map<edm::BranchID, std::set<edm::BranchID>>& parentToChildren) const {
1123 for (auto const& childBranchID : parentToChildren[branchID]) {
1124 if (descendantBranchIDs.insert(childBranchID).second) {
1125 addDescendants(childBranchID, descendantBranchIDs, sout, parentToChildren);
1126 }
1127 }
1128 }
1129
1130 static char const* const kSortOpt = "sort";
1131 static char const* const kSortCommandOpt = "sort,s";
1132 static char const* const kDependenciesOpt = "dependencies";
1133 static char const* const kDependenciesCommandOpt = "dependencies,d";
1134 static char const* const kExtendedAncestorsOpt = "extendedAncestors";
1135 static char const* const kExtendedAncestorsCommandOpt = "extendedAncestors,x";
1136 static char const* const kExtendedDescendantsOpt = "extendedDescendants";
1137 static char const* const kExtendedDescendantsCommandOpt = "extendedDescendants,c";
1138 static char const* const kExcludeESModulesOpt = "excludeESModules";
1139 static char const* const kExcludeESModulesCommandOpt = "excludeESModules,e";
1140 static char const* const kShowAllModulesOpt = "showAllModules";
1141 static char const* const kShowAllModulesCommandOpt = "showAllModules,a";
1142 static char const* const kFindMatchOpt = "findMatch";
1143 static char const* const kFindMatchCommandOpt = "findMatch,f";
1144 static char const* const kDontPrintProductsOpt = "dontPrintProducts";
1145 static char const* const kDontPrintProductsCommandOpt = "dontPrintProducts,p";
1146 static char const* const kShowTopLevelPSetsOpt = "showTopLevelPSets";
1147 static char const* const kShowTopLevelPSetsCommandOpt = "showTopLevelPSets,t";
1148 static char const* const kHelpOpt = "help";
1149 static char const* const kHelpCommandOpt = "help,h";
1150 static char const* const kFileNameOpt = "input-file";
1151 static char const* const kDumpPSetIDOpt = "dumpPSetID";
1152 static char const* const kDumpPSetIDCommandOpt = "dumpPSetID,i";
1153 static char const* const kProductIDEntryOpt = "productIDEntry";
1154 static char const* const kHardwareOpt = "hardware";
1155
1156 int main(int argc, char* argv[]) {
1157 using namespace boost::program_options;
1158
1159 std::string descString(argv[0]);
1160 descString += " [options] <filename>";
1161 descString += "\nAllowed options";
1162 options_description desc(descString);
1163
1164
1165 desc.add_options()(kHelpCommandOpt, "show help message")(kSortCommandOpt, "alphabetially sort EventSetup components")(
1166 kDependenciesCommandOpt, "print what data each EDProducer is directly dependent upon")(
1167 kExtendedAncestorsCommandOpt, "print what data each EDProducer is dependent upon including indirect dependences")(
1168 kExtendedDescendantsCommandOpt,
1169 "print what data depends on the data each EDProducer produces including indirect dependences")(
1170 kExcludeESModulesCommandOpt, "do not print ES module information")(
1171 kShowAllModulesCommandOpt, "show all modules (not just those that created data in the file)")(
1172 kShowTopLevelPSetsCommandOpt, "show all top level PSets")(
1173 kFindMatchCommandOpt,
1174 boost::program_options::value<std::vector<std::string>>(),
1175 "show only modules whose information contains the matching string (or all the matching strings, this option can "
1176 "be repeated with different strings)")(kDontPrintProductsCommandOpt, "do not print products produced by module")(
1177 kDumpPSetIDCommandOpt,
1178 value<std::string>(),
1179 "print the parameter set associated with the parameter set ID string (and print nothing else)")(
1180 kProductIDEntryOpt,
1181 value<int>(),
1182 "show ProductID instead of BranchID using the specified entry in the Events tree")(
1183 kHardwareOpt,
1184 "include hardware provenance");
1185
1186
1187
1188
1189 options_description hidden;
1190 hidden.add_options()(kFileNameOpt, value<std::string>(), "file name");
1191
1192
1193 options_description cmdline_options;
1194 cmdline_options.add(desc).add(hidden);
1195
1196 positional_options_description p;
1197 p.add(kFileNameOpt, -1);
1198
1199 variables_map vm;
1200 try {
1201 store(command_line_parser(argc, argv).options(cmdline_options).positional(p).run(), vm);
1202 notify(vm);
1203 } catch (error const& iException) {
1204 std::cerr << iException.what();
1205 return 1;
1206 }
1207
1208 if (vm.count(kHelpOpt)) {
1209 std::cout << desc << std::endl;
1210 return 0;
1211 }
1212
1213 if (vm.count(kSortOpt)) {
1214 HistoryNode::sort_ = true;
1215 }
1216
1217 bool showDependencies = false;
1218 if (vm.count(kDependenciesOpt)) {
1219 showDependencies = true;
1220 }
1221
1222 bool extendedAncestors = false;
1223 if (vm.count(kExtendedAncestorsOpt)) {
1224 extendedAncestors = true;
1225 }
1226
1227 bool extendedDescendants = false;
1228 if (vm.count(kExtendedDescendantsOpt)) {
1229 extendedDescendants = true;
1230 }
1231
1232 bool excludeESModules = false;
1233 if (vm.count(kExcludeESModulesOpt)) {
1234 excludeESModules = true;
1235 }
1236
1237 bool showAllModules = false;
1238 if (vm.count(kShowAllModulesOpt)) {
1239 showAllModules = true;
1240 }
1241
1242 bool showTopLevelPSets = false;
1243 if (vm.count(kShowTopLevelPSetsOpt)) {
1244 showTopLevelPSets = true;
1245 }
1246
1247 std::string fileName;
1248 if (vm.count(kFileNameOpt)) {
1249 try {
1250 fileName = vm[kFileNameOpt].as<std::string>();
1251 } catch (boost::bad_any_cast const& e) {
1252 std::cout << e.what() << std::endl;
1253 return 2;
1254 }
1255 } else {
1256 std::cout << "Data file not specified." << std::endl;
1257 std::cout << desc << std::endl;
1258 return 2;
1259 }
1260
1261 std::string dumpPSetID;
1262 if (vm.count(kDumpPSetIDOpt)) {
1263 try {
1264 dumpPSetID = vm[kDumpPSetIDOpt].as<std::string>();
1265 } catch (boost::bad_any_cast const& e) {
1266 std::cout << e.what() << std::endl;
1267 return 2;
1268 }
1269 }
1270
1271 std::vector<std::string> findMatch;
1272 if (vm.count(kFindMatchOpt)) {
1273 try {
1274 findMatch = vm[kFindMatchOpt].as<std::vector<std::string>>();
1275 } catch (boost::bad_any_cast const& e) {
1276 std::cout << e.what() << std::endl;
1277 return 2;
1278 }
1279 }
1280
1281 bool dontPrintProducts = false;
1282 if (vm.count(kDontPrintProductsOpt)) {
1283 dontPrintProducts = true;
1284 }
1285
1286 int productIDEntry = -1;
1287 if (vm.count(kProductIDEntryOpt)) {
1288 try {
1289 productIDEntry = vm[kProductIDEntryOpt].as<int>();
1290 } catch (boost::bad_any_cast const& e) {
1291 std::cout << e.what() << std::endl;
1292 return 2;
1293 }
1294 }
1295
1296 bool printHardwareResourcesDescription = false;
1297 if (vm.count(kHardwareOpt)) {
1298 printHardwareResourcesDescription = true;
1299 }
1300
1301
1302 gErrorIgnoreLevel = kError;
1303
1304 ProvenanceDumper dumper(fileName,
1305 showDependencies,
1306 extendedAncestors,
1307 extendedDescendants,
1308 excludeESModules,
1309 showAllModules,
1310 showTopLevelPSets,
1311 findMatch,
1312 dontPrintProducts,
1313 dumpPSetID,
1314 productIDEntry,
1315 printHardwareResourcesDescription);
1316 int exitCode(0);
1317 try {
1318 dumper.dump();
1319 exitCode = dumper.exitCode();
1320 } catch (cms::Exception const& x) {
1321 std::cerr << "cms::Exception caught\n";
1322 std::cerr << x.what() << '\n';
1323 exitCode = 2;
1324 } catch (std::exception& x) {
1325 std::cerr << "std::exception caught\n";
1326 std::cerr << x.what() << '\n';
1327 exitCode = 3;
1328 } catch (...) {
1329 std::cerr << "Unknown exception caught\n";
1330 exitCode = 4;
1331 }
1332
1333 dumper.printErrors(std::cerr);
1334 return exitCode;
1335 }