CMS 3D CMS Logo

EdmProvDump.cc

Go to the documentation of this file.
00001 #include "TFile.h"
00002 #include "TTree.h"
00003 #include "Cintex/Cintex.h"
00004 
00005 #include "DataFormats/Provenance/interface/BranchType.h"
00006 #include "DataFormats/Provenance/interface/EventSelectionID.h"
00007 #include "DataFormats/Provenance/interface/History.h"
00008 #include "DataFormats/Provenance/interface/ParameterSetBlob.h"
00009 #include "DataFormats/Provenance/interface/ParameterSetID.h"
00010 #include "DataFormats/Provenance/interface/ProcessHistoryRegistry.h"
00011 #include "DataFormats/Provenance/interface/ProductRegistry.h"
00012 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00013 #include "FWCore/Utilities/interface/Exception.h"
00014 
00015 #include <assert.h>
00016 #include <iostream>
00017 #include <memory>
00018 #include <sstream>
00019 
00020 #include "boost/utility.hpp"
00021 #include "boost/scoped_ptr.hpp"
00022 
00023 namespace {
00024 typedef std::map<edm::ParameterSetID, edm::ParameterSetBlob> ParameterSetMap;
00025 
00026   class HistoryNode {
00027   public:
00028     HistoryNode() :
00029       config_(),
00030       simpleId_(0)
00031     { }
00032 
00033     HistoryNode(const edm::ProcessConfiguration& iConfig, unsigned int iSimpleId) :
00034       config_(iConfig), 
00035       simpleId_(iSimpleId) 
00036     { }
00037 
00038     void addChild(HistoryNode const& child) {
00039       children_.push_back(child);
00040     }
00041 
00042     edm::ParameterSetID const& 
00043     parameterSetID() const {
00044       return config_.parameterSetID();
00045     }
00046 
00047     std::string const&
00048     processName() const {
00049       return config_.processName();
00050     }
00051 
00052     std::size_t
00053     size() const {
00054       return children_.size();
00055     }
00056 
00057     HistoryNode *
00058     lastChildAddress() {
00059       return &children_.back();
00060     }
00061 
00062     typedef std::vector<HistoryNode>::const_iterator const_iterator;
00063     typedef std::vector<HistoryNode>::iterator iterator;
00064     
00065     iterator begin() { return children_.begin();}
00066     iterator end() { return children_.end();}
00067 
00068     const_iterator begin() const { return children_.begin();}
00069     const_iterator end() const { return children_.end();}
00070 
00071     void print(std::ostream& os) const {
00072       os << config_.processName() 
00073          << " '" << config_.passID() << "' '"
00074          << config_.releaseVersion() << "' ["
00075          << simpleId_<<"]  (" 
00076          << config_.parameterSetID() << ")"
00077          << std::endl;
00078     }
00079 
00080     void printHistory(const std::string& iIndent = std::string("  ")) const;
00081     void printEventSetupHistory(const ParameterSetMap& iPSM, std::ostream& oErrorLog) const;
00082 
00083     edm::ProcessConfigurationID
00084     configurationID() const {
00085       return config_.id();
00086     }
00087 
00088     static bool sort_;
00089   private:
00090     edm::ProcessConfiguration config_;
00091     std::vector<HistoryNode>  children_;
00092     unsigned int              simpleId_;    
00093   };
00094 
00095   std::ostream& operator<<(std::ostream& os, const HistoryNode& node) {
00096     node.print(os);
00097     return os;
00098   }
00099   bool HistoryNode::sort_ = false;
00100 }
00101 
00102 
00103 std::ostream&
00104 operator<< (std::ostream& os, edm::ProcessHistory& iHist)
00105 {
00106   const std::string indentDelta("  ");
00107   std::string indent = indentDelta;
00108   for (edm::ProcessHistory::const_iterator i = iHist.begin(), e = iHist.end();
00109        i != e;
00110        ++i) {
00111     os << indent 
00112        <<i->processName() <<" '"
00113        <<i->passID()      <<"' '"
00114        <<i->releaseVersion() << "' ("
00115        <<i->parameterSetID()<<")"
00116        << std::endl;
00117     indent += indentDelta;
00118   }
00119   return os;
00120 }
00121 
00122 void HistoryNode::printHistory(const std::string& iIndent) const
00123 {
00124   const std::string indentDelta("  ");
00125   std::string indent = iIndent;
00126   for (const_iterator i = begin(), e = end();
00127        i != e;
00128        ++i) {
00129     std::cout << indent << *i;
00130     i->printHistory(indent+indentDelta);
00131   }
00132 }
00133 
00134 std::string eventSetupComponent(const char* iType, const std::string& iCompName, const edm::ParameterSet& iProcessConfig, const std::string& iProcessName) {
00135   std::ostringstream result;
00136   const edm::ParameterSet& pset = iProcessConfig.getParameter<edm::ParameterSet>(iCompName);
00137   std::string name( pset.getParameter<std::string>("@module_label") );
00138   if(0 == name.size() ) {
00139     name = pset.getParameter<std::string>("@module_type");
00140   }
00141   
00142   result <<iType<<": "<< name<<" "<<iProcessName << "\n"
00143          <<" parameters: "<<pset;
00144   return result.str();
00145 }
00146 
00147 void HistoryNode::printEventSetupHistory(const ParameterSetMap& iPSM, ostream& oErrorLog) const
00148 {
00149   for (const_iterator itH = begin(), e = end();
00150        itH != e;
00151        ++itH) {
00152     //Get ParameterSet for process
00153     ParameterSetMap::const_iterator itFind = iPSM.find(itH->parameterSetID());
00154     if(itFind == iPSM.end()){
00155       oErrorLog << "No ParameterSetID for " << itH->parameterSetID() << std::endl;
00156     } else {
00157       edm::ParameterSet processConfig(itFind->second.pset_);
00158       std::vector<std::string> sourceStrings, moduleStrings;
00159       //get the sources
00160       std::vector<std::string> sources = processConfig.getParameter<std::vector<std::string> >("@all_essources");
00161       for(std::vector<std::string>::iterator itM = sources.begin(); itM != sources.end(); ++itM) {
00162         sourceStrings.push_back(eventSetupComponent("ESSource",
00163                                  *itM,
00164                                  processConfig,
00165                                  itH->processName()) );
00166       }
00167       //get the modules
00168       std::vector<std::string> modules = processConfig.getParameter<std::vector<std::string> >("@all_esmodules");
00169       for(std::vector<std::string>::iterator itM = modules.begin(); itM != modules.end(); ++itM) {
00170         moduleStrings.push_back(eventSetupComponent("ESModule",
00171                                  *itM,
00172                                  processConfig,
00173                                  itH->processName()));
00174       }
00175       if(sort_) 
00176       {
00177         std::sort(sourceStrings.begin(), sourceStrings.end());
00178         std::sort(moduleStrings.begin(), moduleStrings.end());
00179       }
00180       std::copy(sourceStrings.begin(), sourceStrings.end(), 
00181                 std::ostream_iterator<std::string>(std::cout,"\n"));
00182       std::copy(moduleStrings.begin(), moduleStrings.end(), 
00183                 std::ostream_iterator<std::string>(std::cout,"\n"));
00184 
00185     }
00186     itH->printEventSetupHistory(iPSM, oErrorLog);
00187   }
00188 }
00189 
00190 namespace {
00191 
00192   // Open the input file, returning the TFile object that represents
00193   // it. The returned auto_ptr will not be null. The argument must not
00194   // be null.
00195   std::auto_ptr<TFile> 
00196   makeTFile(const char* filename) 
00197   {
00198     std::auto_ptr<TFile> result(TFile::Open(filename));
00199     if (!result.get()) {
00200       throw cms::Exception("FileNotFound","RootFile::RootFile()")
00201         << "File " << filename << " was not found or could not be opened.\n";
00202     }
00203     return result;
00204   }
00205 
00206 }
00207 
00208 
00209 
00210 class ProvenanceDumper : boost::noncopyable
00211 {
00212 public:
00213   // It is illegal to call this constructor with a null pointer; a
00214   // legal C-style string is required.
00215   explicit ProvenanceDumper(const char* filename);
00216 
00217   // Write the provenenace information to the given stream.
00218   void dump(std::ostream& os);
00219   void printErrors(std::ostream& os);
00220   int exitCode() const;
00221 
00222 private:
00223   std::string              filename_;
00224   boost::scoped_ptr<TFile> inputFile_;
00225   int                      exitCode_;
00226   std::stringstream        errorLog_;
00227   int                      errorCount_;
00228   edm::ProductRegistry     reg_;
00229   edm::ProcessHistoryMap   phm_;
00230   ParameterSetMap          psm_;
00231   HistoryNode              historyGraph_;
00232 
00233   void work_();
00234   void dumpProcessHistory_(TTree& history);
00235   void dumpEventFilteringParameterSets_(TTree& history);
00236   void dumpParameterSetForID_(edm::ParameterSetID const& id);
00237 };
00238 
00239 ProvenanceDumper::ProvenanceDumper(const char* filename) :
00240   filename_( filename),
00241   inputFile_(makeTFile(filename)),
00242   exitCode_(0),
00243   errorLog_(),
00244   errorCount_(0)
00245 { 
00246 }
00247 
00248 void
00249 ProvenanceDumper::dump(std::ostream& os)
00250 {
00251   work_();
00252 }
00253 
00254 void
00255 ProvenanceDumper::printErrors(std::ostream& os)
00256 {
00257   if (errorCount_ > 0) os << errorLog_.str() << std::endl;
00258 }
00259 
00260 int
00261 ProvenanceDumper::exitCode() const
00262 {
00263   return exitCode_;
00264 }
00265 
00266 void
00267 ProvenanceDumper::dumpEventFilteringParameterSets_(TTree& history)
00268 {
00269   // This is how one reads a TTree ...
00270   edm::History h; 
00271   edm::History* ph = &h;
00272 
00273   history.SetBranchAddress(edm::poolNames::eventHistoryBranchName().c_str(), &ph);
00274   if (history.GetEntry(0) <= 0)
00275     {
00276       std::cout << "No event filtering information is available; the event history tree has no entries\n";
00277     }
00278   else
00279     {
00280       edm::EventSelectionIDVector const& ids = h.eventSelectionIDs();
00281       edm::EventSelectionIDVector::size_type num_ids = ids.size();
00282       if ( num_ids == 0)
00283         {
00284           std::cout << "No event filtering information is available.\n";
00285           std::cout << "------------------------------\n";
00286         }
00287       else
00288         {
00289           std::cout << "Event filtering information for "
00290                     << num_ids
00291                     << " processing steps is available.\n"
00292                     << "The ParameterSets will be printed out, "
00293                     << "with the oldest printed first.\n";
00294           for (edm::EventSelectionIDVector::size_type i = 0; i != num_ids; ++i)
00295             dumpParameterSetForID_(ids[i]);
00296         }
00297     }
00298 }
00299 
00300 void
00301 ProvenanceDumper::dumpParameterSetForID_(edm::ParameterSetID const& id)
00302 {
00303   std::cout << "ParameterSetID: " << id << '\n';
00304   if (id.isValid())
00305     {
00306       ParameterSetMap::const_iterator i = psm_.find(id);
00307       if (i == psm_.end())
00308         {
00309           std::cout << "We are unable to find the corresponding ParameterSet\n";
00310           edm::ParameterSet empty;
00311           if (id == empty.id())
00312             {
00313               std::cout << "But it would have been empty anyway\n";
00314             }
00315         }
00316       else
00317         {
00318           edm::ParameterSet ps(i->second.pset_);
00319           std::cout << ps << '\n';
00320         }      
00321     }
00322   else
00323     {
00324       std::cout << "This ID is not valid\n";
00325     }
00326   std::cout << "     -------------------------\n";
00327 }
00328 
00329 void
00330 ProvenanceDumper::dumpProcessHistory_(TTree& history)
00331 {
00332   dumpEventFilteringParameterSets_(history);
00333   std::cout << "Processing History:"<<std::endl;
00334   if (1 == phm_.size()) {
00335     std::cout << phm_.begin()->second;
00336     historyGraph_.addChild(HistoryNode(*(phm_.begin()->second.begin()), 1));
00337   } else {
00338     bool multipleHistories =false;
00339     std::map<edm::ProcessConfigurationID, unsigned int> simpleIDs;
00340     for (edm::ProcessHistoryMap::const_iterator it = phm_.begin(), itEnd = phm_.end();
00341          it != itEnd;
00342          ++it) {
00343       //loop over the history entries looking for matches
00344       HistoryNode* parent = &historyGraph_;
00345       for (edm::ProcessHistory::const_iterator itH = it->second.begin(), e = it->second.end();
00346            itH != e;
00347            ++itH) {
00348         if (parent->size() == 0) {
00349           unsigned int id = simpleIDs[itH->id()];
00350           if (0 == id) {
00351             id = 1;
00352             simpleIDs[itH->id()] = id;
00353           }
00354           parent->addChild(HistoryNode(*itH,id));
00355           parent = parent->lastChildAddress();
00356         } else {
00357           //see if this is unique
00358           bool unique = true;
00359           for (HistoryNode::iterator itChild = parent->begin(), itChildEnd = parent->end();
00360                itChild != itChildEnd;
00361                ++itChild) {
00362             if (itChild->configurationID() == itH->id()) {
00363               unique = false;
00364               parent = &(*itChild);
00365               break;
00366             }
00367           }
00368           if (unique) {
00369             multipleHistories = true;
00370             simpleIDs[itH->id()]=parent->size()+1;
00371             parent->addChild(HistoryNode(*itH,simpleIDs[itH->id()]));
00372             parent = parent->lastChildAddress();
00373           }
00374         }
00375       }
00376     }
00377     historyGraph_.printHistory();
00378   }
00379 }
00380 
00381 void
00382 ProvenanceDumper::work_() {
00383 
00384   std::auto_ptr<TFile> f = makeTFile(filename_.c_str());
00385 
00386   TTree* history = dynamic_cast<TTree*>(f->Get(edm::poolNames::eventHistoryTreeName().c_str()));
00387   assert(0!=history);
00388 
00389   TTree* meta = dynamic_cast<TTree*>(f->Get(edm::poolNames::metaDataTreeName().c_str()));
00390   assert(0!=meta);
00391 
00392   edm::ProductRegistry* pReg=&reg_;
00393   meta->SetBranchAddress(edm::poolNames::productDescriptionBranchName().c_str(),&pReg);
00394 
00395   ParameterSetMap* pPsm =&psm_;
00396   meta->SetBranchAddress(edm::poolNames::parameterSetMapBranchName().c_str(),&pPsm);
00397 
00398   edm::ProcessHistoryMap* pPhm=&phm_;
00399   meta->SetBranchAddress(edm::poolNames::processHistoryMapBranchName().c_str(),&pPhm);
00400 
00401   meta->GetEntry(0);
00402   assert(0!=pReg);
00403   pReg->setFrozen();
00404 
00405   dumpProcessHistory_(*history);
00406   
00407   std::cout <<"---------Event---------"<<std::endl;
00408   /*
00409     for (std::vector<edm::ProcessHistory>::const_iterator it = uniqueLongHistories.begin(),
00410     itEnd = uniqueLongHistories.end();
00411     it != itEnd;
00412     ++it) {
00413     //ParameterSetMap::const_iterator itpsm = psm.find(psid);
00414     for (edm::ProcessHistory::const_iterator itH = it->begin(), e = it->end();
00415     itH != e;
00416     ++itH) {
00417     std::cout << edm::ParameterSet(psm[ itH->parameterSetID() ].pset_) <<std::endl;
00418     }
00419     }
00420   */
00421   //using edm::ParameterSetID as the key does not work
00422   //   typedef std::map<edm::ParameterSetID,std::vector<edm::BranchDescription> > IdToBranches
00423   typedef std::map<std::string,std::vector<edm::BranchDescription> > IdToBranches;
00424   typedef std::map<std::pair<std::string,std::string>,IdToBranches> ModuleToIdBranches;
00425   ModuleToIdBranches moduleToIdBranches;
00426   //IdToBranches idToBranches;
00427   for (edm::ProductRegistry::ProductList::const_iterator it = 
00428          reg_.productList().begin(), itEnd = reg_.productList().end();
00429        it != itEnd;
00430        ++it) {
00431     //force it to rebuild the branch name
00432     it->second.init();
00433 
00434     /*
00435       std::cout << it->second.branchName()
00436       << " id " << it->second.productID() << std::endl;
00437     */
00438     for (std::set<edm::ParameterSetID>::const_iterator itId = it->second.psetIDs().begin(),
00439            itIdEnd = it->second.psetIDs().end();
00440          itId != itIdEnd;
00441          ++itId) {
00442          
00443       std::stringstream s;
00444       s <<*itId;
00445       moduleToIdBranches[std::make_pair(it->second.processName(),it->second.moduleLabel())][s.str()].push_back(it->second);
00446       //idToBranches[*itId].push_back(it->second);
00447     }
00448   }
00449   for (ModuleToIdBranches::const_iterator it = moduleToIdBranches.begin(),
00450          itEnd = moduleToIdBranches.end();
00451        it != itEnd;
00452        ++it) {
00453     std::cout <<"Module: "<<it->first.second<<" "<<it->first.first<<std::endl;
00454     const IdToBranches& idToBranches = it->second;
00455     for (IdToBranches::const_iterator itIdBranch = idToBranches.begin(),
00456            itIdBranchEnd = idToBranches.end();
00457          itIdBranch != itIdBranchEnd;
00458          ++itIdBranch) {
00459       std::cout <<" PSet id:"<<itIdBranch->first<<std::endl;
00460       std::cout <<" products: {"<<std::endl;
00461       for (std::vector<edm::BranchDescription>::const_iterator itBranch = itIdBranch->second.begin(),
00462              itBranchEnd = itIdBranch->second.end();
00463            itBranch != itBranchEnd;
00464            ++itBranch) {
00465         std::cout << "  "<< itBranch->branchName()<<std::endl;
00466       }
00467       std::cout <<"}"<<std::endl;
00468       edm::ParameterSetID psid(itIdBranch->first);
00469       ParameterSetMap::const_iterator itpsm = psm_.find(psid);
00470       if (psm_.end() == itpsm) {
00471         ++errorCount_;
00472         errorLog_ << "No ParameterSetID for " << psid << std::endl;
00473         exitCode_ = 1;
00474       } else {
00475         std::cout <<" parameters: "<<
00476           edm::ParameterSet((*itpsm).second.pset_)<<std::endl;
00477       }
00478       std::cout << std::endl;
00479     }
00480   }
00481   std::cout <<"---------EventSetup---------"<<std::endl;
00482   historyGraph_.printEventSetupHistory(psm_, errorLog_);
00483   if (errorCount_ != 0) {
00484     exitCode_ = 1;
00485   }
00486 }
00487 
00488 
00489 int main(int argc, char* argv[])
00490 {
00491   // will need boost::program_options someday
00492   std::string fileName;
00493   if(argc == 3 && std::string(argv[1]) == "--sort")
00494   {
00495     HistoryNode::sort_ = true;
00496     fileName = argv[2];
00497   }
00498   else if (argc == 2)
00499   {
00500      fileName = argv[1];
00501   }
00502   else
00503   {
00504     std::cerr << "Usage: " << argv[0] << " [--sort] <filename> \n";
00505     return 2;
00506   }
00507 
00508   ROOT::Cintex::Cintex::Enable();
00509   ProvenanceDumper dumper(fileName.c_str());
00510   int exitCode(0);
00511   try 
00512     {
00513       dumper.dump(std::cout);
00514     }
00515   
00516   catch (cms::Exception const& x) 
00517     {
00518       std::cerr << "cms::Exception caught\n";
00519       std::cerr << x.what() << '\n';
00520       exitCode = 2;
00521     }
00522   catch (std::exception& x) 
00523     {
00524       std::cerr << "std::exception caught\n";
00525       std::cerr << x.what() << '\n';
00526       exitCode = 3;
00527     }
00528   catch (...) 
00529     {
00530       std::cerr << "Unknown exception caught\n";
00531       exitCode = 4;
00532     }
00533   
00534   dumper.printErrors(std::cerr);
00535   return dumper.exitCode();
00536 }

Generated on Tue Jun 9 17:39:10 2009 for CMSSW by  doxygen 1.5.4