CMS 3D CMS Logo

LegacyIOHelper.cc
Go to the documentation of this file.
3 
4 #include <cstdio>
5 #include <cfloat>
6 #include <vector>
7 #include <string>
8 
9 #include "TString.h"
10 #include "TSystem.h"
11 #include "TFile.h"
12 #include "TKey.h"
13 #include <sys/stat.h>
14 
16  std::string const &path /* = "" */,
17  uint32_t const run /* = 0 */,
18  bool saveall /* = true */,
19  std::string const &fileupdate /* = "RECREATE" */) {
20  // TFile flushes to disk with fsync() on every TDirectory written to
21  // the file. This makes DQM file saving painfully slow, and
22  // ironically makes it _more_ likely the file saving gets
23  // interrupted and corrupts the file. The utility class below
24  // simply ignores the flush synchronisation.
25  class TFileNoSync : public TFile {
26  public:
27  TFileNoSync(char const *file, char const *opt) : TFile{file, opt} {}
28  Int_t SysSync(Int_t) override { return 0; }
29  };
30 
31  std::cout << "DQMFileSaver::globalEndRun()" << std::endl;
32 
33  char suffix[64];
34  sprintf(suffix, "R%09d", run);
35  TFileNoSync *file = new TFileNoSync(filename.c_str(), fileupdate.c_str()); // open file
36 
37  // Traverse all MEs
38  std::vector<MonitorElement *> mes;
39  if (saveall) {
40  // this is typically used, at endJob there will only be JOB histos here
41  mes = dbe_->getAllContents(path);
42  } else {
43  // at endRun it might make sense to use this, to not save JOB histos yet.
44  mes = dbe_->getAllContents(path, run, 0);
45  }
46 
47  for (auto me : mes) {
48  // Modify dirname to comply with DQM GUI format. Change:
49  // A/B/C/plot
50  // into:
51  // DQMData/Run X/A/Run summary/B/C/plot
52  std::string dirName = me->getPathname();
53  uint64_t firstSlashPos = dirName.find('/');
54  if (firstSlashPos == std::string::npos) {
55  firstSlashPos = dirName.length();
56  }
57 
58  if (run) {
59  // Rewrite paths to "Run Summary" format when given a run number.
60  // Else, write a simple, flat TDirectory for local usage.
61  dirName = dirName.substr(0, firstSlashPos) + "/Run summary" + dirName.substr(firstSlashPos, dirName.size());
62  dirName = "DQMData/Run " + std::to_string(run) + "/" + dirName;
63  }
64 
65  std::string objectName = me->getName();
66 
67  // Create dir if it doesn't exist and cd into it
69 
70  // INTs are saved as strings in this format: <objectName>i=value</objectName>
71  // REALs are saved as strings in this format: <objectName>f=value</objectName>
72  // STRINGs are saved as strings in this format: <objectName>s="value"</objectName>
73  if (me->kind() == MonitorElement::Kind::INT) {
74  int value = me->getIntValue();
75  std::string content = "<" + objectName + ">i=" + std::to_string(value) + "</" + objectName + ">";
76  TObjString str(content.c_str());
77  str.Write();
78  } else if (me->kind() == MonitorElement::Kind::REAL) {
79  double value = me->getFloatValue();
80  char buf[64];
81  // use printf here to preserve exactly the classic formatting.
82  std::snprintf(buf, sizeof(buf), "%.*g", DBL_DIG + 2, value);
83  std::string content = "<" + objectName + ">f=" + buf + "</" + objectName + ">";
84  TObjString str(content.c_str());
85  str.Write();
86  } else if (me->kind() == MonitorElement::Kind::STRING) {
87  const std::string &value = me->getStringValue();
88  std::string content = "<" + objectName + ">s=" + value + "</" + objectName + ">";
89  TObjString str(content.c_str());
90  str.Write();
91  } else {
92  // Write a histogram
93  TH1 *value = me->getTH1();
94  value->Write();
95 
96  if (me->getEfficiencyFlag()) {
97  std::string content = "<" + objectName + ">e=1</" + objectName + ">";
98  TObjString str(content.c_str());
99  str.Write();
100  }
101 
102  for (QReport *qr : me->getQReports()) {
104  // TODO: 64 is likely too short; memory corruption in the old code?
105  char buf[64];
106  std::snprintf(buf, sizeof(buf), "qr=st:%d:%.*g:", qr->getStatus(), DBL_DIG + 2, qr->getQTresult());
107  result = '<' + objectName + '.' + qr->getQRName() + '>';
108  result += buf;
109  result += qr->getAlgorithm() + ':' + qr->getMessage();
110  result += "</" + objectName + '.' + qr->getQRName() + '>';
111  TObjString str(result.c_str());
112  str.Write();
113  }
114  }
115 
116  // Go back to the root directory
117  gDirectory->cd("/");
118  }
119 
120  file->Close();
121 }
122 
123 // Use this for saving monitoring objects in ROOT files with dir structure;
124 // cds into directory (creates it first if it doesn't exist);
125 // returns a success flag
127  assert(!path.empty());
128 
129  // Find the first path component.
130  size_t start = 0;
131  size_t end = path.find('/', start);
132  if (end == std::string::npos)
133  end = path.size();
134 
135  while (true) {
136  // Check if this subdirectory component exists. If yes, make sure
137  // it is actually a subdirectory. Otherwise create or cd into it.
139  TObject *o = gDirectory->Get(part.c_str());
140  if (o && !dynamic_cast<TDirectory *>(o))
141  throw cms::Exception("DQMFileSaver") << "Attempt to create directory '" << path
142  << "' in a file"
143  " fails because the part '"
144  << part
145  << "' already exists and is not"
146  " directory";
147  else if (!o)
148  gDirectory->mkdir(part.c_str());
149 
150  if (!gDirectory->cd(part.c_str()))
151  throw cms::Exception("DQMFileSaver") << "Attempt to create directory '" << path
152  << "' in a file"
153  " fails because could not cd into subdirectory '"
154  << part << "'";
155 
156  // Stop if we reached the end, ignoring any trailing '/'.
157  if (end + 1 >= path.size())
158  break;
159 
160  // Find the next path component.
161  start = end + 1;
162  end = path.find('/', start);
163  if (end == std::string::npos)
164  end = path.size();
165  }
166 
167  return true;
168 }
169 
170 bool LegacyIOHelper::readdir(TDirectory *dir, const std::string &toppath) {
171  TDirectory *dirsav = gDirectory;
172  LogDebug("LegacyIOHelper") << "Inside:" << gDirectory->GetPath() << std::endl;
173  TIter next(dir->GetListOfKeys());
174  TKey *key;
175  while ((key = (TKey *)next())) {
176  if (key->IsFolder()) {
177  LogDebug("LegacyIOHelper") << key->GetName() << std::endl;
178  dir->cd(key->GetName());
179  TDirectory *subdir = gDirectory;
180  readdir(subdir, toppath);
181  dirsav->cd();
182  continue;
183  } else {
184  TClass *cl = gROOT->GetClass(key->GetClassName());
185  std::string meName;
186  if (cl->InheritsFrom("TProfile")) {
187  TProfile *h = dynamic_cast<TProfile *>(key->ReadObject<TProfile>()->Clone());
188  h->SetDirectory(nullptr);
189  if (h) {
190  getMEName<TProfile>(h, toppath, meName);
191  data_.insert(dbe_->bookProfile(meName, h));
192  }
193  } else if (cl->InheritsFrom("TProfile2D")) {
194  TProfile2D *h = dynamic_cast<TProfile2D *>(key->ReadObject<TProfile2D>()->Clone());
195  h->SetDirectory(nullptr);
196  if (h) {
197  getMEName<TProfile2D>(h, toppath, meName);
198  data_.insert(dbe_->bookProfile2D(meName, h));
199  }
200  } else if (cl->InheritsFrom("TH1F")) {
201  TH1F *h = dynamic_cast<TH1F *>(key->ReadObject<TH1F>()->Clone());
202  h->SetDirectory(nullptr);
203  if (h) {
204  getMEName<TH1F>(h, toppath, meName);
205  data_.insert(dbe_->book1D(meName, h));
206  }
207  } else if (cl->InheritsFrom("TH1S")) {
208  TH1S *h = dynamic_cast<TH1S *>(key->ReadObject<TH1S>()->Clone());
209  h->SetDirectory(nullptr);
210  if (h) {
211  getMEName<TH1S>(h, toppath, meName);
212  data_.insert(dbe_->book1S(meName, h));
213  }
214  } else if (cl->InheritsFrom("TH1D")) {
215  TH1D *h = dynamic_cast<TH1D *>(key->ReadObject<TH1D>()->Clone());
216  h->SetDirectory(nullptr);
217  if (h) {
218  getMEName<TH1D>(h, toppath, meName);
219  data_.insert(dbe_->book1DD(meName, h));
220  }
221  } else if (cl->InheritsFrom("TH2F")) {
222  TH2F *h = dynamic_cast<TH2F *>(key->ReadObject<TH2F>()->Clone());
223  h->SetDirectory(nullptr);
224  if (h) {
225  getMEName<TH2F>(h, toppath, meName);
226  data_.insert(dbe_->book2D(meName, h));
227  }
228  } else if (cl->InheritsFrom("TH2S")) {
229  TH2S *h = dynamic_cast<TH2S *>(key->ReadObject<TH2S>()->Clone());
230  h->SetDirectory(nullptr);
231  if (h) {
232  getMEName<TH2S>(h, toppath, meName);
233  data_.insert(dbe_->book2S(meName, h));
234  }
235  } else if (cl->InheritsFrom("TH2D")) {
236  TH2D *h = dynamic_cast<TH2D *>(key->ReadObject<TH2D>()->Clone());
237  h->SetDirectory(nullptr);
238  if (h) {
239  getMEName<TH2D>(h, toppath, meName);
240  data_.insert(dbe_->book2DD(meName, h));
241  }
242  } else if (cl->InheritsFrom("TH3F")) {
243  TH3F *h = dynamic_cast<TH3F *>(key->ReadObject<TH3F>()->Clone());
244  h->SetDirectory(nullptr);
245  if (h) {
246  getMEName<TH3F>(h, toppath, meName);
247  data_.insert(dbe_->book3D(meName, h));
248  }
249  }
250  }
251  }
252  if (!data_.empty())
253  return true;
254  return false;
255 }
256 
257 bool LegacyIOHelper::open(std::string const &filename, std::string const &path, uint32_t const run) {
258  TFile *f1 = TFile::Open(filename.c_str());
259  if (!f1)
260  return false;
261  std::ostringstream toppath;
262  toppath << filename << ":/DQMData/Run " << run << "/";
263  std::string dirpath = toppath.str();
264  edm::LogPrint("LegacyIOHelper") << dirpath << std::endl;
265  bool flag = readdir(f1, dirpath);
266  f1->Close();
267  return flag;
268 }
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:15
start
Definition: start.py:1
MessageLogger.h
MonitorElementData::Kind::INT
dqm::implementation::IBooker::book2S
MonitorElement * book2S(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:219
dqm::implementation::IBooker::bookProfile2D
MonitorElement * bookProfile2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, double lowZ, double highZ, char const *option="s", FUNC onbooking=NOOP())
Definition: DQMStore.h:399
LegacyIOHelper::readdir
bool readdir(TDirectory *dir, const std::string &toppath)
Definition: LegacyIOHelper.cc:170
gather_cfg.cout
cout
Definition: gather_cfg.py:144
MonitorElementData::Kind::STRING
edm::LogPrint
Log< level::Warning, true > LogPrint
Definition: MessageLogger.h:130
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:307
EcalTangentSkim_cfg.o
o
Definition: EcalTangentSkim_cfg.py:42
createPayload.suffix
suffix
Definition: createPayload.py:281
LegacyIOHelper::dbe_
DQMStore * dbe_
Definition: LegacyIOHelper.h:64
GetRecoTauVFromDQM_MC_cff.cl
cl
Definition: GetRecoTauVFromDQM_MC_cff.py:38
LegacyIOHelper.h
part
part
Definition: HCALResponse.h:20
mps_fire.end
end
Definition: mps_fire.py:242
str
#define str(s)
Definition: TestProcessor.cc:53
dqm::implementation::IBooker::bookProfile
MonitorElement * bookProfile(TString const &name, TString const &title, int nchX, double lowX, double highX, int, double lowY, double highY, char const *option="s", FUNC onbooking=NOOP())
Definition: DQMStore.h:322
corrVsCorr.filename
filename
Definition: corrVsCorr.py:123
dqm::implementation::IBooker::book1S
MonitorElement * book1S(TString const &name, TString const &title, int nchX, double lowX, double highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:133
h
dqm::implementation::IBooker::book1DD
MonitorElement * book1DD(TString const &name, TString const &title, int nchX, double lowX, double highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:155
geometryDiff.file
file
Definition: geometryDiff.py:13
Skims_PA_cff.content
content
Definition: Skims_PA_cff.py:19
dqm::implementation::IBooker::book2DD
MonitorElement * book2DD(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:261
LogDebug
#define LogDebug(id)
Definition: MessageLogger.h:233
LegacyIOHelper::open
bool open(std::string const &filename, std::string const &path="", uint32_t const run=0)
Definition: LegacyIOHelper.cc:257
LegacyIOHelper::data_
MEMap data_
Definition: LegacyIOHelper.h:65
MonitorElementData::QReport
Definition: MonitorElementCollection.h:55
value
Definition: value.py:1
visDQMUpload.buf
buf
Definition: visDQMUpload.py:160
AlCaHLTBitMon_QueryRunRegistry.string
string string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
writedatasetfile.run
run
Definition: writedatasetfile.py:27
dqm::implementation::IBooker::book2D
MonitorElement * book2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
Definition: DQMStore.h:177
Exception
Definition: hltDiff.cc:245
dqm::implementation::IBooker::book3D
MonitorElement * book3D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, int nchZ, double lowZ, double highZ, FUNC onbooking=NOOP())
Definition: DQMStore.h:290
TrackerOfflineValidation_Dqm_cff.dirName
dirName
Definition: TrackerOfflineValidation_Dqm_cff.py:55
LegacyIOHelper::createDirectoryIfNeededAndCd
bool createDirectoryIfNeededAndCd(const std::string &path)
Definition: LegacyIOHelper.cc:126
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
DeadROC_duringRun.f1
f1
Definition: DeadROC_duringRun.py:219
crabWrapper.key
key
Definition: crabWrapper.py:19
MonitorElementData::Kind::REAL
dqm::implementation::IBooker::book1D
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
RemoveAddSevLevel.flag
flag
Definition: RemoveAddSevLevel.py:117
GetRecoTauVFromDQM_MC_cff.next
next
Definition: GetRecoTauVFromDQM_MC_cff.py:31
DeadROC_duringRun.dir
dir
Definition: DeadROC_duringRun.py:23
summarizeEdmComparisonLogfiles.objectName
objectName
Definition: summarizeEdmComparisonLogfiles.py:104