CMS 3D CMS Logo

LegacyIOHelper.cc
Go to the documentation of this file.
2 
3 #include <cstdio>
4 #include <cfloat>
5 #include <vector>
6 #include <string>
7 
8 #include "TString.h"
9 #include "TSystem.h"
10 #include "TFile.h"
11 #include <sys/stat.h>
12 
14  std::string const &path /* = "" */,
15  uint32_t const run /* = 0 */,
16  bool saveall /* = true */,
17  std::string const &fileupdate /* = "RECREATE" */) {
18  // TFile flushes to disk with fsync() on every TDirectory written to
19  // the file. This makes DQM file saving painfully slow, and
20  // ironically makes it _more_ likely the file saving gets
21  // interrupted and corrupts the file. The utility class below
22  // simply ignores the flush synchronisation.
23  class TFileNoSync : public TFile {
24  public:
25  TFileNoSync(char const *file, char const *opt) : TFile{file, opt} {}
26  Int_t SysSync(Int_t) override { return 0; }
27  };
28 
29  std::cout << "DQMFileSaver::globalEndRun()" << std::endl;
30 
31  char suffix[64];
32  sprintf(suffix, "R%09d", run);
33  TFileNoSync *file = new TFileNoSync(filename.c_str(), fileupdate.c_str()); // open file
34 
35  // Traverse all MEs
36  std::vector<MonitorElement *> mes;
37  if (saveall) {
38  // this is typically used, at endJob there will only be JOB histos here
39  mes = dbe_->getAllContents(path);
40  } else {
41  // at endRun it might make sense to use this, to not save JOB histos yet.
42  mes = dbe_->getAllContents(path, run, 0);
43  }
44 
45  for (auto me : mes) {
46  // Modify dirname to comply with DQM GUI format. Change:
47  // A/B/C/plot
48  // into:
49  // DQMData/Run X/A/Run summary/B/C/plot
50  std::string dirName = me->getPathname();
51  uint64_t firstSlashPos = dirName.find('/');
52  if (firstSlashPos == std::string::npos) {
53  firstSlashPos = dirName.length();
54  }
55 
56  if (run) {
57  // Rewrite paths to "Run Summary" format when given a run number.
58  // Else, write a simple, flat TDirectory for local usage.
59  dirName = dirName.substr(0, firstSlashPos) + "/Run summary" + dirName.substr(firstSlashPos, dirName.size());
60  dirName = "DQMData/Run " + std::to_string(run) + "/" + dirName;
61  }
62 
63  std::string objectName = me->getName();
64 
65  // Create dir if it doesn't exist and cd into it
67 
68  // INTs are saved as strings in this format: <objectName>i=value</objectName>
69  // REALs are saved as strings in this format: <objectName>f=value</objectName>
70  // STRINGs are saved as strings in this format: <objectName>s="value"</objectName>
71  if (me->kind() == MonitorElement::Kind::INT) {
72  int value = me->getIntValue();
73  std::string content = "<" + objectName + ">i=" + std::to_string(value) + "</" + objectName + ">";
74  TObjString str(content.c_str());
75  str.Write();
76  } else if (me->kind() == MonitorElement::Kind::REAL) {
77  double value = me->getFloatValue();
78  char buf[64];
79  // use printf here to preserve exactly the classic formatting.
80  std::snprintf(buf, sizeof(buf), "%.*g", DBL_DIG + 2, value);
81  std::string content = "<" + objectName + ">f=" + buf + "</" + objectName + ">";
82  TObjString str(content.c_str());
83  str.Write();
84  } else if (me->kind() == MonitorElement::Kind::STRING) {
85  const std::string &value = me->getStringValue();
86  std::string content = "<" + objectName + ">s=" + value + "</" + objectName + ">";
87  TObjString str(content.c_str());
88  str.Write();
89  } else {
90  // Write a histogram
91  TH1 *value = me->getTH1();
92  value->Write();
93 
94  if (me->getEfficiencyFlag()) {
95  std::string content = "<" + objectName + ">e=1</" + objectName + ">";
96  TObjString str(content.c_str());
97  str.Write();
98  }
99 
100  for (QReport *qr : me->getQReports()) {
102  // TODO: 64 is likely too short; memory corruption in the old code?
103  char buf[64];
104  std::snprintf(buf, sizeof(buf), "qr=st:%d:%.*g:", qr->getStatus(), DBL_DIG + 2, qr->getQTresult());
105  result = '<' + objectName + '.' + qr->getQRName() + '>';
106  result += buf;
107  result += qr->getAlgorithm() + ':' + qr->getMessage();
108  result += "</" + objectName + '.' + qr->getQRName() + '>';
109  TObjString str(result.c_str());
110  str.Write();
111  }
112  }
113 
114  // Go back to the root directory
115  gDirectory->cd("/");
116  }
117 
118  file->Close();
119 }
120 
121 // Use this for saving monitoring objects in ROOT files with dir structure;
122 // cds into directory (creates it first if it doesn't exist);
123 // returns a success flag
125  assert(!path.empty());
126 
127  // Find the first path component.
128  size_t start = 0;
129  size_t end = path.find('/', start);
130  if (end == std::string::npos)
131  end = path.size();
132 
133  while (true) {
134  // Check if this subdirectory component exists. If yes, make sure
135  // it is actually a subdirectory. Otherwise create or cd into it.
137  TObject *o = gDirectory->Get(part.c_str());
138  if (o && !dynamic_cast<TDirectory *>(o))
139  throw cms::Exception("DQMFileSaver") << "Attempt to create directory '" << path
140  << "' in a file"
141  " fails because the part '"
142  << part
143  << "' already exists and is not"
144  " directory";
145  else if (!o)
146  gDirectory->mkdir(part.c_str());
147 
148  if (!gDirectory->cd(part.c_str()))
149  throw cms::Exception("DQMFileSaver") << "Attempt to create directory '" << path
150  << "' in a file"
151  " fails because could not cd into subdirectory '"
152  << part << "'";
153 
154  // Stop if we reached the end, ignoring any trailing '/'.
155  if (end + 1 >= path.size())
156  break;
157 
158  // Find the next path component.
159  start = end + 1;
160  end = path.find('/', start);
161  if (end == std::string::npos)
162  end = path.size();
163  }
164 
165  return true;
166 }
LegacyIOHelper::save
void save(std::string const &filename, std::string const &path="", uint32_t const run=0, bool saveall=true, std::string const &fileupdate="RECREATE")
Definition: LegacyIOHelper.cc:13
start
Definition: start.py:1
MonitorElementData::Kind::INT
gather_cfg.cout
cout
Definition: gather_cfg.py:144
MonitorElementData::Kind::STRING
cms::cuda::assert
assert(be >=bs)
dqm::implementation::IGetter::getAllContents
virtual std::vector< dqm::harvesting::MonitorElement * > getAllContents(std::string const &path) const
Definition: DQMStore.cc:609
runTheMatrix.opt
opt
Definition: runTheMatrix.py:306
EcalTangentSkim_cfg.o
o
Definition: EcalTangentSkim_cfg.py:42
createPayload.suffix
suffix
Definition: createPayload.py:281
LegacyIOHelper::dbe_
DQMStore * dbe_
Definition: LegacyIOHelper.h:37
LegacyIOHelper.h
part
part
Definition: HCALResponse.h:20
mps_fire.end
end
Definition: mps_fire.py:242
str
#define str(s)
Definition: TestProcessor.cc:52
corrVsCorr.filename
filename
Definition: corrVsCorr.py:123
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
Skims_PA_cff.content
content
Definition: Skims_PA_cff.py:19
MonitorElementData::QReport
Definition: MonitorElementCollection.h:55
FrontierConditions_GlobalTag_cff.file
file
Definition: FrontierConditions_GlobalTag_cff.py:13
value
Definition: value.py:1
visDQMUpload.buf
buf
Definition: visDQMUpload.py:154
writedatasetfile.run
run
Definition: writedatasetfile.py:27
Exception
Definition: hltDiff.cc:245
TrackerOfflineValidation_Dqm_cff.dirName
dirName
Definition: TrackerOfflineValidation_Dqm_cff.py:55
LegacyIOHelper::createDirectoryIfNeededAndCd
bool createDirectoryIfNeededAndCd(const std::string &path)
Definition: LegacyIOHelper.cc:124
cond::uint64_t
unsigned long long uint64_t
Definition: Time.h:13
mps_fire.result
result
Definition: mps_fire.py:311
cms::Exception
Definition: Exception.h:70
castor_dqm_sourceclient_file_cfg.path
path
Definition: castor_dqm_sourceclient_file_cfg.py:37
hlt_dqm_clientPB-live_cfg.me
me
Definition: hlt_dqm_clientPB-live_cfg.py:61
MonitorElementData::Kind::REAL
summarizeEdmComparisonLogfiles.objectName
objectName
Definition: summarizeEdmComparisonLogfiles.py:105