CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/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 
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     //Get ParameterSet for process
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       //get the sources
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       //get the modules
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     //Get ParameterSet for process
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       //get all modules
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         //if we didn't already handle this from the branches
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     // See if it is a logical file name.
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     // filename is a valid LFN.
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   // Open the input file, returning the TFile object that represents it.
00304   // The returned auto_ptr will not be null. The argument must not be null.
00305   // We first try the file name as a PFN, so that the catalog and related
00306   // services are not loaded unless needed.
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       // Try again with catalog.
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     // indent a bit
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     // indent a bit
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     // indent a bit
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   // It is illegal to call this constructor with a null pointer; a
00379   // legal C-style string is required.
00380   ProvenanceDumper(std::string const& filename,
00381                    bool showDependencies,
00382                    bool excludeESModules,
00383                    bool showAllModules,
00384                    std::string const& findMatch);
00385 
00386   // Write the provenenace information to the given stream.
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       //loop over the history entries looking for matches
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           //see if this is unique
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 = &reg_;
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   // backward compatibility
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   //Prepare the parentage information if requested
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   //using edm::ParameterSetID as the key does not work
00691   //   typedef std::map<edm::ParameterSetID, std::vector<edm::BranchDescription> > IdToBranches
00692   ModuleToIdBranches moduleToIdBranches;
00693   //IdToBranches idToBranches;
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     //force it to rebuild the branch name
00702     it->second.init();
00703 
00704     if(showDependencies_) {
00705       branchIDToBranchName[it->second.branchID()]=it->second.branchName();
00706     }
00707     /*
00708       std::cout << it->second.branchName()
00709       << " id " << it->second.productID() << std::endl;
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       //idToBranches[*itId].push_back(it->second);
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   //we don't want users to see these in the help messages since this
00844   // name only exists since the parser needs it
00845   options_description hidden;
00846   hidden.add_options()(kFileNameOpt, value<std::string>(), "file name");
00847 
00848   //full list of options for the parser
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   //silence ROOT warnings about missing dictionaries
00904   gErrorIgnoreLevel = kError;
00905 
00906   //make sure dictionaries can be used for reading
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 }