CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/IOPool/Common/bin/EdmProvDump.cc

Go to the documentation of this file.
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     //Get ParameterSet for process
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       //get the sources
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       //get the modules
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     //Get ParameterSet for process
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       //get all modules
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         //if we didn't already handle this from the branches
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     // See if it is a logical file name.
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     // filename is a valid LFN.
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   // Open the input file, returning the TFile object that represents it.
00300   // The returned unique_ptr will not be null. The argument must not be null.
00301   // We first try the file name as a PFN, so that the catalog and related
00302   // services are not loaded unless needed.
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       // Try again with catalog.
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     // indent a bit
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     // indent a bit
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     // indent a bit
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   // It is illegal to call this constructor with a null pointer; a
00375   // legal C-style string is required.
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; // Disallow copying and moving
00383   ProvenanceDumper& operator=(ProvenanceDumper const&) = delete; // Disallow copying and moving
00384 
00385   // Write the provenenace information to the given stream.
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       //loop over the history entries looking for matches
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           //see if this is unique
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 = &reg_;
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   // backward compatibility
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   //Prepare the parentage information if requested
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           //backwards compatible check
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   //using edm::ParameterSetID as the key does not work
00712   //   typedef std::map<edm::ParameterSetID, std::vector<edm::BranchDescription> > IdToBranches
00713   ModuleToIdBranches moduleToIdBranches;
00714   //IdToBranches idToBranches;
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     //force it to rebuild the branch name
00723     it->second.init();
00724 
00725     if(showDependencies_) {
00726       branchIDToBranchName[it->second.branchID()] = it->second.branchName();
00727     }
00728     /*
00729       std::cout << it->second.branchName()
00730       << " id " << it->second.productID() << std::endl;
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       //idToBranches[*itId].push_back(it->second);
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   //we don't want users to see these in the help messages since this
00862   // name only exists since the parser needs it
00863   options_description hidden;
00864   hidden.add_options()(kFileNameOpt, value<std::string>(), "file name");
00865 
00866   //full list of options for the parser
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   //silence ROOT warnings about missing dictionaries
00931   gErrorIgnoreLevel = kError;
00932 
00933   //make sure dictionaries can be used for reading
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 }