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