CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/IOPool/Common/bin/EdmProvDump.cc

Go to the documentation of this file.
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     //Get ParameterSet for process
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       //get the sources
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       //get the modules
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     //Get ParameterSet for process
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       //get all modules
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         //if we didn't already handle this from the branches
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     // See if it is a logical file name.
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     // filename is a valid LFN.
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   // Open the input file, returning the TFile object that represents it.
00301   // The returned auto_ptr will not be null. The argument must not be null.
00302   // We first try the file name as a PFN, so that the catalog and related
00303   // services are not loaded unless needed.
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       // Try again with catalog.
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     // indent a bit
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     // indent a bit
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     // indent a bit
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   // It is illegal to call this constructor with a null pointer; a
00376   // legal C-style string is required.
00377   ProvenanceDumper(std::string const& filename,
00378                    bool showDependencies,
00379                    bool excludeESModules,
00380                    bool showAllModules,
00381                    std::string const& findMatch);
00382 
00383   // Write the provenenace information to the given stream.
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       //loop over the history entries looking for matches
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           //see if this is unique
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 = &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       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   //using edm::ParameterSetID as the key does not work
00688   //   typedef std::map<edm::ParameterSetID, std::vector<edm::BranchDescription> > IdToBranches
00689   ModuleToIdBranches moduleToIdBranches;
00690   //IdToBranches idToBranches;
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     //force it to rebuild the branch name
00699     it->second.init();
00700 
00701     if(showDependencies_) {
00702       branchIDToBranchName[it->second.branchID()] = it->second.branchName();
00703     }
00704     /*
00705       std::cout << it->second.branchName()
00706       << " id " << it->second.productID() << std::endl;
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       //idToBranches[*itId].push_back(it->second);
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   //we don't want users to see these in the help messages since this
00838   // name only exists since the parser needs it
00839   options_description hidden;
00840   hidden.add_options()(kFileNameOpt, value<std::string>(), "file name");
00841 
00842   //full list of options for the parser
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   //silence ROOT warnings about missing dictionaries
00897   gErrorIgnoreLevel = kError;
00898 
00899   //make sure dictionaries can be used for reading
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 }