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 bool isFileOpen() const;
00186 virtual void openFile(edm::FileBlock const&);
00187
00188
00189 virtual void startEndFile();
00190 virtual void finishEndFile();
00191 std::string m_fileName;
00192 std::string m_logicalFileName;
00193 std::auto_ptr<TFile> m_file;
00194 std::vector<boost::shared_ptr<TreeHelperBase> > m_treeHelpers;
00195
00196 unsigned int m_run;
00197 unsigned int m_lumi;
00198 unsigned int m_type;
00199 unsigned int m_presentHistoryIndex;
00200 ULong64_t m_beginTime;
00201 ULong64_t m_endTime;
00202 ULong64_t m_firstIndex;
00203 ULong64_t m_lastIndex;
00204 unsigned int m_filterOnRun;
00205
00206 std::string m_fullNameBuffer;
00207 std::string* m_fullNameBufferPtr;
00208 std::map<unsigned int, unsigned int> m_dqmKindToTypeIndex;
00209 TTree* m_indicesTree;
00210
00211 std::vector<edm::ProcessHistoryID> m_seenHistories;
00212 edm::JobReport::Token m_jrToken;
00213 };
00214
00215
00216
00217
00218
00219 static TreeHelperBase*
00220 makeHelper(unsigned int iTypeIndex,
00221 TTree* iTree,
00222 std::string* iFullNameBufferPtr) {
00223 switch(iTypeIndex) {
00224 case kIntIndex:
00225 return new IntTreeHelper(iTree,iFullNameBufferPtr);
00226 case kFloatIndex:
00227 return new FloatTreeHelper(iTree,iFullNameBufferPtr);
00228 case kStringIndex:
00229 return new StringTreeHelper(iTree,iFullNameBufferPtr);
00230 case kTH1FIndex:
00231 return new TreeHelper<TH1F>(iTree,iFullNameBufferPtr);
00232 case kTH1SIndex:
00233 return new TreeHelper<TH1S>(iTree,iFullNameBufferPtr);
00234 case kTH1DIndex:
00235 return new TreeHelper<TH1D>(iTree,iFullNameBufferPtr);
00236 case kTH2FIndex:
00237 return new TreeHelper<TH2F>(iTree,iFullNameBufferPtr);
00238 case kTH2SIndex:
00239 return new TreeHelper<TH2S>(iTree,iFullNameBufferPtr);
00240 case kTH2DIndex:
00241 return new TreeHelper<TH2D>(iTree,iFullNameBufferPtr);
00242 case kTH3FIndex:
00243 return new TreeHelper<TH3F>(iTree,iFullNameBufferPtr);
00244 case kTProfileIndex:
00245 return new TreeHelper<TProfile>(iTree,iFullNameBufferPtr);
00246 case kTProfile2DIndex:
00247 return new TreeHelper<TProfile2D>(iTree,iFullNameBufferPtr);
00248 }
00249 assert(false);
00250 return 0;
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260 DQMRootOutputModule::DQMRootOutputModule(edm::ParameterSet const& pset):
00261 edm::OutputModule(pset),
00262 m_fileName(pset.getUntrackedParameter<std::string>("fileName")),
00263 m_logicalFileName(pset.getUntrackedParameter<std::string>("logicalFileName","")),
00264 m_file(0),
00265 m_treeHelpers(kNIndicies,boost::shared_ptr<TreeHelperBase>()),
00266 m_presentHistoryIndex(0),
00267 m_filterOnRun(pset.getUntrackedParameter<unsigned int>("filterOnRun",0)),
00268 m_fullNameBufferPtr(&m_fullNameBuffer),
00269 m_indicesTree(0)
00270 {
00271 }
00272
00273
00274
00275
00276
00277
00278 DQMRootOutputModule::~DQMRootOutputModule()
00279 {
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 bool
00298 DQMRootOutputModule::isFileOpen() const
00299 {
00300 return nullptr!=m_file.get();
00301 }
00302
00303 void
00304 DQMRootOutputModule::openFile(edm::FileBlock const&)
00305 {
00306
00307
00308 m_file = std::auto_ptr<TFile>(new TFile(m_fileName.c_str(),"RECREATE",
00309 "1"
00310 ));
00311
00312 edm::Service<edm::JobReport> jr;
00313 cms::Digest branchHash;
00314 m_jrToken = jr->outputFileOpened(m_fileName,
00315 m_logicalFileName,
00316 std::string(),
00317 "DQMRootOutputModule",
00318 description().moduleLabel(),
00319 m_file->GetUUID().AsString(),
00320 std::string(),
00321 branchHash.digest().toString(),
00322 std::vector<std::string>()
00323 );
00324
00325
00326 m_indicesTree = new TTree(kIndicesTree,kIndicesTree);
00327 m_indicesTree->Branch(kRunBranch,&m_run);
00328 m_indicesTree->Branch(kLumiBranch,&m_lumi);
00329 m_indicesTree->Branch(kProcessHistoryIndexBranch,&m_presentHistoryIndex);
00330 m_indicesTree->Branch(kBeginTimeBranch,&m_beginTime);
00331 m_indicesTree->Branch(kEndTimeBranch,&m_endTime);
00332 m_indicesTree->Branch(kTypeBranch,&m_type);
00333 m_indicesTree->Branch(kFirstIndex,&m_firstIndex);
00334 m_indicesTree->Branch(kLastIndex,&m_lastIndex);
00335 m_indicesTree->SetDirectory(m_file.get());
00336
00337 unsigned int i = 0;
00338 for(std::vector<boost::shared_ptr<TreeHelperBase> >::iterator it = m_treeHelpers.begin(), itEnd = m_treeHelpers.end();
00339 it != itEnd;
00340 ++it,++i) {
00341
00342 TTree* tree = new TTree(kTypeNames[i],kTypeNames[i]);
00343 *it = boost::shared_ptr<TreeHelperBase>(makeHelper(i,tree,m_fullNameBufferPtr));
00344 tree->SetDirectory(m_file.get());
00345 }
00346
00347 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_INT]=kIntIndex;
00348 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_REAL]=kFloatIndex;
00349 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_STRING]=kStringIndex;
00350 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH1F]=kTH1FIndex;
00351 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH1S]=kTH1SIndex;
00352 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH1D]=kTH1DIndex;
00353 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH2F]=kTH2FIndex;
00354 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH2S]=kTH2SIndex;
00355 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH2D]=kTH2DIndex;
00356 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TH3F]=kTH3FIndex;
00357 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TPROFILE]=kTProfileIndex;
00358 m_dqmKindToTypeIndex[MonitorElement::DQM_KIND_TPROFILE2D]=kTProfile2DIndex;
00359 }
00360
00361
00362 void
00363 DQMRootOutputModule::write(edm::EventPrincipal const& ){
00364
00365 }
00366 void
00367 DQMRootOutputModule::writeLuminosityBlock(edm::LuminosityBlockPrincipal const& iLumi) {
00368
00369 edm::Service<DQMStore> dstore;
00370 m_run=iLumi.id().run();
00371 m_lumi = iLumi.id().value();
00372 m_beginTime = iLumi.beginTime().value();
00373 m_endTime = iLumi.endTime().value();
00374 bool shouldWrite = (m_filterOnRun == 0 ||
00375 (m_filterOnRun != 0 && m_filterOnRun == m_run));
00376
00377 if (! shouldWrite)
00378 return;
00379 std::vector<MonitorElement *> items(dstore->getAllContents(""));
00380 for(std::vector<MonitorElement*>::iterator it = items.begin(), itEnd=items.end();
00381 it!=itEnd;
00382 ++it) {
00383 if((*it)->getLumiFlag()) {
00384 std::map<unsigned int,unsigned int>::iterator itFound = m_dqmKindToTypeIndex.find((*it)->kind());
00385 assert(itFound !=m_dqmKindToTypeIndex.end());
00386 m_treeHelpers[itFound->second]->fill(*it);
00387 }
00388 }
00389
00390 bool storedLumiIndex = false;
00391 unsigned int typeIndex = 0;
00392 for(std::vector<boost::shared_ptr<TreeHelperBase> >::iterator it = m_treeHelpers.begin(), itEnd = m_treeHelpers.end();
00393 it != itEnd;
00394 ++it,++typeIndex) {
00395 if((*it)->wasFilled()) {
00396 m_type = typeIndex;
00397 (*it)->getRangeAndReset(m_firstIndex,m_lastIndex);
00398 storedLumiIndex = true;
00399 m_indicesTree->Fill();
00400 }
00401 }
00402 if(not storedLumiIndex) {
00403
00404
00405 m_type = kNoTypesStored;
00406 m_firstIndex=0;
00407 m_lastIndex=0;
00408 m_indicesTree->Fill();
00409 }
00410
00411 edm::Service<edm::JobReport> jr;
00412 jr->reportLumiSection(m_run,m_lumi);
00413 }
00414
00415
00416 void DQMRootOutputModule::writeRun(edm::RunPrincipal const& iRun){
00417
00418 edm::Service<DQMStore> dstore;
00419 m_run=iRun.id().run();
00420 m_lumi = 0;
00421 m_beginTime = iRun.beginTime().value();
00422 m_endTime = iRun.endTime().value();
00423 bool shouldWrite = (m_filterOnRun == 0 ||
00424 (m_filterOnRun != 0 && m_filterOnRun == m_run));
00425
00426 if (! shouldWrite)
00427 return;
00428
00429 std::vector<MonitorElement *> items(dstore->getAllContents(""));
00430 for(std::vector<MonitorElement*>::iterator it = items.begin(), itEnd=items.end();
00431 it!=itEnd;
00432 ++it) {
00433 if(not (*it)->getLumiFlag()) {
00434 std::map<unsigned int,unsigned int>::iterator itFound = m_dqmKindToTypeIndex.find((*it)->kind());
00435 assert (itFound !=m_dqmKindToTypeIndex.end());
00436 m_treeHelpers[itFound->second]->fill(*it);
00437 }
00438 }
00439
00440
00441 unsigned int typeIndex = 0;
00442 for(std::vector<boost::shared_ptr<TreeHelperBase> >::iterator it = m_treeHelpers.begin(), itEnd = m_treeHelpers.end();
00443 it != itEnd;
00444 ++it,++typeIndex) {
00445 if((*it)->wasFilled()) {
00446 m_type = typeIndex;
00447 (*it)->getRangeAndReset(m_firstIndex,m_lastIndex);
00448 m_indicesTree->Fill();
00449 }
00450 }
00451
00452 edm::Service<edm::JobReport> jr;
00453 jr->reportRunNumber(m_run);
00454 }
00455
00456 void DQMRootOutputModule::beginRun(edm::RunPrincipal const& iPrincipal) {
00457
00458
00459
00460 edm::ProcessHistoryID id = iPrincipal.processHistoryID();
00461 std::vector<edm::ProcessHistoryID>::iterator itFind = std::find(m_seenHistories.begin(),m_seenHistories.end(),id);
00462 if(itFind == m_seenHistories.end()) {
00463 m_presentHistoryIndex = m_seenHistories.size();
00464 m_seenHistories.push_back(id);
00465 } else {
00466 m_presentHistoryIndex = itFind - m_seenHistories.begin();
00467 }
00468 }
00469
00470 void DQMRootOutputModule::startEndFile() {
00471
00472
00473 m_file->cd();
00474 TDirectory* metaDataDirectory = m_file->mkdir(kMetaDataDirectory);
00475
00476
00477
00478 TTree* processHistoryTree = new TTree(kProcessHistoryTree,kProcessHistoryTree);
00479 processHistoryTree->SetDirectory(metaDataDirectory);
00480
00481 unsigned int index = 0;
00482 processHistoryTree->Branch(kPHIndexBranch,&index);
00483 std::string processName;
00484 processHistoryTree->Branch(kProcessConfigurationProcessNameBranch,&processName);
00485 std::string parameterSetID;
00486 processHistoryTree->Branch(kProcessConfigurationParameterSetIDBranch,¶meterSetID);
00487 std::string releaseVersion;
00488 processHistoryTree->Branch(kProcessConfigurationReleaseVersion,&releaseVersion);
00489 std::string passID;
00490 processHistoryTree->Branch(kProcessConfigurationPassID,&passID);
00491
00492 edm::ProcessHistoryRegistry* phr = edm::ProcessHistoryRegistry::instance();
00493 assert(0!=phr);
00494 for(std::vector<edm::ProcessHistoryID>::iterator it = m_seenHistories.begin(), itEnd = m_seenHistories.end();
00495 it !=itEnd;
00496 ++it) {
00497 const edm::ProcessHistory* history = phr->getMapped(*it);
00498 assert(0!=history);
00499 index = 0;
00500 for(edm::ProcessHistory::collection_type::const_iterator itPC = history->begin(), itPCEnd = history->end();
00501 itPC != itPCEnd;
00502 ++itPC,++index) {
00503 processName = itPC->processName();
00504 releaseVersion = itPC->releaseVersion();
00505 passID = itPC->passID();
00506 parameterSetID = itPC->parameterSetID().compactForm();
00507 processHistoryTree->Fill();
00508 }
00509 }
00510
00511
00512 TTree* parameterSetsTree = new TTree(kParameterSetTree,kParameterSetTree);
00513 parameterSetsTree->SetDirectory(metaDataDirectory);
00514 std::string blob;
00515 parameterSetsTree->Branch(kParameterSetBranch,&blob);
00516
00517 edm::pset::Registry* psr = edm::pset::Registry::instance();
00518 assert(0!=psr);
00519 for(edm::pset::Registry::const_iterator it = psr->begin(), itEnd = psr->end();
00520 it != itEnd;
00521 ++it) {
00522 blob.clear();
00523 it->second.toString(blob);
00524 parameterSetsTree->Fill();
00525 }
00526
00527 }
00528
00529 void DQMRootOutputModule::finishEndFile() {
00530
00531 m_file->Write();
00532 m_file->Close();
00533 edm::Service<edm::JobReport> jr;
00534 jr->outputFileClosed(m_jrToken);
00535 }
00536
00537
00538
00539
00540
00541
00542
00543
00544 void
00545 DQMRootOutputModule::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
00546
00547
00548 edm::ParameterSetDescription desc;
00549 desc.setUnknown();
00550 descriptions.addDefault(desc);
00551
00552
00553
00554 }
00555
00556
00557 DEFINE_FWK_MODULE(DQMRootOutputModule);