00001 #include "DataFormats/Provenance/interface/BranchType.h"
00002 #include "DataFormats/Provenance/interface/EventSelectionID.h"
00003 #include "DataFormats/Provenance/interface/History.h"
00004 #include "DataFormats/Provenance/interface/ParameterSetBlob.h"
00005 #include "DataFormats/Provenance/interface/ProcessConfigurationRegistry.h"
00006 #include "DataFormats/Provenance/interface/ParameterSetID.h"
00007 #include "DataFormats/Provenance/interface/ProcessHistoryRegistry.h"
00008 #include "DataFormats/Provenance/interface/ProcessConfigurationID.h"
00009 #include "DataFormats/Provenance/interface/ProductRegistry.h"
00010 #include "DataFormats/Provenance/interface/Parentage.h"
00011 #include "DataFormats/Provenance/interface/ProductProvenance.h"
00012 #include "DataFormats/Provenance/interface/StoredProductProvenance.h"
00013 #include "DataFormats/Provenance/interface/ParentageRegistry.h"
00014 #include "FWCore/Catalog/interface/InputFileCatalog.h"
00015 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00016 #include "FWCore/ParameterSet/interface/Registry.h"
00017 #include "FWCore/ParameterSet/interface/FillProductRegistryTransients.h"
00018 #include "FWCore/ServiceRegistry/interface/ServiceRegistry.h"
00019 #include "FWCore/Services/src/SiteLocalConfigService.h"
00020
00021 #include "FWCore/Utilities/interface/Algorithms.h"
00022 #include "FWCore/Utilities/interface/Exception.h"
00023
00024 #include "Cintex/Cintex.h"
00025 #include "TError.h"
00026 #include "TFile.h"
00027 #include "TTree.h"
00028
00029 #include "boost/program_options.hpp"
00030
00031 #include <assert.h>
00032 #include <iostream>
00033 #include <memory>
00034 #include <map>
00035 #include <set>
00036 #include <sstream>
00037 #include <vector>
00038
00039 typedef std::map<std::string, std::vector<edm::BranchDescription> > IdToBranches;
00040 typedef std::map<std::pair<std::string, std::string>, IdToBranches> ModuleToIdBranches;
00041
00042 static std::ostream& prettyPrint(std::ostream& oStream, edm::ParameterSet const& iPSet, std::string const& iIndent, std::string const& iIndentDelta);
00043
00044 namespace {
00045 typedef std::map<edm::ParameterSetID, edm::ParameterSetBlob> ParameterSetMap;
00046
00047 class HistoryNode {
00048 public:
00049 HistoryNode() :
00050 config_(),
00051 simpleId_(0) {
00052 }
00053
00054 HistoryNode(edm::ProcessConfiguration const& iConfig, unsigned int iSimpleId) :
00055 config_(iConfig),
00056 simpleId_(iSimpleId) {
00057 }
00058
00059 void addChild(HistoryNode const& child) {
00060 children_.push_back(child);
00061 }
00062
00063 edm::ParameterSetID const&
00064 parameterSetID() const {
00065 return config_.parameterSetID();
00066 }
00067
00068 std::string const&
00069 processName() const {
00070 return config_.processName();
00071 }
00072
00073 std::size_t
00074 size() const {
00075 return children_.size();
00076 }
00077
00078 HistoryNode *
00079 lastChildAddress() {
00080 return &children_.back();
00081 }
00082
00083 typedef std::vector<HistoryNode>::const_iterator const_iterator;
00084 typedef std::vector<HistoryNode>::iterator iterator;
00085
00086 iterator begin() { return children_.begin();}
00087 iterator end() { return children_.end();}
00088
00089 const_iterator begin() const { return children_.begin();}
00090 const_iterator end() const { return children_.end();}
00091
00092 void print(std::ostream& os) const {
00093 os << config_.processName()
00094 << " '" << config_.passID() << "' '"
00095 << config_.releaseVersion() << "' ["
00096 << simpleId_ << "] ("
00097 << config_.parameterSetID() << ")"
00098 << std::endl;
00099 }
00100
00101 void printHistory(std::string const& iIndent = std::string(" ")) const;
00102 void printEventSetupHistory(ParameterSetMap const& iPSM,
00103 std::string const& iFindMatch,
00104 std::ostream& oErrorLog) const;
00105 void printOtherModulesHistory(ParameterSetMap const& iPSM,
00106 ModuleToIdBranches const&,
00107 std::string const& iFindMatch,
00108 std::ostream& oErrorLog) const;
00109 void printTopLevelPSetsHistory(ParameterSetMap const& iPSM,
00110 std::string const& iFindMatch,
00111 std::ostream& oErrorLog) const;
00112
00113 edm::ProcessConfigurationID
00114 configurationID() const {
00115 return config_.id();
00116 }
00117
00118 static bool sort_;
00119 private:
00120 edm::ProcessConfiguration config_;
00121 std::vector<HistoryNode> children_;
00122 unsigned int simpleId_;
00123 };
00124
00125 std::ostream& operator<<(std::ostream& os, HistoryNode const& node) {
00126 node.print(os);
00127 return os;
00128 }
00129 bool HistoryNode::sort_ = false;
00130 }
00131
00132 std::ostream&
00133 operator<<(std::ostream& os, edm::ProcessHistory& iHist) {
00134 std::string const indentDelta(" ");
00135 std::string indent = indentDelta;
00136 for(edm::ProcessHistory::const_iterator i = iHist.begin(), e = iHist.end();
00137 i != e;
00138 ++i) {
00139 os << indent
00140 << i->processName() << " '"
00141 << i->passID() << "' '"
00142 << i->releaseVersion() << "' ("
00143 << i->parameterSetID() << ")"
00144 << std::endl;
00145 indent += indentDelta;
00146 }
00147 return os;
00148 }
00149
00150 void HistoryNode::printHistory(std::string const& iIndent) const {
00151 std::string const indentDelta(" ");
00152 std::string indent = iIndent;
00153 for(const_iterator i = begin(), e = end();
00154 i != e;
00155 ++i) {
00156 std::cout << indent << *i;
00157 i->printHistory(indent+indentDelta);
00158 }
00159 }
00160
00161 std::string eventSetupComponent(char const* iType,
00162 std::string const& iCompName,
00163 edm::ParameterSet const& iProcessConfig,
00164 std::string const& iProcessName) {
00165 std::ostringstream result;
00166 edm::ParameterSet const& pset = iProcessConfig.getParameterSet(iCompName);
00167 std::string name(pset.getParameter<std::string>("@module_label"));
00168 if(0 == name.size()) {
00169 name = pset.getParameter<std::string>("@module_type");
00170 }
00171
00172 result << iType << ": " << name << " " << iProcessName << "\n"
00173 << " parameters: ";
00174 prettyPrint(result, pset, " ", " ");
00175 return result.str();
00176 }
00177
00178 void HistoryNode::printEventSetupHistory(ParameterSetMap const& iPSM,
00179 std::string const& iFindMatch,
00180 std::ostream& oErrorLog) const {
00181 for(const_iterator itH = begin(), e = end();
00182 itH != e;
00183 ++itH) {
00184
00185 ParameterSetMap::const_iterator itFind = iPSM.find(itH->parameterSetID());
00186 if(itFind == iPSM.end()){
00187 oErrorLog << "No ParameterSetID for " << itH->parameterSetID() << std::endl;
00188 } else {
00189 edm::ParameterSet processConfig(itFind->second.pset());
00190 std::vector<std::string> sourceStrings, moduleStrings;
00191
00192 std::vector<std::string> sources = processConfig.getParameter<std::vector<std::string> >("@all_essources");
00193 for(std::vector<std::string>::iterator itM = sources.begin(); itM != sources.end(); ++itM) {
00194 std::string retValue = eventSetupComponent("ESSource",
00195 *itM,
00196 processConfig,
00197 itH->processName());
00198 if(iFindMatch.empty() or retValue.find(iFindMatch) != std::string::npos) {
00199 sourceStrings.push_back(std::move(retValue));
00200 }
00201 }
00202
00203 std::vector<std::string> modules = processConfig.getParameter<std::vector<std::string> >("@all_esmodules");
00204 for(std::vector<std::string>::iterator itM = modules.begin(); itM != modules.end(); ++itM) {
00205 std::string retValue = eventSetupComponent("ESModule",
00206 *itM,
00207 processConfig,
00208 itH->processName());
00209 if(iFindMatch.empty() or retValue.find(iFindMatch) != std::string::npos) {
00210 moduleStrings.push_back(std::move(retValue));
00211 }
00212 }
00213 if(sort_) {
00214 std::sort(sourceStrings.begin(), sourceStrings.end());
00215 std::sort(moduleStrings.begin(), moduleStrings.end());
00216 }
00217 std::copy(sourceStrings.begin(), sourceStrings.end(),
00218 std::ostream_iterator<std::string>(std::cout, "\n"));
00219 std::copy(moduleStrings.begin(), moduleStrings.end(),
00220 std::ostream_iterator<std::string>(std::cout, "\n"));
00221
00222 }
00223 itH->printEventSetupHistory(iPSM, iFindMatch, oErrorLog);
00224 }
00225 }
00226
00227 std::string nonProducerComponent(std::string const& iCompName,
00228 edm::ParameterSet const& iProcessConfig,
00229 std::string const& iProcessName) {
00230 std::ostringstream result;
00231 edm::ParameterSet const& pset = iProcessConfig.getParameterSet(iCompName);
00232 std::string label(pset.getParameter<std::string>("@module_label"));
00233
00234 result << "Module: " << label << " " << iProcessName << "\n" << " parameters: ";
00235 prettyPrint(result, pset, " ", " ");
00236 return result.str();
00237 }
00238
00239 void HistoryNode::printOtherModulesHistory(ParameterSetMap const& iPSM,
00240 ModuleToIdBranches const& iModules,
00241 std::string const& iFindMatch,
00242 std::ostream& oErrorLog) const {
00243 for(const_iterator itH = begin(), e = end();
00244 itH != e;
00245 ++itH) {
00246
00247 ParameterSetMap::const_iterator itFind = iPSM.find(itH->parameterSetID());
00248 if(itFind == iPSM.end()){
00249 oErrorLog << "No ParameterSetID for " << itH->parameterSetID() << std::endl;
00250 } else {
00251 edm::ParameterSet processConfig(itFind->second.pset());
00252 std::vector<std::string> moduleStrings;
00253
00254 std::vector<std::string> modules = processConfig.getParameter<std::vector<std::string> >("@all_modules");
00255 for(std::vector<std::string>::iterator itM = modules.begin(); itM != modules.end(); ++itM) {
00256
00257 if(iModules.end() == iModules.find(std::make_pair(itH->processName(), *itM))) {
00258 std::string retValue(nonProducerComponent(
00259 *itM,
00260 processConfig,
00261 itH->processName()));
00262 if(iFindMatch.empty() or retValue.find(iFindMatch) != std::string::npos) {
00263 moduleStrings.push_back(std::move(retValue));
00264 }
00265 }
00266 }
00267 if(sort_) {
00268 std::sort(moduleStrings.begin(), moduleStrings.end());
00269 }
00270 std::copy(moduleStrings.begin(), moduleStrings.end(),
00271 std::ostream_iterator<std::string>(std::cout, "\n"));
00272 }
00273 itH->printOtherModulesHistory(iPSM, iModules, iFindMatch, oErrorLog);
00274 }
00275 }
00276
00277 static void appendToSet(std::set<std::string>&iSet, std::vector<std::string> const& iFrom){
00278 for( auto const& n: iFrom){
00279 iSet.insert(n);
00280 }
00281 }
00282
00283 static std::string topLevelPSet(std::string const& iName,
00284 edm::ParameterSet const& iProcessConfig,
00285 std::string const& iProcessName) {
00286 std::ostringstream result;
00287 edm::ParameterSet const& pset = iProcessConfig.getParameterSet(iName);
00288
00289 result << "PSet: " << iName << " " << iProcessName << "\n" << " parameters: ";
00290 prettyPrint(result, pset, " ", " ");
00291 return result.str();
00292 }
00293
00294
00295 void HistoryNode::printTopLevelPSetsHistory(ParameterSetMap const& iPSM,
00296 std::string const& iFindMatch,
00297 std::ostream& oErrorLog) const {
00298 for(const_iterator itH = begin(), e = end();
00299 itH != e;
00300 ++itH) {
00301
00302 ParameterSetMap::const_iterator itFind = iPSM.find(itH->parameterSetID());
00303 if(itFind == iPSM.end()){
00304 oErrorLog << "No ParameterSetID for " << itH->parameterSetID() << std::endl;
00305 } else {
00306 edm::ParameterSet processConfig(itFind->second.pset());
00307
00308 std::set<std::string> namesToExclude;
00309 appendToSet(namesToExclude,processConfig.getParameter<std::vector<std::string> >("@all_modules"));
00310 appendToSet(namesToExclude,processConfig.getParameter<std::vector<std::string> >("@all_sources"));
00311 appendToSet(namesToExclude,processConfig.getParameter<std::vector<std::string> >("@all_loopers"));
00312
00313 appendToSet(namesToExclude,processConfig.getParameter<std::vector<std::string> >("@all_esmodules"));
00314 appendToSet(namesToExclude,processConfig.getParameter<std::vector<std::string> >("@all_essources"));
00315 appendToSet(namesToExclude,processConfig.getParameter<std::vector<std::string> >("@all_esprefers"));
00316 if (processConfig.existsAs<std::vector<std::string>>("all_aliases")) {
00317 appendToSet(namesToExclude,processConfig.getParameter<std::vector<std::string> >("@all_aliases"));
00318 }
00319
00320 std::vector<std::string> allNames{};
00321 processConfig.getParameterSetNames(allNames);
00322
00323 std::vector<std::string> results;
00324 for(auto const& name: allNames){
00325 if (name.size() == 0 || '@' == name[0] || namesToExclude.find(name)!=namesToExclude.end()) {
00326 continue;
00327 }
00328 std::string retValue = topLevelPSet(name,processConfig,itH->processName());
00329 if(iFindMatch.empty() or retValue.find(iFindMatch) != std::string::npos) {
00330 results.push_back(std::move(retValue));
00331 }
00332 }
00333 if(sort_) {
00334 std::sort(results.begin(), results.end());
00335 }
00336 std::copy(results.begin(), results.end(),
00337 std::ostream_iterator<std::string>(std::cout, "\n"));
00338 }
00339 itH->printTopLevelPSetsHistory(iPSM, iFindMatch, oErrorLog);
00340 }
00341 }
00342
00343
00344 namespace {
00345 std::unique_ptr<TFile>
00346 makeTFileWithLookup(std::string const& filename) {
00347
00348 std::auto_ptr<edm::SiteLocalConfig> slcptr(new edm::service::SiteLocalConfigService(edm::ParameterSet()));
00349 boost::shared_ptr<edm::serviceregistry::ServiceWrapper<edm::SiteLocalConfig> > slc(new edm::serviceregistry::ServiceWrapper<edm::SiteLocalConfig>(slcptr));
00350 edm::ServiceToken slcToken = edm::ServiceRegistry::createContaining(slc);
00351 edm::ServiceRegistry::Operate operate(slcToken);
00352 std::string override;
00353 std::vector<std::string> fileNames;
00354 fileNames.push_back(filename);
00355 edm::InputFileCatalog catalog(fileNames, override, true);
00356 if(catalog.fileNames()[0] == filename) {
00357 throw cms::Exception("FileNotFound", "RootFile::RootFile()")
00358 << "File " << filename << " was not found or could not be opened.\n";
00359 }
00360
00361 std::unique_ptr<TFile> result(TFile::Open(catalog.fileNames()[0].c_str()));
00362 if(!result.get()) {
00363 throw cms::Exception("FileNotFound", "RootFile::RootFile()")
00364 << "File " << fileNames[0] << " was not found or could not be opened.\n";
00365 }
00366 return result;
00367 }
00368
00369
00370
00371
00372
00373 std::unique_ptr<TFile>
00374 makeTFile(std::string const& filename) {
00375 gErrorIgnoreLevel = kFatal;
00376 std::unique_ptr<TFile> result(TFile::Open(filename.c_str()));
00377 gErrorIgnoreLevel = kError;
00378 if(!result.get()) {
00379
00380 return makeTFileWithLookup(filename);
00381 }
00382 return result;
00383 }
00384 }
00385
00386
00387 static std::ostream& prettyPrint(std::ostream& os, edm::ParameterSetEntry const& psetEntry, std::string const& iIndent, std::string const& iIndentDelta) {
00388 char const* trackiness = (psetEntry.isTracked()?"tracked":"untracked");
00389 os << "PSet " << trackiness << " = (";
00390 prettyPrint(os, psetEntry.pset(), iIndent + iIndentDelta, iIndentDelta);
00391 os << ")";
00392 return os;
00393 }
00394
00395 static std::ostream& prettyPrint(std::ostream& os, edm::VParameterSetEntry const& vpsetEntry, std::string const& iIndent, std::string const& iIndentDelta) {
00396 std::vector<edm::ParameterSet> const& vps = vpsetEntry.vpset();
00397 os << "VPSet " << (vpsetEntry.isTracked() ? "tracked" : "untracked") << " = ({" << std::endl;
00398 std::string newIndent = iIndent+iIndentDelta;
00399 std::string start;
00400 std::string const between(",\n");
00401 for(std::vector<edm::ParameterSet>::const_iterator i = vps.begin(), e = vps.end(); i != e; ++i) {
00402 os << start << newIndent;
00403 prettyPrint(os, *i, newIndent, iIndentDelta);
00404 start = between;
00405 }
00406 if(!vps.empty()) {
00407 os << std::endl;
00408 }
00409 os << iIndent<< "})";
00410 return os;
00411 }
00412
00413
00414 static std::ostream& prettyPrint(std::ostream& oStream, edm::ParameterSet const& iPSet, std::string const& iIndent, std::string const& iIndentDelta) {
00415 std::string newIndent = iIndent+iIndentDelta;
00416
00417 oStream << "{" << std::endl;
00418 for(edm::ParameterSet::table::const_iterator i = iPSet.tbl().begin(), e = iPSet.tbl().end(); i != e; ++i) {
00419
00420 oStream << newIndent<< i->first << ": " << i->second << std::endl;
00421 }
00422 for(edm::ParameterSet::psettable::const_iterator i = iPSet.psetTable().begin(), e = iPSet.psetTable().end(); i != e; ++i) {
00423
00424 edm::ParameterSetEntry const& pe = i->second;
00425 oStream << newIndent << i->first << ": ";
00426 prettyPrint(oStream, pe, iIndent, iIndentDelta);
00427 oStream<< std::endl;
00428 }
00429 for(edm::ParameterSet::vpsettable::const_iterator i = iPSet.vpsetTable().begin(), e = iPSet.vpsetTable().end(); i != e; ++i) {
00430
00431 edm::VParameterSetEntry const& pe = i->second;
00432 oStream << newIndent << i->first << ": ";
00433 prettyPrint(oStream, pe, newIndent, iIndentDelta);
00434 oStream<< std::endl;
00435 }
00436 oStream << iIndent<< "}";
00437
00438 return oStream;
00439 }
00440
00441
00442 class ProvenanceDumper {
00443 public:
00444
00445
00446 ProvenanceDumper(std::string const& filename,
00447 bool showDependencies,
00448 bool excludeESModules,
00449 bool showAllModules,
00450 bool showTopLevelPSets,
00451 std::string const& findMatch);
00452
00453 ProvenanceDumper(ProvenanceDumper const&) = delete;
00454 ProvenanceDumper& operator=(ProvenanceDumper const&) = delete;
00455
00456
00457 void dump();
00458 void printErrors(std::ostream& os);
00459 int exitCode() const;
00460
00461 private:
00462 std::string filename_;
00463 std::unique_ptr<TFile> inputFile_;
00464 int exitCode_;
00465 std::stringstream errorLog_;
00466 int errorCount_;
00467 edm::ProductRegistry reg_;
00468 edm::ProcessConfigurationVector phc_;
00469 edm::ProcessHistoryVector phv_;
00470 ParameterSetMap psm_;
00471 HistoryNode historyGraph_;
00472 bool showDependencies_;
00473 bool excludeESModules_;
00474 bool showOtherModules_;
00475 bool showTopLevelPSets_;
00476 std::string findMatch_;
00477
00478 void work_();
00479 void dumpProcessHistory_();
00480 void dumpEventFilteringParameterSets_(TFile * file);
00481 void dumpEventFilteringParameterSets(edm::EventSelectionIDVector const& ids);
00482 void dumpParameterSetForID_(edm::ParameterSetID const& id);
00483 };
00484
00485 ProvenanceDumper::ProvenanceDumper(std::string const& filename,
00486 bool showDependencies,
00487 bool excludeESModules,
00488 bool showOtherModules,
00489 bool showTopLevelPSets,
00490 std::string const& findMatch) :
00491 filename_(filename),
00492 inputFile_(makeTFile(filename)),
00493 exitCode_(0),
00494 errorLog_(),
00495 errorCount_(0),
00496 showDependencies_(showDependencies),
00497 excludeESModules_(excludeESModules),
00498 showOtherModules_(showOtherModules),
00499 showTopLevelPSets_(showTopLevelPSets),
00500 findMatch_(findMatch) {
00501 }
00502
00503 void
00504 ProvenanceDumper::dump() {
00505 work_();
00506 }
00507
00508 void
00509 ProvenanceDumper::printErrors(std::ostream& os) {
00510 if(errorCount_ > 0) os << errorLog_.str() << std::endl;
00511 }
00512
00513 int
00514 ProvenanceDumper::exitCode() const {
00515 return exitCode_;
00516 }
00517
00518 void
00519 ProvenanceDumper::dumpEventFilteringParameterSets(edm::EventSelectionIDVector const& ids) {
00520 edm::EventSelectionIDVector::size_type num_ids = ids.size();
00521 if(num_ids == 0) {
00522 std::cout << "No event filtering information is available.\n";
00523 std::cout << "------------------------------\n";
00524 } else {
00525 std::cout << "Event filtering information for "
00526 << num_ids
00527 << " processing steps is available.\n"
00528 << "The ParameterSets will be printed out, "
00529 << "with the oldest printed first.\n";
00530 for(edm::EventSelectionIDVector::size_type i = 0; i != num_ids; ++i) {
00531 dumpParameterSetForID_(ids[i]);
00532 }
00533 }
00534 }
00535
00536 void
00537 ProvenanceDumper::dumpEventFilteringParameterSets_(TFile* file) {
00538
00539 TTree* history = dynamic_cast<TTree*>(file->Get(edm::poolNames::eventHistoryTreeName().c_str()));
00540 if(history != 0) {
00541 edm::History h;
00542 edm::History* ph = &h;
00543
00544 history->SetBranchAddress(edm::poolNames::eventHistoryBranchName().c_str(), &ph);
00545 if(history->GetEntry(0) <= 0) {
00546 std::cout << "No event filtering information is available; the event history tree has no entries\n";
00547 } else {
00548 dumpEventFilteringParameterSets(h.eventSelectionIDs());
00549 }
00550 } else {
00551 TTree* events = dynamic_cast<TTree*>(file->Get(edm::poolNames::eventTreeName().c_str()));
00552 assert (events != 0);
00553 TBranch* eventSelectionsBranch = events->GetBranch(edm::poolNames::eventSelectionsBranchName().c_str());
00554 assert (eventSelectionsBranch != 0);
00555 edm::EventSelectionIDVector ids;
00556 edm::EventSelectionIDVector* pids = &ids;
00557 eventSelectionsBranch->SetAddress(&pids);
00558 if(eventSelectionsBranch->GetEntry(0) <= 0) {
00559 std::cout << "No event filtering information is available; the event selections branch has no entries\n";
00560 } else {
00561 dumpEventFilteringParameterSets(ids);
00562 }
00563 }
00564 }
00565
00566 void
00567 ProvenanceDumper::dumpParameterSetForID_(edm::ParameterSetID const& id) {
00568 std::cout << "ParameterSetID: " << id << '\n';
00569 if(id.isValid()) {
00570 ParameterSetMap::const_iterator i = psm_.find(id);
00571 if(i == psm_.end()) {
00572 std::cout << "We are unable to find the corresponding ParameterSet\n";
00573 edm::ParameterSet empty;
00574 if(id == empty.id()) {
00575 std::cout << "But it would have been empty anyway\n";
00576 }
00577 } else {
00578 edm::ParameterSet ps(i->second.pset());
00579 prettyPrint(std::cout, ps, " ", " ");
00580 std::cout<< '\n';
00581 }
00582 } else {
00583 std::cout << "This ID is not valid\n";
00584 }
00585 std::cout << " -------------------------\n";
00586 }
00587
00588 void
00589 ProvenanceDumper::dumpProcessHistory_() {
00590 std::cout << "Processing History:" << std::endl;
00591 if(1 == phv_.size()) {
00592 std::cout << *phv_.begin();
00593 historyGraph_.addChild(HistoryNode(*(phv_.begin()->begin()), 1));
00594 } else {
00595 std::map<edm::ProcessConfigurationID, unsigned int> simpleIDs;
00596 for(edm::ProcessHistoryVector::const_iterator it = phv_.begin(), itEnd = phv_.end();
00597 it != itEnd;
00598 ++it) {
00599
00600 HistoryNode* parent = &historyGraph_;
00601 for(edm::ProcessHistory::const_iterator itH = it->begin(), e = it->end();
00602 itH != e;
00603 ++itH) {
00604 if(parent->size() == 0) {
00605 unsigned int id = simpleIDs[itH->id()];
00606 if(0 == id) {
00607 id = 1;
00608 simpleIDs[itH->id()] = id;
00609 }
00610 parent->addChild(HistoryNode(*itH, id));
00611 parent = parent->lastChildAddress();
00612 } else {
00613
00614 bool isUnique = true;
00615 for(HistoryNode::iterator itChild = parent->begin(), itChildEnd = parent->end();
00616 itChild != itChildEnd;
00617 ++itChild) {
00618 if(itChild->configurationID() == itH->id()) {
00619 isUnique = false;
00620 parent = &(*itChild);
00621 break;
00622 }
00623 }
00624 if(isUnique) {
00625 simpleIDs[itH->id()] = parent->size() + 1;
00626 parent->addChild(HistoryNode(*itH, simpleIDs[itH->id()]));
00627 parent = parent->lastChildAddress();
00628 }
00629 }
00630 }
00631 }
00632 historyGraph_.printHistory();
00633 }
00634 }
00635
00636 void
00637 ProvenanceDumper::work_() {
00638
00639 TTree* meta = dynamic_cast<TTree*>(inputFile_->Get(edm::poolNames::metaDataTreeName().c_str()));
00640 assert(0 != meta);
00641
00642 edm::ProductRegistry* pReg = ®_;
00643 meta->SetBranchAddress(edm::poolNames::productDescriptionBranchName().c_str(), &pReg);
00644
00645 ParameterSetMap* pPsm = &psm_;
00646 if(meta->FindBranch(edm::poolNames::parameterSetMapBranchName().c_str()) != 0) {
00647 meta->SetBranchAddress(edm::poolNames::parameterSetMapBranchName().c_str(), &pPsm);
00648 } else {
00649 TTree* psetTree = dynamic_cast<TTree *>(inputFile_->Get(edm::poolNames::parameterSetsTreeName().c_str()));
00650 assert(0 != psetTree);
00651 typedef std::pair<edm::ParameterSetID, edm::ParameterSetBlob> IdToBlobs;
00652 IdToBlobs idToBlob;
00653 IdToBlobs* pIdToBlob = &idToBlob;
00654 psetTree->SetBranchAddress(edm::poolNames::idToParameterSetBlobsBranchName().c_str(), &pIdToBlob);
00655 for(long long i = 0; i != psetTree->GetEntries(); ++i) {
00656 psetTree->GetEntry(i);
00657 psm_.insert(idToBlob);
00658 }
00659 }
00660 edm::ProcessConfigurationVector* pPhc = &phc_;
00661 if(meta->FindBranch(edm::poolNames::processConfigurationBranchName().c_str()) != 0) {
00662 meta->SetBranchAddress(edm::poolNames::processConfigurationBranchName().c_str(), &pPhc);
00663 }
00664
00665 edm::ProcessHistoryVector* pPhv = &phv_;
00666 if(meta->FindBranch(edm::poolNames::processHistoryBranchName().c_str()) != 0) {
00667 meta->SetBranchAddress(edm::poolNames::processHistoryBranchName().c_str(), &pPhv);
00668 }
00669
00670 edm::ProcessHistoryMap phm;
00671 edm::ProcessHistoryMap* pPhm = &phm;
00672 if(meta->FindBranch(edm::poolNames::processHistoryMapBranchName().c_str()) != 0) {
00673 meta->SetBranchAddress(edm::poolNames::processHistoryMapBranchName().c_str(), &pPhm);
00674 }
00675
00676 if(meta->FindBranch(edm::poolNames::moduleDescriptionMapBranchName().c_str()) != 0) {
00677 if(meta->GetBranch(edm::poolNames::moduleDescriptionMapBranchName().c_str())->GetSplitLevel() != 0) {
00678 meta->SetBranchStatus((edm::poolNames::moduleDescriptionMapBranchName() + ".*").c_str(), 0);
00679 } else {
00680 meta->SetBranchStatus(edm::poolNames::moduleDescriptionMapBranchName().c_str(), 0);
00681 }
00682 }
00683
00684 meta->GetEntry(0);
00685 assert(0 != pReg);
00686
00687 edm::pset::Registry& psetRegistry = *edm::pset::Registry::instance();
00688 for(ParameterSetMap::const_iterator i = psm_.begin(), iEnd = psm_.end(); i != iEnd; ++i) {
00689 edm::ParameterSet pset(i->second.pset());
00690 pset.setID(i->first);
00691 psetRegistry.insertMapped(pset);
00692 }
00693
00694
00695
00696 if(!phm.empty()) {
00697 for(edm::ProcessHistoryMap::const_iterator i = phm.begin(), e = phm.end(); i != e; ++i) {
00698 phv_.push_back(i->second);
00699 for(edm::ProcessConfigurationVector::const_iterator j = i->second.begin(), f = i->second.end(); j != f; ++j) {
00700 phc_.push_back(*j);
00701 }
00702 }
00703 edm::sort_all(phc_);
00704 phc_.erase(std::unique(phc_.begin(), phc_.end()), phc_.end());
00705 }
00706
00707 fillProductRegistryTransients(phc_, reg_, true);
00708
00709
00710 std::map<edm::BranchID, std::set<edm::ParentageID> > perProductParentage;
00711
00712 if(showDependencies_){
00713 TTree* parentageTree = dynamic_cast<TTree*>(inputFile_->Get(edm::poolNames::parentageTreeName().c_str()));
00714 if(0 == parentageTree) {
00715 std::cerr << "no Parentage tree available so can not show dependencies/n";
00716 showDependencies_ = false;
00717 } else {
00718
00719 edm::ParentageRegistry& registry = *edm::ParentageRegistry::instance();
00720
00721 std::vector<edm::ParentageID> orderedParentageIDs;
00722 orderedParentageIDs.reserve(parentageTree->GetEntries());
00723 for(Long64_t i = 0, numEntries = parentageTree->GetEntries(); i < numEntries; ++i) {
00724 edm::Parentage parentageBuffer;
00725 edm::Parentage *pParentageBuffer = &parentageBuffer;
00726 parentageTree->SetBranchAddress(edm::poolNames::parentageBranchName().c_str(), &pParentageBuffer);
00727 parentageTree->GetEntry(i);
00728 registry.insertMapped(parentageBuffer);
00729 orderedParentageIDs.push_back(parentageBuffer.id());
00730 }
00731 parentageTree->SetBranchAddress(edm::poolNames::parentageBranchName().c_str(), 0);
00732
00733 TTree* eventMetaTree = dynamic_cast<TTree*>(inputFile_->Get(edm::BranchTypeToMetaDataTreeName(edm::InEvent).c_str()));
00734 if(0 == eventMetaTree) {
00735 eventMetaTree = dynamic_cast<TTree*>(inputFile_->Get(edm::BranchTypeToProductTreeName(edm::InEvent).c_str()));
00736 }
00737 if(0 == eventMetaTree) {
00738 std::cerr << "no '" << edm::BranchTypeToProductTreeName(edm::InEvent)<< "' Tree in file so can not show dependencies\n";
00739 showDependencies_ = false;
00740 } else {
00741 TBranch* storedProvBranch = eventMetaTree->GetBranch(edm::BranchTypeToProductProvenanceBranchName(edm::InEvent).c_str());
00742
00743 if(0!=storedProvBranch) {
00744 std::vector<edm::StoredProductProvenance> info;
00745 std::vector<edm::StoredProductProvenance>* pInfo = &info;
00746 storedProvBranch->SetAddress(&pInfo);
00747 for(Long64_t i = 0, numEntries = eventMetaTree->GetEntries(); i < numEntries; ++i) {
00748 storedProvBranch->GetEntry(i);
00749 for(std::vector<edm::StoredProductProvenance>::const_iterator it = info.begin(), itEnd = info.end();
00750 it != itEnd; ++it) {
00751 edm::BranchID bid(it->branchID_);
00752 perProductParentage[bid].insert(orderedParentageIDs[it->parentageIDIndex_]);
00753 }
00754 }
00755 } else {
00756
00757 TBranch* productProvBranch = eventMetaTree->GetBranch(edm::BranchTypeToBranchEntryInfoBranchName(edm::InEvent).c_str());
00758 if (0 != productProvBranch) {
00759 std::vector<edm::ProductProvenance> info;
00760 std::vector<edm::ProductProvenance>* pInfo = &info;
00761 productProvBranch->SetAddress(&pInfo);
00762 for(Long64_t i = 0, numEntries = eventMetaTree->GetEntries(); i < numEntries; ++i) {
00763 productProvBranch->GetEntry(i);
00764 for(std::vector<edm::ProductProvenance>::const_iterator it = info.begin(), itEnd = info.end();
00765 it != itEnd; ++it) {
00766 perProductParentage[it->branchID()].insert(it->parentageID());
00767 }
00768 }
00769 } else {
00770 std::cerr <<" could not find provenance information so can not show dependencies\n";
00771 showDependencies_=false;
00772 }
00773 }
00774 }
00775 }
00776 }
00777
00778
00779 dumpEventFilteringParameterSets_(inputFile_.get());
00780
00781 dumpProcessHistory_();
00782
00783 std::cout << "---------Producers with data in file---------" << std::endl;
00784
00785
00786
00787 ModuleToIdBranches moduleToIdBranches;
00788
00789
00790 std::map<edm::BranchID, std::string> branchIDToBranchName;
00791
00792 for(edm::ProductRegistry::ProductList::const_iterator it =
00793 reg_.productList().begin(), itEnd = reg_.productList().end();
00794 it != itEnd;
00795 ++it) {
00796
00797 it->second.init();
00798
00799 if(showDependencies_) {
00800 branchIDToBranchName[it->second.branchID()] = it->second.branchName();
00801 }
00802
00803
00804
00805
00806 for(std::map<edm::ProcessConfigurationID, edm::ParameterSetID>::const_iterator
00807 itId = it->second.parameterSetIDs().begin(),
00808 itIdEnd = it->second.parameterSetIDs().end();
00809 itId != itIdEnd;
00810 ++itId) {
00811
00812 std::stringstream s;
00813 s << itId->second;
00814 moduleToIdBranches[std::make_pair(it->second.processName(), it->second.moduleLabel())][s.str()].push_back(it->second);
00815
00816 }
00817 }
00818 for(ModuleToIdBranches::const_iterator it = moduleToIdBranches.begin(),
00819 itEnd = moduleToIdBranches.end();
00820 it != itEnd;
00821 ++it) {
00822 std::ostringstream sout;
00823 sout << "Module: " << it->first.second << " " << it->first.first << std::endl;
00824 IdToBranches const& idToBranches = it->second;
00825 for(IdToBranches::const_iterator itIdBranch = idToBranches.begin(),
00826 itIdBranchEnd = idToBranches.end();
00827 itIdBranch != itIdBranchEnd;
00828 ++itIdBranch) {
00829 sout << " PSet id:" << itIdBranch->first << std::endl;
00830 sout << " products: {" << std::endl;
00831 std::set<edm::BranchID> branchIDs;
00832 for(std::vector<edm::BranchDescription>::const_iterator itBranch = itIdBranch->second.begin(),
00833 itBranchEnd = itIdBranch->second.end();
00834 itBranch != itBranchEnd;
00835 ++itBranch) {
00836 sout << " " << itBranch->branchName() << std::endl;
00837 branchIDs.insert(itBranch->branchID());
00838 }
00839 sout << " }" << std::endl;
00840 edm::ParameterSetID psid(itIdBranch->first);
00841 ParameterSetMap::const_iterator itpsm = psm_.find(psid);
00842 if(psm_.end() == itpsm) {
00843 ++errorCount_;
00844 errorLog_ << "No ParameterSetID for " << psid << std::endl;
00845 exitCode_ = 1;
00846 } else {
00847 sout << " parameters: ";
00848 prettyPrint(sout, edm::ParameterSet((*itpsm).second.pset()), " ", " ");
00849 sout << std::endl;
00850 }
00851 if(showDependencies_) {
00852 edm::ParentageRegistry& registry = *edm::ParentageRegistry::instance();
00853
00854 sout << " dependencies: {" << std::endl;
00855 std::set<edm::ParentageID> parentageIDs;
00856 for(std::set<edm::BranchID>::const_iterator itBranch = branchIDs.begin(), itBranchEnd = branchIDs.end();
00857 itBranch != itBranchEnd;
00858 ++itBranch) {
00859 std::set<edm::ParentageID> const& temp = perProductParentage[*itBranch];
00860 parentageIDs.insert(temp.begin(), temp.end());
00861 }
00862 for(std::set<edm::ParentageID>::const_iterator itParentID = parentageIDs.begin(), itEndParentID = parentageIDs.end();
00863 itParentID != itEndParentID;
00864 ++itParentID) {
00865 edm::Parentage const* parentage = registry.getMapped(*itParentID);
00866 if(0 != parentage) {
00867 for(std::vector<edm::BranchID>::const_iterator itBranch = parentage->parents().begin(), itEndBranch = parentage->parents().end();
00868 itBranch != itEndBranch;
00869 ++itBranch) {
00870 sout << " " << branchIDToBranchName[*itBranch] << std::endl;
00871 }
00872 } else {
00873 sout << " ERROR:parentage info not in registry ParentageID=" << *itParentID << std::endl;
00874 }
00875 }
00876 if(parentageIDs.empty()) {
00877 sout << " no dependencies recorded (event may not contain data from this module)" << std::endl;
00878 }
00879 sout << " }" << std::endl;
00880 }
00881 if(findMatch_.empty() or sout.str().find(findMatch_) != std::string::npos) {
00882 std::cout <<sout.str()<<std::endl;
00883 }
00884 }
00885 }
00886 if(showOtherModules_) {
00887 std::cout << "---------Other Modules---------" << std::endl;
00888 historyGraph_.printOtherModulesHistory(psm_, moduleToIdBranches, findMatch_, errorLog_);
00889 }
00890
00891 if(!excludeESModules_) {
00892 std::cout << "---------EventSetup---------" << std::endl;
00893 historyGraph_.printEventSetupHistory(psm_, findMatch_, errorLog_);
00894 }
00895
00896 if(showTopLevelPSets_) {
00897 std::cout << "---------Top Level PSets---------" << std::endl;
00898 historyGraph_.printTopLevelPSetsHistory(psm_, findMatch_, errorLog_);
00899 }
00900 if(errorCount_ != 0) {
00901 exitCode_ = 1;
00902 }
00903 }
00904
00905 static char const* const kSortOpt = "sort";
00906 static char const* const kSortCommandOpt = "sort,s";
00907 static char const* const kDependenciesOpt = "dependencies";
00908 static char const* const kDependenciesCommandOpt = "dependencies,d";
00909 static char const* const kExcludeESModulesOpt = "excludeESModules";
00910 static char const* const kExcludeESModulesCommandOpt = "excludeESModules,e";
00911 static char const* const kShowAllModulesOpt = "showAllModules";
00912 static char const* const kShowAllModulesCommandOpt = "showAllModules,a";
00913 static char const* const kFindMatchOpt = "findMatch";
00914 static char const* const kFindMatchCommandOpt = "findMatch,f";
00915 static char const* const kShowTopLevelPSetsOpt = "showTopLevelPSets";
00916 static char const* const kShowTopLevelPSetsCommandOpt ="showTopLevelPSets,t";
00917 static char const* const kHelpOpt = "help";
00918 static char const* const kHelpCommandOpt = "help,h";
00919 static char const* const kFileNameOpt = "input-file";
00920 static char const* const kFileNameCommandOpt = "input-file";
00921
00922 int main(int argc, char* argv[]) {
00923 using namespace boost::program_options;
00924
00925 std::string descString(argv[0]);
00926 descString += " [options] <filename>";
00927 descString += "\nAllowed options";
00928 options_description desc(descString);
00929 desc.add_options()
00930 (kHelpCommandOpt, "show help message")
00931 (kSortCommandOpt
00932 , "alphabetially sort EventSetup components")
00933 (kDependenciesCommandOpt
00934 , "print what data each EDProducer is dependent upon")
00935 (kExcludeESModulesCommandOpt
00936 , "do not print ES module information")
00937 (kShowAllModulesCommandOpt
00938 , "show all modules (not just those that created data in the file)")
00939 (kShowTopLevelPSetsCommandOpt,"show all top level PSets")
00940 (kFindMatchCommandOpt, boost::program_options::value<std::string>(),
00941 "show only modules whose information contains the matching string")
00942 ;
00943
00944
00945 options_description hidden;
00946 hidden.add_options()(kFileNameOpt, value<std::string>(), "file name");
00947
00948
00949 options_description cmdline_options;
00950 cmdline_options.add(desc).add(hidden);
00951
00952 positional_options_description p;
00953 p.add(kFileNameOpt, -1);
00954
00955 variables_map vm;
00956 try {
00957 store(command_line_parser(argc, argv).options(cmdline_options).positional(p).run(), vm);
00958 notify(vm);
00959 } catch(error const& iException) {
00960 std::cerr << iException.what();
00961 return 1;
00962 }
00963
00964 if(vm.count(kHelpOpt)) {
00965 std::cout << desc << std::endl;
00966 return 0;
00967 }
00968
00969 if(vm.count(kSortOpt)) {
00970 HistoryNode::sort_ = true;
00971 }
00972
00973 bool showDependencies = false;
00974 if(vm.count(kDependenciesOpt)) {
00975 showDependencies = true;
00976 }
00977
00978 bool excludeESModules = false;
00979 if(vm.count(kExcludeESModulesOpt)) {
00980 excludeESModules = true;
00981 }
00982
00983 bool showAllModules = false;
00984 if(vm.count(kShowAllModulesOpt)) {
00985 showAllModules = true;
00986 }
00987
00988 bool showTopLevelPSets = false;
00989 if(vm.count(kShowTopLevelPSetsOpt)) {
00990 showTopLevelPSets=true;
00991 }
00992
00993 std::string fileName;
00994 if(vm.count(kFileNameOpt)) {
00995 try {
00996 fileName = vm[kFileNameOpt].as<std::string>();
00997 } catch(boost::bad_any_cast const& e) {
00998 std::cout << e.what() << std::endl;
00999 return 2;
01000 }
01001 } else {
01002 std::cout << "Data file not specified." << std::endl;
01003 std::cout << desc << std::endl;
01004 return 2;
01005 }
01006
01007 std::string findMatch;
01008 if(vm.count(kFindMatchOpt)) {
01009 try {
01010 findMatch = vm[kFindMatchOpt].as<std::string>();
01011 } catch(boost::bad_any_cast const& e) {
01012 std::cout << e.what() << std::endl;
01013 return 2;
01014 }
01015 }
01016
01017
01018 gErrorIgnoreLevel = kError;
01019
01020
01021 ROOT::Cintex::Cintex::Enable();
01022
01023 ProvenanceDumper dumper(fileName, showDependencies, excludeESModules, showAllModules, showTopLevelPSets, findMatch);
01024 int exitCode(0);
01025 try {
01026 dumper.dump();
01027 exitCode = dumper.exitCode();
01028 }
01029 catch (cms::Exception const& x) {
01030 std::cerr << "cms::Exception caught\n";
01031 std::cerr << x.what() << '\n';
01032 exitCode = 2;
01033 }
01034 catch (std::exception& x) {
01035 std::cerr << "std::exception caught\n";
01036 std::cerr << x.what() << '\n';
01037 exitCode = 3;
01038 }
01039 catch (...) {
01040 std::cerr << "Unknown exception caught\n";
01041 exitCode = 4;
01042 }
01043
01044 dumper.printErrors(std::cerr);
01045 return exitCode;
01046 }