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