CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
DQMFileSaver.cc
Go to the documentation of this file.
12 #include <sys/stat.h>
13 #include <unistd.h>
14 #include <iostream>
15 #include <vector>
16 #include <string>
17 #include <TString.h>
18 #include <TSystem.h>
19 
20 //--------------------------------------------------------
21 static void
23 {
24  value = ps.getUntrackedParameter<int>(name, value);
25  if (value < 1 && value != -1)
26  throw cms::Exception("DQMFileSaver")
27  << "Invalid '" << name << "' parameter '" << value
28  << "'. Must be -1 or >= 1.";
29 }
30 
31 void
33 {
34 
35  char suffix[64];
36  sprintf(suffix, "R%09d", run);
37 
38  char rewrite[128];
39  if (lumi == 0) // save for run
40  sprintf(rewrite, "\\1Run %d/\\2/Run summary", run);
41  else
42  sprintf(rewrite, "\\1Run %d/\\2/By Lumi Section %d-%d", irun_, ilumi_, ilumi_);
43 
44  size_t pos = 0;
45  std::string wflow;
46  wflow.reserve(workflow.size() + 3);
47  wflow = workflow;
48  while ((pos = wflow.find('/', pos)) != std::string::npos)
49  wflow.replace(pos++, 1, "__");
50 
51  std::string filename = fileBaseName_ + suffix + wflow + ".root";
52 
53  if (lumi == 0) // save for run
54  {
55  // set run end flag
56  dbe_->cd();
57  dbe_->setCurrentFolder("Info/ProvInfo");
58 
59  // do this, because ProvInfo is not yet run in offline DQM
60  MonitorElement* me = dbe_->get("Info/ProvInfo/CMSSW");
61  if (!me) me = dbe_->bookString("CMSSW",edm::getReleaseVersion().c_str() );
62 
63  me = dbe_->get("Info/ProvInfo/runIsComplete");
64  if (!me) me = dbe_->bookFloat("runIsComplete");
65 
66  if (me)
67  {
68  if (runIsComplete_)
69  me->Fill(1.);
70  else
71  me->Fill(0.);
72  }
73 
74  dbe_->save(filename,
75  "",
76  "^(Reference/)?([^/]+)",
77  rewrite,
80  fileUpdate_);
81  }
82  else // save EventInfo folders for luminosity sections
83  {
84  std::vector<std::string> systems = (dbe_->cd(), dbe_->getSubdirs());
85 
86  std::cout << " DQMFileSaver: storing EventInfo folders for Run: "
87  << irun_ << ", Lumi Section: " << ilumi_ << ", Subsystems: " ;
88 
89  for (size_t i = 0, e = systems.size(); i != e; ++i) {
90  if (systems[i] != "Reference") {
91  dbe_->cd();
92  std::cout << systems[i] << " " ;
93  dbe_->save(filename,
94  systems[i]+"/EventInfo", "^(Reference/)?([^/]+)", rewrite,
97  fileUpdate_);
98  // from now on update newly created file
99  if (fileUpdate_=="RECREATE") fileUpdate_="UPDATE";
100  }
101  }
102  std::cout << "\n";
103  }
104 
105  if (pastSavedFiles_.size() == 0)
106  {
107  // save JobReport upon creation of file (once per job)
108  saveJobReport(filename);
109  pastSavedFiles_.push_back(filename);
110  }
111 
112 }
113 
114 static void
115 doSaveForOnline(std::list<std::string> &pastSavedFiles,
116  size_t numKeepSavedFiles,
117  DQMStore *store,
118  const std::string &filename,
119  const std::string &directory,
120  const std::string &rxpat,
121  const std::string &rewrite,
123  int saveRefQMin)
124 {
125  store->save(filename, directory , rxpat,
126  rewrite, saveref, saveRefQMin);
127  pastSavedFiles.push_back(filename);
128  if (pastSavedFiles.size() > numKeepSavedFiles)
129  {
130  remove(pastSavedFiles.front().c_str());
131  pastSavedFiles.pop_front();
132  }
133 }
134 
135 void
137 {
138  std::vector<std::string> systems = (dbe_->cd(), dbe_->getSubdirs());
139 
140  for (size_t i = 0, e = systems.size(); i != e; ++i)
141  {
142  if (systems[i] != "Reference")
143  {
144  dbe_->cd();
145  if (MonitorElement* me = dbe_->get(systems[i] + "/EventInfo/processName"))
146  {
148  fileBaseName_ + me->getStringValue() + suffix + ".root",
149  "", "^(Reference/)?([^/]+)", rewrite,
152  return;
153  }
154  }
155  }
156 
157  // look for EventInfo folder in an unorthodox location
158  for (size_t i = 0, e = systems.size(); i != e; ++i)
159  if (systems[i] != "Reference")
160  {
161  dbe_->cd();
162  std::vector<MonitorElement*> pNamesVector = dbe_->getMatchingContents("^" + systems[i] + "/.*/EventInfo/processName",lat::Regexp::Perl);
163  if (pNamesVector.size() > 0){
165  fileBaseName_ + systems[i] + suffix + ".root",
166  "", "^(Reference/)?([^/]+)", rewrite,
169  pNamesVector.clear();
170  return;
171  }
172  }
173 
174  // if no EventInfo Folder is found, then store subsystem wise
175  for (size_t i = 0, e = systems.size(); i != e; ++i)
176  if (systems[i] != "Reference")
178  fileBaseName_ + systems[i] + suffix + ".root",
179  systems[i], "^(Reference/)?([^/]+)", rewrite,
182 }
183 
184 void
186 {
187 
188  // Report the file to job report service.
190  if (jr.isAvailable())
191  {
192  std::map<std::string, std::string> info;
193  info["Source"] = "DQMStore";
194  info["FileClass"] = "DQM";
195  jr->reportAnalysisFile(filename, info);
196  }
197 
198 }
199 
200 //--------------------------------------------------------
202  : convention_ (Offline),
203  workflow_ (""),
204  producer_ ("DQM"),
205  dirName_ ("."),
206  version_ (1),
207  runIsComplete_ (false),
208  saveByLumiSection_ (-1),
209  saveByEvent_ (-1),
210  saveByMinute_ (-1),
211  saveByTime_ (-1),
212  saveByRun_ (1),
213  saveAtJobEnd_ (false),
214  saveReference_ (DQMStore::SaveWithReference),
215  saveReferenceQMin_ (dqm::qstatus::STATUS_OK),
216  forceRunNumber_ (-1),
217  fileBaseName_ (""),
218  fileUpdate_ ("RECREATE"),
219  dbe_ (&*edm::Service<DQMStore>()),
220  irun_ (-1),
221  ilumi_ (-1),
222  ilumiprev_ (-1),
223  ievent_ (-1),
224  nrun_ (0),
225  nlumi_ (0),
226  nevent_ (0),
227  numKeepSavedFiles_ (5)
228 {
229  // Determine the file saving convention, and adjust defaults accordingly.
230  std::string convention = ps.getUntrackedParameter<std::string>("convention", "Offline");
231  if (convention == "Offline")
233  else if (convention == "Online")
235  else
236  throw cms::Exception("DQMFileSaver")
237  << "Invalid 'convention' parameter '" << convention << "'."
238  << " Expected one of 'Online' or 'Offline'.";
239 
240  // If this isn't online convention, check workflow.
241  if (convention_ != Online)
242  {
244  if (workflow_.empty()
245  || workflow_[0] != '/'
246  || *workflow_.rbegin() == '/'
247  || std::count(workflow_.begin(), workflow_.end(), '/') != 3
248  || workflow_.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
249  "abcdefghijklmnopqrstuvwxyz"
250  "0123456789"
251  "-_/") != std::string::npos)
252  throw cms::Exception("DQMFileSaver")
253  << "Invalid 'workflow' parameter '" << workflow_
254  << "'. Expected '/A/B/C'.";
255  }
256  else if (! ps.getUntrackedParameter<std::string>("workflow", "").empty())
257  throw cms::Exception("DQMFileSaver")
258  << "The 'workflow' parameter must be empty in 'Online' convention.";
259  else // for online set parameters
260  {
261  workflow_="/Global/Online/P5";
262  }
263 
264  // Allow file producer to be set to specific values in certain conditions.
266  if (convention_ == Online
267  && producer_ != "DQM"
268  && producer_ != "HLTDQM"
269  && producer_ != "Playback")
270  {
271  throw cms::Exception("DQMFileSaver")
272  << "Invalid 'producer' parameter '" << producer_
273  << "'. Expected 'DQM', 'HLTDQM' or 'Playback'.";
274  }
275  else if (convention_ != Online && producer_ != "DQM")
276  {
277  throw cms::Exception("DQMFileSaver")
278  << "Invalid 'producer' parameter '" << producer_
279  << "'. Expected 'DQM'.";
280  }
281 
282  // version number to be used in filename
283  version_ = ps.getUntrackedParameter<int>("version", version_);
284  // flag to signal that file contains data from complete run
285  runIsComplete_ = ps.getUntrackedParameter<bool>("runIsComplete", runIsComplete_);
286 
287  // Check how we should save the references.
288  std::string refsave = ps.getUntrackedParameter<std::string>("referenceHandling", "default");
289  if (refsave == "default")
290  ;
291  else if (refsave == "skip")
292  {
294  // std::cout << "skip saving all references" << std::endl;
295  }
296  else if (refsave == "all")
297  {
299  // std::cout << "saving all references" << std::endl;
300  }
301  else if (refsave == "qtests")
302  {
304  // std::cout << "saving qtest references" << std::endl;
305  }
306  else
307  throw cms::Exception("DQMFileSaver")
308  << "Invalid 'referenceHandling' parameter '" << refsave
309  << "'. Expected 'default', 'skip', 'all' or 'qtests'.";
310 
311  // Check minimum required quality test result for which reference is saved.
312  saveReferenceQMin_ = ps.getUntrackedParameter<int>("referenceRequireStatus", saveReferenceQMin_);
313 
314  // Get and check the output directory.
315  struct stat s;
317  if (dirName_.empty() || stat(dirName_.c_str(), &s) == -1)
318  throw cms::Exception("DQMFileSaver")
319  << "Invalid 'dirName' parameter '" << dirName_ << "'.";
320 
321  // Find out when and how to save files. The following contraints apply:
322  // - For online, allow files to be saved at event and time intervals.
323  // - For online and offline, allow files to be saved per run, lumi and job end
324  // - For offline allow run number to be overridden (for mc data).
325  if (convention_ == Online)
326  {
327  getAnInt(ps, saveByEvent_, "saveByEvent");
328  getAnInt(ps, saveByMinute_, "saveByMinute");
329  getAnInt(ps, saveByTime_, "saveByTime");
330  getAnInt(ps, numKeepSavedFiles_, "maxSavedFilesCount");
331  }
332 
333  if (convention_ == Online || convention_ == Offline)
334  {
335  getAnInt(ps, saveByRun_, "saveByRun");
336  getAnInt(ps, saveByLumiSection_, "saveByLumiSection");
337  }
338 
339  if (convention_ != Online)
340  {
341  getAnInt(ps, forceRunNumber_, "forceRunNumber");
342  saveAtJobEnd_ = ps.getUntrackedParameter<bool>("saveAtJobEnd", saveAtJobEnd_);
343  }
344 
345  if (saveAtJobEnd_ && forceRunNumber_ < 1)
346  throw cms::Exception("DQMFileSaver")
347  << "If saving at the end of the job, the run number must be"
348  << " overridden to a specific value using 'forceRunNumber'.";
349 
350 
351  // Set up base file name and determine the start time.
352  char version[8];
353  sprintf(version, "_V%04d_", int(version_));
354  version[7]='\0';
355  fileBaseName_ = dirName_ + "/" + producer_ + version;
356  gettimeofday(&start_, 0);
357  saved_ = start_;
358 
359  // Log some information what we will do.
360  edm::LogInfo("DQMFileSaver")
361  << "DQM file saving settings:\n"
362  << " using base file name '" << fileBaseName_ << "'\n"
363  << " forcing run number " << forceRunNumber_ << "\n"
364  << " saving every " << saveByLumiSection_ << " lumi section(s)\n"
365  << " saving every " << saveByEvent_ << " event(s)\n"
366  << " saving every " << saveByMinute_ << " minute(s)\n"
367  << " saving every 2^n*" << saveByTime_ << " minutes \n"
368  << " saving every " << saveByRun_ << " run(s)\n"
369  << " saving at job end: " << (saveAtJobEnd_ ? "yes" : "no") << "\n"
370  << " keeping at most " << numKeepSavedFiles_ << " files\n";
371 }
372 
373 //--------------------------------------------------------
374 void
376 {
377  irun_ = ilumi_ = ilumiprev_ = ievent_ = -1;
378  nrun_ = nlumi_ = nevent_ = 0;
379 }
380 
381 void
383 {
384  irun_ = (forceRunNumber_ == -1 ? r.id().run() : forceRunNumber_);
385  ++nrun_;
386 }
387 
388 void
390 {
391  ilumi_ = l.id().luminosityBlock();
392  if (ilumiprev_ == -1) ilumiprev_ = ilumi_;
393  ++nlumi_;
394 }
395 
397 {
398  ++nevent_;
399 
400  ievent_ = e.id().event();
401 
402  // Check if we should save for this event.
403  char suffix[64];
404  if (ievent_ > 0 && saveByEvent_ > 0 && nevent_ == saveByEvent_)
405  {
406  if (convention_ != Online)
407  throw cms::Exception("DQMFileSaver")
408  << "Internal error, can save files by event"
409  << " only in Online mode.";
410 
411  sprintf(suffix, "_R%09d_E%08d", irun_, ievent_);
412  saveForOnline(suffix, "\\1\\2");
413  nevent_ = 0;
414  }
415 
416  // Check if we should save due to elapsed time.
417  if ( ievent_ > 0 && ( saveByMinute_ > 0 || saveByTime_ > 0 ) )
418  {
419  if (convention_ != Online)
420  throw cms::Exception("DQMFileSaver")
421  << "Internal error, can save files by time"
422  << " only in Online mode.";
423 
424  // Compute elapsed time in minutes.
425  struct timeval tv;
426  gettimeofday(&tv, 0);
427 
428  double totalelapsed = ((tv.tv_sec + tv.tv_usec*1e-6)
429  - (start_.tv_sec + start_.tv_usec*1e-6)) / 60;
430  double elapsed = ((tv.tv_sec + tv.tv_usec*1e-6)
431  - (saved_.tv_sec + saved_.tv_usec*1e-6)) / 60;
432 
433  // Save if enough time has elapsed since the last save.
434  if ( (saveByMinute_ > 0 && elapsed > saveByMinute_ ) ||
435  (saveByTime_ > 0 && totalelapsed > saveByTime_ ) )
436  {
437  if ( saveByTime_ > 0 ) saveByTime_ *= 2;
438  saved_ = tv;
439  sprintf(suffix, "_R%09d_T%08d", irun_, int(totalelapsed));
440  char rewrite[64]; sprintf(rewrite, "\\1Run %d/\\2/Run summary", irun_);
441  saveForOnline(suffix, rewrite);
442  }
443  }
444 }
445 
446 void
448 {
449 
450  if (ilumi_ > 0 && saveByLumiSection_ > 0 )
451  {
452  if (convention_ != Online && convention_ != Offline )
453  throw cms::Exception("DQMFileSaver")
454  << "Internal error, can save files at end of lumi block"
455  << " only in Online or Offline mode.";
456 
457  if (convention_ == Online && nlumi_ == saveByLumiSection_) // insist on lumi section ordering
458  {
459  char suffix[64];
460  char rewrite[128];
461  sprintf(suffix, "_R%09d_L%06d", irun_, ilumi_);
462  sprintf(rewrite, "\\1Run %d/\\2/By Lumi Section %d-%d", irun_, ilumiprev_, ilumi_);
463  saveForOnline(suffix, rewrite);
464  ilumiprev_ = -1;
465  nlumi_ = 0;
466  }
467  if (convention_ == Offline)
469  }
470 }
471 
472 void
474 {
475  if (irun_ > 0 && saveByRun_ > 0 && nrun_ == saveByRun_)
476  {
477  if (convention_ == Online)
478  {
479  char suffix[64]; sprintf(suffix, "_R%09d", irun_);
480  char rewrite[64]; sprintf(rewrite, "\\1Run %d/\\2/Run summary", irun_);
481  saveForOnline(suffix, rewrite);
482  }
483  else if (convention_ == Offline)
485  else
486  throw cms::Exception("DQMFileSaver")
487  << "Internal error. Can only save files in endRun()"
488  << " in Online and Offline modes.";
489 
490  nrun_ = 0;
491  }
492 }
493 
494 void
496 {
497  if (saveAtJobEnd_)
498  {
499  if (convention_ == Offline && forceRunNumber_ > 0)
501  else
502  throw cms::Exception("DQMFileSaver")
503  << "Internal error. Can only save files at the end of the"
504  << " job in Offline mode with run number overridden.";
505  }
506 
507 }
LuminosityBlockID id() const
EventNumber_t event() const
Definition: EventID.h:44
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
DQMFileSaver(const edm::ParameterSet &ps)
int forceRunNumber_
Definition: DQMFileSaver.h:50
int saveReferenceQMin_
Definition: DQMFileSaver.h:49
RunID const & id() const
Definition: RunBase.h:41
std::vector< std::string > getSubdirs(void) const
Definition: DQMStore.cc:1424
virtual void beginRun(const edm::Run &, const edm::EventSetup &)
RunNumber_t run() const
Definition: RunID.h:44
std::string fileUpdate_
Definition: DQMFileSaver.h:53
void saveForOnline(const std::string &suffix, const std::string &rewrite)
Convention convention_
Definition: DQMFileSaver.h:35
void cd(void)
go to top directory (ie. root)
Definition: DQMStore.cc:411
tuple lumi
Definition: fjr2json.py:35
void save(const std::string &filename, const std::string &path="", const std::string &pattern="", const std::string &rewrite="", SaveReferenceTag ref=SaveWithReference, int minStatus=dqm::qstatus::STATUS_OK, const std::string &fileupdate="RECREATE")
Definition: DQMStore.cc:2118
void reportAnalysisFile(std::string const &fileName, std::map< std::string, std::string > const &fileData)
Definition: JobReport.cc:685
std::list< std::string > pastSavedFiles_
Definition: DQMFileSaver.h:68
std::vector< MonitorElement * > getMatchingContents(const std::string &pattern, lat::Regexp::Syntax syntaxType=lat::Regexp::Wildcard) const
Definition: DQMStore.cc:1696
DQMStore * dbe_
Definition: DQMFileSaver.h:55
std::string dirName_
Definition: DQMFileSaver.h:38
void saveJobReport(const std::string &filename)
std::string fileBaseName_
Definition: DQMFileSaver.h:52
static void doSaveForOnline(std::list< std::string > &pastSavedFiles, size_t numKeepSavedFiles, DQMStore *store, const std::string &filename, const std::string &directory, const std::string &rxpat, const std::string &rewrite, DQMStore::SaveReferenceTag saveref, int saveRefQMin)
MonitorElement * bookFloat(const char *name)
Book float.
Definition: DQMStore.cc:659
SaveReferenceTag
Definition: DQMStore.h:70
void Fill(long long x)
virtual void beginLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &)
int saveByLumiSection_
Definition: DQMFileSaver.h:42
static void getAnInt(const edm::ParameterSet &ps, int &value, const std::string &name)
Definition: DQMFileSaver.cc:22
MonitorElement * bookString(const char *name, const char *value)
Book string.
Definition: DQMStore.cc:688
bool isAvailable() const
Definition: Service.h:47
bool runIsComplete_
Definition: DQMFileSaver.h:40
MonitorElement * get(const std::string &path) const
get ME from full pathname (e.g. &quot;my/long/dir/my_histo&quot;)
Definition: DQMStore.cc:1473
timeval start_
Definition: DQMFileSaver.h:64
DQMStore * dbe_
std::string workflow_
Definition: DQMFileSaver.h:36
std::string getReleaseVersion()
std::string producer_
Definition: DQMFileSaver.h:37
int saveReference_
Definition: DQMFileSaver.h:48
LuminosityBlockNumber_t luminosityBlock() const
virtual void endLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &)
edm::EventID id() const
Definition: EventBase.h:56
bool saveAtJobEnd_
Definition: DQMFileSaver.h:47
void saveForOffline(const std::string &workflow, int run, int lumi)
Definition: DQMFileSaver.cc:32
virtual void analyze(const edm::Event &e, const edm::EventSetup &)
tuple filename
Definition: lut2db_cfg.py:20
timeval saved_
Definition: DQMFileSaver.h:65
static const int STATUS_OK
virtual void endRun(const edm::Run &, const edm::EventSetup &)
tuple cout
Definition: gather_cfg.py:121
virtual void beginJob(void)
virtual void endJob(void)
void setCurrentFolder(const std::string &fullpath)
Definition: DQMStore.cc:434
Definition: Run.h:36
int numKeepSavedFiles_
Definition: DQMFileSaver.h:67