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