00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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
00038 #include "DataFormats/Provenance/interface/ProcessHistory.h"
00039 #include "DataFormats/Provenance/interface/ProcessHistoryRegistry.h"
00040 #include "FWCore/ParameterSet/interface/Registry.h"
00041
00042 #include "format.h"
00043
00044 namespace {
00045 class TreeHelperBase {
00046 public:
00047 TreeHelperBase(): m_wasFilled(false), m_firstIndex(0),m_lastIndex(0) {}
00048 virtual ~TreeHelperBase(){}
00049 void fill(MonitorElement* iElement) {
00050 doFill(iElement);
00051 if(m_wasFilled) {++m_lastIndex;}
00052 m_wasFilled = true; }
00053 bool wasFilled() const { return m_wasFilled;}
00054 void getRangeAndReset(ULong64_t& iFirstIndex, ULong64_t& iLastIndex) {
00055 iFirstIndex = m_firstIndex;
00056 iLastIndex = m_lastIndex;
00057 m_wasFilled = false;
00058 m_firstIndex = m_lastIndex +1;
00059 m_lastIndex = m_firstIndex;
00060 }
00061 private:
00062 virtual void doFill(MonitorElement*) = 0;
00063 bool m_wasFilled;
00064 ULong64_t m_firstIndex;
00065 ULong64_t m_lastIndex;
00066 };
00067
00068 template<class T>
00069 class TreeHelper : public TreeHelperBase {
00070 public:
00071 TreeHelper(TTree* iTree, std::string* iFullNameBufferPtr ):
00072 m_tree(iTree), m_flagBuffer(0),m_fullNameBufferPtr(iFullNameBufferPtr){ setup();}
00073 virtual void doFill(MonitorElement* iElement) {
00074 *m_fullNameBufferPtr = iElement->getFullname();
00075 m_flagBuffer = iElement->getTag();
00076 m_bufferPtr = dynamic_cast<T*>(iElement->getRootObject());
00077 assert(0!=m_bufferPtr);
00078
00079 m_tree->Fill();
00080 }
00081
00082
00083 private:
00084 void setup() {
00085 m_tree->Branch(kFullNameBranch,&m_fullNameBufferPtr);
00086 m_tree->Branch(kFlagBranch,&m_flagBuffer);
00087
00088 m_bufferPtr = 0;
00089 m_tree->Branch(kValueBranch,&m_bufferPtr,128*1024,0);
00090 }
00091 TTree* m_tree;
00092 uint32_t m_flagBuffer;
00093 std::string* m_fullNameBufferPtr;
00094 T* m_bufferPtr;
00095 };
00096
00097 class IntTreeHelper: public TreeHelperBase {
00098 public:
00099 IntTreeHelper(TTree* iTree, std::string* iFullNameBufferPtr):
00100 m_tree(iTree), m_flagBuffer(0),m_fullNameBufferPtr(iFullNameBufferPtr)
00101 {setup();}
00102
00103 virtual void doFill(MonitorElement* iElement) {
00104 *m_fullNameBufferPtr = iElement->getFullname();
00105 m_flagBuffer = iElement->getTag();
00106 m_buffer = iElement->getIntValue();
00107 m_tree->Fill();
00108 }
00109
00110 private:
00111 void setup() {
00112 m_tree->Branch(kFullNameBranch,&m_fullNameBufferPtr);
00113 m_tree->Branch(kFlagBranch,&m_flagBuffer);
00114 m_tree->Branch(kValueBranch,&m_buffer);
00115 }
00116 TTree* m_tree;
00117 uint32_t m_flagBuffer;
00118 std::string* m_fullNameBufferPtr;
00119 Long64_t m_buffer;
00120 };
00121
00122 class FloatTreeHelper: public TreeHelperBase {
00123 public:
00124 FloatTreeHelper(TTree* iTree, std::string* iFullNameBufferPtr):
00125 m_tree(iTree), m_flagBuffer(0),m_fullNameBufferPtr(iFullNameBufferPtr)
00126 {setup();}
00127 virtual void doFill(MonitorElement* iElement) {
00128 *m_fullNameBufferPtr = iElement->getFullname();
00129 m_flagBuffer = iElement->getTag();
00130 m_buffer = iElement->getFloatValue();
00131 m_tree->Fill();
00132 }
00133 private:
00134 void setup() {
00135 m_tree->Branch(kFullNameBranch,&m_fullNameBufferPtr);
00136 m_tree->Branch(kFlagBranch,&m_flagBuffer);
00137 m_tree->Branch(kValueBranch,&m_buffer);
00138 }
00139
00140 TTree* m_tree;
00141 uint32_t m_flagBuffer;
00142 std::string* m_fullNameBufferPtr;
00143 double m_buffer;
00144 };
00145
00146 class StringTreeHelper: public TreeHelperBase {
00147 public:
00148 StringTreeHelper(TTree* iTree, std::string* iFullNameBufferPtr):
00149 m_tree(iTree), m_flagBuffer(0),m_fullNameBufferPtr(iFullNameBufferPtr), m_bufferPtr(&m_buffer)
00150 {setup();}
00151 virtual void doFill(MonitorElement* iElement) {
00152 *m_fullNameBufferPtr = iElement->getFullname();
00153 m_flagBuffer = iElement->getTag();
00154 m_buffer = iElement->getStringValue();
00155 m_tree->Fill();
00156 }
00157 private:
00158 void setup() {
00159 m_tree->Branch(kFullNameBranch,&m_fullNameBufferPtr);
00160 m_tree->Branch(kFlagBranch,&m_flagBuffer);
00161 m_tree->Branch(kValueBranch,&m_bufferPtr);
00162 }
00163
00164 TTree* m_tree;
00165 uint32_t m_flagBuffer;
00166 std::string* m_fullNameBufferPtr;
00167 std::string m_buffer;
00168 std::string* m_bufferPtr;
00169 };
00170
00171 }
00172
00173
00174 class DQMRootOutputModule : public edm::OutputModule {
00175 public:
00176 explicit DQMRootOutputModule(edm::ParameterSet const& pset);
00177 virtual ~DQMRootOutputModule();
00178 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
00179
00180 private:
00181 virtual void write(edm::EventPrincipal const& e);
00182 virtual void writeLuminosityBlock(edm::LuminosityBlockPrincipal const&);
00183 virtual void writeRun(edm::RunPrincipal const&);
00184 virtual void beginRun(edm::RunPrincipal const& r);
00185 virtual void startEndFile();
00186 virtual void finishEndFile();
00187 std::string m_fileName;
00188 std::string m_logicalFileName;
00189 std::auto_ptr<TFile> m_file;
00190 std::vector<boost::shared_ptr<TreeHelperBase> > m_treeHelpers;
00191
00192 unsigned int m_run;
00193 unsigned int m_lumi;
00194 unsigned int m_type;
00195 unsigned int m_presentHistoryIndex;
00196 ULong64_t m_beginTime;
00197 ULong64_t m_endTime;
00198 ULong64_t m_firstIndex;
00199 ULong64_t m_lastIndex;
00200
00201 std::string m_fullNameBuffer;
00202 std::string* m_fullNameBufferPtr;
00203 std::map<unsigned int, unsigned int> m_dqmKindToTypeIndex;
00204 TTree* m_indicesTree;
00205
00206 std::vector<edm::ProcessHistoryID> m_seenHistories;
00207 edm::JobReport::Token m_jrToken;
00208 };
00209
00210
00211
00212
00213
00214 static TreeHelperBase*
00215 makeHelper(unsigned int iTypeIndex,
00216 TTree* iTree,
00217 std::string* iFullNameBufferPtr) {
00218 switch(iTypeIndex) {
00219 case kIntIndex:
00220 return new IntTreeHelper(iTree,iFullNameBufferPtr);
00221 case kFloatIndex:
00222 return new FloatTreeHelper(iTree,iFullNameBufferPtr);
00223 case kStringIndex:
00224 return new StringTreeHelper(iTree,iFullNameBufferPtr);
00225 case kTH1FIndex:
00226 return new TreeHelper<TH1F>(iTree,iFullNameBufferPtr);
00227 case kTH1SIndex:
00228 return new TreeHelper<TH1S>(iTree,iFullNameBufferPtr);
00229 case kTH1DIndex:
00230 return new TreeHelper<TH1D>(iTree,iFullNameBufferPtr);
00231 case kTH2FIndex:
00232 return new TreeHelper<TH2F>(iTree,iFullNameBufferPtr);
00233 case kTH2SIndex:
00234 return new TreeHelper<TH2S>(iTree,iFullNameBufferPtr);
00235 case kTH2DIndex:
00236 return new TreeHelper<TH2D>(iTree,iFullNameBufferPtr);
00237 case kTH3FIndex:
00238 return new TreeHelper<TH3F>(iTree,iFullNameBufferPtr);
00239 case kTProfileIndex:
00240 return new TreeHelper<TProfile>(iTree,iFullNameBufferPtr);
00241 case kTProfile2DIndex:
00242 return new TreeHelper<TProfile2D>(iTree,iFullNameBufferPtr);
00243 }
00244 assert(false);
00245 return 0;
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255 DQMRootOutputModule::DQMRootOutputModule(edm::ParameterSet const& pset):
00256 edm::OutputModule(pset),
00257 m_fileName(pset.getUntrackedParameter<std::string>("fileName")),
00258 m_logicalFileName(pset.getUntrackedParameter<std::string>("logicalFileName","")),
00259 m_file(0),
00260 m_treeHelpers(kNIndicies,boost::shared_ptr<TreeHelperBase>()),
00261 m_presentHistoryIndex(0),
00262 m_fullNameBufferPtr(&m_fullNameBuffer),
00263 m_indicesTree(0)
00264 {
00265
00266
00267 m_file = std::auto_ptr<TFile>(new TFile(m_fileName.c_str(),"CREATE",
00268 "1"
00269 ));
00270
00271 edm::Service<edm::JobReport> jr;
00272 cms::Digest branchHash;
00273 m_jrToken = jr->outputFileOpened(m_fileName,
00274 m_logicalFileName,
00275 std::string(),
00276 "DQMRootOutputModule",
00277 pset.getParameter<std::string>("@module_label"),
00278 m_file->GetUUID().AsString(),
00279 std::string(),
00280 branchHash.digest().toString(),
00281 std::vector<std::string>()
00282 );
00283
00284
00285 m_indicesTree = new TTree(kIndicesTree,kIndicesTree);
00286 m_indicesTree->Branch(kRunBranch,&m_run);
00287 m_indicesTree->Branch(kLumiBranch,&m_lumi);
00288 m_indicesTree->Branch(kProcessHistoryIndexBranch,&m_presentHistoryIndex);
00289 m_indicesTree->Branch(kBeginTimeBranch,&m_beginTime);
00290 m_indicesTree->Branch(kEndTimeBranch,&m_endTime);
00291 m_indicesTree->Branch(kTypeBranch,&m_type);
00292 m_indicesTree->Branch(kFirstIndex,&m_firstIndex);
00293 m_indicesTree->Branch(kLastIndex,&m_lastIndex);
00294 m_indicesTree->SetDirectory(m_file.get());
00295
00296 unsigned int i = 0;
00297 for(std::vector<boost::shared_ptr<TreeHelperBase> >::iterator it = m_treeHelpers.begin(), itEnd = m_treeHelpers.end();
00298 it != itEnd;
00299 ++it,++i) {
00300
00301 TTree* tree = new TTree(kTypeNames[i],kTypeNames[i]);
00302 *it = boost::shared_ptr<TreeHelperBase>(makeHelper(i,tree,m_fullNameBufferPtr));
00303 tree->SetDirectory(m_file.get());
00304 }
00305
00306 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_INT]=kIntIndex;
00307 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_REAL]=kFloatIndex;
00308 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_STRING]=kStringIndex;
00309 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH1F]=kTH1FIndex;
00310 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH1S]=kTH1SIndex;
00311 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH1D]=kTH1DIndex;
00312 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH2F]=kTH2FIndex;
00313 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH2S]=kTH2SIndex;
00314 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH2D]=kTH2DIndex;
00315 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH3F]=kTH3FIndex;
00316 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TPROFILE]=kTProfileIndex;
00317 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TPROFILE2D]=kTProfile2DIndex;
00318 }
00319
00320
00321
00322
00323
00324
00325 DQMRootOutputModule::~DQMRootOutputModule()
00326 {
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 void
00345 DQMRootOutputModule::write(edm::EventPrincipal const& ){
00346
00347 }
00348 void
00349 DQMRootOutputModule::writeLuminosityBlock(edm::LuminosityBlockPrincipal const& iLumi) {
00350 edm::Service<DQMStore> dstore;
00351 m_run=iLumi.id().run();
00352 m_lumi = iLumi.id().value();
00353 m_beginTime = iLumi.beginTime().value();
00354 m_endTime = iLumi.endTime().value();
00355
00356 std::vector<MonitorElement *> items(dstore->getAllContents(""));
00357 for(std::vector<MonitorElement*>::iterator it = items.begin(), itEnd=items.end();
00358 it!=itEnd;
00359 ++it) {
00360 if((*it)->getLumiFlag()) {
00361 std::map<unsigned int,unsigned int>::iterator itFound = m_dqmKindToTypeIndex.find((*it)->kind());
00362 assert(itFound !=m_dqmKindToTypeIndex.end());
00363 m_treeHelpers[itFound->second]->fill(*it);
00364 }
00365 }
00366
00367 bool storedLumiIndex = false;
00368 unsigned int typeIndex = 0;
00369 for(std::vector<boost::shared_ptr<TreeHelperBase> >::iterator it = m_treeHelpers.begin(), itEnd = m_treeHelpers.end();
00370 it != itEnd;
00371 ++it,++typeIndex) {
00372 if((*it)->wasFilled()) {
00373 m_type = typeIndex;
00374 (*it)->getRangeAndReset(m_firstIndex,m_lastIndex);
00375 storedLumiIndex = true;
00376 m_indicesTree->Fill();
00377 }
00378 }
00379 if(not storedLumiIndex) {
00380
00381
00382 m_type = kNoTypesStored;
00383 m_firstIndex=0;
00384 m_lastIndex=0;
00385 m_indicesTree->Fill();
00386 }
00387
00388 edm::Service<edm::JobReport> jr;
00389 jr->reportLumiSection(m_run,m_lumi);
00390 }
00391
00392 void DQMRootOutputModule::writeRun(edm::RunPrincipal const& iRun){
00393 edm::Service<DQMStore> dstore;
00394 m_run=iRun.id().run();
00395 m_lumi = 0;
00396 m_beginTime = iRun.beginTime().value();
00397 m_endTime = iRun.endTime().value();
00398
00399 std::vector<MonitorElement *> items(dstore->getAllContents(""));
00400 for(std::vector<MonitorElement*>::iterator it = items.begin(), itEnd=items.end();
00401 it!=itEnd;
00402 ++it) {
00403 if(not (*it)->getLumiFlag()) {
00404 std::map<unsigned int,unsigned int>::iterator itFound = m_dqmKindToTypeIndex.find((*it)->kind());
00405 assert (itFound !=m_dqmKindToTypeIndex.end());
00406 m_treeHelpers[itFound->second]->fill(*it);
00407 }
00408 }
00409
00410
00411 unsigned int typeIndex = 0;
00412 for(std::vector<boost::shared_ptr<TreeHelperBase> >::iterator it = m_treeHelpers.begin(), itEnd = m_treeHelpers.end();
00413 it != itEnd;
00414 ++it,++typeIndex) {
00415 if((*it)->wasFilled()) {
00416 m_type = typeIndex;
00417 (*it)->getRangeAndReset(m_firstIndex,m_lastIndex);
00418 m_indicesTree->Fill();
00419 }
00420 }
00421
00422 edm::Service<edm::JobReport> jr;
00423 jr->reportRunNumber(m_run);
00424 }
00425
00426 void DQMRootOutputModule::beginRun(edm::RunPrincipal const& iPrincipal) {
00427
00428
00429 edm::ProcessHistoryID id = iPrincipal.processHistoryID();
00430 std::vector<edm::ProcessHistoryID>::iterator itFind = std::find(m_seenHistories.begin(),m_seenHistories.end(),id);
00431 if(itFind == m_seenHistories.end()) {
00432 m_presentHistoryIndex = m_seenHistories.size();
00433 m_seenHistories.push_back(id);
00434 } else {
00435 m_presentHistoryIndex = itFind - m_seenHistories.begin();
00436 }
00437 }
00438
00439 void DQMRootOutputModule::startEndFile() {
00440
00441 m_file->cd();
00442 TDirectory* metaDataDirectory = m_file->mkdir(kMetaDataDirectory);
00443
00444
00445
00446 TTree* processHistoryTree = new TTree(kProcessHistoryTree,kProcessHistoryTree);
00447 processHistoryTree->SetDirectory(metaDataDirectory);
00448
00449 unsigned int index = 0;
00450 processHistoryTree->Branch(kPHIndexBranch,&index);
00451 std::string processName;
00452 processHistoryTree->Branch(kProcessConfigurationProcessNameBranch,&processName);
00453 std::string parameterSetID;
00454 processHistoryTree->Branch(kProcessConfigurationParameterSetIDBranch,¶meterSetID);
00455 std::string releaseVersion;
00456 processHistoryTree->Branch(kProcessConfigurationReleaseVersion,&releaseVersion);
00457 std::string passID;
00458 processHistoryTree->Branch(kProcessConfigurationPassID,&passID);
00459
00460 edm::ProcessHistoryRegistry* phr = edm::ProcessHistoryRegistry::instance();
00461 assert(0!=phr);
00462 for(std::vector<edm::ProcessHistoryID>::iterator it = m_seenHistories.begin(), itEnd = m_seenHistories.end();
00463 it !=itEnd;
00464 ++it) {
00465 const edm::ProcessHistory* history = phr->getMapped(*it);
00466 assert(0!=history);
00467 index = 0;
00468 for(edm::ProcessHistory::collection_type::const_iterator itPC = history->begin(), itPCEnd = history->end();
00469 itPC != itPCEnd;
00470 ++itPC,++index) {
00471 processName = itPC->processName();
00472 releaseVersion = itPC->releaseVersion();
00473 passID = itPC->passID();
00474 parameterSetID = itPC->parameterSetID().compactForm();
00475 processHistoryTree->Fill();
00476 }
00477 }
00478
00479
00480 TTree* parameterSetsTree = new TTree(kParameterSetTree,kParameterSetTree);
00481 parameterSetsTree->SetDirectory(metaDataDirectory);
00482 std::string blob;
00483 parameterSetsTree->Branch(kParameterSetBranch,&blob);
00484
00485 edm::pset::Registry* psr = edm::pset::Registry::instance();
00486 assert(0!=psr);
00487 for(edm::pset::Registry::const_iterator it = psr->begin(), itEnd = psr->end();
00488 it != itEnd;
00489 ++it) {
00490 blob.clear();
00491 it->second.toString(blob);
00492 parameterSetsTree->Fill();
00493 }
00494
00495 }
00496
00497 void DQMRootOutputModule::finishEndFile() {
00498 m_file->Write();
00499 m_file->Close();
00500 edm::Service<edm::JobReport> jr;
00501 jr->outputFileClosed(m_jrToken);
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00511 void
00512 DQMRootOutputModule::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
00513
00514
00515 edm::ParameterSetDescription desc;
00516 desc.setUnknown();
00517 descriptions.addDefault(desc);
00518
00519
00520
00521 }
00522
00523
00524 DEFINE_FWK_MODULE(DQMRootOutputModule);