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