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