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 
15 
16 #include <sys/stat.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19 #include <iostream>
20 #include <vector>
21 #include <string>
22 #include <fstream>
23 #include <utility>
24 #include <TString.h>
25 #include <TSystem.h>
26 
27 #include <boost/property_tree/json_parser.hpp>
28 #include <boost/property_tree/ptree.hpp>
29 #include <boost/filesystem.hpp>
30 #include <boost/format.hpp>
31 
32 //--------------------------------------------------------
34 const std::string DQMFileSaver::streamSuffix_("Histograms");
35 
36 //--------------------------------------------------------
37 static void
39 {
40  value = ps.getUntrackedParameter<int>(name, value);
41  if (value < 1 && value != -1)
42  throw cms::Exception("DQMFileSaver")
43  << "Invalid '" << name << "' parameter '" << value
44  << "'. Must be -1 or >= 1.";
45 }
46 
47 static std::string
49 {
50  std::string extension;
51  if (fileFormat == DQMFileSaver::ROOT)
52  extension = ".root";
53  else if (fileFormat == DQMFileSaver::PB)
54  extension = ".pb";
55  return extension;
56 }
57 
58 static std::string
59 onlineOfflineFileName(const std::string &fileBaseName,
60  const std::string &suffix,
61  const std::string &workflow,
62  const std::string &child,
63  DQMFileSaver::FileFormat fileFormat)
64 {
65  size_t pos = 0;
66  std::string wflow;
67  wflow.reserve(workflow.size() + 3);
68  wflow = workflow;
69  while ((pos = wflow.find('/', pos)) != std::string::npos)
70  wflow.replace(pos++, 1, "__");
71 
72  std::string filename = fileBaseName + suffix + wflow + child + dataFileExtension(fileFormat);
73  return filename;
74 }
75 
76 void
78 {
79  char suffix[64];
80  sprintf(suffix, "R%09d", run);
82  dbe_->savePB(filename, filterName_);
83 }
84 
85 void
87 {
88  char suffix[64];
89  sprintf(suffix, "R%09d", run);
90 
91  char rewrite[128];
92  if (lumi == 0) // save for run
93  sprintf(rewrite, "\\1Run %d/\\2/Run summary", run);
94  else
95  sprintf(rewrite, "\\1Run %d/\\2/By Lumi Section %d-%d", run, lumi, lumi);
96 
98 
99  if (lumi == 0) // save for run
100  {
101  dbe_->save(filename,
102  "",
103  "^(Reference/)?([^/]+)",
104  rewrite,
105  enableMultiThread_ ? run : 0,
106  lumi,
109  fileUpdate_ ? "UPDATE" : "RECREATE");
110  }
111  else // save EventInfo folders for luminosity sections
112  {
113  std::vector<std::string> systems = (dbe_->cd(), dbe_->getSubdirs());
114 
115  edm::LogAbsolute msg("fileAction");
116  msg << "DQMFileSaver: storing EventInfo folders for Run: "
117  << run << ", Lumi Section: " << lumi << ", Subsystems: " ;
118 
119  for (size_t i = 0, e = systems.size(); i != e; ++i) {
120  if (systems[i] != "Reference") {
121  dbe_->cd();
122  msg << systems[i] << " " ;
123 
124  dbe_->save(filename,
125  systems[i]+"/EventInfo", "^(Reference/)?([^/]+)",
126  rewrite,
127  enableMultiThread_ ? run : 0,
128  lumi,
131  fileUpdate_ ? "UPDATE" : "RECREATE");
132 
133  // from now on update newly created file
134  if (fileUpdate_.load() == 0) fileUpdate_ = 1;
135  }
136  }
137  }
138 }
139 
140 static void
142  int run,
143  bool enableMultiThread,
144  const std::string &filename,
145  const std::string &directory,
146  const std::string &rxpat,
147  const std::string &rewrite,
149  int saveRefQMin,
150  const std::string &filterName,
151  DQMFileSaver::FileFormat fileFormat)
152 {
153  // TODO(rovere): fix the online case. so far we simply rely on the
154  // fact that we assume we will not run multithreaded in online.
155  if (fileFormat == DQMFileSaver::ROOT)
156  store->save(filename,
157  directory,
158  rxpat,
159  rewrite,
160  enableMultiThread ? run : 0,
161  0,
162  saveref,
163  saveRefQMin);
164  else if (fileFormat == DQMFileSaver::PB)
165  store->savePB(filename,
166  filterName,
167  enableMultiThread ? run : 0);
168 }
169 
170 void
172 {
173  // The file name contains the Online workflow name,
174  // as we do not want to look inside the DQMStore,
175  // and the @a suffix, defined in the run/lumi transitions.
176  // TODO(diguida): add the possibility to change the dir structure with rewrite.
179  filename,
180  "", "^(Reference/)?([^/]+)", "\\1\\2",
183  filterName_,
184  PB);
185 }
186 
187 void
189 {
190  std::vector<std::string> systems = (dbe_->cd(), dbe_->getSubdirs());
191 
192  for (size_t i = 0, e = systems.size(); i != e; ++i)
193  {
194  if (systems[i] != "Reference")
195  {
196  dbe_->cd();
197  if (MonitorElement* me = dbe_->get(systems[i] + "/EventInfo/processName"))
198  {
200  fileBaseName_ + me->getStringValue() + suffix + child_ + ".root",
201  "", "^(Reference/)?([^/]+)", rewrite,
204  "", ROOT);
205  return;
206  }
207  }
208  }
209 
210  // look for EventInfo folder in an unorthodox location
211  for (size_t i = 0, e = systems.size(); i != e; ++i)
212  if (systems[i] != "Reference")
213  {
214  dbe_->cd();
215  std::vector<MonitorElement*> pNamesVector = dbe_->getMatchingContents("^" + systems[i] + "/.*/EventInfo/processName",lat::Regexp::Perl);
216  if (pNamesVector.size() > 0){
218  fileBaseName_ + systems[i] + suffix + child_ + ".root",
219  "", "^(Reference/)?([^/]+)", rewrite,
222  "", ROOT);
223  pNamesVector.clear();
224  return;
225  }
226  }
227 
228  // if no EventInfo Folder is found, then store subsystem wise
229  for (size_t i = 0, e = systems.size(); i != e; ++i)
230  if (systems[i] != "Reference")
232  fileBaseName_ + systems[i] + suffix + child_ + ".root",
233  systems[i], "^(Reference/)?([^/]+)", rewrite,
236  "", ROOT);
237 }
238 
239 
240 boost::property_tree::ptree
241 DQMFileSaver::fillJson(int run, int lumi, const std::string& dataFilePathName, evf::FastMonitoringService *fms)
242 {
243  namespace bpt = boost::property_tree;
244  namespace bfs = boost::filesystem;
245 
246  bpt::ptree pt;
247 
248  int hostnameReturn;
249  char host[32];
250  hostnameReturn = gethostname(host ,sizeof(host));
251  if (hostnameReturn == -1)
252  throw cms::Exception("fillJson")
253  << "Internal error, cannot get host name";
254 
255  int pid = getpid();
256  std::ostringstream oss_pid;
257  oss_pid << pid;
258 
259  // Stat the data file: if not there, throw
260  struct stat dataFileStat;
261  if (stat(dataFilePathName.c_str(), &dataFileStat) != 0)
262  throw cms::Exception("fillJson")
263  << "Internal error, cannot get data file: "
264  << dataFilePathName;
265  // Extract only the data file name from the full path
266  std::string dataFileName = bfs::path(dataFilePathName).filename().string();
267  // The availability test of the FastMonitoringService was done in the ctor.
268  bpt::ptree data;
269  bpt::ptree processedEvents, acceptedEvents, errorEvents, bitmask, fileList, fileSize, inputFiles, fileAdler32;
270 
271  processedEvents.put("", fms ? (fms->getEventsProcessedForLumi(lumi)) : -1); // Processed events
272  acceptedEvents.put("", fms ? (fms->getEventsProcessedForLumi(lumi)) : -1); // Accepted events, same as processed for our purposes
273 
274  errorEvents.put("", 0); // Error events
275  bitmask.put("", 0); // Bitmask of abs of CMSSW return code
276  fileList.put("", dataFileName); // Data file the information refers to
277  fileSize.put("", dataFileStat.st_size); // Size in bytes of the data file
278  inputFiles.put("", ""); // We do not care about input files!
279  fileAdler32.put("", -1); // placeholder to match output json definition
280 
281  data.push_back(std::make_pair("", processedEvents));
282  data.push_back(std::make_pair("", acceptedEvents));
283  data.push_back(std::make_pair("", errorEvents));
284  data.push_back(std::make_pair("", bitmask));
285  data.push_back(std::make_pair("", fileList));
286  data.push_back(std::make_pair("", fileSize));
287  data.push_back(std::make_pair("", inputFiles));
288  data.push_back(std::make_pair("", fileAdler32));
289 
290  pt.add_child("data", data);
291 
292  if (fms == nullptr) {
293  pt.put("definition", "/fakeDefinition.jsn");
294  } else {
295  // The availability test of the EvFDaqDirector Service was done in the ctor.
296  bfs::path outJsonDefName(edm::Service<evf::EvFDaqDirector>()->baseRunDir()); //we assume this file is written bu the EvF Output module
297  outJsonDefName /= (std::string("output_") + oss_pid.str() + std::string(".jsd"));
298  pt.put("definition", outJsonDefName.string());
299  }
300 
301  char sourceInfo[64]; //host and pid information
302  sprintf(sourceInfo, "%s_%d", host, pid);
303  pt.put("source", sourceInfo);
304 
305  return pt;
306 }
307 
308 void
309 DQMFileSaver::saveForFilterUnit(const std::string& rewrite, int run, int lumi, const DQMFileSaver::FileFormat fileFormat) const
310 {
311  // get from DAQ2 services where to store the files according to their format
312  namespace bpt = boost::property_tree;
313 
314  std::string openJsonFilePathName;
315  std::string jsonFilePathName;
316  std::string openHistoFilePathName;
317  std::string histoFilePathName;
318 
319  // create the files names
320  if (fakeFilterUnitMode_) {
321  std::string runDir = str(boost::format("%s/run%06d") % dirName_ % run);
322  std::string baseName = str(boost::format("%s/run%06d_ls%04d_%s") % runDir % run % lumi % stream_label_ );
323 
324  boost::filesystem::create_directories(runDir);
325 
326  jsonFilePathName = baseName + ".jsn";
327  openJsonFilePathName = jsonFilePathName + ".open";
328 
329  histoFilePathName = baseName + dataFileExtension(fileFormat);
330  openHistoFilePathName = histoFilePathName + ".open";
331  } else {
332  openJsonFilePathName = edm::Service<evf::EvFDaqDirector>()->getOpenOutputJsonFilePath(lumi, stream_label_);
333  jsonFilePathName = edm::Service<evf::EvFDaqDirector>()->getOutputJsonFilePath(lumi, stream_label_);
334 
335  if (fileFormat == ROOT) {
336  openHistoFilePathName = edm::Service<evf::EvFDaqDirector>()->getOpenRootHistogramFilePath(lumi, stream_label_);
337  histoFilePathName = edm::Service<evf::EvFDaqDirector>()->getRootHistogramFilePath(lumi, stream_label_);
338  } else if (fileFormat == PB) {
339  openHistoFilePathName = edm::Service<evf::EvFDaqDirector>()->getOpenProtocolBufferHistogramFilePath(lumi, stream_label_);
340  histoFilePathName = edm::Service<evf::EvFDaqDirector>()->getProtocolBufferHistogramFilePath(lumi, stream_label_);
341  }
342  }
343 
344  if (fileFormat == ROOT)
345  {
346  // Save the file with the full directory tree,
347  // modifying it according to @a rewrite,
348  // but not looking for MEs inside the DQMStore, as in the online case,
349  // nor filling new MEs, as in the offline case.
350  dbe_->save(openHistoFilePathName,
351  "",
352  "^(Reference/)?([^/]+)",
353  rewrite,
354  enableMultiThread_ ? run : 0,
355  lumi,
358  fileUpdate_ ? "UPDATE" : "RECREATE",
359  true);
360  }
361  else if (fileFormat == PB)
362  {
363  // Save the file in the open directory.
364  dbe_->savePB(openHistoFilePathName,
365  filterName_,
366  enableMultiThread_ ? run : 0,
367  lumi,
368  true);
369  }
370  else
371  throw cms::Exception("DQMFileSaver")
372  << "Internal error, can save files"
373  << " only in ROOT or ProtocolBuffer format.";
374 
375  // Now move the the data and json files into the output directory.
376  rename(openHistoFilePathName.c_str(), histoFilePathName.c_str());
377 
378  // Write the json file in the open directory.
379  bpt::ptree pt = fillJson(run, lumi, histoFilePathName, fms_);
380  write_json(openJsonFilePathName, pt);
381  rename(openJsonFilePathName.c_str(), jsonFilePathName.c_str());
382 }
383 
384 void
386 {
387 
388  // Report the file to job report service.
390  if (jr.isAvailable())
391  {
392  std::map<std::string, std::string> info;
393  info["Source"] = "DQMStore";
394  info["FileClass"] = "DQM";
395  jr->reportAnalysisFile(filename, info);
396  }
397 
398 }
399 
400 //--------------------------------------------------------
402  : convention_ (Offline),
403  fileFormat_(ROOT),
404  workflow_ (""),
405  producer_ ("DQM"),
406  stream_label_ (""),
407  dirName_ ("."),
408  child_ (""),
409  filterName_(""),
410  version_ (1),
411  runIsComplete_ (false),
412  enableMultiThread_ (false),
413  saveByLumiSection_ (-1),
414  saveByRun_ (-1),
415  saveAtJobEnd_ (false),
416  saveReference_ (DQMStore::SaveWithReference),
417  saveReferenceQMin_ (dqm::qstatus::STATUS_OK),
418  forceRunNumber_ (-1),
419  fileBaseName_ (""),
420  fileUpdate_ (0),
421  dbe_ (&*edm::Service<DQMStore>()),
422  nrun_ (0),
423  nlumi_ (0),
424  irun_ (0),
425  fms_(nullptr)
426 {
427  // Determine the file saving convention, and adjust defaults accordingly.
428  std::string convention = ps.getUntrackedParameter<std::string>("convention", "Offline");
429  fakeFilterUnitMode_ = ps.getUntrackedParameter<bool>("fakeFilterUnitMode", false);
430 
431  if (convention == "Offline")
433  else if (convention == "Online")
435  else if (convention == "FilterUnit")
437  else
438  throw cms::Exception("DQMFileSaver")
439  << "Invalid 'convention' parameter '" << convention << "'."
440  << " Expected one of 'Online' or 'Offline' or 'FilterUnit'.";
441 
442  // If this is neither online nor FU convention, check workflow.
443  // In this way, FU is treated as online, so we cannot specify a workflow. TBC
445  {
447  if (workflow_.empty()
448  || workflow_[0] != '/'
449  || *workflow_.rbegin() == '/'
450  || std::count(workflow_.begin(), workflow_.end(), '/') != 3
451  || workflow_.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ"
452  "abcdefghijklmnopqrstuvwxyz"
453  "0123456789"
454  "-_/") != std::string::npos)
455  throw cms::Exception("DQMFileSaver")
456  << "Invalid 'workflow' parameter '" << workflow_
457  << "'. Expected '/A/B/C'.";
458  }
459  else if (! ps.getUntrackedParameter<std::string>("workflow", "").empty())
460  throw cms::Exception("DQMFileSaver")
461  << "The 'workflow' parameter must be empty in 'Online' and 'FilterUnit' conventions.";
462  else // for online set parameters
463  {
464  workflow_="/Global/Online/P5";
465  }
466 
467  // Determine the file format, and adjust defaults accordingly.
468  std::string fileFormat = ps.getUntrackedParameter<std::string>("fileFormat", "ROOT");
469  if (fileFormat == "ROOT")
470  fileFormat_ = ROOT;
471  else if (fileFormat == "PB")
472  fileFormat_ = PB;
473  else
474  throw cms::Exception("DQMFileSaver")
475  << "Invalid 'fileFormat' parameter '" << fileFormat << "'."
476  << " Expected one of 'ROOT' or 'PB'.";
477 
478  // Allow file producer to be set to specific values in certain conditions.
480  // Setting the same constraints on file producer both for online and FilterUnit conventions
481  // TODO(diguida): limit the producer for FilterUnit to be 'DQM' or 'HLTDQM'?
482  // TODO(diguida): how to handle histograms produced in the playback for the FU case?
484  && producer_ != "DQM"
485  && producer_ != "HLTDQM"
486  && producer_ != "Playback")
487  {
488  throw cms::Exception("DQMFileSaver")
489  << "Invalid 'producer' parameter '" << producer_
490  << "'. Expected 'DQM', 'HLTDQM' or 'Playback'.";
491  }
492  else if (convention_ != Online
493  && convention != FilterUnit
494  && producer_ != "DQM")
495  {
496  throw cms::Exception("DQMFileSaver")
497  << "Invalid 'producer' parameter '" << producer_
498  << "'. Expected 'DQM'.";
499  }
500 
502 
503  // version number to be used in filename
504  version_ = ps.getUntrackedParameter<int>("version", version_);
505  // flag to signal that file contains data from complete run
506  runIsComplete_ = ps.getUntrackedParameter<bool>("runIsComplete", runIsComplete_);
507 
508  // Check how we should save the references.
509  std::string refsave = ps.getUntrackedParameter<std::string>("referenceHandling", "default");
510  if (refsave == "default")
511  ;
512  else if (refsave == "skip")
513  {
515  // std::cout << "skip saving all references" << std::endl;
516  }
517  else if (refsave == "all")
518  {
520  // std::cout << "saving all references" << std::endl;
521  }
522  else if (refsave == "qtests")
523  {
525  // std::cout << "saving qtest references" << std::endl;
526  }
527  else
528  throw cms::Exception("DQMFileSaver")
529  << "Invalid 'referenceHandling' parameter '" << refsave
530  << "'. Expected 'default', 'skip', 'all' or 'qtests'.";
531 
532  // Check minimum required quality test result for which reference is saved.
533  saveReferenceQMin_ = ps.getUntrackedParameter<int>("referenceRequireStatus", saveReferenceQMin_);
534 
535  // Get and check the output directory.
536  struct stat s;
538  if (dirName_.empty() || stat(dirName_.c_str(), &s) == -1)
539  throw cms::Exception("DQMFileSaver")
540  << "Invalid 'dirName' parameter '" << dirName_ << "'.";
541 
543  // Find out when and how to save files. The following contraints apply:
544  // - For online, filter unit, and offline, allow files to be saved per lumi
545  // - For online, allow files to be saved per run, at event and time intervals.
546  // - For offline allow files to be saved per run, at job end, and run number to be overridden (for mc data).
548  {
549  getAnInt(ps, saveByLumiSection_, "saveByLumiSection");
550  }
551 
552  if (convention_ == Online)
553  {
554  getAnInt(ps, saveByRun_, "saveByRun");
555  }
556 
557  if (convention_ == Offline)
558  {
559  getAnInt(ps, saveByRun_, "saveByRun");
560  getAnInt(ps, forceRunNumber_, "forceRunNumber");
561  saveAtJobEnd_ = ps.getUntrackedParameter<bool>("saveAtJobEnd", saveAtJobEnd_);
562  }
563 
564  // Set up base file name:
565  // - for online and offline, follow the convention <dirName>/<producer>_V<4digits>_
566  // - for FilterUnit, we need to follow the DAQ2 convention, so we need the run and lumisection:
567  // the path is provided by the DAQ director service.
568  if (convention_ != FilterUnit)
569  {
570  char version[8];
571  sprintf(version, "_V%04d_", int(version_));
572  version[7]='\0';
573  fileBaseName_ = dirName_ + "/" + producer_ + version;
574  }
575  else if (fakeFilterUnitMode_)
576  {
577  edm::LogInfo("DQMFileSaver")
578  << "Fake FU mode, files are saved under <dirname>/runXXXXXX/runXXXXXX_lsXXXX_<stream_Label>.pb.\n";
579  }
580  else
581  {
582  // For FU, dirName_ will not be considered at all
583  edm::LogInfo("DQMFileSaver")
584  << "The base dir provided in the configuration '" << dirName_ << "'\n"
585  << " will not be considered: for FU, the DAQ2 services will handle directories\n";
586  //check that DAQ2 services are available: throw if not
589 
590  if (!(fms_ && daqDirector))
591  throw cms::Exception("DQMFileSaver")
592  << "Internal error, cannot initialize DAQ services.";
593  }
594 
595  // Log some information what we will do.
596  edm::LogInfo("DQMFileSaver")
597  << "DQM file saving settings:\n"
598  << " using base file name '" << fileBaseName_ << "'\n"
599  << " forcing run number " << forceRunNumber_ << "\n"
600  << " saving every " << saveByLumiSection_ << " lumi section(s)\n"
601  << " saving every " << saveByRun_ << " run(s)\n"
602  << " saving at job end: " << (saveAtJobEnd_ ? "yes" : "no") << "\n";
603 }
604 
605 //--------------------------------------------------------
606 void
608 {
609  nrun_ = nlumi_ = irun_ = 0;
610 
611  // Determine if we are running multithreading asking to the DQMStore. Not to be moved in the ctor
612  enableMultiThread_ = dbe_->enableMultiThread_;
613 }
614 
615 std::shared_ptr<saverDetails::NoCache>
617 {
618  ++nrun_;
619 
620  // For Filter Unit, create an empty ini file:
621  // it is needed by the HLT deamon in order to start merging
622  // The run number is established in the service
623  // TODO(diguida): check that they are the same?
625  {
627  const std::string initFileName = daqDirector->getInitFilePath(stream_label_);
628  std::ofstream file(initFileName);
629  file.close();
630  }
631 
632  return nullptr;
633 }
634 
635 std::shared_ptr<saverDetails::NoCache>
637 {
638  ++nlumi_;
639  return nullptr;
640 }
641 
643 {
644  //save by event and save by time are not supported
645  //anymore in the threaded framework. please use
646  //savebyLumiSection instead.
647 }
648 
649 void
651 {
652  int ilumi = iLS.id().luminosityBlock();
653  int irun = iLS.id().run();
654  if (ilumi > 0 && saveByLumiSection_ > 0 )
655  {
657  throw cms::Exception("DQMFileSaver")
658  << "Internal error, can save files at end of lumi block"
659  << " only in Online, FilterUnit or Offline mode.";
660 
661  if (convention_ == Online && (nlumi_ % saveByLumiSection_) == 0) // insist on lumi section ordering
662  {
663  char suffix[64];
664  char rewrite[128];
665  sprintf(suffix, "_R%09d_L%06d", irun, ilumi);
666  sprintf(rewrite, "\\1Run %d/\\2/By Lumi Section %d-%d", irun, ilumi-nlumi_, ilumi);
667  if (fileFormat_ == ROOT)
668  saveForOnline(irun, suffix, rewrite);
669  else if (fileFormat_ == PB)
670  saveForOnlinePB(irun, suffix);
671  else
672  throw cms::Exception("DQMFileSaver")
673  << "Internal error, can save files"
674  << " only in ROOT or ProtocolBuffer format.";
675  }
676 
677  // Store at every lumi section end only if some events have been processed.
678  // Caveat: if faking FilterUnit, i.e. not accessing DAQ2 services,
679  // we cannot ask FastMonitoringService the processed events, so we are forced
680  // to save the file at every lumisection, even with no statistics.
681  // Here, we protect the call to get the processed events in a lumi section
682  // by testing the pointer to FastMonitoringService: if not null, i.e. in real FU mode,
683  // we check that the events are not 0; otherwise, we skip the test, so we store at every lumi transition.
684  // TODO(diguida): allow fake FU mode to skip file creation at empty lumi sections.
685  if (convention_ == FilterUnit && (fms_ ? (fms_->getEventsProcessedForLumi(ilumi) > 0) : !fms_))
686  {
687  char rewrite[128];
688  sprintf(rewrite, "\\1Run %d/\\2/By Lumi Section %d-%d", irun, ilumi, ilumi);
689  saveForFilterUnit(rewrite, irun, ilumi, fileFormat_);
690  }
691  if (convention_ == Offline)
692  {
693  if (fileFormat_ == ROOT)
694  saveForOffline(workflow_, irun, ilumi);
695  else
696  // TODO(diguida): do we need to support lumisection saving in Offline for PB?
697  // In this case, for ROOT, we only save EventInfo folders: we can filter them...
698  throw cms::Exception("DQMFileSaver")
699  << "Internal error, can save files"
700  << " only in ROOT format.";
701  }
702 
703  // after saving per LS, delete the old LS global histograms.
704  dbe_->markForDeletion(enableMultiThread_ ? irun : 0, ilumi);
705  }
706 }
707 
708 void
710 {
711  int irun = iRun.id().run();
712  irun_ = irun;
713  if (irun > 0 && saveByRun_ > 0 && (nrun_ % saveByRun_) == 0)
714  {
715  if (convention_ == Online)
716  {
717  char suffix[64];
718  sprintf(suffix, "_R%09d", irun);
719  char rewrite[64];
720  sprintf(rewrite, "\\1Run %d/\\2/Run summary", irun);
721  if (fileFormat_ == ROOT)
722  saveForOnline(irun, suffix, rewrite);
723  else if (fileFormat_ == PB)
724  saveForOnlinePB(irun, suffix);
725  else
726  throw cms::Exception("DQMFileSaver")
727  << "Internal error, can save files"
728  << " only in ROOT or ProtocolBuffer format.";
729  }
730  else if (convention_ == Offline && fileFormat_ == ROOT)
731  saveForOffline(workflow_, irun, 0);
732  else if (convention_ == Offline && fileFormat_ == PB)
734  else
735  throw cms::Exception("DQMFileSaver")
736  << "Internal error. Can only save files in endRun()"
737  << " in Online and Offline modes.";
738  }
739 
740  // create a fake EoR file for testing purposes.
741  if (fakeFilterUnitMode_) {
742  edm::LogInfo("DQMFileSaver")
743  << "Producing fake EoR file.\n";
744 
745  std::string runDir = str(boost::format("%s/run%06d") % dirName_ % irun);
746  std::string jsonFilePathName = str(boost::format("%s/run%06d_ls0000_EoR.jsn") % runDir % irun);
747  std::string openJsonFilePathName = jsonFilePathName + ".open";
748 
749  boost::filesystem::create_directories(runDir);
750 
751  using namespace boost::property_tree;
752  ptree pt;
753  ptree data;
754 
755  ptree child1, child2, child3;
756 
757  child1.put("", -1); // Processed
758  child2.put("", -1); // Accepted
759  child3.put("", nlumi_); // number of lumi
760 
761  data.push_back(std::make_pair("", child1));
762  data.push_back(std::make_pair("", child2));
763  data.push_back(std::make_pair("", child3));
764 
765  pt.add_child("data", data);
766  pt.put("definition", "/non-existant/");
767  pt.put("source", "--hostname--");
768 
769  std::ofstream file(jsonFilePathName);
770  write_json(file, pt, true);
771  file.close();
772 
773  rename(openJsonFilePathName.c_str(), jsonFilePathName.c_str());
774  }
775 }
776 
777 void
779 {
780  if (saveAtJobEnd_)
781  {
782  if (convention_ == Offline && forceRunNumber_ > 0)
784  else if (convention_ == Offline)
786  else
787  throw cms::Exception("DQMFileSaver")
788  << "Internal error. Can only save files at the end of the"
789  << " job in Offline mode.";
790  }
791 
792  // save JobReport once per job
793  char suffix[64];
794  sprintf(suffix, "R%09d", irun_.load());
796  saveJobReport(filename);
797 }
798 
799 void
800 DQMFileSaver::postForkReacquireResources(unsigned int childIndex, unsigned int numberOfChildren)
801 {
802  // this is copied from IOPool/Output/src/PoolOutputModule.cc, for consistency
803  unsigned int digits = 0;
804  while (numberOfChildren != 0) {
805  ++digits;
806  numberOfChildren /= 10;
807  }
808  // protect against zero numberOfChildren
809  if (digits == 0) {
810  digits = 3;
811  }
812 
813  char buffer[digits + 2];
814  snprintf(buffer, digits + 2, "_%0*d", digits, childIndex);
815  child_ = std::string(buffer);
816 }
LuminosityBlockID id() const
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
DQMFileSaver(const edm::ParameterSet &ps)
int forceRunNumber_
Definition: DQMFileSaver.h:80
int saveReferenceQMin_
Definition: DQMFileSaver.h:79
static const TGPicture * info(bool iBackgroundIsBlack)
RunID const & id() const
Definition: RunBase.h:41
void saveForOffline(const std::string &workflow, int run, int lumi) const
Definition: DQMFileSaver.cc:86
RunNumber_t run() const
Definition: RunID.h:39
static std::string dataFileExtension(DQMFileSaver::FileFormat fileFormat)
Definition: DQMFileSaver.cc:48
virtual void globalEndRun(const edm::Run &, const edm::EventSetup &) const
Convention convention_
Definition: DQMFileSaver.h:62
std::string getInitFilePath(std::string const &stream) const
tuple lumi
Definition: fjr2json.py:35
evf::FastMonitoringService * fms_
Definition: DQMFileSaver.h:93
DQMStore * dbe_
Definition: DQMFileSaver.h:85
string format
Some error handling for the usage.
std::atomic< int > nlumi_
Definition: DQMFileSaver.h:87
#define nullptr
std::string dirName_
Definition: DQMFileSaver.h:67
std::string fileBaseName_
Definition: DQMFileSaver.h:82
virtual void globalEndLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &) const
SaveReferenceTag
Definition: DQMStore.h:78
unsigned int getEventsProcessedForLumi(unsigned int lumi)
int saveByLumiSection_
Definition: DQMFileSaver.h:75
bool enableMultiThread_
Definition: DQMFileSaver.h:72
tuple path
else: Piece not in the list, fine.
void saveJobReport(const std::string &filename) const
static void getAnInt(const edm::ParameterSet &ps, int &value, const std::string &name)
Definition: DQMFileSaver.cc:38
static boost::property_tree::ptree fillJson(int run, int lumi, const std::string &dataFilePathName, evf::FastMonitoringService *fms)
bool isAvailable() const
Definition: Service.h:46
RunNumber_t run() const
static std::string onlineOfflineFileName(const std::string &fileBaseName, const std::string &suffix, const std::string &workflow, const std::string &child, DQMFileSaver::FileFormat fileFormat)
Definition: DQMFileSaver.cc:59
void saveForOnline(int run, const std::string &suffix, const std::string &rewrite) const
bool fakeFilterUnitMode_
Definition: DQMFileSaver.h:73
bool runIsComplete_
Definition: DQMFileSaver.h:71
std::string stream_label_
Definition: DQMFileSaver.h:66
static const std::string streamPrefix_
Definition: DQMFileSaver.h:95
DQMStore * dbe_
std::string workflow_
Definition: DQMFileSaver.h:64
virtual std::shared_ptr< saverDetails::NoCache > globalBeginRun(const edm::Run &, const edm::EventSetup &) const
string host
Definition: query.py:114
std::string producer_
Definition: DQMFileSaver.h:65
std::string child_
Definition: DQMFileSaver.h:68
int saveReference_
Definition: DQMFileSaver.h:78
void saveForOnlinePB(int run, const std::string &suffix) const
std::string filterName_
Definition: DQMFileSaver.h:69
std::atomic< int > fileUpdate_
Definition: DQMFileSaver.h:83
tuple pid
Definition: sysUtil.py:22
FileFormat fileFormat_
Definition: DQMFileSaver.h:63
LuminosityBlockNumber_t luminosityBlock() const
virtual void analyze(edm::StreamID, const edm::Event &e, const edm::EventSetup &) const
std::atomic< int > irun_
Definition: DQMFileSaver.h:90
virtual std::shared_ptr< saverDetails::NoCache > globalBeginLuminosityBlock(const edm::LuminosityBlock &, const edm::EventSetup &) const
void saveForOfflinePB(const std::string &workflow, int run) const
Definition: DQMFileSaver.cc:77
bool saveAtJobEnd_
Definition: DQMFileSaver.h:77
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
void reportAnalysisFile(std::string const &fileName, std::map< std::string, std::string > const &fileData)
Definition: JobReport.cc:559
std::atomic< int > nrun_
Definition: DQMFileSaver.h:86
static void doSaveForOnline(DQMStore *store, int run, bool enableMultiThread, const std::string &filename, const std::string &directory, const std::string &rxpat, const std::string &rewrite, DQMStore::SaveReferenceTag saveref, int saveRefQMin, const std::string &filterName, DQMFileSaver::FileFormat fileFormat)
tuple filename
Definition: lut2db_cfg.py:20
static const int STATUS_OK
tuple inputFiles
Definition: merge.py:5
virtual void postForkReacquireResources(unsigned int childIndex, unsigned int numberOfChildren)
volatile std::atomic< bool > shutdown_flag false
virtual void beginJob(void)
virtual void endJob(void)
static const std::string streamSuffix_
Definition: DQMFileSaver.h:96
Definition: Run.h:41
void saveForFilterUnit(const std::string &rewrite, int run, int lumi, const FileFormat fileFormat) const