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