CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_1/src/DQMServices/FwkIO/plugins/DQMRootOutputModule.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     FwkIO
00004 // Class  :     DQMRootOutputModule
00005 // 
00006 // Implementation:
00007 //     [Notes on implementation]
00008 //
00009 // Original Author:  Chris Jones
00010 //         Created:  Fri Apr 29 13:26:29 CDT 2011
00011 // $Id: DQMRootOutputModule.cc,v 1.15 2012/05/14 20:07:26 wmtan Exp $
00012 //
00013 
00014 // system include files
00015 #include <iostream>
00016 #include <string>
00017 #include <map>
00018 #include <memory>
00019 #include <boost/shared_ptr.hpp>
00020 #include "TFile.h"
00021 #include "TTree.h"
00022 #include "TString.h"
00023 #include "TH1.h"
00024 #include "TH2.h"
00025 #include "TProfile.h"
00026 
00027 // user include files
00028 #include "FWCore/Framework/interface/OutputModule.h"
00029 #include "FWCore/Framework/interface/RunPrincipal.h"
00030 #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h"
00031 #include "DQMServices/Core/interface/DQMStore.h"
00032 #include "DQMServices/Core/interface/MonitorElement.h"
00033 #include "FWCore/ServiceRegistry/interface/Service.h"
00034 #include "FWCore/Framework/interface/MakerMacros.h"
00035 #include "FWCore/MessageLogger/interface/JobReport.h"
00036 #include "FWCore/Utilities/interface/Digest.h"
00037 #include "FWCore/Utilities/interface/GlobalIdentifier.h"
00038 
00039 #include "DataFormats/Provenance/interface/ProcessHistory.h"
00040 #include "DataFormats/Provenance/interface/ProcessHistoryRegistry.h"
00041 #include "FWCore/ParameterSet/interface/Registry.h"
00042 
00043 #include "format.h"
00044 
00045 namespace {
00046   class TreeHelperBase {
00047   public:
00048     TreeHelperBase(): m_wasFilled(false), m_firstIndex(0),m_lastIndex(0) {}
00049     virtual ~TreeHelperBase(){}
00050     void fill(MonitorElement* iElement) {
00051       doFill(iElement); 
00052       if(m_wasFilled) {++m_lastIndex;} 
00053       m_wasFilled = true; }
00054     bool wasFilled() const { return m_wasFilled;}
00055     void getRangeAndReset(ULong64_t& iFirstIndex, ULong64_t& iLastIndex) {
00056       iFirstIndex = m_firstIndex;
00057       iLastIndex = m_lastIndex;
00058       m_wasFilled = false;
00059       m_firstIndex = m_lastIndex +1;
00060       m_lastIndex = m_firstIndex;
00061     }
00062   private:
00063     virtual void doFill(MonitorElement*) = 0;
00064     bool m_wasFilled;
00065     ULong64_t m_firstIndex;
00066     ULong64_t m_lastIndex;
00067   };
00068   
00069   template<class T>
00070   class TreeHelper : public TreeHelperBase {
00071   public:
00072     TreeHelper(TTree* iTree, std::string* iFullNameBufferPtr ):
00073      m_tree(iTree), m_flagBuffer(0),m_fullNameBufferPtr(iFullNameBufferPtr){ setup();}
00074      virtual void doFill(MonitorElement* iElement) {
00075        *m_fullNameBufferPtr = iElement->getFullname();
00076        m_flagBuffer = iElement->getTag();
00077        m_bufferPtr = dynamic_cast<T*>(iElement->getRootObject());
00078        assert(0!=m_bufferPtr);
00079        //std::cout <<"#entries: "<<m_bufferPtr->GetEntries()<<std::endl;
00080        m_tree->Fill();
00081      }
00082      
00083      
00084   private:
00085     void setup() {
00086       m_tree->Branch(kFullNameBranch,&m_fullNameBufferPtr);
00087       m_tree->Branch(kFlagBranch,&m_flagBuffer);
00088       
00089       m_bufferPtr = 0;
00090       m_tree->Branch(kValueBranch,&m_bufferPtr,128*1024,0);
00091     }
00092     TTree* m_tree;
00093     uint32_t m_flagBuffer;
00094     std::string* m_fullNameBufferPtr;
00095     T* m_bufferPtr;
00096   };
00097   
00098   class IntTreeHelper: public TreeHelperBase {
00099   public:
00100     IntTreeHelper(TTree* iTree, std::string* iFullNameBufferPtr):
00101      m_tree(iTree), m_flagBuffer(0),m_fullNameBufferPtr(iFullNameBufferPtr)
00102      {setup();}
00103 
00104     virtual void doFill(MonitorElement* iElement) {
00105      *m_fullNameBufferPtr = iElement->getFullname();
00106      m_flagBuffer = iElement->getTag();
00107      m_buffer = iElement->getIntValue();
00108      m_tree->Fill();
00109     }
00110 
00111   private:
00112     void setup() {
00113       m_tree->Branch(kFullNameBranch,&m_fullNameBufferPtr);
00114       m_tree->Branch(kFlagBranch,&m_flagBuffer);
00115       m_tree->Branch(kValueBranch,&m_buffer);
00116     }
00117     TTree* m_tree;
00118     uint32_t m_flagBuffer;
00119     std::string* m_fullNameBufferPtr;
00120     Long64_t m_buffer;
00121   };
00122 
00123   class FloatTreeHelper: public TreeHelperBase {
00124   public:
00125     FloatTreeHelper(TTree* iTree, std::string* iFullNameBufferPtr):
00126      m_tree(iTree), m_flagBuffer(0),m_fullNameBufferPtr(iFullNameBufferPtr)
00127      {setup();}
00128    virtual void doFill(MonitorElement* iElement) {
00129      *m_fullNameBufferPtr = iElement->getFullname();
00130      m_flagBuffer = iElement->getTag();
00131      m_buffer = iElement->getFloatValue();
00132      m_tree->Fill();
00133    }
00134   private:
00135     void setup() {
00136       m_tree->Branch(kFullNameBranch,&m_fullNameBufferPtr);
00137       m_tree->Branch(kFlagBranch,&m_flagBuffer);
00138       m_tree->Branch(kValueBranch,&m_buffer);
00139     }
00140     
00141     TTree* m_tree;
00142     uint32_t m_flagBuffer;
00143     std::string* m_fullNameBufferPtr;
00144     double m_buffer;
00145   };
00146 
00147   class StringTreeHelper: public TreeHelperBase {
00148   public:
00149     StringTreeHelper(TTree* iTree, std::string* iFullNameBufferPtr):
00150      m_tree(iTree), m_flagBuffer(0),m_fullNameBufferPtr(iFullNameBufferPtr), m_bufferPtr(&m_buffer)
00151      {setup();}
00152    virtual void doFill(MonitorElement* iElement) {
00153      *m_fullNameBufferPtr = iElement->getFullname();
00154      m_flagBuffer = iElement->getTag();
00155      m_buffer = iElement->getStringValue();
00156      m_tree->Fill();
00157    }
00158   private:
00159     void setup() {
00160       m_tree->Branch(kFullNameBranch,&m_fullNameBufferPtr);
00161       m_tree->Branch(kFlagBranch,&m_flagBuffer);
00162       m_tree->Branch(kValueBranch,&m_bufferPtr);
00163     }
00164     
00165     TTree* m_tree;
00166     uint32_t m_flagBuffer;
00167     std::string* m_fullNameBufferPtr;
00168     std::string m_buffer;
00169     std::string* m_bufferPtr;
00170   };
00171 
00172 }
00173 
00174 
00175 class DQMRootOutputModule : public edm::OutputModule {
00176 public:
00177   explicit DQMRootOutputModule(edm::ParameterSet const& pset);
00178   virtual ~DQMRootOutputModule();
00179   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
00180 
00181 private:
00182   virtual void write(edm::EventPrincipal const& e);
00183   virtual void writeLuminosityBlock(edm::LuminosityBlockPrincipal const&);
00184   virtual void writeRun(edm::RunPrincipal const&);
00185   virtual void beginRun(edm::RunPrincipal const& r);
00186   virtual bool isFileOpen() const;
00187   virtual void openFile(edm::FileBlock const&);
00188 
00189 
00190   virtual void startEndFile();
00191   virtual void finishEndFile();
00192   std::string m_fileName;
00193   std::string m_logicalFileName;
00194   std::auto_ptr<TFile> m_file;
00195   std::vector<boost::shared_ptr<TreeHelperBase> > m_treeHelpers;
00196   
00197   unsigned int m_run;
00198   unsigned int m_lumi;
00199   unsigned int m_type;
00200   unsigned int m_presentHistoryIndex;
00201   ULong64_t m_beginTime;
00202   ULong64_t m_endTime;
00203   ULong64_t m_firstIndex;
00204   ULong64_t m_lastIndex;
00205   unsigned int m_filterOnRun;
00206   
00207   std::string m_fullNameBuffer;
00208   std::string* m_fullNameBufferPtr;
00209   std::map<unsigned int, unsigned int> m_dqmKindToTypeIndex;
00210   TTree* m_indicesTree;
00211   
00212   std::vector<edm::ProcessHistoryID> m_seenHistories;
00213   edm::JobReport::Token m_jrToken;
00214 };
00215 
00216 //
00217 // constants, enums and typedefs
00218 //
00219 
00220 static TreeHelperBase*
00221 makeHelper(unsigned int iTypeIndex,
00222            TTree* iTree, 
00223            std::string* iFullNameBufferPtr) {
00224   switch(iTypeIndex) {
00225     case kIntIndex:
00226     return new IntTreeHelper(iTree,iFullNameBufferPtr);
00227     case kFloatIndex:
00228     return new FloatTreeHelper(iTree,iFullNameBufferPtr);
00229     case kStringIndex:
00230     return new StringTreeHelper(iTree,iFullNameBufferPtr);
00231     case kTH1FIndex:
00232     return new TreeHelper<TH1F>(iTree,iFullNameBufferPtr);
00233     case kTH1SIndex:
00234     return new TreeHelper<TH1S>(iTree,iFullNameBufferPtr);
00235     case kTH1DIndex:
00236     return new TreeHelper<TH1D>(iTree,iFullNameBufferPtr);
00237     case kTH2FIndex:
00238     return new TreeHelper<TH2F>(iTree,iFullNameBufferPtr);
00239     case kTH2SIndex:
00240     return new TreeHelper<TH2S>(iTree,iFullNameBufferPtr);
00241     case kTH2DIndex:
00242     return new TreeHelper<TH2D>(iTree,iFullNameBufferPtr);
00243     case kTH3FIndex:
00244     return new TreeHelper<TH3F>(iTree,iFullNameBufferPtr);
00245     case kTProfileIndex:
00246     return new TreeHelper<TProfile>(iTree,iFullNameBufferPtr);
00247     case kTProfile2DIndex:
00248     return new TreeHelper<TProfile2D>(iTree,iFullNameBufferPtr);
00249   }
00250   assert(false);
00251   return 0;
00252 }
00253 
00254 //
00255 // static data member definitions
00256 //
00257 
00258 //
00259 // constructors and destructor
00260 //
00261 DQMRootOutputModule::DQMRootOutputModule(edm::ParameterSet const& pset):
00262 edm::OutputModule(pset),
00263 m_fileName(pset.getUntrackedParameter<std::string>("fileName")),
00264 m_logicalFileName(pset.getUntrackedParameter<std::string>("logicalFileName","")),
00265 m_file(0),
00266 m_treeHelpers(kNIndicies,boost::shared_ptr<TreeHelperBase>()),
00267 m_presentHistoryIndex(0),
00268 m_filterOnRun(pset.getUntrackedParameter<unsigned int>("filterOnRun",0)),
00269 m_fullNameBufferPtr(&m_fullNameBuffer),
00270 m_indicesTree(0)
00271 {
00272 }
00273 
00274 // DQMRootOutputModule::DQMRootOutputModule(const DQMRootOutputModule& rhs)
00275 // {
00276 //    // do actual copying here;
00277 // }
00278 
00279 DQMRootOutputModule::~DQMRootOutputModule()
00280 {
00281 }
00282 
00283 //
00284 // assignment operators
00285 //
00286 // const DQMRootOutputModule& DQMRootOutputModule::operator=(const DQMRootOutputModule& rhs)
00287 // {
00288 //   //An exception safe implementation is
00289 //   DQMRootOutputModule temp(rhs);
00290 //   swap(rhs);
00291 //
00292 //   return *this;
00293 // }
00294 
00295 //
00296 // member functions
00297 //
00298 bool 
00299 DQMRootOutputModule::isFileOpen() const
00300 {
00301   return nullptr!=m_file.get();
00302 }
00303 
00304 void 
00305 DQMRootOutputModule::openFile(edm::FileBlock const&)
00306 {
00307   //NOTE: I need to also set the I/O performance settings
00308   
00309   m_file = std::auto_ptr<TFile>(new TFile(m_fileName.c_str(),"RECREATE",
00310                                 "1" //This is the file format version number
00311                                 ));  
00312   
00313   edm::Service<edm::JobReport> jr;
00314   cms::Digest branchHash;
00315   m_jrToken = jr->outputFileOpened(m_fileName,
00316                                    m_logicalFileName,
00317                                    std::string(),
00318                                    "DQMRootOutputModule",
00319                                    description().moduleLabel(),
00320                                    edm::createGlobalIdentifier(),
00321                                    std::string(),
00322                                    branchHash.digest().toString(),
00323                                    std::vector<std::string>()
00324     );
00325 
00326 
00327   m_indicesTree = new TTree(kIndicesTree,kIndicesTree);
00328   m_indicesTree->Branch(kRunBranch,&m_run);
00329   m_indicesTree->Branch(kLumiBranch,&m_lumi);
00330   m_indicesTree->Branch(kProcessHistoryIndexBranch,&m_presentHistoryIndex);
00331   m_indicesTree->Branch(kBeginTimeBranch,&m_beginTime);
00332   m_indicesTree->Branch(kEndTimeBranch,&m_endTime);
00333   m_indicesTree->Branch(kTypeBranch,&m_type);
00334   m_indicesTree->Branch(kFirstIndex,&m_firstIndex);
00335   m_indicesTree->Branch(kLastIndex,&m_lastIndex);
00336   m_indicesTree->SetDirectory(m_file.get());
00337   
00338   unsigned int i = 0;
00339   for(std::vector<boost::shared_ptr<TreeHelperBase> >::iterator it = m_treeHelpers.begin(), itEnd = m_treeHelpers.end();
00340   it != itEnd;
00341   ++it,++i) {
00342     //std::cout <<"making "<<kTypeNames[i]<<std::endl;
00343     TTree* tree = new TTree(kTypeNames[i],kTypeNames[i]);
00344     *it = boost::shared_ptr<TreeHelperBase>(makeHelper(i,tree,m_fullNameBufferPtr));
00345     tree->SetDirectory(m_file.get()); //TFile takes ownership
00346   }
00347   
00348   m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_INT]=kIntIndex;
00349   m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_REAL]=kFloatIndex;
00350   m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_STRING]=kStringIndex;
00351   m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH1F]=kTH1FIndex;
00352   m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH1S]=kTH1SIndex;
00353   m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH1D]=kTH1DIndex;
00354   m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH2F]=kTH2FIndex;
00355   m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH2S]=kTH2SIndex;
00356   m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH2D]=kTH2DIndex;
00357   m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH3F]=kTH3FIndex;
00358   m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TPROFILE]=kTProfileIndex;
00359   m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TPROFILE2D]=kTProfile2DIndex;
00360 }
00361 
00362 
00363 void 
00364 DQMRootOutputModule::write(edm::EventPrincipal const& ){
00365   
00366 }
00367 void 
00368 DQMRootOutputModule::writeLuminosityBlock(edm::LuminosityBlockPrincipal const& iLumi) {
00369   //std::cout << "DQMRootOutputModule::writeLuminosityBlock"<< std::endl;
00370   edm::Service<DQMStore> dstore;
00371   m_run=iLumi.id().run();
00372   m_lumi = iLumi.id().value();
00373   m_beginTime = iLumi.beginTime().value();
00374   m_endTime = iLumi.endTime().value();
00375   bool shouldWrite = (m_filterOnRun == 0 ||
00376                       (m_filterOnRun != 0 && m_filterOnRun == m_run));
00377 
00378   if (! shouldWrite)
00379     return;
00380   std::vector<MonitorElement *> items(dstore->getAllContents(""));
00381   for(std::vector<MonitorElement*>::iterator it = items.begin(), itEnd=items.end();
00382       it!=itEnd;
00383       ++it) {
00384     if((*it)->getLumiFlag()) {
00385       std::map<unsigned int,unsigned int>::iterator itFound = m_dqmKindToTypeIndex.find((*it)->kind());
00386       assert(itFound !=m_dqmKindToTypeIndex.end());
00387       m_treeHelpers[itFound->second]->fill(*it);
00388     }
00389   }
00390   //Now store the relationship between run/lumi and indices in the other TTrees
00391   bool storedLumiIndex = false;
00392   unsigned int typeIndex = 0;
00393   for(std::vector<boost::shared_ptr<TreeHelperBase> >::iterator it = m_treeHelpers.begin(), itEnd = m_treeHelpers.end();
00394       it != itEnd;
00395       ++it,++typeIndex) {
00396     if((*it)->wasFilled()) {
00397       m_type = typeIndex;
00398       (*it)->getRangeAndReset(m_firstIndex,m_lastIndex);
00399       storedLumiIndex = true;
00400       m_indicesTree->Fill();
00401     }
00402   }
00403   if(not storedLumiIndex) {
00404     //need to record lumis even if we stored no MonitorElements since some later DQM modules
00405     // look to see what lumis were processed
00406     m_type = kNoTypesStored;
00407     m_firstIndex=0;
00408     m_lastIndex=0;
00409     m_indicesTree->Fill();
00410   }
00411   
00412   edm::Service<edm::JobReport> jr;
00413   jr->reportLumiSection(m_run,m_lumi);
00414 }
00415 
00416 
00417 void DQMRootOutputModule::writeRun(edm::RunPrincipal const& iRun){
00418   //std::cout << "DQMRootOutputModule::writeRun"<< std::endl;
00419   edm::Service<DQMStore> dstore;
00420   m_run=iRun.id().run();
00421   m_lumi = 0;
00422   m_beginTime = iRun.beginTime().value();
00423   m_endTime = iRun.endTime().value();
00424   bool shouldWrite = (m_filterOnRun == 0 ||
00425                       (m_filterOnRun != 0 && m_filterOnRun == m_run));
00426 
00427   if (! shouldWrite)
00428     return;
00429 
00430   std::vector<MonitorElement *> items(dstore->getAllContents(""));
00431   for(std::vector<MonitorElement*>::iterator it = items.begin(), itEnd=items.end();
00432       it!=itEnd;
00433       ++it) {
00434     if(not (*it)->getLumiFlag()) {
00435       std::map<unsigned int,unsigned int>::iterator itFound = m_dqmKindToTypeIndex.find((*it)->kind());
00436       assert  (itFound !=m_dqmKindToTypeIndex.end());
00437       m_treeHelpers[itFound->second]->fill(*it);
00438     }
00439   }
00440   
00441   //Now store the relationship between run/lumi and indices in the other TTrees
00442   unsigned int typeIndex = 0;
00443   for(std::vector<boost::shared_ptr<TreeHelperBase> >::iterator it = m_treeHelpers.begin(), itEnd = m_treeHelpers.end();
00444       it != itEnd;
00445       ++it,++typeIndex) {
00446     if((*it)->wasFilled()) {
00447       m_type = typeIndex;
00448       (*it)->getRangeAndReset(m_firstIndex,m_lastIndex);
00449       m_indicesTree->Fill();
00450     }
00451   }
00452   
00453   edm::Service<edm::JobReport> jr;
00454   jr->reportRunNumber(m_run);  
00455 }
00456 
00457 void DQMRootOutputModule::beginRun(edm::RunPrincipal const& iPrincipal) {
00458   //std::cout << "DQMRootOutputModule::beginRun"<< std::endl;
00459   //The ProcessHistory for a lumi must be the same as its Run so we only need to 
00460   // record it at Run time
00461   edm::ProcessHistoryID id = iPrincipal.processHistoryID();
00462   std::vector<edm::ProcessHistoryID>::iterator itFind = std::find(m_seenHistories.begin(),m_seenHistories.end(),id);
00463   if(itFind == m_seenHistories.end()) {
00464     m_presentHistoryIndex = m_seenHistories.size();
00465     m_seenHistories.push_back(id);
00466   } else {
00467     m_presentHistoryIndex = itFind - m_seenHistories.begin();
00468   }
00469 }
00470 
00471 void DQMRootOutputModule::startEndFile() {
00472   //std::cout << "DQMRootOutputModule::startEndFile"<< std::endl;
00473   //fill in the meta data
00474   m_file->cd();
00475   TDirectory* metaDataDirectory = m_file->mkdir(kMetaDataDirectory);
00476 
00477 
00478   //Write out the Process History
00479   TTree* processHistoryTree = new TTree(kProcessHistoryTree,kProcessHistoryTree);
00480   processHistoryTree->SetDirectory(metaDataDirectory);
00481   
00482   unsigned int index = 0;
00483   processHistoryTree->Branch(kPHIndexBranch,&index);
00484   std::string processName;
00485   processHistoryTree->Branch(kProcessConfigurationProcessNameBranch,&processName);
00486   std::string parameterSetID;
00487   processHistoryTree->Branch(kProcessConfigurationParameterSetIDBranch,&parameterSetID);
00488   std::string releaseVersion;
00489   processHistoryTree->Branch(kProcessConfigurationReleaseVersion,&releaseVersion);
00490   std::string passID;
00491   processHistoryTree->Branch(kProcessConfigurationPassID,&passID);
00492 
00493   edm::ProcessHistoryRegistry* phr = edm::ProcessHistoryRegistry::instance();
00494   assert(0!=phr);
00495   for(std::vector<edm::ProcessHistoryID>::iterator it = m_seenHistories.begin(), itEnd = m_seenHistories.end();
00496       it !=itEnd;
00497       ++it) {
00498     const edm::ProcessHistory* history = phr->getMapped(*it);
00499     assert(0!=history);
00500     index = 0;
00501     for(edm::ProcessHistory::collection_type::const_iterator itPC = history->begin(), itPCEnd = history->end();
00502         itPC != itPCEnd;
00503         ++itPC,++index) {
00504       processName = itPC->processName();
00505       releaseVersion = itPC->releaseVersion();
00506       passID = itPC->passID();
00507       parameterSetID = itPC->parameterSetID().compactForm();
00508       processHistoryTree->Fill();
00509     }
00510   }
00511   
00512   //Store the ParameterSets
00513   TTree* parameterSetsTree = new TTree(kParameterSetTree,kParameterSetTree);
00514   parameterSetsTree->SetDirectory(metaDataDirectory);
00515   std::string blob;
00516   parameterSetsTree->Branch(kParameterSetBranch,&blob);
00517   
00518   edm::pset::Registry* psr = edm::pset::Registry::instance();
00519   assert(0!=psr);
00520   for(edm::pset::Registry::const_iterator it = psr->begin(), itEnd = psr->end();
00521   it != itEnd;
00522   ++it) {
00523     blob.clear();
00524     it->second.toString(blob);
00525     parameterSetsTree->Fill();
00526   }
00527   
00528 }
00529 
00530 void DQMRootOutputModule::finishEndFile() {
00531   //std::cout << "DQMRootOutputModule::finishEndFile"<< std::endl;
00532   m_file->Write();
00533   m_file->Close();
00534   edm::Service<edm::JobReport> jr;
00535   jr->outputFileClosed(m_jrToken);
00536 }
00537 
00538 //
00539 // const member functions
00540 //
00541 
00542 //
00543 // static member functions
00544 //
00545 void
00546 DQMRootOutputModule::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
00547   //The following says we do not know what parameters are allowed so do no validation
00548   // Please change this to state exactly what you do use, even if it is no parameters
00549   edm::ParameterSetDescription desc;
00550   desc.setUnknown();
00551   descriptions.addDefault(desc);
00552 
00553   //NOTE: when actually filling this in, do not forget to add a untracked PSet 'dataset'
00554   // which is used for bookkeeping by the DMWM
00555 }
00556 
00557 
00558 DEFINE_FWK_MODULE(DQMRootOutputModule);