CMS 3D CMS Logo

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