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