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 #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
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
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
00256
00257
00258
00259
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
00275
00276
00277
00278
00279 DQMRootOutputModule::~DQMRootOutputModule()
00280 {
00281 }
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
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
00308
00309 m_file = std::auto_ptr<TFile>(new TFile(m_fileName.c_str(),"RECREATE",
00310 "1"
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
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());
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
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
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
00405
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
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
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
00459
00460
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
00473
00474 m_file->cd();
00475 TDirectory* metaDataDirectory = m_file->mkdir(kMetaDataDirectory);
00476
00477
00478
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,¶meterSetID);
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
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
00532 m_file->Write();
00533 m_file->Close();
00534 edm::Service<edm::JobReport> jr;
00535 jr->outputFileClosed(m_jrToken);
00536 }
00537
00538
00539
00540
00541
00542
00543
00544
00545 void
00546 DQMRootOutputModule::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
00547
00548
00549 edm::ParameterSetDescription desc;
00550 desc.setUnknown();
00551 descriptions.addDefault(desc);
00552
00553
00554
00555 }
00556
00557
00558 DEFINE_FWK_MODULE(DQMRootOutputModule);