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