CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
DQMRootSource.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: FwkIO
4 // Class : DQMRootSource
5 //
6 // Implementation:
7 // [Notes on implementation]
8 //
9 // Original Author: Chris Jones
10 // Created: Tue May 3 11:13:47 CDT 2011
11 //
12 
13 // system include files
14 #include <vector>
15 #include <string>
16 #include <map>
17 #include <memory>
18 #include <list>
19 #include <set>
20 #include "TFile.h"
21 #include "TTree.h"
22 #include "TString.h"
23 #include "TH1.h"
24 #include "TH2.h"
25 #include "TProfile.h"
26 
27 // user include files
35 //#include "FWCore/Utilities/interface/GlobalIdentifier.h"
37 
40 
43 
46 
49 
52 
57 
60 
61 #include "format.h"
62 
63 namespace {
64  //adapter functions
65  MonitorElement* createElement(DQMStore& iStore, const char* iName, TH1F* iHist) {
66  //std::cout <<"create: hist size "<<iName <<" "<<iHist->GetEffectiveEntries()<<std::endl;
67  return iStore.book1D(iName, iHist);
68  }
69  //NOTE: the merge logic comes from DataFormats/Histograms/interface/MEtoEDMFormat.h
70  void mergeTogether(TH1* iOriginal,TH1* iToAdd) {
71  if(iOriginal->TestBit(TH1::kCanRebin)==true && iToAdd->TestBit(TH1::kCanRebin) ==true) {
72  TList list;
73  list.Add(iToAdd);
74  if( -1 == iOriginal->Merge(&list)) {
75  edm::LogError("MergeFailure")<<"Failed to merge DQM element "<<iOriginal->GetName();
76  }
77  } else {
78  if (iOriginal->GetNbinsX() == iToAdd->GetNbinsX() &&
79  iOriginal->GetXaxis()->GetXmin() == iToAdd->GetXaxis()->GetXmin() &&
80  iOriginal->GetXaxis()->GetXmax() == iToAdd->GetXaxis()->GetXmax() &&
81  iOriginal->GetNbinsY() == iToAdd->GetNbinsY() &&
82  iOriginal->GetYaxis()->GetXmin() == iToAdd->GetYaxis()->GetXmin() &&
83  iOriginal->GetYaxis()->GetXmax() == iToAdd->GetYaxis()->GetXmax() &&
84  iOriginal->GetNbinsZ() == iToAdd->GetNbinsZ() &&
85  iOriginal->GetZaxis()->GetXmin() == iToAdd->GetZaxis()->GetXmin() &&
86  iOriginal->GetZaxis()->GetXmax() == iToAdd->GetZaxis()->GetXmax()) {
87  iOriginal->Add(iToAdd);
88  } else {
89  edm::LogError("MergeFailure")<<"Found histograms with different axis limits '"<<iOriginal->GetName()<<"' not merged.";
90  }
91  }
92  }
93  void mergeWithElement(MonitorElement* iElement, TH1F* iHist) {
94  //std::cout <<"merge: hist size "<<iElement->getName() <<" "<<iHist->GetEffectiveEntries()<<std::endl;
95  mergeTogether(iElement->getTH1F(),iHist);
96  }
97  MonitorElement* createElement(DQMStore& iStore, const char* iName, TH1S* iHist) {
98  return iStore.book1S(iName, iHist);
99  }
100  void mergeWithElement(MonitorElement* iElement, TH1S* iHist) {
101  mergeTogether(iElement->getTH1S(),iHist);
102  }
103  MonitorElement* createElement(DQMStore& iStore, const char* iName, TH1D* iHist) {
104  return iStore.book1DD(iName, iHist);
105  }
106  void mergeWithElement(MonitorElement* iElement, TH1D* iHist) {
107  mergeTogether(iElement->getTH1D(),iHist);
108  }
109  MonitorElement* createElement(DQMStore& iStore, const char* iName, TH2F* iHist) {
110  return iStore.book2D(iName, iHist);
111  }
112  void mergeWithElement(MonitorElement* iElement, TH2F* iHist) {
113  mergeTogether(iElement->getTH2F(),iHist);
114  }
115  MonitorElement* createElement(DQMStore& iStore, const char* iName, TH2S* iHist) {
116  return iStore.book2S(iName, iHist);
117  }
118  void mergeWithElement(MonitorElement* iElement, TH2S* iHist) {
119  mergeTogether(iElement->getTH2S(),iHist);
120  }
121  MonitorElement* createElement(DQMStore& iStore, const char* iName, TH2D* iHist) {
122  return iStore.book2DD(iName, iHist);
123  }
124  void mergeWithElement(MonitorElement* iElement, TH2D* iHist) {
125  mergeTogether(iElement->getTH2D(),iHist);
126  }
127  MonitorElement* createElement(DQMStore& iStore, const char* iName, TH3F* iHist) {
128  return iStore.book3D(iName, iHist);
129  }
130  void mergeWithElement(MonitorElement* iElement, TH3F* iHist) {
131  mergeTogether(iElement->getTH3F(),iHist);
132  }
133  MonitorElement* createElement(DQMStore& iStore, const char* iName, TProfile* iHist) {
134  return iStore.bookProfile(iName, iHist);
135  }
136  void mergeWithElement(MonitorElement* iElement, TProfile* iHist) {
137  mergeTogether(iElement->getTProfile(),iHist);
138  }
139  MonitorElement* createElement(DQMStore& iStore, const char* iName, TProfile2D* iHist) {
140  return iStore.bookProfile2D(iName, iHist);
141  }
142  void mergeWithElement(MonitorElement* iElement, TProfile2D* iHist) {
143  mergeTogether(iElement->getTProfile2D(),iHist);
144  }
145 
146  MonitorElement* createElement(DQMStore& iStore, const char* iName, Long64_t& iValue) {
147  MonitorElement* e = iStore.bookInt(iName);
148  e->Fill(iValue);
149  return e;
150  }
151 
152  //NOTE: the merge logic comes from DataFormats/Histograms/interface/MEtoEDMFormat.h
153  void mergeWithElement(MonitorElement* iElement, Long64_t& iValue) {
154  const std::string& name = iElement->getFullname();
155  if(name.find("EventInfo/processedEvents") != std::string::npos) {
156  iElement->Fill(iValue+iElement->getIntValue());
157  } else {
158  if(name.find("EventInfo/iEvent") != std::string::npos ||
159  name.find("EventInfo/iLumiSection") != std::string::npos) {
160  if(iValue > iElement->getIntValue()) {
161  iElement->Fill(iValue);
162  }
163  }
164  }
165  }
166 
167  MonitorElement* createElement(DQMStore& iStore, const char* iName, double& iValue) {
168  MonitorElement* e = iStore.bookFloat(iName);
169  e->Fill(iValue);
170  return e;
171  }
172  void mergeWithElement(MonitorElement* iElement, double& iValue) {
173  //no merging
174  }
175  MonitorElement* createElement(DQMStore& iStore, const char* iName, std::string* iValue) {
176  return iStore.bookString(iName,*iValue);
177  }
178  void mergeWithElement(MonitorElement* , std::string* ) {
179  //no merging
180  }
181 
182  void splitName(const std::string& iFullName, std::string& oPath,const char*& oName) {
183  oPath = iFullName;
184  size_t index = oPath.find_last_of('/');
185  if(index == std::string::npos) {
186  oPath = std::string();
187  oName = iFullName.c_str();
188  } else {
189  oPath.resize(index);
190  oName = iFullName.c_str()+index+1;
191  }
192  }
193 
194  struct RunLumiToRange {
195  unsigned int m_run, m_lumi,m_historyIDIndex;
196  ULong64_t m_beginTime;
197  ULong64_t m_endTime;
198  ULong64_t m_firstIndex, m_lastIndex; //last is inclusive
199  unsigned int m_type; //A value in TypeIndex
200  };
201 
202  class TreeReaderBase {
203  public:
204  TreeReaderBase() {}
205  virtual ~TreeReaderBase() {}
206 
207  MonitorElement* read(ULong64_t iIndex, DQMStore& iStore, bool iIsLumi){
208  return doRead(iIndex,iStore,iIsLumi);
209  }
210  virtual void setTree(TTree* iTree) =0;
211  protected:
212  TTree* m_tree;
213  private:
214  virtual MonitorElement* doRead(ULong64_t iIndex, DQMStore& iStore, bool iIsLumi)=0;
215  };
216 
217  template<class T>
218  class TreeObjectReader: public TreeReaderBase {
219  public:
220  TreeObjectReader():m_tree(0),m_fullName(0),m_buffer(0),m_tag(0){
221  }
222  virtual MonitorElement* doRead(ULong64_t iIndex, DQMStore& iStore, bool iIsLumi) override {
223  m_tree->GetEntry(iIndex);
224  MonitorElement* element = iStore.get(*m_fullName);
225  if(0 == element) {
227  const char* name;
228  splitName(*m_fullName, path,name);
229  iStore.setCurrentFolder(path);
230  element = createElement(iStore,name,m_buffer);
231  if(iIsLumi) { element->setLumiFlag();}
232  } else {
233  mergeWithElement(element,m_buffer);
234  }
235  if(0!= m_tag) {
236  iStore.tag(element,m_tag);
237  }
238  return element;
239  }
240  virtual void setTree(TTree* iTree) override {
241  m_tree = iTree;
242  m_tree->SetBranchAddress(kFullNameBranch,&m_fullName);
243  m_tree->SetBranchAddress(kFlagBranch,&m_tag);
244  m_tree->SetBranchAddress(kValueBranch,&m_buffer);
245  }
246  private:
247  TTree* m_tree;
248  std::string* m_fullName;
249  T* m_buffer;
250  uint32_t m_tag;
251  };
252 
253  template<class T>
254  class TreeSimpleReader : public TreeReaderBase {
255  public:
256  TreeSimpleReader():m_tree(0),m_fullName(0),m_buffer(),m_tag(0){
257  }
258  virtual MonitorElement* doRead(ULong64_t iIndex, DQMStore& iStore,bool iIsLumi) override {
259  m_tree->GetEntry(iIndex);
260  MonitorElement* element = iStore.get(*m_fullName);
261  if(0 == element) {
263  const char* name;
264  splitName(*m_fullName, path,name);
265  iStore.setCurrentFolder(path);
266  element = createElement(iStore,name,m_buffer);
267  if(iIsLumi) { element->setLumiFlag();}
268  } else {
269  mergeWithElement(element, m_buffer);
270  }
271  if(0!=m_tag) {
272  iStore.tag(element,m_tag);
273  }
274  return element;
275  }
276  virtual void setTree(TTree* iTree) override {
277  m_tree = iTree;
278  m_tree->SetBranchAddress(kFullNameBranch,&m_fullName);
279  m_tree->SetBranchAddress(kFlagBranch,&m_tag);
280  m_tree->SetBranchAddress(kValueBranch,&m_buffer);
281  }
282  private:
283  TTree* m_tree;
284  std::string* m_fullName;
285  T m_buffer;
286  uint32_t m_tag;
287  };
288 
289 }
290 
292 {
293 
294  public:
296  virtual ~DQMRootSource();
297 
298  // ---------- const member functions ---------------------
299 
300  // ---------- static member functions --------------------
301 
302  // ---------- member functions ---------------------------
303  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
304 
305  private:
306 
307  DQMRootSource(const DQMRootSource&); // stop default
308 
309  class RunPHIDKey {
310  public:
311  RunPHIDKey(edm::ProcessHistoryID const& phid, unsigned int run) :
312  processHistoryID_(phid), run_(run) { }
314  unsigned int run() const { return run_; }
315  bool operator<(RunPHIDKey const& right) const {
316  if (processHistoryID_ == right.processHistoryID()) {
317  return run_ < right.run();
318  }
319  return processHistoryID_ < right.processHistoryID();
320  }
321  private:
323  unsigned int run_;
324  };
325 
327  public:
328  RunLumiPHIDKey(edm::ProcessHistoryID const& phid, unsigned int run, unsigned int lumi) :
329  processHistoryID_(phid), run_(run), lumi_(lumi) { }
331  unsigned int run() const { return run_; }
332  unsigned int lumi() const { return lumi_; }
333  bool operator<(RunLumiPHIDKey const& right) const {
334  if (processHistoryID_ == right.processHistoryID()) {
335  if (run_ == right.run()) {
336  return lumi_ < right.lumi();
337  }
338  return run_ < right.run();
339  }
340  return processHistoryID_ < right.processHistoryID();
341  }
342  private:
344  unsigned int run_;
345  unsigned int lumi_;
346  };
347 
348  virtual edm::InputSource::ItemType getNextItemType() override;
349  //NOTE: the following is really read next run auxiliary
350  virtual boost::shared_ptr<edm::RunAuxiliary> readRunAuxiliary_() override ;
351  virtual boost::shared_ptr<edm::LuminosityBlockAuxiliary> readLuminosityBlockAuxiliary_() override ;
352  virtual void readRun_(edm::RunPrincipal& rpCache) override;
353  virtual void readLuminosityBlock_(edm::LuminosityBlockPrincipal& lbCache) override;
354  virtual void readEvent_(edm::EventPrincipal&) override ;
355 
356  virtual std::unique_ptr<edm::FileBlock> readFile_() override;
357  virtual void closeFile_() override;
358 
359  void logFileAction(char const* msg, char const* fileName) const;
360 
361  void readNextItemType();
362  bool setupFile(unsigned int iIndex);
363  void readElements();
364 
365  const DQMRootSource& operator=(const DQMRootSource&); // stop default
366 
367  // ---------- member data --------------------------------
372 
373  size_t m_fileIndex;
375  std::list<unsigned int>::iterator m_nextIndexItr;
376  std::list<unsigned int>::iterator m_presentIndexItr;
377  std::vector<RunLumiToRange> m_runlumiToRange;
378  std::auto_ptr<TFile> m_file;
379  std::vector<TTree*> m_trees;
380  std::vector<boost::shared_ptr<TreeReaderBase> > m_treeReaders;
381 
382  std::list<unsigned int> m_orderedIndices;
384  unsigned int m_lastSeenRun;
386  unsigned int m_lastSeenRun2;
387  unsigned int m_lastSeenLumi2;
388  unsigned int m_filterOnRun;
392  std::set<MonitorElement*> m_lumiElements;
393  std::set<MonitorElement*> m_runElements;
394  std::vector<edm::ProcessHistoryID> m_historyIDs;
395  std::vector<edm::ProcessHistoryID> m_reducedHistoryIDs;
396 
398 };
399 
400 //
401 // constants, enums and typedefs
402 //
403 
404 //
405 // static data member definitions
406 //
407 
408 void
411  desc.addUntracked<std::vector<std::string> >("fileNames")
412  ->setComment("Names of files to be processed.");
413  desc.addUntracked<unsigned int>("filterOnRun",0)
414  ->setComment("Just limit the process to the selected run.");
415  desc.addUntracked<bool>("skipBadFiles",false)
416  ->setComment("Skip the file is it is not valid");
417  desc.addUntracked<std::string>("overrideCatalog",std::string())
418  ->setComment("An alternate file catalog to use instead of the standard site one.");
419  descriptions.addDefault(desc);
420 }
421 //
422 // constructors and destructor
423 //
425  edm::InputSource(iPSet,iDesc),
426  m_catalog(iPSet.getUntrackedParameter<std::vector<std::string> >("fileNames"),
427  iPSet.getUntrackedParameter<std::string>("overrideCatalog")),
428  m_nextItemType(edm::InputSource::IsFile),
429  m_fileIndex(0),
430  m_presentlyOpenFileIndex(0),
431  m_trees(kNIndicies,static_cast<TTree*>(0)),
432  m_treeReaders(kNIndicies,boost::shared_ptr<TreeReaderBase>()),
433  m_lastSeenReducedPHID(),
434  m_lastSeenRun(0),
435  m_lastSeenReducedPHID2(),
436  m_lastSeenRun2(0),
437  m_lastSeenLumi2(0),
438  m_filterOnRun(iPSet.getUntrackedParameter<unsigned int>("filterOnRun", 0)),
439  m_skipBadFiles(iPSet.getUntrackedParameter<bool>("skipBadFiles", false)),
440  m_justOpenedFileSoNeedToGenerateRunTransition(false),
441  m_shouldReadMEs(true)
442 {
443  if(m_fileIndex ==m_catalog.fileNames().size()) {
445  } else{
446  m_treeReaders[kIntIndex].reset(new TreeSimpleReader<Long64_t>());
447  m_treeReaders[kFloatIndex].reset(new TreeSimpleReader<double>());
448  m_treeReaders[kStringIndex].reset(new TreeObjectReader<std::string>());
449  m_treeReaders[kTH1FIndex].reset(new TreeObjectReader<TH1F>());
450  m_treeReaders[kTH1SIndex].reset(new TreeObjectReader<TH1S>());
451  m_treeReaders[kTH1DIndex].reset(new TreeObjectReader<TH1D>());
452  m_treeReaders[kTH2FIndex].reset(new TreeObjectReader<TH2F>());
453  m_treeReaders[kTH2SIndex].reset(new TreeObjectReader<TH2S>());
454  m_treeReaders[kTH2DIndex].reset(new TreeObjectReader<TH2D>());
455  m_treeReaders[kTH3FIndex].reset(new TreeObjectReader<TH3F>());
456  m_treeReaders[kTProfileIndex].reset(new TreeObjectReader<TProfile>());
457  m_treeReaders[kTProfile2DIndex].reset(new TreeObjectReader<TProfile2D>());
458  }
459 
460 }
461 
462 // DQMRootSource::DQMRootSource(const DQMRootSource& rhs)
463 // {
464 // // do actual copying here;
465 // }
466 
468 {
469  if(m_file.get() != 0 && m_file->IsOpen()) {
470  m_file->Close();
471  logFileAction(" Closed file ", m_catalog.fileNames()[m_presentlyOpenFileIndex].c_str());
472  }
473 }
474 
475 //
476 // assignment operators
477 //
478 // const DQMRootSource& DQMRootSource::operator=(const DQMRootSource& rhs)
479 // {
480 // //An exception safe implementation is
481 // DQMRootSource temp(rhs);
482 // swap(rhs);
483 //
484 // return *this;
485 // }
486 
487 //
488 // member functions
489 //
491 {
492 }
493 
495 {
496  //std::cout <<"getNextItemType "<<m_nextItemType<<std::endl;
497  return m_nextItemType;
498 }
499 
500 boost::shared_ptr<edm::RunAuxiliary> DQMRootSource::readRunAuxiliary_()
501 {
502  //std::cout <<"readRunAuxiliary_"<<std::endl;
503  assert(m_nextIndexItr != m_orderedIndices.end());
504  RunLumiToRange runLumiRange = m_runlumiToRange[*m_nextIndexItr];
505 
506  //NOTE: the setBeginTime and setEndTime functions of RunAuxiliary only work if the previous value was invalid
507  // therefore we must copy
508  m_runAux = edm::RunAuxiliary(runLumiRange.m_run,edm::Timestamp(runLumiRange.m_beginTime),edm::Timestamp(runLumiRange.m_endTime));
509  assert(m_historyIDs.size() > runLumiRange.m_historyIDIndex);
510  //std::cout <<"readRunAuxiliary_ "<<m_historyIDs[runLumiRange.m_historyIDIndex]<<std::endl;
511  m_runAux.setProcessHistoryID(m_historyIDs[runLumiRange.m_historyIDIndex]);
512  return boost::shared_ptr<edm::RunAuxiliary>( new edm::RunAuxiliary(m_runAux) );
513 }
514 
515 boost::shared_ptr<edm::LuminosityBlockAuxiliary>
517 {
518  //std::cout <<"readLuminosityBlockAuxiliary_"<<std::endl;
519  assert(m_nextIndexItr != m_orderedIndices.end());
520  const RunLumiToRange runLumiRange = m_runlumiToRange[*m_nextIndexItr];
521  m_lumiAux = edm::LuminosityBlockAuxiliary(edm::LuminosityBlockID(runLumiRange.m_run,runLumiRange.m_lumi),
522  edm::Timestamp(runLumiRange.m_beginTime),
523  edm::Timestamp(runLumiRange.m_endTime));
524  assert(m_historyIDs.size() > runLumiRange.m_historyIDIndex);
525  //std::cout <<"lumi "<<m_lumiAux.beginTime().value()<<" "<<runLumiRange.m_beginTime<<std::endl;
526  m_lumiAux.setProcessHistoryID(m_historyIDs[runLumiRange.m_historyIDIndex]);
527 
528  return boost::shared_ptr<edm::LuminosityBlockAuxiliary>(new edm::LuminosityBlockAuxiliary(m_lumiAux));
529 }
530 
531 void
533 {
534  assert(m_presentIndexItr != m_orderedIndices.end());
535  RunLumiToRange runLumiRange = m_runlumiToRange[*m_presentIndexItr];
536 
538  unsigned int runID =rpCache.id().run();
539  assert(runID == runLumiRange.m_run);
540 
541  m_shouldReadMEs = (m_filterOnRun == 0 ||
542  (m_filterOnRun != 0 && m_filterOnRun == runID));
543  // std::cout <<"readRun_"<<std::endl;
544  // std::cout <<"m_shouldReadMEs " << m_shouldReadMEs <<std::endl;
545 
556  //NOTE: need to reset all run elements at this point
557  if( m_lastSeenRun != runID ||
558  m_lastSeenReducedPHID != m_reducedHistoryIDs.at(runLumiRange.m_historyIDIndex) ) {
559  if (m_shouldReadMEs) {
561  std::vector<MonitorElement*> allMEs = (*store).getAllContents("");
562  for(auto const& ME : allMEs) {
563  // We do not want to reset here Lumi products, since a dedicated
564  // resetting is done at every lumi transition.
565  if (ME->getLumiFlag()) continue;
566  if ( !(*store).isCollate() )
567  ME->Reset();
568  }
569  }
570  m_lastSeenReducedPHID = m_reducedHistoryIDs.at(runLumiRange.m_historyIDIndex);
571  m_lastSeenRun = runID;
572  }
573 
575 
576  //NOTE: it is possible to have a Run when all we have stored is lumis
577  if(runLumiRange.m_lumi == 0) {
578  readElements();
579  }
580 
582  jr->reportInputRunNumber(rpCache.id().run());
583 
585 }
586 
587 void
589 {
590  assert(m_presentIndexItr != m_orderedIndices.end());
591  RunLumiToRange runLumiRange = m_runlumiToRange[*m_presentIndexItr];
592  assert(runLumiRange.m_run == lbCache.id().run());
593  assert(runLumiRange.m_lumi == lbCache.id().luminosityBlock());
594 
595  //NOTE: need to reset all lumi block elements at this point
596  if( ( m_lastSeenLumi2 != runLumiRange.m_lumi ||
597  m_lastSeenRun2 != runLumiRange.m_run ||
598  m_lastSeenReducedPHID2 != m_reducedHistoryIDs.at(runLumiRange.m_historyIDIndex) )
599  && m_shouldReadMEs) {
600 
602  std::vector<MonitorElement*> allMEs = (*store).getAllContents("");
603  for(auto const& ME : allMEs) {
604  // We do not want to reset Run Products here!
605  if (ME->getLumiFlag()) {
606  ME->Reset();
607  }
608  }
609  m_lastSeenReducedPHID2 = m_reducedHistoryIDs.at(runLumiRange.m_historyIDIndex);
610  m_lastSeenRun2 = runLumiRange.m_run;
611  m_lastSeenLumi2 = runLumiRange.m_lumi;
612  }
614  //std::cout <<"readLuminosityBlock_"<<std::endl;
615 
616  readElements();
617 
619  jr->reportInputLumiSection(lbCache.id().run(),lbCache.id().luminosityBlock());
620 
622 }
623 
624 std::unique_ptr<edm::FileBlock>
626  //std::cout <<"readFile_"<<std::endl;
627  auto const numFiles = m_catalog.fileNames().size();
628  while(m_fileIndex < numFiles && not setupFile(m_fileIndex++)) {}
629 
630  if(m_file.get() == nullptr) {
631  //last file in list was bad
633  return std::unique_ptr<edm::FileBlock>(new edm::FileBlock);
634  }
635 
637 
641  std::string(),
642  std::string(),
643  "DQMRootSource",
644  "source",
645  m_file->GetUUID().AsString(),//edm::createGlobalIdentifier(),
646  std::vector<std::string>()
647  );
648 
649  return std::unique_ptr<edm::FileBlock>(new edm::FileBlock);
650 }
651 
652 void
654  if(m_file.get()==nullptr) { return; }
657 }
658 
661  RunLumiToRange runLumiRange = m_runlumiToRange[*m_presentIndexItr];
662  bool shouldContinue = false;
663  do
664  {
665  shouldContinue = false;
667  if(runLumiRange.m_type == kNoTypesStored) {continue;}
668  boost::shared_ptr<TreeReaderBase> reader = m_treeReaders[runLumiRange.m_type];
669  ULong64_t index = runLumiRange.m_firstIndex;
670  ULong64_t endIndex = runLumiRange.m_lastIndex+1;
671  for (; index != endIndex; ++index)
672  {
673  bool isLumi = runLumiRange.m_lumi !=0;
674  if (m_shouldReadMEs)
675  reader->read(index,*store,isLumi);
676 // if (isLumi)
677 // {
678 // std::cout << runLumiRange.m_run << " " << runLumiRange.m_lumi << " lumi element "<< element->getFullname()<<" "<<index<< " " << runLumiRange.m_type << std::endl;
679 // m_lumiElements.insert(element);
680 // }
681 // else
682 // {
683 // std::cout << runLumiRange.m_run << " " << runLumiRange.m_lumi << " run element "<< element->getFullname()<<" "<<index<< " " << runLumiRange.m_type << std::endl;
684 // m_runElements.insert(element);
685 // }
686  }
687  if (m_presentIndexItr != m_orderedIndices.end())
688  {
689  //are there more parts to this same run/lumi?
690  const RunLumiToRange nextRunLumiRange = m_runlumiToRange[*m_presentIndexItr];
691  //continue to the next item if that item is either
692  if ( (m_reducedHistoryIDs.at(nextRunLumiRange.m_historyIDIndex) == m_reducedHistoryIDs.at(runLumiRange.m_historyIDIndex)) &&
693  (nextRunLumiRange.m_run == runLumiRange.m_run) &&
694  (nextRunLumiRange.m_lumi == runLumiRange.m_lumi) )
695  {
696  shouldContinue= true;
697  runLumiRange = nextRunLumiRange;
698  }
699  }
700  } while(shouldContinue);
701 }
702 
704 {
705  //Do the work of actually figuring out where next to go
706 
707  assert (m_nextIndexItr != m_orderedIndices.end());
708  RunLumiToRange runLumiRange = m_runlumiToRange[*m_nextIndexItr];
709 
711  if (runLumiRange.m_lumi != 0 && m_nextItemType == edm::InputSource::IsRun) {
713  return;
714  }
715  ++m_nextIndexItr;
716  }
717  else
718  {
719  //NOTE: the following makes the iterator not be advanced in the
720  //do while loop below.
721  runLumiRange.m_run=0;
722  }
723 
724  bool shouldContinue = false;
725  do
726  {
727  shouldContinue = false;
728  if (m_nextIndexItr == m_orderedIndices.end())
729  {
730  //go to next file
732  //std::cout <<"going to next file"<<std::endl;
733  if(m_fileIndex == m_catalog.fileNames().size()) {
735  }
736  break;
737  }
738  const RunLumiToRange nextRunLumiRange = m_runlumiToRange[*m_nextIndexItr];
739  //continue to the next item if that item is the same run or lumi as we just did
740  if( (m_reducedHistoryIDs.at(nextRunLumiRange.m_historyIDIndex) == m_reducedHistoryIDs.at(runLumiRange.m_historyIDIndex) ) &&
741  (nextRunLumiRange.m_run == runLumiRange.m_run) &&
742  (nextRunLumiRange.m_lumi == runLumiRange.m_lumi) ) {
743  shouldContinue= true;
744  ++m_nextIndexItr;
745  //std::cout <<" advancing " <<nextRunLumiRange.m_run<<" "<<nextRunLumiRange.m_lumi<<std::endl;
746  }
747  } while(shouldContinue);
748 
749  if(m_nextIndexItr != m_orderedIndices.end()) {
754  } else {
756  }
757  }
758 }
759 
760 bool
761 DQMRootSource::setupFile(unsigned int iIndex)
762 {
763  if(m_file.get() != 0 && iIndex > 0) {
764  m_file->Close();
765  logFileAction(" Closed file ", m_catalog.fileNames()[iIndex-1].c_str());
766  }
767  logFileAction(" Initiating request to open file ", m_catalog.fileNames()[iIndex].c_str());
768  m_presentlyOpenFileIndex = iIndex;
769  m_file.reset();
770  std::auto_ptr<TFile> newFile;
771  try {
772  newFile = std::auto_ptr<TFile>(TFile::Open(m_catalog.fileNames()[iIndex].c_str()));
773  } catch(cms::Exception const& e) {
774  if(!m_skipBadFiles) {
776  ex.addContext("Opening DQM Root file");
777  ex <<"\nInput file " << m_catalog.fileNames()[iIndex] << " was not found, could not be opened, or is corrupted.\n";
778  throw ex;
779  }
780  return 0;
781  }
782  if(not newFile->IsZombie()) {
783  logFileAction(" Successfully opened file ", m_catalog.fileNames()[iIndex].c_str());
784  } else {
785  if(!m_skipBadFiles) {
787  ex<<"Input file "<<m_catalog.fileNames()[iIndex].c_str() <<" could not be opened.\n";
788  ex.addContext("Opening DQM Root file");
789  throw ex;
790  }
791  return 0;
792  }
793  //Check file format version, which is encoded in the Title of the TFile
794  if(0 != strcmp(newFile->GetTitle(),"1")) {
796  ex<<"Input file "<<m_catalog.fileNames()[iIndex].c_str() <<" does not appear to be a DQM Root file.\n";
797  }
798 
799  //Get meta Data
800  TDirectory* metaDir = newFile->GetDirectory(kMetaDataDirectoryAbsolute);
801  if(0==metaDir) {
802  if(!m_skipBadFiles) {
804  ex<<"Input file "<<m_catalog.fileNames()[iIndex].c_str() <<" appears to be corrupted since it does not have the proper internal structure.\n"
805  " Check to see if the file was closed properly.\n";
806  ex.addContext("Opening DQM Root file");
807  throw ex;
808  }
809  else {return 0;}
810  }
811  m_file = newFile; //passed all tests so now we want to use this file
812  TTree* parameterSetTree = dynamic_cast<TTree*>(metaDir->Get(kParameterSetTree));
813  assert(0!=parameterSetTree);
814 
816  assert(0!=psr);
817  {
818  std::string blob;
819  std::string* pBlob = &blob;
820  parameterSetTree->SetBranchAddress(kParameterSetBranch,&pBlob);
821  for(unsigned int index = 0; index != parameterSetTree->GetEntries();++index)
822  {
823  parameterSetTree->GetEntry(index);
825  }
826  }
827 
828  {
829  TTree* processHistoryTree = dynamic_cast<TTree*>(metaDir->Get(kProcessHistoryTree));
830  assert(0!=processHistoryTree);
831  unsigned int phIndex = 0;
832  processHistoryTree->SetBranchAddress(kPHIndexBranch,&phIndex);
833  std::string processName;
834  std::string* pProcessName = &processName;
835  processHistoryTree->SetBranchAddress(kProcessConfigurationProcessNameBranch,&pProcessName);
836  std::string parameterSetIDBlob;
837  std::string* pParameterSetIDBlob = &parameterSetIDBlob;
838  processHistoryTree->SetBranchAddress(kProcessConfigurationParameterSetIDBranch,&pParameterSetIDBlob);
839  std::string releaseVersion;
840  std::string* pReleaseVersion = &releaseVersion;
841  processHistoryTree->SetBranchAddress(kProcessConfigurationReleaseVersion,&pReleaseVersion);
842  std::string passID;
843  std::string* pPassID = &passID;
844  processHistoryTree->SetBranchAddress(kProcessConfigurationPassID,&pPassID);
845 
847  std::vector<edm::ProcessConfiguration> configs;
848  configs.reserve(5);
849  m_historyIDs.clear();
850  m_reducedHistoryIDs.clear();
851  for(unsigned int i=0; i != processHistoryTree->GetEntries(); ++i) {
852  processHistoryTree->GetEntry(i);
853  if(phIndex==0) {
854  if(not configs.empty()) {
855  edm::ProcessHistory ph(configs);
856  m_historyIDs.push_back(ph.id());
857  phr.registerProcessHistory(ph);
858  m_reducedHistoryIDs.push_back(phr.reducedProcessHistoryID(ph.id()));
859  }
860  configs.clear();
861  }
862  edm::ParameterSetID psetID(parameterSetIDBlob);
863  edm::ProcessConfiguration pc(processName, psetID,releaseVersion,passID);
864  configs.push_back(pc);
865  }
866  if(not configs.empty()) {
867  edm::ProcessHistory ph(configs);
868  m_historyIDs.push_back(ph.id());
869  phr.registerProcessHistory(ph);
870  m_reducedHistoryIDs.push_back(phr.reducedProcessHistoryID(ph.id()));
871  //std::cout <<"inserted "<<ph.id()<<std::endl;
872  }
873  }
874 
875  //Setup the indices
876  TTree* indicesTree = dynamic_cast<TTree*>(m_file->Get(kIndicesTree));
877  assert(0!=indicesTree);
878 
879  m_runlumiToRange.clear();
880  m_runlumiToRange.reserve(indicesTree->GetEntries());
881  m_orderedIndices.clear();
882 
883  RunLumiToRange temp;
884  indicesTree->SetBranchAddress(kRunBranch,&temp.m_run);
885  indicesTree->SetBranchAddress(kLumiBranch,&temp.m_lumi);
886  indicesTree->SetBranchAddress(kBeginTimeBranch,&temp.m_beginTime);
887  indicesTree->SetBranchAddress(kEndTimeBranch,&temp.m_endTime);
888  indicesTree->SetBranchAddress(kProcessHistoryIndexBranch,&temp.m_historyIDIndex);
889  indicesTree->SetBranchAddress(kTypeBranch,&temp.m_type);
890  indicesTree->SetBranchAddress(kFirstIndex,&temp.m_firstIndex);
891  indicesTree->SetBranchAddress(kLastIndex,&temp.m_lastIndex);
892 
893  //Need to reorder items since if there was a merge done the same Run
894  //and/or Lumi can appear multiple times but we want to process them
895  //all at once
896 
897  //We use a std::list for m_orderedIndices since inserting into the
898  //middle of a std::list does not disrupt the iterators to already
899  //existing entries
900 
901  //The Map is used to see if a Run/Lumi pair has appeared before
902  typedef std::map<RunLumiPHIDKey, std::list<unsigned int>::iterator > RunLumiToLastEntryMap;
903  RunLumiToLastEntryMap runLumiToLastEntryMap;
904 
905  //Need to group all lumis for the same run together and move the run
906  //entry to the beginning
907  typedef std::map<RunPHIDKey, std::pair< std::list<unsigned int>::iterator, std::list<unsigned int>::iterator> > RunToFirstLastEntryMap;
908  RunToFirstLastEntryMap runToFirstLastEntryMap;
909 
910  for (Long64_t index = 0; index != indicesTree->GetEntries(); ++index)
911  {
912  indicesTree->GetEntry(index);
913 // std::cout <<"read r:"<<temp.m_run
914 // <<" l:"<<temp.m_lumi
915 // <<" b:"<<temp.m_beginTime
916 // <<" e:"<<temp.m_endTime
917 // <<" fi:" << temp.m_firstIndex
918 // <<" li:" << temp.m_lastIndex
919 // <<" type:" << temp.m_type << std::endl;
920  m_runlumiToRange.push_back(temp);
921 
922  RunLumiPHIDKey runLumi(m_reducedHistoryIDs.at(temp.m_historyIDIndex), temp.m_run, temp.m_lumi);
923  RunPHIDKey runKey(m_reducedHistoryIDs.at(temp.m_historyIDIndex), temp.m_run);
924 
925  RunLumiToLastEntryMap::iterator itFind = runLumiToLastEntryMap.find(runLumi);
926  if (itFind == runLumiToLastEntryMap.end())
927  {
928  //does not already exist
929  //does the run for this already exist?
930  std::list<unsigned int>::iterator itLastOfRun = m_orderedIndices.end();
931 
932  RunToFirstLastEntryMap::iterator itRunFirstLastEntryFind = runToFirstLastEntryMap.find(runKey);
933  bool needNewEntryInRunFirstLastEntryMap = true;
934  if (itRunFirstLastEntryFind != runToFirstLastEntryMap.end())
935  {
936  needNewEntryInRunFirstLastEntryMap=false;
937  if (temp.m_lumi!=0)
938  {
939  //lumis go to the end
940  itLastOfRun = itRunFirstLastEntryFind->second.second;
941  //we want to insert after this one so must advance the iterator
942  ++itLastOfRun;
943  }
944  else
945  {
946  //runs go at the beginning
947  itLastOfRun = itRunFirstLastEntryFind->second.first;
948  }
949  }
950  std::list<unsigned int>::iterator iter = m_orderedIndices.insert(itLastOfRun,index);
951  runLumiToLastEntryMap[runLumi]=iter;
952  if (needNewEntryInRunFirstLastEntryMap)
953  runToFirstLastEntryMap[runKey]=std::make_pair(iter,iter);
954  else
955  {
956  if(temp.m_lumi!=0)
957  {
958  //lumis go at end
959  runToFirstLastEntryMap[runKey].second = iter;
960  }
961  else
962  {
963  //since we haven't yet seen this run/lumi combination it means we haven't yet seen
964  // a run so we can put this first
965  runToFirstLastEntryMap[runKey].first = iter;
966  }
967  }
968  }
969  else
970  {
971  //We need to do a merge since the run/lumi already appeared. Put it after the existing entry
972  //std::cout <<" found a second instance of "<<runLumi.first<<" "<<runLumi.second<<" at "<<index<<std::endl;
973  std::list<unsigned int>::iterator itNext = itFind->second;
974  ++itNext;
975  std::list<unsigned int>::iterator iter = m_orderedIndices.insert(itNext,index);
976  RunToFirstLastEntryMap::iterator itRunFirstLastEntryFind = runToFirstLastEntryMap.find(runKey);
977  if (itRunFirstLastEntryFind->second.second == itFind->second)
978  {
979  //if the previous one was the last in the run, we need to update to make this one the last
980  itRunFirstLastEntryFind->second.second = iter;
981  }
982  itFind->second = iter;
983  }
984  }
987 
988  if(m_nextIndexItr != m_orderedIndices.end()) {
989  for( size_t index = 0; index < kNIndicies; ++index) {
990  m_trees[index] = dynamic_cast<TTree*>(m_file->Get(kTypeNames[index]));
991  assert(0!=m_trees[index]);
992  m_treeReaders[index]->setTree(m_trees[index]);
993  }
994  }
995  //After a file open, the framework expects to see a new 'IsRun'
997 
998  return 1;
999 }
1000 
1001 void
1002 DQMRootSource::logFileAction(char const* msg, char const* fileName) const {
1003  edm::LogAbsolute("fileAction") << std::setprecision(0) << edm::TimeOfDay() << msg << fileName;
1005 }
1006 
1007 //
1008 // const member functions
1009 //
1010 
1011 //
1012 // static member functions
1013 //
const DQMRootSource & operator=(const DQMRootSource &)
TH2S * getTH2S(void) const
TH1S * getTH1S(void) const
edm::InputSource::ItemType m_nextItemType
unsigned int m_lastSeenRun2
int i
Definition: DBlmapReader.cc:9
static const char *const kProcessHistoryTree
Definition: format.h:54
static const char *const kRunBranch
Definition: format.h:41
unsigned int lumi() const
MonitorElement * book2S(const char *name, const char *title, int nchX, double lowX, double highX, int nchY, double lowY, double highY)
Book 2S histogram.
Definition: DQMStore.cc:1023
static const char *const kTypeNames[]
Definition: format.h:28
edm::JobReport::Token m_jrToken
void readNextItemType()
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
virtual void closeFile_() override
TProfile2D * getTProfile2D(void) const
void logFileAction(char const *msg, char const *fileName) const
RunNumber_t run() const
Definition: RunID.h:43
MonitorElement * book1D(const char *name, const char *title, int nchX, double lowX, double highX)
Book 1D histogram.
Definition: DQMStore.cc:873
edm::RunAuxiliary m_runAux
void FlushMessageLog()
void reportInputRunNumber(unsigned int run)
Definition: JobReport.cc:554
std::vector< boost::shared_ptr< TreeReaderBase > > m_treeReaders
edm::ProcessHistoryID const & processHistoryID() const
MonitorElement * book3D(const char *name, const char *title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, int nchZ, double lowZ, double highZ)
Book 3D histogram.
Definition: DQMStore.cc:1135
MonitorElement * book2DD(const char *name, const char *title, int nchX, double lowX, double highX, int nchY, double lowY, double highY)
Book 2D double histogram.
Definition: DQMStore.cc:1045
static const char *const kIndicesTree
Definition: format.h:40
bool registerProcessHistory(ProcessHistory const &processHistory)
std::set< MonitorElement * > m_lumiElements
static const char *const kFirstIndex
Definition: format.h:47
TH3F * getTH3F(void) const
TH1D * getTH1D(void) const
static const char *const kLumiBranch
Definition: format.h:42
size_t m_presentlyOpenFileIndex
std::list< unsigned int >::iterator m_presentIndexItr
unsigned int m_filterOnRun
bool operator<(RunPHIDKey const &right) const
std::set< MonitorElement * > m_runElements
TH2D * getTH2D(void) const
static const char *const kFullNameBranch
Definition: format.h:34
MonitorElement * book1DD(const char *name, const char *title, int nchX, double lowX, double highX)
Book 1S histogram.
Definition: DQMStore.cc:905
void fillRunPrincipal(ProcessHistoryRegistry const &processHistoryRegistry, DelayedReader *reader=0)
Definition: RunPrincipal.cc:22
std::vector< edm::ProcessHistoryID > m_reducedHistoryIDs
MonitorElement * bookFloat(const char *name)
Book float.
Definition: DQMStore.cc:810
unsigned int run() const
Token inputFileOpened(std::string const &physicalFileName, std::string const &logicalFileName, std::string const &catalog, std::string const &inputType, std::string const &inputSourceClassName, std::string const &moduleLabel, std::string const &guid, std::vector< std::string > const &branchNames)
Definition: JobReport.cc:393
void Fill(long long x)
void tag(MonitorElement *me, unsigned int myTag)
Definition: DQMStore.cc:1510
virtual boost::shared_ptr< edm::LuminosityBlockAuxiliary > readLuminosityBlockAuxiliary_() override
Definition: ME.h:11
static const char *const kPHIndexBranch
Definition: format.h:55
static const char *const kParameterSetBranch
Definition: format.h:62
virtual edm::InputSource::ItemType getNextItemType() override
void fillLuminosityBlockPrincipal(ProcessHistoryRegistry const &processHistoryRegistry, DelayedReader *reader=0)
std::vector< RunLumiToRange > m_runlumiToRange
void addDefault(ParameterSetDescription const &psetDescription)
edm::LuminosityBlockAuxiliary m_lumiAux
#define DEFINE_FWK_INPUT_SOURCE(type)
std::vector< edm::ProcessHistoryID > m_historyIDs
edm::ProcessHistoryID const & processHistoryID() const
MonitorElement * bookString(const char *name, const char *value)
Book string.
Definition: DQMStore.cc:839
edm::ProcessHistoryID processHistoryID_
void reportInputLumiSection(unsigned int run, unsigned int lumiSectId)
Definition: JobReport.cc:544
bool m_justOpenedFileSoNeedToGenerateRunTransition
virtual ~DQMRootSource()
edm::InputFileCatalog m_catalog
edm::ProcessHistoryID m_lastSeenReducedPHID2
static const char *const kParameterSetTree
Definition: format.h:61
std::list< unsigned int > m_orderedIndices
RunNumber_t run() const
static const char *const kFlagBranch
Definition: format.h:35
static const char *const kTypeBranch
Definition: format.h:46
std::auto_ptr< TFile > m_file
ProcessHistoryID const & reducedProcessHistoryID(ProcessHistoryID const &fullID) const
static const char *const kProcessHistoryIndexBranch
Definition: format.h:43
MonitorElement * bookProfile(const char *name, const char *title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, const char *option="s")
Definition: DQMStore.cc:1187
void setProcessHistoryID(ProcessHistoryID const &phid)
static const char *const kEndTimeBranch
Definition: format.h:45
std::vector< std::string > const & logicalFileNames() const
virtual boost::shared_ptr< edm::RunAuxiliary > readRunAuxiliary_() override
MonitorElement * get(const std::string &path) const
get ME from full pathname (e.g. &quot;my/long/dir/my_histo&quot;)
Definition: DQMStore.cc:1624
virtual std::unique_ptr< edm::FileBlock > readFile_() override
const std::string getFullname(void) const
get full name of ME including Pathname
std::vector< TTree * > m_trees
unsigned int run() const
std::size_t Token
Definition: JobReport.h:105
static const char *const kProcessConfigurationPassID
Definition: format.h:59
RunID const & id() const
Definition: RunPrincipal.h:69
static void registerFromString(std::string const &rep)
Definition: ParameterSet.cc:95
static const char *const kMetaDataDirectoryAbsolute
Definition: format.h:51
std::vector< std::string > const & fileNames() const
unsigned int m_lastSeenLumi2
static const char *const kLastIndex
Definition: format.h:48
int64_t getIntValue(void) const
bool operator<(RunLumiPHIDKey const &right) const
TH1F * getTH1F(void) const
LuminosityBlockNumber_t luminosityBlock() const
static const char *const kProcessConfigurationReleaseVersion
Definition: format.h:58
void addContext(std::string const &context)
Definition: Exception.cc:227
virtual void readRun_(edm::RunPrincipal &rpCache) override
ProcessHistoryRegistry & processHistoryRegistryForUpdate()
Non-const accessor for process history registry.
Definition: InputSource.h:173
static const char *const kProcessConfigurationProcessNameBranch
Definition: format.h:56
edm::ProcessHistoryID m_lastSeenReducedPHID
static const char *const kBeginTimeBranch
Definition: format.h:44
TProfile * getTProfile(void) const
RunPHIDKey(edm::ProcessHistoryID const &phid, unsigned int run)
ProcessHistoryRegistry & processHistoryRegistryUpdate() const
Definition: InputSource.h:344
RunLumiPHIDKey(edm::ProcessHistoryID const &phid, unsigned int run, unsigned int lumi)
std::list< unsigned int >::iterator m_nextIndexItr
void setProcessHistoryID(ProcessHistoryID const &phid)
Definition: RunAuxiliary.h:36
DQMRootSource(edm::ParameterSet const &, const edm::InputSourceDescription &)
volatile std::atomic< bool > shutdown_flag false
void setLumiFlag(void)
this ME is meant to be stored for each luminosity section
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
TH2F * getTH2F(void) const
MonitorElement * bookInt(const char *name)
Book int.
Definition: DQMStore.cc:780
MonitorElement * book2D(const char *name, const char *title, int nchX, double lowX, double highX, int nchY, double lowY, double highY)
Book 2D histogram.
Definition: DQMStore.cc:1001
virtual void readEvent_(edm::EventPrincipal &) override
long double T
virtual void readLuminosityBlock_(edm::LuminosityBlockPrincipal &lbCache) override
ProcessHistoryID id() const
unsigned int m_lastSeenRun
void inputFileClosed(InputType inputType, Token fileToken)
Definition: JobReport.cc:453
edm::ProcessHistoryID processHistoryID_
MonitorElement * book1S(const char *name, const char *title, int nchX, double lowX, double highX)
Book 1S histogram.
Definition: DQMStore.cc:889
void setCurrentFolder(const std::string &fullpath)
Definition: DQMStore.cc:585
static Registry * instance()
Definition: Registry.cc:14
Helper class to handle FWLite file input sources.
static const char *const kValueBranch
Definition: format.h:36
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger list("!*","!HLTx*"if it matches 2 triggers or more) will accept the event if all the matching triggers are FAIL.It will reject the event if any of the triggers are PASS or EXCEPTION(this matches the behavior of"!*"before the partial wildcard feature was incorporated).Triggers which are in the READY state are completely ignored.(READY should never be returned since the trigger paths have been run
static const char *const kProcessConfigurationParameterSetIDBranch
Definition: format.h:57
bool setupFile(unsigned int iIndex)
MonitorElement * bookProfile2D(const char *name, const char *title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, int nchZ, double lowZ, double highZ, const char *option="s")
Definition: DQMStore.cc:1331