ATLAS Offline Software
HanOutputFile.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3  */
4 
5 // **********************************************************************
6 // $Id: HanOutputFile.cxx,v 1.59 2009-05-18 15:37:12 ponyisi Exp $
7 // **********************************************************************
8 
10 
11 #include <TBufferJSON.h>
12 #include <TCanvas.h>
13 #include <TDirectory.h>
14 #include <TEfficiency.h>
15 #include <TF1.h>
16 #include <TFile.h>
17 #include <TGraph.h>
18 #include <TGraphAsymmErrors.h>
19 #include <TH1.h>
20 #include <TH2.h>
21 #include <THStack.h>
22 #include <TImage.h>
23 #include <TIterator.h>
24 #include <TKey.h>
25 #include <TLatex.h>
26 #include <TLegend.h>
27 #include <TLine.h>
28 #include <TMath.h>
29 #include <TProfile.h>
30 #include <TROOT.h>
31 #include <TString.h>
32 #include <TStyle.h>
33 #include <TText.h>
34 #include <TImageDump.h>
35 #include <TFrame.h>
36 
37 #include <boost/algorithm/string/case_conv.hpp>
38 #include <boost/lexical_cast.hpp>
39 #include <cstdlib>
40 #include <fstream>
41 #include <sstream>
42 #include <iostream>
43 #include <tuple> //for std::ignore
44 
46 #include "TPluginManager.h"
47 
48 #define BINLOEDGE(h, n) h->GetXaxis()->GetBinLowEdge(n)
49 #define BINWIDTH(h, n) h->GetXaxis()->GetBinWidth(n)
50 
52 
53 namespace
54 {
55  // class DisableMustClean {
56  // public:
57  // inline DisableMustClean() : useRecursiveDelete(gROOT->MustClean()) { gROOT->SetMustClean(false); }
58  // inline ~DisableMustClean() { gROOT->SetMustClean(useRecursiveDelete); }
59  // private:
60  // bool useRecursiveDelete;
61  // };
62 
63  Double_t getScaleVal(std::string& display) {
64  std::size_t found = display.find("ScaleRef");
65  std::size_t found2 = display.find_first_of(',', found + 1);
66  // has multiple entries? Do this later.
67  try
68  {
69  return boost::lexical_cast<Double_t>(display.substr(found + 9, found2 - found - 9));
70  }
71  catch (boost::bad_lexical_cast const&)
72  {
73  std::cerr << "Unable to cast scaling value " << display.substr(found + 9, found2 - found - 9) << " to double"
74  << std::endl;
75  return 1.;
76  }
77  }
78 } // end unnamed namespace
79 
80 namespace dqutils
81 {
82  // *********************************************************************
83  // Public Methods
84  // *********************************************************************
85 
86  std::vector<int> root_color_choices = {
87  kBlue, kRed, kGray, kOrange, kViolet, kGreen + 1
88  };
89 
90  HanOutputFile::HanOutputFile() : m_file(0), m_style(0) {
92  TPluginHandler* h;
93  if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualPS", "image"))) {
94  if (h->LoadPlugin() == -1) return;
95 
96  h->ExecPlugin(0);
97  }
98  }
99 
100  HanOutputFile::HanOutputFile(const std::string& fileName) : m_file(0), m_style(0) {
103  TPluginHandler* h;
104  if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualPS", "image"))) {
105  if (h->LoadPlugin() == -1) return;
106 
107  h->ExecPlugin(0);
108  }
109  }
110 
112  // bool useRecursiveDelete = gROOT->MustClean();
113  // gROOT->SetMustClean(false);
114 
116 
117  // gROOT->SetMustClean(useRecursiveDelete);
118  }
119 
120  void HanOutputFile::getAllGroupDirs(DirMap_t& dirmap, TDirectory* dir, const std::string& dirName) {
121  if (dir == 0) return;
122 
123  if (dirName != "") { // Not a file
124  std::string name(dir->GetName());
125  if (name == "Config" || name == "Results") {
126  delete dir;
127  return;
128  }
129 
130  std::string::size_type i = name.find_last_of('_');
131  if (i == (name.size() - 1)) {
132  delete dir;
133  return;
134  }
135 
136  DirMap_t::value_type dirmapVal(dirName, dir);
137  dirmap.insert(dirmapVal);
138  } else {
139  DirMap_t::value_type dirmapVal("<top_level>", dir);
140  dirmap.insert(dirmapVal);
141  }
142 
143  dir->cd();
144 
145  TIter next(dir->GetListOfKeys());
146  TKey* key;
147  while ((key = dynamic_cast<TKey*>(next())) != 0) {
148  // don't delete TDirectories
149  TObject* obj = key->ReadObj();
150  TDirectory* subdir = dynamic_cast<TDirectory*>(obj);
151  if (subdir != 0) {
152  std::string subdirName(subdir->GetName());
153  std::string fName("");
154  if (dirName != "") {
155  fName += dirName;
156  fName += "/";
157  }
158  fName += subdirName;
159  getAllGroupDirs(dirmap, subdir, fName);
160  } else {
161  delete obj;
162  }
163  }
164  }
165 
166  void HanOutputFile::getAllGroupDirs_V2(DirStrMap_t& dirstrmap, TObject* obj, const std::string& objName) {
167  if (obj == nullptr) return;
168 
169  TDirectory* dir {};
170  TString obj_type = obj->ClassName();
171 
172  if (objName != "") { // Not a file
173  if (obj_type == "TDirectoryFile" || obj_type == "TDirectory" || obj_type == "TFile") {
174  dir = (TDirectory*) obj;
175  std::string name(dir->GetName());
176  if (name == "Config" || name == "Results") {
177  delete dir;
178  return;
179  }
180 
181  std::string::size_type i = name.find_last_of('_'); // If this dir is a histgram info
182  if (i == (name.size() - 1)) {
183  delete dir;
184  return;
185  }
186  DirStrMap_t::value_type dirstrmapVal(objName, obj);
187  dirstrmap.insert(dirstrmapVal);
188  } else {
189  DirStrMap_t::value_type dirstrmapVal(objName, obj);
190  dirstrmap.insert(dirstrmapVal);
191  }
192  } else { // If the object is a file
193  DirStrMap_t::value_type dirstrmapVal("<top_level>", obj);
194  dirstrmap.insert(dirstrmapVal);
195  }
196 
197  if (obj_type == "TDirectoryFile" || obj_type == "TDirectory" || obj_type == "TFile") {
198  dir = (TDirectory*) obj;
199  dir->cd();
200  TIter next(dir->GetListOfKeys());
201  TKey* key;
202  while ((key = dynamic_cast<TKey*>(next())) != 0) {
203  // don't delete TDirectories
204  std::string fName("");
205  TObject* obj_in_dir = key->ReadObj();
206  TString obj_in_dir_type = obj_in_dir->ClassName();
207  // Check if this is node (not a histogram)
208  if (obj_in_dir_type == "TDirectoryFile" || obj_in_dir_type == "TDirectory" || obj_in_dir_type == "TFile" ||
209  obj_in_dir_type == "TObjString") {
210  std::string obj_in_dirName;
211  obj_in_dirName = key->GetName(); // If we will read name of the string, it will actually be a content of
212  // the string, so that's why we read name of the key
213  if (objName != "") {
214  fName += objName;
215  fName += "/";
216  }
217  fName += obj_in_dirName; //?
218  if (obj_in_dirName != "Config" && obj_in_dirName != "Results" && obj_in_dirName != "Version_name") { // We
219  // don't
220  // save
221  // 'Config'
222  // and
223  // 'Results'
224  // in
225  // dirstrmap
226  // structure.
227  // And we
228  // don't
229  // store
230  // version
231  // flag
232  // in
233  // dirstrmap
234  // object
235  std::string::size_type i =
236  obj_in_dirName.find_last_of('_'); // if it's an object, that stores info about histogram
237  if (i != (obj_in_dirName.size() - 1)) { // We don't store it in a dirstrmap object
238  getAllGroupDirs_V2(dirstrmap, obj_in_dir,
239  fName); // Everything else we store in dirstrmap as it is for getAllGroupDirs method
240  }
241  }
242  } else { // in case if it isn't a node but a histogram
243  delete obj_in_dir;
244  }
245  }
246  }
247  }
248 
249  void HanOutputFile::getAllAssessments(AssMap_t& dirmap, TDirectory* dir) {
251 
252  dir->cd();
253  TIter next(dir->GetListOfKeys());
254  TKey* key;
255  while ((key = dynamic_cast<TKey*>(next())) != 0) {
256  TObject* obj = key->ReadObj();
257  if (dynamic_cast<TH1*>(obj) || dynamic_cast<TGraph*>(obj) || dynamic_cast<TEfficiency*>(obj)) {
258  const char* path(dir->GetPath());
259  std::string assName(obj->GetName());
260  AssMap_t::value_type AssmapVal(assName, path);
261  dirmap.insert(AssmapVal);
262  }
263  delete obj;
264  }
265  }
266 
267  void HanOutputFile::printDQGroupJSON(const nlohmann::json& j, const std::string& location, const char* path_to_file) {
268  // Parse our JSON and get all nested Assessments
269  nlohmann::json valuestring;
270  for (nlohmann::json::const_iterator it = j.begin(); it != j.end(); ++it) {
271  std::string sName = location;
272  std::string keyname = it.key();
273  if (keyname != "Config" && keyname != "Results") { // We are now at subAssessments (not at Results and Config
274  // nodes)
275  std::string::size_type i = keyname.find_last_of('_'); // if it's an object, that stores info about histogram
276  if (i != (keyname.size() - 1)) { // We don't store it in a dirstrmap object
277  if (location != "") { // Path to the TObjString
278  sName += "/"; // increment the path for the nested assesment
279  }
280  sName += keyname;
281  std::cout << "name: " << sName << ", path: " << path_to_file << sName << "\n";
282  valuestring = it.value(); // JSON content inside the subAssessment
283  printDQGroupJSON(valuestring, sName, path_to_file); // Recursively print Results/Status, Config/name of this
284  // subAssessment and looking for subsubAssessment
285  }
286  }
287  }
288  }
289 
290  std::string HanOutputFile::getStringName(const std::string& location, int file_version) {
291  std::string stringName("Undefined");
292  if (file_version == 1) {
293  // bool success = gROOT->cd(location.c_str() );
294  // if( !success ) {
295  if (gROOT->cd(location.c_str()) == 0) {
296  // std::cout << "Directory \"" << location << "\" is not in han output file\n";
297  return "Undefined";
298  }
299  TIter mylist(gDirectory->GetListOfKeys());
300  TKey* key;
301  while ((key = dynamic_cast<TKey*>(mylist.Next())) != 0) {
302  TObject* obj = key->ReadObj();
303  stringName = (obj->GetName());
304  delete obj;
305  }
306  return stringName;
307  } else if (file_version == 2) {
308  // Split path to TDirectories part and JSON part
309  // All JSON strings are Results or Config
310  std::size_t split_point = 0;
311  std::string JSON_name(""); // Results or Config
312  std::string path_inTDir(""); // Path befor Results
313  std::string path_inJSON(""); // Path after Results
314  if ((split_point = location.find("/Results/")) != std::string::npos) {
315  JSON_name = "Results";
316  path_inTDir = location.substr(0, split_point);
317  path_inJSON = location.substr(split_point + 8); // 8 - is the length of "/Results"
318  } else if ((split_point = location.find("/Config/")) != std::string::npos) {
319  JSON_name = "Config";
320  path_inTDir = location.substr(0, split_point);
321  path_inJSON = location.substr(split_point + 7); // 7 - is the length of "/Config"
322  }
323  // Go to TDirectory path
324  if (gROOT->cd(path_inTDir.c_str()) == 0) {
325  return "Undefined";
326  }
327  // Extract JSON object
328  TObjString* JSON_obj = dynamic_cast<TObjString*>(gDirectory->GetKey(JSON_name.c_str())->ReadObj());
329  if (not JSON_obj) {
330  std::cerr << "HanOutputFile::getStringName : dynamic cast failed\n";
331  return "Null";
332  }
333  std::string JSON_str = (JSON_obj->GetName());
335  nlohmann::json::json_pointer JSON_ptr(path_inJSON);
336  delete JSON_obj; // Maybe should not be used
337  try
338  {
339  auto val = j.at(JSON_ptr);
340  if (!(val.is_null())) stringName = val.get<std::string>();
341  else return "Null";
342  }
343  catch (...)
344  {
345  // Exception. In case if json_pointer (used above) doesn't exist
346  return "Null";
347  }
348  }
349  return stringName;
350  }
351 
352  bool HanOutputFile::containsDir(std::string dirname, std::string maindir) {
353  while (dirname.size() > 0 && dirname[dirname.size() - 1] == '/') {
354  dirname.erase(dirname.size() - 2, dirname.size());
355  }
356  while (dirname.size() > 0 && dirname[0] == '/') {
357  dirname = dirname.substr(1, dirname.size());
358  }
359  std::size_t found = dirname.find_first_of("/", 1);
360  std::string str = dirname.substr(0, found);
361  gROOT->cd(maindir.c_str());
362  TKey* key = gDirectory->FindKey(str.c_str());
363  bool status = false;
364  TObject* obj(0);
365  TDirectory* dirobj(0);
366  if (key != 0) {
367  obj = key->ReadObj();
368  dirobj = dynamic_cast<TDirectory*>(obj);
369  }
370  if (dirobj != 0) {
371  if (found != std::string::npos) {
372  maindir = maindir + "/" + str;
373  dirname = dirname.substr(found + 1, dirname.size());
374  status = containsDir(std::move(dirname), std::move(maindir));
375  } else {
376  status = true;
377  }
378  }
379  delete obj;
380  return status;
381  }
382 
383  std::optional<std::string> HanOutputFile::containsKeyInJSON(
384  const std::string& pathInJSON, const std::string& jsonName, const std::string& path_to_JSON) {
385  gROOT->cd(path_to_JSON.c_str());
386  TKey* key = gDirectory->FindKey(jsonName.c_str());
387  TObject* obj(0);
388  if (key == 0) {
389  return {}; // the JSON with this name is absent
390  } else {
391  obj = key->ReadObj();
392  }
393  std::string content = obj->GetName(); // In ATLAS DQM root files GetName() actually returns the content rather
394  // than the name of a string
395  if (pathInJSON == "") { // If we should check just the existense of the JSON string
396  delete obj;
397  return "JSON exists";
398  }
399  if (pathInJSON == "/") { // When we need the whole JSON string
400  delete obj;
401  return content;
402  }
403  nlohmann::ordered_json j = nlohmann::ordered_json::parse(content);
404  nlohmann::ordered_json::json_pointer p1(pathInJSON);
405  std::string return_string;
406  try
407  {
408  auto val1 = j.at(p1);
409  if (val1.type() == nlohmann::json::value_t::string) {
410  val1.get_to(return_string);
411  } else if (val1.type() == nlohmann::json::value_t::object) {
412  return_string = val1.dump();
413  } else {
414  std::cout << "Warning: Strange part of JSON" << std::endl;
415  delete obj;
416  return {};
417  }
418  }
419  catch (...)
420  {
421  // std::cout<<" the path not exists\n";
422  // std::cout<<"J\n";
423  delete obj;
424  return {};
425  }
426  delete obj;
427  return return_string;
428  }
429 
430  double HanOutputFile::getNEntries(std::string location, std::string histname) {
431  if (m_file == 0) {
432  std::cerr << "HanOutputFile::getNEntries(): "
433  << "No input file is open\n";
434  return 0.0;
435  }
436 
437  double Nentries = 0.0;
438  m_file->cd(location.c_str());
439  // gdirectory->cd(location.c_str() );
440  TH1* h(0);
441  gDirectory->GetObject(histname.c_str(), h);
442  if (h != 0) {
443  Nentries = h->GetEntries();
444  delete h;
445  }
446  TGraph* g(0);
447  gDirectory->GetObject(histname.c_str(), g);
448  if (g != 0) {
449  Nentries = g->GetN();
450  delete g;
451  }
452  TEfficiency* e(0);
453  gDirectory->GetObject(histname.c_str(), e);
454  if (e != 0) {
455  Nentries = e->GetCopyTotalHisto()->GetEntries();
456  delete e;
457  }
458 
459  return Nentries;
460  }
461 
462  double HanOutputFile::getNEntries(const TObject* obj) {
463  if (const TH1* h = dynamic_cast<const TH1*>(obj)) {
464  return h->GetEntries();
465  } else if (const TGraph* g = dynamic_cast<const TGraph*>(obj)) {
466  return g->GetN();
467  } else if (const TEfficiency* e = dynamic_cast<const TEfficiency*>(obj)) {
468  return e->GetCopyTotalHisto()->GetEntries();
469  } else {
470  std::cerr << "HanOutputFile::getNEntries(): "
471  << "provided object is not a histogram or graph\n";
472  return 0.0;
473  }
474  }
475 
476  std::string HanOutputFile::getInfo(const std::string& location, int file_version) {
478  std::string value("");
479  if (file_version == 1) {
480  gROOT->cd(location.c_str());
481  TIter mylist(gDirectory->GetListOfKeys());
482  TKey* key;
483  while ((key = dynamic_cast<TKey*>(mylist.Next())) != 0) {
484  TObject* obj = key->ReadObj();
485  TDirectory* subdir = dynamic_cast<TDirectory*>(obj);
486  if (subdir != 0) {
487  std::string name_subdir = subdir->GetName();
488  gROOT->cd((location + "/" + name_subdir).c_str());
489  TIter mylist1(gDirectory->GetListOfKeys());
490  TKey* key1;
491  while ((key1 = dynamic_cast<TKey*>(mylist1.Next())) != 0) {
492  TObject* obj1 = key1->ReadObj();
493  TDirectory* subsubdir = dynamic_cast<TDirectory*>(obj1);
494  if (subsubdir != 0) {
495  std::string name_subsubdir = obj1->GetName();
496  gROOT->cd((location + "/" + name_subdir + "/" + name_subsubdir).c_str());
497  TIter mylist2(gDirectory->GetListOfKeys());
498  TKey* key2;
499  while ((key2 = dynamic_cast<TKey*>(mylist2.Next())) != 0) {
500  TObject* obj2 = key2->ReadObj();
501  TDirectory* finaldir = dynamic_cast<TDirectory*>(obj2);
502  if (finaldir != 0) {
503  std::string name_finaldir = obj2->GetName();
504  gROOT->cd((location + "/" + name_subdir + "/" + name_subsubdir + "/" + name_finaldir).c_str());
505  TIter mylist3(gDirectory->GetListOfKeys());
506  TKey* key3;
507  while ((key3 = dynamic_cast<TKey*>(mylist3.Next())) != 0) {
508  TObject* obj3 = key3->ReadObj();
509  std::string value_info = obj3->GetName();
510  value += (name_subsubdir + name_finaldir + ": " + value_info + " ");
511  delete obj3;
512  }
513  gROOT->cd((location + "/" + name_subdir + "/" + name_subsubdir).c_str());
514  } else if (name_subsubdir != "name" && name_subsubdir != "Status" && name_subsubdir != "display") {
515  // else if(name_subsubdir!="name" && name_subsubdir!="Status"){
516  std::string value_info = obj2->GetName();
517  value += (name_subsubdir + ": " + value_info + " ");
518  }
519  delete obj2;
520  }
521  gROOT->cd((location + "/" + name_subdir).c_str());
522  } else if (name_subdir != "name" && name_subdir != "Status") {
523  std::string value_info = obj1->GetName();
524  value += (name_subdir + ": " + value_info + " ");
525  }
526  delete obj1;
527  }
528  gROOT->cd((location).c_str());
529  }
530  delete obj;
531  }
532  } else if (file_version == 2) {
533  // Separate Tdirectory from the JSON file. JSON File starts with Results or Config Node
534  std::string JSON_name(""); // Results or Config
535  std::string TDir_path(""); // Path befor Results
536  std::string path_inJSON(""); // Path after Results
537  std::size_t split_point = 0;
538  if ((split_point = location.rfind("/Results")) != std::string::npos) {
539  JSON_name = "Results";
540  TDir_path = location.substr(0, split_point);
541  path_inJSON = location.substr(split_point + 8); // 8 - is the length of "/Results"
542  } else if ((split_point = location.rfind("/Config")) != std::string::npos) {
543  JSON_name = "Config";
544  TDir_path = location.substr(0, split_point);
545  path_inJSON = location.substr(split_point + 7); // 7 - is the length of "/Config"
546  }
547  // Go to TDirectory path
548  if (gROOT->cd(TDir_path.c_str()) == 0) { // Go to Tdirectory, that contains JSON
549  return "Undefined";
550  }
551  // Extract JSON object
552  std::unique_ptr<TObjString> JSON_obj(dynamic_cast<TObjString*>(gDirectory->GetKey(JSON_name.c_str())->ReadObj()));
553  if (not JSON_obj) {
554  std::cerr << "HanOutputFile::getInfo : dynamic cast failed\n";
555  return "Null";
556  }
557  std::string JSON_str = (JSON_obj->GetName());
558  nlohmann::ordered_json j = nlohmann::ordered_json::parse(JSON_str);
559  nlohmann::ordered_json json_in_j;
560  if (path_inJSON != "") {
561  nlohmann::ordered_json::json_pointer JSON_ptr(path_inJSON);
562  try
563  {
564  json_in_j = j.at(JSON_ptr);
565  }
566  catch (...)
567  {
568  // Exception. In case if json_pointer (used above) doesn't exist
569  std::cout << "Wrong path: " << location << "\n";
570  return "Null";
571  }
572  } else {
573  json_in_j = std::move(j);
574  }
575  value = processJSON_ingetInfo(json_in_j);
576  }
577  return value;
578  }
579 
580  std::string HanOutputFile::getInfo(const std::string& JSON_str) {
582  std::string value("");
583  nlohmann::ordered_json j = nlohmann::ordered_json::parse(JSON_str);
585  return value;
586  }
587 
588  std::string HanOutputFile::processJSON_ingetInfo(const nlohmann::ordered_json& j) {
589  std::string value("");
590  for (nlohmann::ordered_json::const_iterator it = j.begin(); it != j.end(); ++it) { // Search in Results/Config node
591  const auto& key = it.key(); // subdir name analog
592  auto val = it.value();
593  if (strcmp(val.type_name(), "object") == 0) { // subsubdir analog
594  for (nlohmann::ordered_json::const_iterator it1 = val.begin(); it1 != val.end(); ++it1) {
595  const auto& key1 = it1.key(); // subsubdir name analog
596  auto val1 = it1.value();
597  if (strcmp(val1.type_name(), "object") == 0) { // finaldir analog
598  for (nlohmann::ordered_json::const_iterator it2 = val1.begin(); it2 != val1.end(); ++it2) {
599  const auto& key2 = it2.key(); // finaldir name analog
600  auto val2 = it2.value(); // leaf
601  value += (key1 + key2 + ": " + val2.get<std::string>() +
602  " "); //.get<std::string is needed to get rid of quotes in cout
603  }
604  } else if (key1 != "name" && key1 != "Status" && key1 != "display") {
605  value += (key1 + ": " + val1.get<std::string>() +
606  " "); //.get<std::string is needed to get rid of quotes in cout
607  }
608  }
609  } else if (key != "name" && key != "Status") {
610  if (val.is_null()) {
611  value += (key + ": null ");
612  } else {
613  value +=
614  (key + ": " + val.get<std::string>() + " "); //.get<std::string is needed to get rid of quotes in cout
615  }
616  }
617  }
618  return value;
619  }
620 
621  std::string HanOutputFile::getIndentation(const std::string& pathName, const std::string& leadingSpace) {
622  std::string space = leadingSpace;
623  std::string::size_type i = pathName.find_first_of('/');
624  if (i != std::string::npos) {
625  std::string subPath(pathName, i + 1, std::string::npos);
626  space += " ";
627  return getIndentation(subPath, space);
628  }
629  return space;
630  }
631 
632  bool HanOutputFile::setFile(const std::string& fileName) {
633  clearData();
634  if (fileName == "") return false;
635 
636  m_file = TFile::Open(fileName.c_str());
637  if (m_file != 0) return true;
638 
639  return false;
640  }
641 
643  if (m_file == 0) {
644  std::cerr << "HanOutputFile::getFileVersion(): "
645  << "No input file is open\n";
646  return 0;
647  }
648 
649  m_file->cd("HanMetadata_");
650 
651  if (gDirectory->FindKey("File")) {
652  gDirectory->cd("File");
653  gDirectory->cd("Version_name");
654  TIter next(gDirectory->GetListOfKeys());
655  TKey* key;
656  while ((key = (TKey*) next())) {
657  TString key_name = key->GetName();
658  if (key_name == "V.2.3") {
659  return 2;
660  } else {
661  return 1;
662  }
663  }
664  } else {
665  return 1;
666  }
667  return 0;
668  }
669 
671  if (m_file == 0) {
672  std::cerr << "HanOutputFile::printAllGroupDirs(): "
673  << "No input file is open\n";
674  return;
675  }
676  int file_version = getFileVersion();
677  if (file_version == 1) {
678  if (m_indirMap.size() == 0) {
680  }
681 
682  DirMap_t::const_iterator idirend = m_indirMap.end();
683  for (DirMap_t::const_iterator idir = m_indirMap.begin(); idir != idirend; ++idir) {
684  std::string idirName = idir->first;
685  const char* path(idir->second->GetPath());
686  std::cout << "name: " << idirName << ", path: " << path << "\n";
687  }
688  } else if (file_version == 2) {
689  if (m_indirstrMap.size() == 0) {
691  }
692  const char* path_to_file = m_file->GetPath();
693  DirStrMap_t::const_iterator idirend = m_indirstrMap.end();
694  for (DirStrMap_t::const_iterator idir = m_indirstrMap.begin(); idir != idirend; ++idir) {
695  std::string idirName = idir->first; // Actually it's a path
696  TDirectory* dirobj = dynamic_cast<TDirectory*>(idir->second);
697  if (dirobj != 0) { // If the object is a TDirectory type
698  std::string pathname(dirobj->GetPath());
699  std::cout << "name: " << idirName << ", path: " << pathname << "\n";
700  } else {
701  std::cout << "name: " << idirName << ", path: " << path_to_file << idirName << "\n";
702  TObjString* strobj = dynamic_cast<TObjString*>(idir->second);
703  if (not strobj) {
704  std::cerr << "HanOutputFile::printAllGroupDirs(): dynamic cast failed\n";
705  continue;
706  }
707  std::string content = strobj->GetName(); // In ATLAS DQM root files GetName() actually returns the
708  // content rather than the name of a string
709  nlohmann::json j = nlohmann::json::parse(content); // Get JSON object from TObjString
710  printDQGroupJSON(j, idirName, path_to_file); // Recursive parsing and print of the nested Assessment in
711  // the form of TOBJString
712  }
713  }
714  }
715  }
716 
718 
720 
722  if (m_file == 0) {
723  std::cerr << "HanOutputFile::stringListSystemPaths(): "
724  << "No input file is open\n";
725  return "";
726  }
727 
728  if (m_indirMap.size() == 0) {
730  }
731 
732  std::string result("");
733 
734  DirMap_t::const_iterator idirend = m_indirMap.end();
735  for (DirMap_t::const_iterator idir = m_indirMap.begin(); idir != idirend; ++idir) {
736  DirToAssMap_t::const_iterator aMapIter = m_assessMap.find(idir->first);
737  if (aMapIter == m_assessMap.end()) {
738  AssMap_t* aMap = new AssMap_t();
739  DirToAssMap_t::value_type aMapVal(idir->first, aMap);
740  aMapIter = m_assessMap.insert(aMapVal).first;
741  getAllAssessments(*aMap, idir->second);
742  }
743 
744  AssMap_t::const_iterator ias = aMapIter->second->begin();
745  if (ias != aMapIter->second->end()) {
746  std::string hisPath = ias->second;
747  std::string::size_type sepi = hisPath.find(':');
748  if (sepi != std::string::npos) {
749  hisPath = std::string(hisPath, sepi + 1, std::string::npos);
750  }
751  std::string completeDir(location);
752  completeDir += hisPath;
753  result += completeDir;
754  result += " ";
755  }
756  }
757  return result;
758  }
759 
761  std::ostringstream result;
763  return result.str();
764  }
765 
767  std::ostringstream result;
769  return result.str();
770  }
771 
773  std::ostringstream result;
775  return result.str();
776  }
777 
778  void HanOutputFile::streamAllDQAssessments(std::ostream& o, bool streamAll) {
779  if (m_file == 0) {
780  std::cerr << "HanOutputFile::streamAllDQAssessments(): "
781  << "No input file is open\n";
782  return;
783  }
784 
785  int file_version = getFileVersion();
786 
787  if ((file_version == 1) || (file_version == 2)) {
788  if (m_indirMap.size() == 0) {
790  }
791 
792  DirMap_t::const_iterator idirend = m_indirMap.end();
793  for (DirMap_t::const_iterator idir = m_indirMap.begin(); idir != idirend; ++idir) {
794  std::string idirName = idir->first;
795  std::string pathname(idir->second->GetPath());
796  std::string::size_type i = pathname.find_last_of('/');
797  if (i != (pathname.size() - 1)) {
798  pathname += "/";
799  }
800  std::string pathnameS = pathname + "Results/Status";
801  std::string pathnameA = pathname + "Config/name";
802  std::string idirStatus = getStringName(pathnameS, file_version);
803  std::string idirAlg = getStringName(pathnameA, file_version);
804  std::string indent = (idirName == "<top_level>") ? "" : getIndentation(idirName, " ");
805  if (!streamAll) {
806  std::string::size_type idirNamei = idirName.find_last_of('/');
807  if (idirNamei != std::string::npos) {
808  idirName = std::string(idirName, idirNamei + 1, std::string::npos);
809  }
810  }
811  std::string formattedName(indent);
812  formattedName += idirName;
813 
814  // left-align this text
815  const std::ios_base::fmtflags savedFlags = o.setf(std::ios_base::left, std::ios_base::adjustfield);
816  // set the width of the next item to be printed
817 
818  o.width(40);
819  o << formattedName << " ";
820  // return to normal right-alignment
821  o.setf(std::ios_base::right, std::ios_base::adjustfield);
822  o.width(9);
823  o << idirStatus << " ";
824  o.width(30);
825  o << idirAlg;
826  if (streamAll) {
827  o << " dir\n";
828  } else {
829  o << "\n";
830  }
831  o.flags(savedFlags);
832 
833  DirToAssMap_t::const_iterator aMapIter = m_assessMap.find(idir->first);
834  if (aMapIter == m_assessMap.end()) {
835  AssMap_t* aMap = new AssMap_t();
836  DirToAssMap_t::value_type aMapVal(idir->first, aMap);
837  aMapIter = m_assessMap.insert(aMapVal).first;
838  getAllAssessments(*aMap, idir->second);
839  }
840 
841  AssMap_t::const_iterator aend = aMapIter->second->end();
842  std::string info1("");
843  std::string info2("");
844  for (AssMap_t::const_iterator ias = aMapIter->second->begin(); ias != aend; ++ias) {
845  std::string hisName = ias->first;
846  std::string hisPath = ias->second;
847  std::string Path1 = hisPath + "/" + hisName + "_/Results";
848  std::string Path2 = hisPath + "/" + hisName + "_/Config";
849  if (streamAll) {
850  info1 = getInfo(Path1, file_version);
851 
852  info2 = getInfo(Path2, file_version);
853  }
854  std::string formattedHistName(indent);
855  std::string status = getStringName(Path1 + "/Status", file_version);
856  std::string algo = getStringName(Path2 + "/name", file_version);
857  formattedHistName += " ";
858  formattedHistName += hisName;
859  // left-align this text
860  const std::ios_base::fmtflags savedFlags = o.setf(std::ios_base::left, std::ios_base::adjustfield);
861  // set the width of the next item to be printed
862 
863  o.width(40);
864  o << formattedHistName << " ";
865  // return to normal right-alignment
866  o.setf(std::ios_base::right, std::ios_base::adjustfield);
867  o.width(9);
868  o << status << " ";
869  o.width(30);
870  o << algo;
871  if (streamAll) {
872  // Get information about hsitogram
873  gDirectory->cd(pathname.c_str());
874  TObject* h;
875  // TH1 *h;
876  gDirectory->GetObject(hisName.c_str(), h);
877  std::string hisTitle = h->GetTitle();
878  // Print information about histograms
879  o << " ass entries: " << getNEntries(h) << " ";
880  TH1* h1;
881  if ((h1 = dynamic_cast<TH1*>(h)) && h1->GetDimension() == 1) {
882  o << " Underflow: " << h1->GetBinContent(0) << " Overflow: " << h1->GetBinContent(h1->GetNbinsX() + 1)
883  << " ";
884  }
885  if (info1 != "" && info2 != "") {
886  o << "Config "
887  << "Config " << info2 << " Results "
888  << "Results " << info1 << " title " << hisTitle << "\n";
889  } else if (info1 != "") {
890  o << "Results Results " << info1 << " title " << hisTitle << "\n";
891  } else if (info2 != "") {
892  o << "Config Config " << info2 << " title " << hisTitle << "\n";
893  } else {
894  o << " title " << hisTitle << "\n";
895  }
896  delete h;
897  } else {
898  o << "\n";
899  }
900  o.flags(savedFlags);
901  }
902  }
903  }
904  }
905 
906  void HanOutputFile::streamHistoAssessments(std::ostream& o, bool streamAll) {
907  if (m_file == 0) {
908  std::cerr << "HanOutputFile::streamHistoAssessments(): "
909  << "No input file is open\n";
910  return;
911  }
912 
913  if (m_indirMap.size() == 0) {
915  }
916 
917  DirMap_t::const_iterator idirend = m_indirMap.end();
918  for (DirMap_t::const_iterator idir = m_indirMap.begin(); idir != idirend; ++idir) {
919  std::string idirName = idir->first;
920  std::string pathname(idir->second->GetPath());
921  std::string::size_type i = pathname.find_last_of('/');
922  if (i != (pathname.size() - 1)) {
923  pathname += "/";
924  }
925  std::string idirStatus = "Undefined";
926  std::string idirAlg = "Undefined";
927  std::string indent = (idirName == "<top_level>") ? "" : getIndentation(idirName, " ");
928  if (!streamAll) {
929  std::string::size_type idirNamei = idirName.find_last_of('/');
930  if (idirNamei != std::string::npos) {
931  idirName = std::string(idirName, idirNamei + 1, std::string::npos);
932  }
933  }
934  std::string formattedName;
935  formattedName += idirName;
936 
937  DirToAssMap_t::const_iterator aMapIter = m_assessMap.find(idir->first);
938  if (aMapIter == m_assessMap.end()) {
939  AssMap_t* aMap = new AssMap_t();
940  DirToAssMap_t::value_type aMapVal(idir->first, aMap);
941  aMapIter = m_assessMap.insert(aMapVal).first;
942  getAllAssessments(*aMap, idir->second);
943  }
944 
945  AssMap_t::const_iterator aend = aMapIter->second->end();
946  for (AssMap_t::const_iterator ias = aMapIter->second->begin(); ias != aend; ++ias) {
947  std::string hisName = ias->first;
948  std::string hisPath = ias->second;
949  std::string formattedHistName;
950  gDirectory->cd(pathname.c_str());
951  // TH1 *h;
952  TObject* h;
953  gDirectory->GetObject(hisName.c_str(), h);
954  std::string hisTitle(h->GetTitle());
955  formattedHistName += "";
956  formattedHistName += hisName;
957  // left-align this text
958  const std::ios_base::fmtflags savedFlags = o.setf(std::ios_base::left, std::ios_base::adjustfield);
959  o.width(40);
960 
961  if (streamAll) {
962  o << hisPath << "/" << formattedHistName << " "
963  << "\n";
964  } else {
965  o << "\n";
966  }
967  o.flags(savedFlags);
968  }
969  }
970  }
971 
972  void HanOutputFile::streamAllHistograms(std::ostream& o, bool streamAll) {
973  if (m_file == 0) {
974  std::cerr << "HanOutputFile::streamAllDQAssessments(): "
975  << "No input file is open\n";
976  return;
977  }
978 
979  if (m_indirMap.size() == 0) {
981  }
982 
983  DirMap_t::const_iterator idirend = m_indirMap.end();
984  for (DirMap_t::const_iterator idir = m_indirMap.begin(); idir != idirend; ++idir) {
985  std::string idirName = idir->first;
986  std::string pathname(idir->second->GetPath());
987  std::string::size_type i = pathname.find_last_of('/');
988  if (i != (pathname.size() - 1)) {
989  pathname += "/";
990  }
991  std::string idirStatus = "Undefined";
992  std::string idirAlg = "Undefined";
993  std::string indent = (idirName == "<top_level>") ? "" : getIndentation(idirName, " ");
994  if (!streamAll) {
995  std::string::size_type idirNamei = idirName.find_last_of('/');
996  if (idirNamei != std::string::npos) {
997  idirName = std::string(idirName, idirNamei + 1, std::string::npos);
998  }
999  }
1000  std::string formattedName(indent);
1001  formattedName += idirName;
1002 
1003  // left-align this text
1004  const std::ios_base::fmtflags savedFlags = o.setf(std::ios_base::left, std::ios_base::adjustfield);
1005  // set the width of the next item to be printed
1006  o.width(40);
1007  o << formattedName << " ";
1008  // return to normal right-alignment
1009  o.setf(std::ios_base::right, std::ios_base::adjustfield);
1010  o.width(9);
1011  o << idirStatus << " ";
1012  o.width(30);
1013  o << idirAlg;
1014  if (streamAll) {
1015  o << " dir\n";
1016  } else {
1017  o << "\n";
1018  }
1019  o.flags(savedFlags);
1020 
1021  DirToAssMap_t::const_iterator aMapIter = m_assessMap.find(idir->first);
1022  if (aMapIter == m_assessMap.end()) {
1023  AssMap_t* aMap = new AssMap_t();
1024  DirToAssMap_t::value_type aMapVal(idir->first, aMap);
1025  aMapIter = m_assessMap.insert(aMapVal).first;
1026  getAllAssessments(*aMap, idir->second);
1027  }
1028 
1029  AssMap_t::const_iterator aend = aMapIter->second->end();
1030  for (AssMap_t::const_iterator ias = aMapIter->second->begin(); ias != aend; ++ias) {
1031  std::string hisName = ias->first;
1032  std::string hisPath = ias->second;
1033  // std::string Path1 = hisPath + "/"+ hisName + "_/Results";
1034  // std::string info1 = getInfo(Path1);
1035  std::string info1, info2;
1036  // std::string Path2 = hisPath + "/"+ hisName + "_/Config";
1037  // std::string info2 = getInfo(Path2);
1038  std::string formattedHistName(indent);
1039  std::string status = "Undefined";
1040  std::string algo = "Undefined";
1041  gDirectory->cd(pathname.c_str());
1042  // TH1 *h;
1043  TObject* h;
1044  gDirectory->GetObject(hisName.c_str(), h);
1045  std::string hisTitle(h->GetTitle());
1046  formattedHistName += " ";
1047  formattedHistName += hisName;
1048  // left-align this text
1049  const std::ios_base::fmtflags savedFlags = o.setf(std::ios_base::left, std::ios_base::adjustfield);
1050  // set the width of the next item to be printed
1051  o.width(40);
1052  o << formattedHistName << " ";
1053  // return to normal right-alignment
1054  o.setf(std::ios_base::right, std::ios_base::adjustfield);
1055  o.width(9);
1056  o << status << " ";
1057  o.width(30);
1058  o << algo;
1059  if (streamAll) {
1060  o << " ass entries: " << getNEntries(h) << " ";
1061  if (info1 != "" && info2 != "") {
1062  o << "Config "
1063  << "Config " << info2 << " Results "
1064  << "Results " << info1 << " title " << hisTitle << "\n";
1065  } else if (info1 != "") {
1066  o << "Results Results " << info1 << " title " << hisTitle << "\n";
1067  } else if (info2 != "") {
1068  o << "Config Config " << info2 << " title " << hisTitle << "\n";
1069  } else {
1070  o << " title " << hisTitle << "\n";
1071  }
1072  } else {
1073  o << "\n";
1074  }
1075  o.flags(savedFlags);
1076  }
1077  }
1078  }
1079 
1080  int HanOutputFile::saveAllHistograms(const std::string& location, bool drawRefs, const std::string& run_min_LB,
1081  int cnvsType) {
1082  if (m_file == 0) {
1083  std::cerr << "HanOutputFile::saveAllHistograms(): "
1084  << "No input file is open\n";
1085  return 0;
1086  }
1087 
1088  if (m_indirMap.size() == 0) {
1090  }
1091 
1092  int nSaved = 0;
1093 
1094  DirMap_t::const_iterator idirend = m_indirMap.end();
1095  for (DirMap_t::const_iterator idir = m_indirMap.begin(); idir != idirend; ++idir) {
1096  DirToAssMap_t::const_iterator aMapIter = m_assessMap.find(idir->first);
1097  if (aMapIter == m_assessMap.end()) {
1098  AssMap_t* aMap = new AssMap_t();
1099  DirToAssMap_t::value_type aMapVal(idir->first, aMap);
1100  aMapIter = m_assessMap.insert(aMapVal).first;
1101  getAllAssessments(*aMap, idir->second);
1102  }
1103  AssMap_t::const_iterator aend = aMapIter->second->end();
1104  for (AssMap_t::const_iterator ias = aMapIter->second->begin(); ias != aend; ++ias) {
1105  std::string hisName = ias->first;
1106  std::string hisPath = ias->second;
1107  std::string::size_type sepi = hisPath.find(':');
1108  if (sepi != std::string::npos) {
1109  hisPath = std::string(hisPath, sepi + 1, std::string::npos);
1110  }
1111  std::string completeDir(location);
1112  completeDir += hisPath;
1113  completeDir += "/";
1114  std::cout << "Saving " << completeDir << " " << hisName << std::endl;
1115  try
1116  {
1117  bool isSaved = saveHistogramToFile(
1118  hisName, std::move(completeDir), idir->second, drawRefs, run_min_LB, (hisPath + "/" + hisName), cnvsType);
1119  if (isSaved) ++nSaved;
1120  }
1121  catch (std::exception& e)
1122  {
1123  std::cerr << "Exception caught: " << e.what() << std::endl;
1124  }
1125  }
1126  }
1127  return nSaved;
1128  }
1129 
1130  void getImageBuffer ATLAS_NOT_THREAD_SAFE(TImage** img, TCanvas* myC, char** x, int* y) {
1131  gVirtualPS->Open(myC->GetName(), 114);
1132  myC->Paint();
1133  auto pImgDump = dynamic_cast<TImageDump*>(gVirtualPS);
1134  if (pImgDump) {
1135  (*img) = pImgDump->GetImage();
1136  if (*img) {
1137  (*img)->GetImageBuffer(x, y, TImage::kPng);
1138  }
1139  }
1140  }
1141 
1142  bool HanOutputFile::saveHistogramToFile(const std::string& nameHis, std::string location, TDirectory* groupDir,
1143  bool drawRefs, const std::string& run_min_LB, const std::string& pathName,
1144  int cnvsType) {
1145  std::pair<std::string, std::string> pngAndJson =
1146  getHistogram(nameHis, groupDir, drawRefs, run_min_LB, pathName, cnvsType);
1147  // std::string tosave = getHistogramPNG(nameHis, groupDir, drawRefs, run_min_LB, pathName);
1148  if (pngAndJson.first == "" && pngAndJson.second == "") {
1149  return false;
1150  }
1151  std::string namePNG = nameHis;
1152  std::string nameJSON = nameHis;
1153 
1154  namePNG += ".png";
1155  nameJSON += ".json";
1156 
1157  std::string::size_type i = location.find_last_of('/');
1158  if (i != (location.size() - 1)) {
1159  location += '/';
1160  }
1161 
1162  namePNG = location + namePNG;
1163  nameJSON = location + nameJSON;
1164  return saveFile(cnvsType, namePNG, pngAndJson.first, nameJSON, pngAndJson.second);
1165  }
1166 
1168  const std::string& nameHis, TDirectory* groupDir, bool drawRefs, const std::string& run_min_LB,
1169  const std::string& pathName) {
1170  int cnvsType = 1;
1171 
1172  return getHistogram(nameHis, groupDir, drawRefs, run_min_LB, pathName, cnvsType).first;
1173  }
1174 
1175  std::pair<std::string, std::string> HanOutputFile::getHistogramJSON(
1176  const std::string& nameHis, TDirectory* groupDir, bool drawRefs, const std::string& run_min_LB,
1177  const std::string& pathName) {
1178  int cnvsType = 2;
1179 
1180  return getHistogram(nameHis, groupDir, drawRefs, run_min_LB, pathName, cnvsType);
1181  }
1182 
1183  std::pair<std::string, std::string> HanOutputFile::getHistogram(const std::string& nameHis, TDirectory* groupDir,
1184  bool drawRefs, const std::string& run_min_LB,
1185  const std::string& pathName, int cnvsType) {
1187  groupDir->cd();
1188 
1189  int iMarkerStyle = 20;
1190  gStyle->SetFrameBorderMode(0);
1191  gStyle->SetFrameFillColor(0);
1192  gStyle->SetCanvasBorderMode(0);
1193  gStyle->SetPadBorderMode(0);
1194  gStyle->SetPadColor(0);
1195  gStyle->SetCanvasColor(0);
1196  gStyle->SetTitleColor(0);
1197  gStyle->SetStatColor(0);
1198  gStyle->SetFillColor(1);
1199  gStyle->SetPalette(1, 0);
1200  gStyle->SetTitleFontSize(0.06);
1201  gStyle->SetTitleH(0.06);
1202  gStyle->SetMarkerStyle(iMarkerStyle);
1203  gStyle->SetOptStat(111100);
1204  gStyle->SetStatBorderSize(0);
1205  gStyle->SetStatX(0.99);
1206  gStyle->SetStatY(0.99);
1207  gStyle->SetStatW(0.2);
1208  gStyle->SetStatH(0.1);
1209 
1210  //Used in TASImage::GetImageBuffer, Buffer must be deallocated after usage with free(buffer) call
1211  char* x = nullptr;
1212  int y {};
1213  std::string json;
1214  TImage* img = nullptr;
1215 
1216  gROOT->SetBatch();
1217  TImageDump tid;
1218  std::string pathname(groupDir->GetPath());
1219  std::string display = "";
1220  bool WasCollectionReference = false;
1221  int file_version = getFileVersion();
1222  bool LookForDisplay;
1223  if (file_version == 1) {
1224  LookForDisplay = containsDir("Config/annotations/display", (pathname + "/" + nameHis + "_"));
1225  if (LookForDisplay) {
1226  display = getStringName(pathname + "/" + nameHis + "_/Config/annotations/display", file_version);
1227  }
1228  } else if (file_version == 2) {
1229  std::optional<std::string> JSON_content;
1230  LookForDisplay = containsDir((nameHis + "_"), pathname);
1231  if (LookForDisplay) {
1232  JSON_content = containsKeyInJSON("/annotations/display", "Config", (pathname + "/" + nameHis + "_"));
1233  if (JSON_content) {
1234  LookForDisplay = true;
1235  } else {
1236  LookForDisplay = false;
1237  }
1238  }
1239  if (LookForDisplay) {
1240  display = JSON_content.value();
1241  }
1242  }
1243  // Plot overflows?
1244  bool PlotOverflows = (display.find("PlotUnderOverflow") != std::string::npos);
1245  // Look for Draw Options
1246  std::size_t found = display.find("Draw=");
1247  std::string drawopt = "";
1248  while (found != std::string::npos) {
1249  std::size_t found1 = display.find_first_of(',', found + 1);
1250  if (found1 != std::string::npos) {
1251  drawopt += boost::algorithm::to_lower_copy(display.substr(found + 5, found1 - found - 5));
1252  } else {
1253  drawopt += boost::algorithm::to_lower_copy(display.substr(found + 5, display.size()));
1254  }
1255  found = display.find("Draw=", found + 1);
1256  }
1257  // Look for DrawRef Options
1258  found = display.find("DrawRef=");
1259  std::string drawrefopt = "";
1260  while (found != std::string::npos) {
1261  std::size_t found1 = display.find_first_of(',', found + 1);
1262  if (found1 != std::string::npos) {
1263  drawrefopt += boost::algorithm::to_lower_copy(display.substr(found + 8, found1 - found - 8));
1264  } else {
1265  drawrefopt += boost::algorithm::to_lower_copy(display.substr(found + 8, display.size()));
1266  }
1267  found = display.find("DrawRef=", found + 1);
1268  }
1269  if (drawrefopt == "") {
1270  drawrefopt = drawopt;
1271  }
1272  // Look for DrawRef2D Options
1273  found = display.find("DrawRef2D=");
1274  std::string drawrefopt2D = "";
1275  while (found != std::string::npos) {
1276  std::size_t found1 = display.find_first_of(',', found + 1);
1277  if (found1 != std::string::npos) {
1278  drawrefopt2D += boost::algorithm::to_lower_copy(display.substr(found + 10, found1 - found - 10));
1279  } else {
1280  drawrefopt2D += boost::algorithm::to_lower_copy(display.substr(found + 10, display.size()));
1281  }
1282  found = display.find("DrawRef2D=", found + 1);
1283  }
1284 
1285  // should we rename "Data" ?
1286  found = display.find("DataName");
1287  std::string datatitle;
1288  if (found == std::string::npos) {
1289  datatitle = "Data";
1290  }
1291  while (found != std::string::npos) {
1292  std::size_t found1 = display.find_first_of(',', found + 1);
1293  if (found1 != std::string::npos) {
1294  datatitle += display.substr(found + 9, found1 - found - 9);
1295  } else {
1296  datatitle += display.substr(found + 9, display.size());
1297  }
1298  found = display.find("DataName", found + 1);
1299  }
1300  groupDir->cd();
1301  TKey* hkey = groupDir->FindKey(nameHis.c_str());
1302  if (hkey == 0) {
1303  std::cerr << "Did not find TKey for \"" << nameHis << "\", will not save this histogram.\n";
1304  return std::pair<std::string, std::string>{
1305  "", ""
1306  };
1307  }
1308  TLegend* legend(0);
1309  TObject* hobj = hkey->ReadObj();
1310  TObject* ref(0);
1311  TH1* hRef(0);
1312  TEfficiency* eRef(0);
1313  TH2* h2Ref(0);
1314  std::vector<TH1*> hRefs;
1315  std::vector<TEfficiency*> eRefs;
1316  bool hasPlotted(false);
1317  TH1* h = dynamic_cast<TH1*>(hobj);
1318  TH2* h2 = dynamic_cast<TH2*>(h);
1319  TGraph* g = dynamic_cast<TGraph*>(hobj);
1320  TEfficiency* e = dynamic_cast<TEfficiency*>(hobj);
1321 
1322  std::string name = nameHis;
1323  /* name+=".png";
1324  std::string::size_type i = location.find_last_of( '/' );
1325  if( i != (location.size()-1) ) {
1326  location+="/";
1327  }
1328  name=location + name; */
1329  std::string AlgoName("");
1330  AlgoName = getStringName(pathname + "/" + nameHis + "_/Config/name", file_version);
1331  int ww = 550;
1332  int wh = 490;
1333  found = display.find("TCanvas", found + 1);
1334  if (found != std::string::npos) {
1335  std::size_t found1 = display.find_first_of(',', found + 1);
1336  ww = std::atoi((display.substr(found + 8, found1 - found - 8)).c_str());
1337  found = display.find_first_of(')', found1 + 1);
1338  wh = std::atoi((display.substr(found1 + 1, found - found1 - 1)).c_str());
1339  }
1340  if (h != 0) {
1341  auto myC = std::make_unique<TCanvas>(nameHis.c_str(), "myC", ww, wh);
1342 
1343  // if( h->GetMinimum() >= 0) {
1344  // gPad->SetLogy(display.find("LogY")!=std::string::npos );
1345  // }
1346  // if( BINLOEDGE(h, 1) > 0) {
1347  // gPad->SetLogx(display.find("LogX")!=std::string::npos );
1348  // }
1349  gPad->SetGridx(display.find("SetGridx") != std::string::npos);
1350  gPad->SetGridy(display.find("SetGridy") != std::string::npos);
1351  std::size_t found = display.find("SetPalette");
1352  if (found != std::string::npos) {
1353  std::size_t found1 = display.find_first_of('(', found + 1);
1354  std::size_t found2 = display.find_first_of(",)", found + 1);
1355  std::string cn = display.substr(found1 + 1, found2 - found1 - 1);
1356  int n1 = std::strtol(cn.c_str(), NULL, 0);
1357  gStyle->SetPalette((Int_t) n1);
1358  }
1359  found = display.find("SetGridStyle");
1360  if (found != std::string::npos) {
1361  std::size_t found1 = display.find_first_of('(', found + 1);
1362  std::size_t found2 = display.find_first_of(",)", found + 1);
1363  std::string cn = display.substr(found1 + 1, found2 - found1 - 1);
1364  int n1 = std::strtol(cn.c_str(), NULL, 0);
1365  gStyle->SetGridStyle((Style_t) n1);
1366  }
1367 
1368  /******************* for plotting fit function on top of histogram ******************/
1369  found = display.find("gaus");
1370  if (found != std::string::npos) {
1371  Double_t minstat = 0.;
1372  std::size_t fpos1, fpos2, fpos;
1373  fpos = display.find("MinStat");
1374  if (fpos != std::string::npos) {
1375  fpos1 = display.find('(', fpos + 1);
1376  if (fpos1 != std::string::npos) {
1377  fpos2 = display.find(')', fpos1 + 1);
1378  if (fpos2 != std::string::npos) {
1379  std::string s_minstat = display.substr(fpos1 + 1, fpos2 - fpos1 - 1);
1380  minstat = std::strtod(s_minstat.c_str(), NULL);
1381  }
1382  }
1383  }
1384  std::string fitopt("");
1385  fpos = display.find("FitOption");
1386  if (fpos != std::string::npos) {
1387  fpos1 = display.find('(', fpos + 1);
1388  if (fpos1 != std::string::npos) {
1389  fpos2 = display.find(')', fpos1 + 1);
1390  if (fpos2 != std::string::npos) {
1391  fitopt = display.substr(fpos1 + 1, fpos2 - fpos1 - 1);
1392  }
1393  }
1394  }
1395  // plot double gaus
1396  std::size_t found1 = display.find("doublegaus");
1397  if (found1 != std::string::npos) {
1398  std::size_t found2 = display.find('(', found1 + 1);
1399  if (found2 != std::string::npos) {
1400  std::size_t found3 = display.find(')', found2 + 1);
1401  if (found3 != std::string::npos) {
1402  std::string range = display.substr(found2 + 1, found3 - found2 - 1);
1403  Double_t xmin = std::strtod(range.c_str(), NULL);
1404  std::size_t found4 = display.find(',', found2 + 1);
1405  if (found4 != std::string::npos) {
1406  range = display.substr(found4 + 1, found3 - found4 - 1);
1407  Double_t xmax = std::strtod(range.c_str(), NULL);
1408  TF1* f1 = new TF1("f1", "gaus", xmin, xmax);
1409  h->Fit(f1, "q");
1410  Double_t par[6];
1411  f1->GetParameters(par);
1412  TF1* func = new TF1("func", "gaus(0)+gaus(3)", xmin, xmax);
1413  func->SetParameters(par);
1414  func->SetParameter(3, h->GetBinContent(h->GetMaximumBin()));
1415  func->SetParameter(4, h->GetMean());
1416  func->SetParameter(5, par[2]);
1417  func->SetLineColor(kRed);
1418  func->SetLineWidth(2);
1419  if (h->GetEffectiveEntries() > minstat) {
1420  h->Fit(func, ("rq" + fitopt).c_str());
1421  }
1422  delete f1;
1423  delete func;
1424  }
1425  }
1426  }
1427  } else {
1428  // draw gaus+pol1
1429  std::size_t found1 = display.find("gauspluspol1");
1430  if (found1 != std::string::npos) {
1431  std::size_t found2 = display.find('(', found1 + 1);
1432  if (found2 != std::string::npos) {
1433  std::size_t found3 = display.find(')', found2 + 1);
1434  if (found3 != std::string::npos) {
1435  std::string range = display.substr(found2 + 1, found3 - found2 - 1);
1436  Double_t xmin = std::strtod(range.c_str(), NULL);
1437  std::size_t found4 = display.find(',', found2 + 1);
1438  if (found4 != std::string::npos) {
1439  range = display.substr(found4 + 1, found3 - found4 - 1);
1440  Double_t xmax = std::strtod(range.c_str(), NULL);
1441  TF1* func = new TF1("func", "gaus(0)+pol1(3)", xmin, xmax);
1442  func->SetLineColor(kRed);
1443  func->SetLineWidth(2);
1444  func->SetParameters(h->GetBinContent(h->GetMaximumBin()), h->GetMean(), h->GetRMS());
1445  if (h->GetEffectiveEntries() > minstat) {
1446  h->Fit(func, ("rq" + fitopt).c_str());
1447  }
1448  delete func;
1449  }
1450  }
1451  }
1452  } else {
1453  // draw gaus+expo
1454  found1 = display.find("gausplusexpo");
1455  if (found1 != std::string::npos) {
1456  std::size_t found2 = display.find('(', found1 + 1);
1457  if (found2 != std::string::npos) {
1458  std::size_t found3 = display.find(')', found2 + 1);
1459  if (found3 != std::string::npos) {
1460  std::string range = display.substr(found2 + 1, found3 - found2 - 1);
1461  Double_t xmin = std::strtod(range.c_str(), NULL);
1462  std::size_t found4 = display.find(',', found2 + 1);
1463  if (found4 != std::string::npos) {
1464  range = display.substr(found4 + 1, found3 - found4 - 1);
1465  Double_t xmax = std::strtod(range.c_str(), NULL);
1466 
1467  TF1* func = new TF1("func", "gaus(0)+expo(3)", xmin, xmax);
1468  func->SetLineColor(kRed);
1469  func->SetLineWidth(2);
1470  func->SetParameters(h->GetBinContent(h->GetMaximumBin()), h->GetMean(), h->GetRMS());
1471  if (h->GetEffectiveEntries() > minstat) {
1472  h->Fit(func, ("rq" + fitopt).c_str());
1473  }
1474  delete func;
1475  }
1476  }
1477  }
1478  } else {
1479  // the last case: single gaus
1480  std::size_t found2 = display.find('(', found + 1);
1481  if (found2 != std::string::npos) {
1482  std::size_t found3 = display.find(')', found2 + 1);
1483  if (found3 != std::string::npos) {
1484  std::string range = display.substr(found2 + 1, found3 - found2 - 1);
1485  Double_t xmin = std::strtod(range.c_str(), NULL);
1486  std::size_t found4 = display.find(',', found2 + 1);
1487  if (found4 != std::string::npos) {
1488  range = display.substr(found4 + 1, found3 - found4 - 1);
1489  Double_t xmax = std::strtod(range.c_str(), NULL);
1490  TF1* func = new TF1("func", "gaus", xmin, xmax);
1491  func->SetLineColor(kRed);
1492  func->SetLineWidth(2);
1493  if (h->GetEffectiveEntries() > minstat) {
1494  h->Fit(func, ("rq" + fitopt).c_str());
1495  }
1496  delete func;
1497  }
1498  }
1499  }
1500  }
1501  }
1502  }
1503  }
1504  if (h2 != 0) {
1505  formatTH2(myC.get(), h2);
1506  myC->cd();
1507  if (h2->GetMinimum() >= 0 && h2->GetMaximum() > 0.) {
1508  gPad->SetLogy(display.find("LogY") != std::string::npos);
1509  gPad->SetLogz(display.find("LogZ") != std::string::npos);
1510  }
1511  if (BINLOEDGE(h2, 1) > 0) {
1512  gPad->SetLogx(display.find("LogX") != std::string::npos);
1513  }
1514  if (h->GetXaxis()->GetXmin() >= h->GetXaxis()->GetXmax()) {
1515  std::cerr << "HanOutputFile::saveHistogramToFile(): "
1516  << "Inconsistent x-axis settings: min=" << h->GetXaxis()->GetXmin() << ", "
1517  << "max=" << h->GetXaxis()->GetXmax() << ", "
1518  << "Will not save this histogram.\n";
1519  return std::pair<std::string, std::string>{
1520  "", ""
1521  };
1522  }
1523  if (h->GetYaxis()->GetXmin() >= h->GetYaxis()->GetXmax()) {
1524  std::cerr << "HanOutputFile::saveHistogramToFile(): "
1525  << "Inconsistent y-axis settings: min=" << h->GetYaxis()->GetXmin() << ", "
1526  << "max=" << h->GetYaxis()->GetXmax() << ", "
1527  << "Will not save this histogram.\n";
1528  return std::pair<std::string, std::string>{
1529  "", ""
1530  };
1531  }
1532  axisOption(display, h2);
1533  if (drawopt == "") {
1534  drawopt = "COLZ";
1535  }
1536  if (drawRefs) {
1537  if (file_version == 1) {
1538  groupDir->cd((nameHis + "_/Results").c_str());
1539  gDirectory->GetObject("Reference;1", ref);
1540  } else if (file_version == 2) {
1541  if (groupDir->GetDirectory((nameHis + "_").c_str()) != 0) {
1542  groupDir->cd((nameHis + "_").c_str());
1543  gDirectory->GetObject("Reference;1", ref);
1544  }
1545  }
1546  h2Ref = dynamic_cast<TH2*>(ref);
1547  TCollection* colln = dynamic_cast<TCollection*>(ref);
1548  if (colln) {
1549  h2Ref = dynamic_cast<TH2*>(colln->MakeIterator()->Next());
1550  }
1551  if (h2Ref && (drawrefopt2D != "")) {
1552  formatTH2(myC.get(), h2Ref);
1553  h2Ref->Draw(drawrefopt2D.c_str());
1554  }
1555  }
1556  h2->Draw(("SAME" + drawopt).c_str());
1557  displayExtra(myC.get(), display);
1558  if (drawopt.find("lego") == std::string::npos) {
1559  myC->RedrawAxis();
1560  }
1561  if (h2Ref) ratioplot2D(myC.get(), h2, h2Ref, display);
1562 
1563  polynomial(myC.get(), display, h2);
1564  TLatex t;
1565  t.SetNDC();
1566  t.SetTextSize(0.03);
1567  t.DrawLatex(0.02, 0.04, run_min_LB.c_str());
1568  TLatex tt;
1569  tt.SetNDC();
1570  tt.SetTextSize(0.03);
1571  tt.DrawLatex(0.02, 0.01, pathName.c_str());
1572  convertToGraphics(cnvsType, myC.get(), json, &img, &x, &y);
1573  } else if (h != 0) {
1574  formatTH1(myC.get(), h);
1575  if (display.find("StatBox") != std::string::npos) {
1576  h->SetStats(kTRUE);
1577  }
1578  if (h->GetXaxis()->GetXmin() >= h->GetXaxis()->GetXmax()) {
1579  std::cerr << "HanOutputFile::saveHistogramToFile(): "
1580  << "Inconsistent x-axis settings: min=" << h->GetXaxis()->GetXmin() << ", "
1581  << "max=" << h->GetXaxis()->GetXmax() << ", "
1582  << "Will not save this histogram.\n";
1583  return std::pair<std::string, std::string>{
1584  "", ""
1585  };
1586  }
1587  h->SetLineColor(kBlack);
1588  h->SetMarkerColor(1);
1589  // h->SetMarkerStyle(iMarkerStyle);
1590  // h->SetMarkerSize(0.8);
1591  h->SetFillStyle(0);
1592  h->SetLineWidth(2);
1593  myC->cd();
1594  if (drawRefs) {
1595  if (file_version == 1) {
1596  groupDir->cd((nameHis + "_/Results").c_str());
1597  gDirectory->GetObject("Reference;1", ref);
1598  } else if (file_version == 2) {
1599  if (groupDir->GetDirectory((nameHis + "_").c_str()) != 0) {
1600  groupDir->cd((nameHis + "_").c_str());
1601  gDirectory->GetObject("Reference;1", ref);
1602  }
1603  }
1604  hRef = dynamic_cast<TH1*>(ref);
1605  if (hRef) {
1606  hRefs.push_back(hRef);
1607  } else {
1608  TCollection* colln = dynamic_cast<TCollection*>(ref);
1609  if (colln) {
1610  WasCollectionReference = true;
1611  std::unique_ptr<TIterator> icolln(colln->MakeIterator());
1612  TObject* ref2;
1613  while ((ref2 = icolln->Next())) {
1614  hRef = dynamic_cast<TH1*>(ref2);
1615  if (hRef) {
1616  if (hRef->GetDimension() == h->GetDimension()) {
1617  hRefs.push_back(hRef);
1618  }
1619  } else std::cout << "hRef cast failed!!!" << std::endl;
1620  }
1621  }
1622  }
1623  groupDir->cd();
1624  }
1625 
1626  if (hRefs.size() > 0) {
1627  legend = new TLegend(0.55, 0.77, 0.87, 0.87);
1628  legend->SetTextFont(62);
1629  legend->SetMargin(0.15);
1630  legend->SetFillStyle(0);
1631  legend->SetBorderSize(0);
1632  legend->AddEntry(h, datatitle.c_str());
1633  int itrcolor(0);
1634  for (auto hRef : hRefs) {
1635  int local_color = root_color_choices[itrcolor];
1636  itrcolor++;
1637  formatTH1(myC.get(), hRef);
1638  TProfile* pRef = dynamic_cast<TProfile*>(hRef);
1639  if (pRef != 0) {
1640  hRef->SetMarkerColor(local_color);
1641  // hRef->SetMarkerStyle(iMarkerStyle);
1642  // hRef->SetMarkerSize(0.8);
1643  hRef->SetLineColor(local_color);
1644  hRef->SetLineWidth(2);
1645  double ymin = (hRef->GetMinimum() < h->GetMinimum()) ? hRef->GetMinimum() : h->GetMinimum();
1646  double ymax = (hRef->GetMaximum() > h->GetMaximum()) ? hRef->GetMaximum() : h->GetMaximum();
1647  double xmin, xmax;
1648  if (PlotOverflows) {
1649  xmin = (BINLOEDGE(hRef, 1) < BINLOEDGE(h, 1) ? BINLOEDGE(hRef, 1) - BINWIDTH(hRef, 1)
1650  : BINLOEDGE(h, 1) - BINWIDTH(h, 1));
1651  xmax = (BINLOEDGE(hRef, hRef->GetNbinsX()) + BINWIDTH(hRef, hRef->GetNbinsX()) >
1652  BINLOEDGE(h, h->GetNbinsX()) + BINWIDTH(h, h->GetNbinsX()))
1653  ? BINLOEDGE(hRef, hRef->GetNbinsX()) + 2.0 * BINWIDTH(hRef, hRef->GetNbinsX())
1654  : BINLOEDGE(h, h->GetNbinsX()) + 2.0 * BINWIDTH(h, h->GetNbinsX());
1655  } else {
1656  xmin = (BINLOEDGE(hRef, 1) < BINLOEDGE(h, 1)) ? BINLOEDGE(hRef, 1) : BINLOEDGE(h, 1);
1657  xmax = (BINLOEDGE(hRef, hRef->GetNbinsX()) > BINLOEDGE(h, h->GetNbinsX())
1658  ? BINLOEDGE(hRef, hRef->GetNbinsX()) + BINWIDTH(hRef, hRef->GetNbinsX())
1659  : BINLOEDGE(h, h->GetNbinsX()) + BINWIDTH(h, h->GetNbinsX()));
1660  }
1661  // double y_av = (ymax + ymin)/2;
1662  // double y_halv = (ymax-ymin)*0.6;
1663  bool isLogY = (display.find("LogY") != std::string::npos);
1664  if (isLogY) {
1665  if (ymax <= 0.) ymax = 5.0;
1666  if (ymin > 0.) {
1667  double lymax = log(ymax);
1668  double lymin = log(ymin);
1669  h->SetAxisRange(exp(lymin - (lymax - lymin) * 0.05), exp(lymax + (lymax - lymin) * 0.05),
1670  "Y"); // leave 5% gap on above and below
1671  } else {
1672  std::cerr << "ymin is <0. and LogY requested for histogram \"" << pathname + "/" + nameHis
1673  << "\", ymin=" << ymin << std::endl;
1674  }
1675  } else {
1676  double yMargin = (ymax - ymin) * 0.05;
1677  h->SetAxisRange(ymin - yMargin, ymax + yMargin, "Y");
1678  }
1679  h->GetXaxis()->SetRangeUser(xmin, xmax);
1680  hRef->GetXaxis()->SetRangeUser(xmin, xmax);
1681  axisOption(display, h);
1682  if (h->GetMinimum() >= 0. && hRef->GetMinimum() >= 0. && h->GetMaximum() > 0. &&
1683  hRef->GetMaximum() > 0.) {
1684  gPad->SetLogy(display.find("LogY") != std::string::npos);
1685  }
1686  if (BINLOEDGE(h, 1) > 0 && BINLOEDGE(hRef, 1) > 0) {
1687  gPad->SetLogx(display.find("LogX") != std::string::npos);
1688  }
1689  if (!hasPlotted) {
1690  h->Draw(drawopt.c_str());
1691  hasPlotted = true;
1692  }
1693  hRef->Draw(("SAME" + drawrefopt).c_str());
1694  } else {
1695  double scale = 1.0;
1696  if (display.find("ScaleRef") != std::string::npos) {
1697  scale = getScaleVal(display);
1698  } else if (h->Integral("width") > 0.0 && hRef->Integral("width") > 0.0 &&
1699  (AlgoName.find("BinContentComp") == std::string::npos) &&
1700  (display.find("NoNorm") == std::string::npos)) {
1701  scale = h->Integral("width") / hRef->Integral("width");
1702  }
1703  hRef->Scale(scale);
1704  // hRef->SetMarkerStyle(iMarkerStyle);
1705  // hRef->SetMarkerSize(0.8);
1706  hRef->SetMarkerColor(local_color);
1707  // hRef->SetFillColor(local_color);
1708  hRef->SetLineColor(local_color);
1709  double ymin = (hRef->GetMinimum() < h->GetMinimum()) ? hRef->GetMinimum() : h->GetMinimum();
1710  double ymax = (hRef->GetMaximum() > h->GetMaximum()) ? hRef->GetMaximum() : h->GetMaximum();
1711  double xmin, xmax;
1712  if (PlotOverflows) {
1713  xmin = (BINLOEDGE(hRef, 1) < BINLOEDGE(h, 1)) ? BINLOEDGE(hRef, 1) - BINWIDTH(hRef, 1)
1714  : BINLOEDGE(h, 1) - BINWIDTH(h, 1);
1715  xmax = (BINLOEDGE(hRef, hRef->GetNbinsX()) + BINWIDTH(hRef, hRef->GetNbinsX()) >
1716  BINLOEDGE(h, h->GetNbinsX()) + BINWIDTH(h, h->GetNbinsX()))
1717  ? BINLOEDGE(hRef, hRef->GetNbinsX()) + 2.0 * BINWIDTH(hRef, hRef->GetNbinsX())
1718  : BINLOEDGE(h, h->GetNbinsX()) + 2.0 * BINWIDTH(h, h->GetNbinsX());
1719  } else {
1720  xmin = (BINLOEDGE(hRef, 1) < BINLOEDGE(h, 1)) ? BINLOEDGE(hRef, 1) : BINLOEDGE(h, 1);
1721  xmax = (BINLOEDGE(hRef, hRef->GetNbinsX()) + BINWIDTH(hRef, hRef->GetNbinsX()) >
1722  BINLOEDGE(h, h->GetNbinsX()) + BINWIDTH(h, h->GetNbinsX()))
1723  ? BINLOEDGE(hRef, hRef->GetNbinsX()) + BINWIDTH(hRef, hRef->GetNbinsX())
1724  : BINLOEDGE(h, h->GetNbinsX()) + BINWIDTH(h, h->GetNbinsX());
1725  }
1726 
1727  // double y_av = (ymax + ymin)/2;
1728  // double y_halv = (ymax-ymin)*0.6;
1729  bool isLogY = (display.find("LogY") != std::string::npos);
1730  // if ( ymin == 0.0 && display.find("LogY")!=std::string::npos ){
1731 
1732  if (isLogY) {
1733  if (ymax <= 0.) ymax = 5.0;
1734  if (ymin > 0.) {
1735  double lymax = log(ymax);
1736  double lymin = log(ymin);
1737  h->SetAxisRange(exp(lymin - (lymax - lymin) * 0.05), exp(lymax + (lymax - lymin) * 0.05), "Y");
1738  // leave 5% gap on above and below
1739  } else {
1740  std::cerr << "ymin is <=0. and LogY requested for histogram \"" << pathname + "/" + nameHis
1741  << "\", ymin=" << ymin << std::endl;
1742  }
1743  } else {
1744  double yDiff = ymax - ymin;
1745  h->SetAxisRange(ymin - yDiff * 0.05, ymax + yDiff * 0.05, "Y"); // leave 5% gap above and below
1746  }
1747 
1748  h->GetXaxis()->SetRangeUser(xmin, xmax);
1749  hRef->GetXaxis()->SetRangeUser(xmin, xmax);
1750  myC->cd();
1751  if (h->GetMinimum() >= 0 && hRef->GetMinimum() >= 0 && h->GetMaximum() > 0. && hRef->GetMaximum() > 0.) {
1752  gPad->SetLogy(display.find("LogY") != std::string::npos);
1753  }
1754  if (BINLOEDGE(h, 1) > 0 && BINLOEDGE(hRef, 1) > 0) {
1755  gPad->SetLogx(display.find("LogX") != std::string::npos);
1756  }
1757  axisOption(display, h);
1758  if (!hasPlotted) {
1759  h->Draw(drawopt.c_str());
1760  hasPlotted = true;
1761  }
1762  hRef->Draw(("SAME" + drawrefopt).c_str());
1763  }
1764  if (WasCollectionReference) {
1765  legend->AddEntry(hRef, hRef->GetName());
1766  } else {
1767  std::string refInfo("");
1768  refInfo = getStringName(pathname + "/" + nameHis + "_/Config/annotations/refInfo", file_version);
1769  legend->AddEntry(hRef, refInfo != "Undefined" ? refInfo.c_str() : "Reference");
1770  }
1771  }
1772  h->Draw(("SAME" + drawopt).c_str());
1773  legend->Draw();
1774  } else {
1775  myC->cd();
1776  if (h->GetMinimum() >= 0) {
1777  gPad->SetLogy(display.find("LogY") != std::string::npos);
1778  }
1779  if (BINLOEDGE(h, 1) > 0) {
1780  gPad->SetLogx(display.find("LogX") != std::string::npos);
1781  }
1782  axisOption(display, h);
1783  h->Draw(drawopt.c_str());
1784  }
1785  myC->cd();
1786  displayExtra(myC.get(), display);
1787  myC->RedrawAxis();
1788 
1789  if (hRef) {
1790  ratioplot(myC.get(), h, hRef, display); // RatioPad
1791  }
1792  myC->cd(); // might be unnecessary
1793  polynomial(myC.get(), display, h); // draw polynome for TH1
1794 
1795  TLatex t;
1796  t.SetNDC();
1797  t.SetTextSize(0.03);
1798  t.DrawLatex(0.02, 0.04, run_min_LB.c_str());
1799  TLatex tt;
1800  tt.SetNDC();
1801  tt.SetTextSize(0.03);
1802  tt.DrawLatex(0.02, 0.01, pathName.c_str());
1803 
1804  convertToGraphics(cnvsType, myC.get(), json, &img, &x, &y);
1805  }
1806  // delete myC;
1807  gStyle->Reset();
1808  }
1809  if (g) {
1810  auto myC = std::make_unique<TCanvas>(nameHis.c_str(), "myC", ww, wh);
1811  myC->cd();
1812  if (g->GetMinimum() >= 0. && g->GetMaximum() > 0.) {
1813  gPad->SetLogy(display.find("LogY") != std::string::npos);
1814  }
1815  // if( BINLOEDGE(h2, 1) > 0) {
1816  // gPad->SetLogx(display.find("LogX")!=std::string::npos );
1817  // }
1818  // gPad->SetLogz(display.find("LogZ")!=std::string::npos );
1819  formatTGraph(myC.get(), g);
1820  // axisOption(display,g);
1821  g->Draw((std::string("AP") + drawopt).c_str());
1822  displayExtra(myC.get(), display);
1823  TLatex t;
1824  t.SetNDC();
1825  t.SetTextSize(0.03);
1826  t.DrawLatex(0.02, 0.04, run_min_LB.c_str());
1827  TLatex tt;
1828  tt.SetNDC();
1829  tt.SetTextSize(0.03);
1830  tt.DrawLatex(0.02, 0.01, pathName.c_str());
1831  // myC->SaveAs( name.c_str() );
1832 
1833  convertToGraphics(cnvsType, myC.get(), json, &img, &x, &y);
1834 
1835  gStyle->Reset();
1836  }
1837  if (e != 0) {
1838  hasPlotted = false;
1839  auto myC = std::make_unique<TCanvas>(nameHis.c_str(), "myC", ww, wh);
1840  formatTEfficiency(myC.get(), e);
1841  if (drawopt == "") {
1842  if (e->GetDimension() == 1) {
1843  drawopt = "AP";
1844  } else {
1845  drawopt = "COLZ";
1846  }
1847  }
1848  if (drawRefs) {
1849  if (file_version == 1) {
1850  groupDir->cd((nameHis + "_/Results").c_str());
1851  gDirectory->GetObject("Reference;1", ref);
1852  } else if (file_version == 2) {
1853  if (groupDir->cd((nameHis + "_").c_str())) {
1854  gDirectory->GetObject("Reference;1", ref);
1855  }
1856  }
1857  eRef = dynamic_cast<TEfficiency*>(ref);
1858  if (eRef) {
1859  eRefs.push_back(eRef);
1860  } else {
1861  TCollection* colln = dynamic_cast<TCollection*>(ref);
1862  if (colln) {
1863  WasCollectionReference = true;
1864  TIterator* icolln = colln->MakeIterator();
1865  TObject* ref2;
1866  while ((ref2 = icolln->Next())) {
1867  eRef = dynamic_cast<TEfficiency*>(ref2);
1868  if (eRef) {
1869  if (eRef->GetDimension() == e->GetDimension()) {
1870  eRefs.push_back(eRef);
1871  }
1872  } else std::cout << "eRef cast failed!!!" << std::endl;
1873  }
1874  }
1875  }
1876  groupDir->cd();
1877  }
1878  if (eRefs.size() > 0) {
1879  legend = new TLegend(0.55, 0.77, 0.87, 0.87);
1880  legend->SetTextFont(62);
1881  legend->SetMargin(0.15);
1882  legend->SetFillStyle(0);
1883  legend->SetBorderSize(0);
1884  legend->AddEntry(e, datatitle.c_str());
1885  int itrcolor(0);
1886  for (auto eRef : eRefs) {
1887  myC->cd();
1888  e->Draw("");
1889  eRef->Draw("");
1890  gPad->Update();
1891 
1892  int local_color = root_color_choices[itrcolor];
1893  itrcolor++;
1894 
1895  formatTEfficiency(myC.get(), eRef);
1896  eRef->SetMarkerColor(local_color);
1897  eRef->SetLineColor(local_color);
1898 
1899  if (!hasPlotted) {
1900  e->Draw(drawopt.c_str());
1901  hasPlotted = true;
1902  }
1903  eRef->Draw("SAME");
1904  myC->Update();
1905 
1906  if (WasCollectionReference) {
1907  legend->AddEntry(eRef, eRef->GetName());
1908  } else {
1909  std::string refInfo("");
1910  refInfo = getStringName(pathname + "/" + nameHis + "_/Config/annotations/refInfo", file_version);
1911  legend->AddEntry(eRef, refInfo != "Undefined" ? refInfo.c_str() : "Reference");
1912  }
1913  }
1914  legend->Draw();
1915  } else {
1916  myC->cd();
1917  e->Draw(drawopt.c_str());
1918  }
1919 
1920  // Fix to display x axis title
1921  myC->Update();
1922  e->GetPaintedGraph()->GetXaxis()->SetTitleColor();
1923 
1924  myC->cd();
1925  displayExtra(myC.get(), display);
1926  TLatex t;
1927  t.SetNDC();
1928  t.SetTextSize(0.03);
1929  t.DrawLatex(0.02, 0.04, run_min_LB.c_str());
1930  TLatex tt;
1931  tt.SetNDC();
1932  tt.SetTextSize(0.03);
1933  tt.DrawLatex(0.02, 0.01, pathName.c_str());
1934  convertToGraphics(cnvsType, myC.get(), json, &img, &x, &y);
1935  gStyle->Reset();
1936  }
1937  std::string rv;
1938  if (cnvsType & GENERATE_PNG) {
1939  if (x) rv.assign(x, y);
1940  }
1941  ;
1942  std::pair<std::string, std::string> rvPair {
1943  rv, json
1944  };
1945  //deallocate image buffer with free(x), see https://root.cern.ch/doc/master/classTASImage.html
1946  free(x);
1947  delete hobj;
1948  delete ref;
1949  delete legend;
1950  return rvPair;
1951  }
1952 
1953  bool HanOutputFile::saveHistogramToFileSuperimposed(const std::string& nameHis, std::string location,
1954  TDirectory* groupDir1,
1955  TDirectory* groupDir2, bool drawRefs,
1956  const std::string& run_min_LB, const std::string& pathName,
1957  int cnvsType) {
1959  groupDir1->cd();
1960  gStyle->SetFrameBorderMode(0);
1961  gStyle->SetFrameFillColor(0);
1962  gStyle->SetCanvasBorderMode(0);
1963  gStyle->SetPadBorderMode(0);
1964  gStyle->SetPadColor(0);
1965  gStyle->SetCanvasColor(0);
1966  gStyle->SetTitleColor(0);
1967  gStyle->SetStatColor(0);
1968  gStyle->SetFillColor(1);
1969  gStyle->SetPalette(1, 0);
1970  gStyle->SetTitleFontSize(0.06);
1971  gStyle->SetTitleH(0.06);
1972  gStyle->SetMarkerStyle(20);
1973  gStyle->SetOptStat(111100);
1974  gStyle->SetStatBorderSize(0);
1975  gStyle->SetStatX(0.99);
1976  gStyle->SetStatY(0.99);
1977  gStyle->SetStatW(0.2);
1978  gStyle->SetStatH(0.1);
1979 
1980  gROOT->SetBatch();
1981  std::string pathname(groupDir1->GetPath());
1982  std::string display = "";
1983  int file_version = getFileVersion();
1984  bool LookForDisplay;
1985  if (file_version == 1) {
1986  LookForDisplay = containsDir("Config/annotations/display", (pathname + "/" + nameHis + "_"));
1987  if (LookForDisplay) {
1988  display = getStringName(pathname + "/" + nameHis + "_/Config/annotations/display", file_version);
1989  }
1990  } else if (file_version == 2) {
1991  std::optional<std::string> JSON_content;
1992  LookForDisplay = containsDir((nameHis + "_"), pathname);
1993  if (LookForDisplay) {
1994  JSON_content = containsKeyInJSON("/annotations/display", "Config", (pathname + "/" + nameHis + "_"));
1995  if (JSON_content) {
1996  LookForDisplay = true;
1997  } else {
1998  LookForDisplay = false;
1999  }
2000  }
2001  if (LookForDisplay) {
2002  display = JSON_content.value();
2003  }
2004  }
2005 
2006  // Look for Draw Options
2007  std::size_t found = display.find("Draw");
2008  std::string drawopt = "";
2009  while (found != std::string::npos) {
2010  std::size_t found1 = display.find_first_of(',', found + 1);
2011  if (found1 != std::string::npos) {
2012  drawopt += boost::algorithm::to_lower_copy(display.substr(found + 5, found1 - found - 5));
2013  } else {
2014  drawopt += boost::algorithm::to_lower_copy(display.substr(found + 5, display.size()));
2015  }
2016  found = display.find("Draw", found + 1);
2017  }
2018 
2019  groupDir1->cd();
2020  TKey* hkey = groupDir1->FindKey(nameHis.c_str());
2021  groupDir2->cd();
2022  TKey* hkey2 = groupDir2->FindKey(nameHis.c_str());
2023  if (hkey == 0 || hkey2 == 0) {
2024  std::cerr << "Did not find TKey for \"" << nameHis << "\", will not save this histogram.\n";
2025  return false;
2026  }
2027  groupDir1->cd();
2028  TLegend* legend(0);
2029  TObject* hobj = hkey->ReadObj();
2030  TObject* hobj2 = hkey2->ReadObj();
2031  TH1* hRef(0);
2032  TH1* h(0), *hist2(0);
2033  TH2* h2(0), *h2_2(0), *h2Diff(0);
2034  TGraph* g(0), *g2(0);
2035  TEfficiency* e(0), *e2(0);
2036 
2037  std::string json;
2038  std::string nameJSON = nameHis;
2039  std::string namePNG = nameHis;
2040  namePNG += ".png";
2041  nameJSON += ".json";
2042  std::string::size_type i = location.find_last_of('/');
2043  if (i != (location.size() - 1)) {
2044  location += "/";
2045  }
2046  namePNG = location + namePNG;
2047  nameJSON = location + nameJSON;
2048  std::string AlgoName = getStringName(pathname + "/" + nameHis + "_/Config/name", file_version);
2049  int ww = 550;
2050  int wh = 490;
2051  found = display.find("TCanvas", found + 1);
2052  if (found != std::string::npos) {
2053  std::size_t found1 = display.find_first_of(',', found + 1);
2054  ww = std::atoi((display.substr(found + 8, found1 - found - 8)).c_str());
2055  found = display.find_first_of(')', found1 + 1);
2056  wh = std::atoi((display.substr(found1 + 1, found - found1 - 1)).c_str());
2057  }
2058 
2059  if ((h = dynamic_cast<TH1*>(hobj)) != 0 && (hist2 = dynamic_cast<TH1*>(hobj2)) != 0) {
2060  auto myC = std::make_unique<TCanvas>(nameHis.c_str(), "myC", ww, wh);
2061  setupCanvas(drawopt, display);
2062  attachFits(h, drawopt, display);
2063  /******************* for plotting fit function on top of histogram ******************/
2064 
2065  /*************************************************************************************************************/
2066  std::string tmpdraw(drawopt);
2067  if ((h2 = dynamic_cast<TH2*>(h)) != 0 && ((h2_2 = dynamic_cast<TH2*>(hist2)) != 0)) {
2068  // if(tmpdraw=="")
2069  h2Diff = (TH2*) h2->Clone("difference");
2070  // tmpdraw="box";//we don't want colz for overlaid histos
2071  // h2->SetLineColor(2);
2072  // h2->SetMarkerColor(2);
2073  // if(!drawH2(myC,h2,tmpdraw,display))return false;
2074  // h2_2->SetMarkerColor(4);
2075  // //h2_2->SetFillColor(4);
2076  // h2_2->SetLineWidth(2);
2077  // h2_2->SetLineColor(4);
2078  // tmpdraw=" box same";
2079  // if(!drawH2(myC,h2_2,tmpdraw,display))return false;
2080  h2Diff->Add(h2, h2_2, 1.0, -1.0);
2081  h2Diff->SetLineColor(2);
2082  h2Diff->SetMarkerColor(2);
2083  if (!drawH2(myC.get(), h2Diff, tmpdraw, display)) return false;
2084 
2085  TLatex t;
2086  t.SetNDC();
2087  t.SetTextSize(0.03);
2088  t.DrawLatex(0.02, 0.04, (run_min_LB + " difference").c_str());
2089  TLatex tt;
2090  tt.SetNDC();
2091  tt.SetTextSize(0.03);
2092  tt.DrawLatex(0.02, 0.01, pathName.c_str());
2093 
2094  convertToGraphics(cnvsType, myC.get(), namePNG, nameJSON);
2095  } else if (h != 0 && hist2 != 0) {
2096  // Petronel
2097  double scale = 1.0;
2098  if (display.find("ScaleRef") != std::string::npos) {
2099  scale = getScaleVal(display);
2100  } else if (h->Integral("width") > 0.0 && hist2->Integral("width") > 0.0 &&
2101  (AlgoName.find("BinContentComp") == std::string::npos) &&
2102  (display.find("NoNorm") == std::string::npos)) {
2103  scale = h->Integral("width") / hist2->Integral("width");
2104  }
2105  hist2->Scale(scale);
2106  double ymin = (hist2->GetMinimum() < h->GetMinimum()) ? hist2->GetMinimum() : h->GetMinimum();
2107  double ymax = (hist2->GetMaximum() > h->GetMaximum()) ? hist2->GetMaximum() : h->GetMaximum();
2108  double yMargin = (ymax - ymin) * 0.05;
2109  h->SetAxisRange(ymin - yMargin, ymax + yMargin, "Y");
2110 
2111  h->SetMarkerColor(1);
2112  h->SetFillStyle(0);
2113  h->SetLineWidth(2);
2114  hist2->SetMarkerColor(4);
2115  hist2->SetLineColor(4);
2116  hist2->SetFillStyle(0);
2117  hist2->SetLineWidth(2);
2118  if (drawRefs) {
2119  if (file_version == 1) {
2120  groupDir1->cd((nameHis + "_/Results").c_str());
2121  } else {
2122  groupDir1->cd((nameHis + "_").c_str());
2123  }
2124  gDirectory->GetObject("Reference;1", hRef);
2125  groupDir1->cd();
2126  }
2127  if (!drawH1(myC.get(), h, hRef, tmpdraw, display, AlgoName)) return false;
2128 
2129  tmpdraw += "same";
2130  if (!drawH1(myC.get(), hist2, 0, tmpdraw, display, AlgoName)) return false;
2131 
2132  legend = new TLegend(0.55, 0.77, 0.87, 0.87);
2133  legend->SetTextFont(62);
2134  legend->SetMargin(0.15);
2135  legend->SetFillStyle(0);
2136  legend->SetBorderSize(0);
2137 
2138  std::size_t foundN1 = run_min_LB.find_first_of("-");
2139  std::size_t foundN2 = run_min_LB.find_first_of(',');
2140 
2141  legend->AddEntry(h, ("Run " + run_min_LB.substr(5, foundN1 - 5)).c_str());
2142  legend->AddEntry(hist2, ("Run " + run_min_LB.substr(foundN1 + 1, foundN2 - foundN1 - 1)).c_str());
2143  if (hRef) {
2144  legend->AddEntry(hRef, "Reference");
2145  }
2146  legend->Draw();
2147 
2148  TLatex t;
2149  t.SetNDC();
2150  t.SetTextSize(0.03);
2151  t.DrawLatex(0.02, 0.04, run_min_LB.c_str());
2152  TLatex tt;
2153  tt.SetNDC();
2154  tt.SetTextSize(0.03);
2155  tt.DrawLatex(0.02, 0.01, pathName.c_str());
2156 
2157  convertToGraphics(cnvsType, myC.get(), namePNG, nameJSON);
2158  } // end histogram drawing
2159  delete h2Diff;
2160  gStyle->Reset();
2161  }
2162 
2163  /*************************************************************************************************************/
2164  if (((g = dynamic_cast<TGraph*>(hobj)) != 0) && ((g2 = dynamic_cast<TGraph*>(hobj2)) != 0)) {
2165  auto myC = std::make_unique<TCanvas>(nameHis.c_str(), "myC", ww, wh);
2166  myC->cd();
2167  if (g->GetMinimum() >= 0. && g2->GetMinimum() >= 0. && g->GetMaximum() > 0. && g2->GetMaximum() > 0.) {
2168  gPad->SetLogy(display.find("LogY") != std::string::npos);
2169  }
2170  formatTGraph(myC.get(), g);
2171  formatTGraph(myC.get(), g2);
2172  g->Draw((std::string("AP") + drawopt).c_str());
2173  displayExtra(myC.get(), display);
2174  g2->SetMarkerColor(2);
2175  g2->SetLineColor(2);
2176  g2->Draw((std::string("P") + drawopt + " same").c_str());
2177  TLatex t;
2178  t.SetNDC();
2179  t.SetTextSize(0.03);
2180  t.DrawLatex(0.02, 0.04, run_min_LB.c_str());
2181  TLatex tt;
2182  tt.SetNDC();
2183  tt.SetTextSize(0.03);
2184  tt.DrawLatex(0.02, 0.01, pathName.c_str());
2185 
2186  convertToGraphics(cnvsType, myC.get(), namePNG, nameJSON);
2187 
2188  gStyle->Reset();
2189  }
2190 
2191  if (((e = dynamic_cast<TEfficiency*>(hobj)) != 0) && ((e2 = dynamic_cast<TEfficiency*>(hobj2)) != 0)) {
2192  auto myC = std::make_unique<TCanvas>(nameHis.c_str(), "myC", ww, wh);
2193  myC->cd();
2194 
2195  formatTEfficiency(myC.get(), e);
2196  formatTEfficiency(myC.get(), e2);
2197  e->Draw((std::string("AP") + drawopt).c_str());
2198 
2199  // Fix to display x axis title
2200  myC->Update();
2201  e->GetPaintedGraph()->GetXaxis()->SetTitleColor();
2202 
2203  displayExtra(myC.get(), display);
2204  e2->SetMarkerColor(2);
2205  e2->SetLineColor(2);
2206  e2->Draw((std::string("P") + drawopt + " same").c_str());
2207  TLatex t;
2208  t.SetNDC();
2209  t.SetTextSize(0.03);
2210  t.DrawLatex(0.02, 0.04, run_min_LB.c_str());
2211  TLatex tt;
2212  tt.SetNDC();
2213  tt.SetTextSize(0.03);
2214  tt.DrawLatex(0.02, 0.01, pathName.c_str());
2215 
2216  convertToGraphics(cnvsType, myC.get(), namePNG, std::move(nameJSON));
2217 
2218  gStyle->Reset();
2219  }
2220 
2221  delete hobj;
2222  delete hobj2;
2223  delete hRef;
2224  delete legend;
2225  return true;
2226  }
2227 
2228  bool HanOutputFile::drawH2(TCanvas* myC, TH2* h2, std::string& drawop, std::string& display) {
2229  std::string drawopt(drawop);
2230  myC->cd();
2231  if (h2->GetMinimum() >= 0 && h2->GetMaximum() > 0) {
2232  gPad->SetLogy(display.find("LogY") != std::string::npos);
2233  gPad->SetLogz(display.find("LogZ") != std::string::npos);
2234  } else {
2235  gPad->SetLogy(false);
2236  }
2237  if (BINLOEDGE(h2, 1) > 0) {
2238  gPad->SetLogx(display.find("LogX") != std::string::npos);
2239  } else {
2240  gPad->SetLogx(false);
2241  }
2242  formatTH2(myC, h2);
2243  if (h2->GetXaxis()->GetXmin() >= h2->GetXaxis()->GetXmax()) {
2244  std::cerr << "HanOutputFile::saveHistogramToFile(): "
2245  << "Inconsistent x-axis settings: min=" << h2->GetXaxis()->GetXmin() << ", "
2246  << "max=" << h2->GetXaxis()->GetXmax() << ", "
2247  << "Will not save this histogram.\n";
2248  return false;
2249  }
2250  if (h2->GetYaxis()->GetXmin() >= h2->GetYaxis()->GetXmax()) {
2251  std::cerr << "HanOutputFile::saveHistogramToFile(): "
2252  << "Inconsistent y-axis settings: min=" << h2->GetYaxis()->GetXmin() << ", "
2253  << "max=" << h2->GetYaxis()->GetXmax() << ", "
2254  << "Will not save this histogram.\n";
2255  return false;
2256  }
2257  axisOption(display, h2);
2258  if (drawopt == "") {
2259  drawopt = "COLZ";
2260  }
2261  h2->Draw(drawopt.c_str());
2262  displayExtra(myC, display);
2263  // std::cout<<"drawh2 drawopt="<<drawopt<<",display="<<display<<std::endl;
2264  // if (drawopt.find("lego") == std::string::npos) {
2265  myC->RedrawAxis();
2266  //}
2267  return true;
2268  }
2269 
2270  void HanOutputFile::setupCanvas(std::string& drawopt, std::string& display) {
2271  gPad->SetGridx(display.find("SetGridx") != std::string::npos);
2272  gPad->SetGridy(display.find("SetGridy") != std::string::npos);
2273  std::size_t found = display.find("SetPalette");
2274  if (found != std::string::npos) {
2275  std::size_t found1 = display.find_first_of('(', found + 1);
2276  std::size_t found2 = display.find_first_of(",)", found + 1);
2277  std::string cn = display.substr(found1 + 1, found2 - found1 - 1);
2278  int n1 = std::strtol(cn.c_str(), NULL, 0);
2279  gStyle->SetPalette((Int_t) n1);
2280  }
2281  found = display.find("SetGridStyle");
2282  if (found != std::string::npos) {
2283  std::size_t found1 = display.find_first_of('(', found + 1);
2284  std::size_t found2 = display.find_first_of(",)", found + 1);
2285  std::string cn = display.substr(found1 + 1, found2 - found1 - 1);
2286  int n1 = std::strtol(cn.c_str(), NULL, 0);
2287  gStyle->SetGridStyle((Style_t) n1);
2288  }
2289  if (!drawopt.empty()) {
2290  // do any modifications coming from drawopt
2291  }
2292  }
2293 
2294  void HanOutputFile::attachFits(TH1* h, std::string& drawopt, std::string& display) {
2295  size_t found = display.find("gaus");
2296 
2297  if (found != std::string::npos) {
2298  Double_t minstat = 0.;
2299  std::size_t fpos1, fpos2, fpos;
2300  fpos = display.find("MinStat");
2301  if (fpos != std::string::npos) {
2302  fpos1 = display.find('(', fpos + 1);
2303  if (fpos1 != std::string::npos) {
2304  fpos2 = display.find(')', fpos1 + 1);
2305  if (fpos2 != std::string::npos) {
2306  std::string s_minstat = display.substr(fpos1 + 1, fpos2 - fpos1 - 1);
2307  minstat = std::strtod(s_minstat.c_str(), NULL);
2308  }
2309  }
2310  }
2311  std::string fitopt("");
2312  fpos = display.find("FitOption");
2313  if (fpos != std::string::npos) {
2314  fpos1 = display.find('(', fpos + 1);
2315  if (fpos1 != std::string::npos) {
2316  fpos2 = display.find(')', fpos1 + 1);
2317  if (fpos2 != std::string::npos) {
2318  fitopt = display.substr(fpos1 + 1, fpos2 - fpos1 - 1);
2319  }
2320  }
2321  }
2322  // plot double gaus
2323  std::size_t found1 = display.find("doublegaus");
2324  if (found1 != std::string::npos) {
2325  std::size_t found2 = display.find('(', found1 + 1);
2326  if (found2 != std::string::npos) {
2327  std::size_t found3 = display.find(')', found2 + 1);
2328  if (found3 != std::string::npos) {
2329  std::string range = display.substr(found2 + 1, found3 - found2 - 1);
2330  Double_t xmin = std::strtod(range.c_str(), NULL);
2331  std::size_t found4 = display.find(',', found2 + 1);
2332  if (found4 != std::string::npos) {
2333  range = display.substr(found4 + 1, found3 - found4 - 1);
2334  Double_t xmax = std::strtod(range.c_str(), NULL);
2335  TF1* f1 = new TF1("f1", "gaus", xmin, xmax);
2336  h->Fit(f1, "q");
2337  Double_t par[6];
2338  f1->GetParameters(par);
2339  TF1* func = new TF1("func", "gaus(0)+gaus(3)", xmin, xmax);
2340  func->SetParameters(par);
2341  func->SetParameter(3, h->GetBinContent(h->GetMaximumBin()));
2342  func->SetParameter(4, h->GetMean());
2343  func->SetParameter(5, par[2]);
2344  func->SetLineColor(kRed);
2345  func->SetLineWidth(2);
2346  if (h->GetEffectiveEntries() > minstat) {
2347  h->Fit(func, ("rq" + fitopt).c_str());
2348  }
2349  delete f1;
2350  delete func;
2351  }
2352  }
2353  }
2354  } else {
2355  // draw gaus+pol1
2356  std::size_t found1 = display.find("gauspluspol1");
2357  if (found1 != std::string::npos) {
2358  std::size_t found2 = display.find('(', found1 + 1);
2359  if (found2 != std::string::npos) {
2360  std::size_t found3 = display.find(')', found2 + 1);
2361  if (found3 != std::string::npos) {
2362  std::string range = display.substr(found2 + 1, found3 - found2 - 1);
2363  Double_t xmin = std::strtod(range.c_str(), NULL);
2364  std::size_t found4 = display.find(',', found2 + 1);
2365  if (found4 != std::string::npos) {
2366  range = display.substr(found4 + 1, found3 - found4 - 1);
2367  Double_t xmax = std::strtod(range.c_str(), NULL);
2368  TF1* func = new TF1("func", "gaus(0)+pol1(3)", xmin, xmax);
2369  func->SetLineColor(kRed);
2370  func->SetLineWidth(2);
2371  func->SetParameters(h->GetBinContent(h->GetMaximumBin()), h->GetMean(), h->GetRMS());
2372  if (h->GetEffectiveEntries() > minstat) {
2373  h->Fit(func, ("rq" + fitopt).c_str());
2374  }
2375  delete func;
2376  }
2377  }
2378  }
2379  } else {
2380  // draw gaus+expo
2381  found1 = display.find("gausplusexpo");
2382  if (found1 != std::string::npos) {
2383  std::size_t found2 = display.find('(', found1 + 1);
2384  if (found2 != std::string::npos) {
2385  std::size_t found3 = display.find(')', found2 + 1);
2386  if (found3 != std::string::npos) {
2387  std::string range = display.substr(found2 + 1, found3 - found2 - 1);
2388  Double_t xmin = std::strtod(range.c_str(), NULL);
2389  std::size_t found4 = display.find(',', found2 + 1);
2390  if (found4 != std::string::npos) {
2391  range = display.substr(found4 + 1, found3 - found4 - 1);
2392  Double_t xmax = std::strtod(range.c_str(), NULL);
2393 
2394  TF1* func = new TF1("func", "gaus(0)+expo(3)", xmin, xmax);
2395  func->SetLineColor(kRed);
2396  func->SetLineWidth(2);
2397  func->SetParameters(h->GetBinContent(h->GetMaximumBin()), h->GetMean(), h->GetRMS());
2398  if (h->GetEffectiveEntries() > minstat) {
2399  h->Fit(func, ("rq" + fitopt).c_str());
2400  }
2401  delete func;
2402  }
2403  }
2404  }
2405  } else {
2406  // the last case: single gaus
2407  std::size_t found2 = display.find('(', found + 1);
2408  if (found2 != std::string::npos) {
2409  std::size_t found3 = display.find(')', found2 + 1);
2410  if (found3 != std::string::npos) {
2411  std::string range = display.substr(found2 + 1, found3 - found2 - 1);
2412  Double_t xmin = std::strtod(range.c_str(), NULL);
2413  std::size_t found4 = display.find(',', found2 + 1);
2414  if (found4 != std::string::npos) {
2415  range = display.substr(found4 + 1, found3 - found4 - 1);
2416  Double_t xmax = std::strtod(range.c_str(), NULL);
2417  TF1* func = new TF1("func", "gaus", xmin, xmax);
2418  func->SetLineColor(kRed);
2419  func->SetLineWidth(2);
2420  if (h->GetEffectiveEntries() > minstat) {
2421  h->Fit(func, ("rq" + fitopt).c_str());
2422  }
2423  delete func;
2424  }
2425  }
2426  }
2427  }
2428  }
2429  }
2430  }
2431  if (!drawopt.empty()) {
2432  // do drawopt related stuff here
2433  }
2434  }
2435 
2437  TCanvas* myC, TH1* h, TH1* hRef, std::string& drawopt, std::string& display, std::string& AlgoName) {
2438  formatTH1(myC, h);
2439  if (display.find("StatBox") != std::string::npos) {
2440  h->SetStats(kTRUE);
2441  }
2442  if (h->GetXaxis()->GetXmin() >= h->GetXaxis()->GetXmax()) {
2443  std::cerr << "HanOutputFile::saveHistogramToFile(): "
2444  << "Inconsistent x-axis settings: min=" << h->GetXaxis()->GetXmin() << ", "
2445  << "max=" << h->GetXaxis()->GetXmax() << ", "
2446  << "Will not save this histogram.\n";
2447  return false;
2448  }
2449  myC->cd();
2450  if (hRef != 0) {
2451  drawReference(myC, hRef, h, drawopt, display, AlgoName);
2452  } else {
2453  myC->cd();
2454  if (h->GetMinimum() >= 0 && h->GetMaximum() > 0.) {
2455  gPad->SetLogy(display.find("LogY") != std::string::npos);
2456  } else {
2457  gPad->SetLogy(false);
2458  }
2459  if (BINLOEDGE(h, 1) > 0) {
2460  gPad->SetLogx(display.find("LogX") != std::string::npos);
2461  } else {
2462  gPad->SetLogx(false);
2463  }
2464  axisOption(display, h);
2465  h->Draw(drawopt.c_str());
2466  }
2467  myC->cd();
2468  displayExtra(myC, display);
2469  myC->RedrawAxis();
2470  return true;
2471  }
2472 
2474  TCanvas* myC, TH1* hRef, TH1* h, std::string& drawopt, std::string& display, std::string& AlgoName) {
2475  formatTH1(myC, hRef);
2476  TProfile* pRef = dynamic_cast<TProfile*>(hRef);
2477  if (pRef != 0) { // profile reference
2478  hRef->SetMarkerColor(2);
2479  hRef->SetLineColor(2);
2480  hRef->SetLineWidth(2);
2481  double ymin = (hRef->GetMinimum() < h->GetMinimum()) ? hRef->GetMinimum() : h->GetMinimum();
2482  double ymax = (hRef->GetMaximum() > h->GetMaximum()) ? hRef->GetMaximum() : h->GetMaximum();
2483  // double xmin = ( BINLOEDGE(hRef, 1) < BINLOEDGE(h, 1)) ? BINLOEDGE(hRef, 1)-BINWIDTH(hRef, 1) : BINLOEDGE(h,
2484  // 1)-BINWIDTH(h, 1); double xmax = ( BINLOEDGE(hRef, hRef->GetNbinsX()) + BINWIDTH(hRef, hRef->GetNbinsX()) >
2485  // BINLOEDGE(h, h->GetNbinsX()) + BINWIDTH(h, h->GetNbinsX()) ) ?
2486  // BINLOEDGE(hRef, hRef->GetNbinsX()) + 2.0*BINWIDTH(hRef, hRef->GetNbinsX()): BINLOEDGE(h, h->GetNbinsX())
2487  // + 2.0*BINWIDTH(h, h->GetNbinsX()) ;
2488  double xmin = (BINLOEDGE(hRef, 1) < BINLOEDGE(h, 1)) ? BINLOEDGE(hRef, 1) : BINLOEDGE(h, 1);
2489  double xmax = (BINLOEDGE(hRef, hRef->GetNbinsX()) + BINWIDTH(hRef, hRef->GetNbinsX()) >
2490  BINLOEDGE(h, h->GetNbinsX()) + BINWIDTH(h, h->GetNbinsX()))
2491  ? BINLOEDGE(hRef, hRef->GetNbinsX()) + BINWIDTH(hRef, hRef->GetNbinsX())
2492  : BINLOEDGE(h, h->GetNbinsX()) + BINWIDTH(h, h->GetNbinsX());
2493  // double y_av = (ymax + ymin)/2;
2494  // double y_halv = (ymax-ymin)*0.6;
2495  bool isLogY = (display.find("LogY") != std::string::npos);
2496  if (isLogY) {
2497  if (ymax <= 0.0) ymax = 5.0;
2498  if (ymin > 0.) {
2499  double lymax = log(ymax);
2500  double lymin = log(ymin);
2501  h->SetAxisRange(exp(lymin - (lymax - lymin) * 0.05), exp(lymax + (lymax - lymin) * 0.05), "Y");
2502  // leave 5% gap on above and below
2503  } else {
2504  std::cerr << "ymin is <0. and LogY requested for histogram \"" << h->GetName() << " "
2505  << h->GetDirectory()->GetPath() << "\", ymin=" << ymin << std::endl;
2506  }
2507  } else {
2508  double yMargin = (ymax - ymin) * 0.05;
2509  h->SetAxisRange(ymin - yMargin, ymax + yMargin, "Y");
2510  }
2511  // h->SetAxisRange(xmin,xmax,"X");
2512  h->GetXaxis()->SetRangeUser(xmin, xmax);
2513  axisOption(display, h);
2514  if (h->GetMinimum() >= 0 && hRef->GetMinimum() >= 0 && h->GetMaximum() > 0 && hRef->GetMaximum() > 0) {
2515  gPad->SetLogy(display.find("LogY") != std::string::npos);
2516  }
2517  if (BINLOEDGE(h, 1) > 0 && BINLOEDGE(hRef, 1) > 0) {
2518  gPad->SetLogx(display.find("LogX") != std::string::npos);
2519  }
2520  h->Draw(drawopt.c_str());
2521  hRef->Draw(("SAME" + drawopt).c_str());
2522  h->Draw(("SAME" + drawopt).c_str());
2523  } else { // ordinary reference
2524  double scale = 1.0;
2525  if (display.find("ScaleRef") != std::string::npos) {
2526  scale = getScaleVal(display);
2527  } else if (h->Integral("width") > 0.0 && hRef->Integral("width") > 0.0 &&
2528  (AlgoName.find("BinContentComp") == std::string::npos) &&
2529  (display.find("NoNorm") == std::string::npos)) {
2530  scale = h->Integral("width") / hRef->Integral("width");
2531  }
2532  hRef->Scale(scale);
2533  hRef->SetMarkerColor(15);
2534  hRef->SetFillColor(15);
2535  hRef->SetLineColor(15);
2536  double ymin = (hRef->GetMinimum() < h->GetMinimum()) ? hRef->GetMinimum() : h->GetMinimum();
2537  double ymax = (hRef->GetMaximum() > h->GetMaximum()) ? hRef->GetMaximum() : h->GetMaximum();
2538  // double xmin = ( BINLOEDGE(hRef, 1) < BINLOEDGE(h, 1)) ? BINLOEDGE(hRef, 1)-BINWIDTH(hRef, 1) : BINLOEDGE(h,
2539  // 1)-BINWIDTH(h, 1); double xmax = ( BINLOEDGE(hRef, hRef->GetNbinsX()) + BINWIDTH(hRef, hRef->GetNbinsX()) >
2540  // BINLOEDGE(h, h->GetNbinsX()) + BINWIDTH(h, h->GetNbinsX()) ) ? BINLOEDGE(hRef, hRef->GetNbinsX())
2541  // + 2.0*BINWIDTH(hRef, hRef->GetNbinsX()): BINLOEDGE(h, h->GetNbinsX()) + 2.0*BINWIDTH(h, h->GetNbinsX()) ;
2542  double xmin = (BINLOEDGE(hRef, 1) < BINLOEDGE(h, 1)) ? BINLOEDGE(hRef, 1) : BINLOEDGE(h, 1);
2543  double xmax = (BINLOEDGE(hRef, hRef->GetNbinsX()) + BINWIDTH(hRef, hRef->GetNbinsX()) >
2544  BINLOEDGE(h, h->GetNbinsX()) + BINWIDTH(h, h->GetNbinsX()))
2545  ? BINLOEDGE(hRef, hRef->GetNbinsX()) + BINWIDTH(hRef, hRef->GetNbinsX())
2546  : BINLOEDGE(h, h->GetNbinsX()) + BINWIDTH(h, h->GetNbinsX());
2547  // double y_av = (ymax + ymin)/2;
2548  // double y_halv = (ymax-ymin)*0.6;
2549  bool isLogY = (display.find("LogY") != std::string::npos);
2550  // if ( ymin == 0.0 && display.find("LogY")!=std::string::npos ){
2551 
2552  if (isLogY) {
2553  if (ymax <= 0.0) ymax = 5.0;
2554  if (ymin > 0.) {
2555  double lymax = log(ymax);
2556  double lymin = log(ymin);
2557  h->SetAxisRange(exp(lymin - (lymax - lymin) * 0.05), exp(lymax + (lymax - lymin) * 0.05), "Y");
2558  // leave 5% gap on above and below
2559  } else {
2560  std::cerr << "ymin is <=0. and LogY requested for histogram \"" << h->GetName() << " "
2561  << h->GetDirectory()->GetPath() << "\", ymin=" << ymin << std::endl;
2562  }
2563  } else {
2564  double yDiff = ymax - ymin;
2565  h->SetAxisRange(ymin - yDiff * 0.05, ymax + yDiff * 0.05, "Y"); // leave 5% gap above and below
2566  }
2567 
2568  // h->SetAxisRange(xmin,xmax,"X");
2569  h->GetXaxis()->SetRangeUser(xmin, xmax);
2570  myC->cd();
2571  if (h->GetMinimum() >= 0. && hRef->GetMinimum() >= 0. && h->GetMaximum() > 0. && hRef->GetMaximum() > 0.) {
2572  gPad->SetLogy(display.find("LogY") != std::string::npos);
2573  }
2574  if (BINLOEDGE(h, 1) > 0 && BINLOEDGE(hRef, 1) > 0) {
2575  gPad->SetLogx(display.find("LogX") != std::string::npos);
2576  }
2577  axisOption(display, h);
2578  h->Draw(drawopt.c_str());
2579  hRef->Draw(("SAME" + drawopt).c_str());
2580  h->Draw(("SAME" + drawopt).c_str());
2581  }
2582  return true;
2583  }
2584 
2585  // bool HanOutputFile::drawGraph(TCanvas* canv,TGraph* hist,std::string &drawopt,std::string &display){
2586  // return false;
2587  // }
2588 
2589  void HanOutputFile::axisOption(std::string str, TH1* h) {
2590  std::size_t found = str.find("AxisRange");
2591  while (found != std::string::npos) {
2592  // std::string coordinates, cx1,cy1 ="";
2593  // std::size_t found1 = str.find_first_of(')',found+1);
2594  // std::size_t found2 = str.find_first_of("\'",found+1);
2595  // if (found2!=std::string::npos){
2596  std::string coordinates, cx1, cy1 = "";
2597  std::size_t found1 = str.find_first_of(')', found + 1);
2598  std::size_t found2 = str.find_first_of("\'", found + 1);
2599  if (found2 != std::string::npos) {
2600  found2 = str.find_first_of("\'", found2 + 1);
2601  if (found1 < found2) {
2602  found1 = str.find_first_of(')', found2 + 1);
2603  }
2604  /* }
2605  if (found1!=std::string::npos){
2606  coordinates = str.substr(found+10,found1-found-10);
2607  found1 = coordinates.find_first_of(',');
2608  if (found1!=std::string::npos){
2609  cx1 = coordinates.substr(0,found1);
2610  double x1=std::strtod(cx1.c_str(),NULL);
2611  found2 = coordinates.find_first_of(',',found1+1);
2612  if (found2!=std::string::npos){
2613  cy1 = coordinates.substr(found1+1,found2-found1-1);
2614  double y1=std::strtod(cy1.c_str(),NULL);
2615  std::string txt = coordinates.substr(found2+2,coordinates.size() );
2616  txt = txt.substr(0,txt.size()-1 );
2617  if (txt == "X" && x1 < y1)
2618  {
2619  h->SetAxisRange(x1,y1,"X");
2620  }
2621  if (txt == "Y" && x1 < y1)
2622  {
2623  h->SetAxisRange(x1,y1,"Y");
2624  }
2625  if (txt == "Z" && x1 < y1)
2626  {
2627  h->SetAxisRange(x1,y1,"Z");
2628  }
2629  }
2630  }
2631  }
2632  found=str.find("AxisRange",found+1);
2633  }
2634  */
2635  }
2636  if (found1 != std::string::npos) {
2637  coordinates = str.substr(found + 10, found1 - found - 10);
2638  found1 = coordinates.find_first_of(',');
2639  if (found1 != std::string::npos) {
2640  cx1 = coordinates.substr(0, found1);
2641  double x1 = std::strtod(cx1.c_str(), NULL);
2642  found2 = coordinates.find_first_of(',', found1 + 1);
2643  if (found2 != std::string::npos) {
2644  cy1 = coordinates.substr(found1 + 1, found2 - found1 - 1);
2645  double y1 = std::strtod(cy1.c_str(), NULL);
2646  std::string txt = coordinates.substr(found2 + 2, coordinates.size());
2647  txt.pop_back();
2648  if (txt == "X" && x1 < y1) {
2649  h->GetXaxis()->SetRangeUser(x1, y1);
2650  }
2651  if (txt == "Y" && x1 < y1) {
2652  h->SetAxisRange(x1, y1, "Y");
2653  }
2654  if (txt == "Z" && x1 < y1) {
2655  h->SetAxisRange(x1, y1, "Z");
2656  }
2657  } else {
2658  std::string txt = coordinates.substr(found1 + 2, coordinates.size());
2659  txt.pop_back();
2660  if (txt[1] == 'M') {
2661  if (txt == "XMax") {
2662  double xmin = BINLOEDGE(h, 1);
2663  h->GetXaxis()->SetRangeUser(xmin, x1);
2664  }
2665  if (txt == "XMin") {
2666  double xmax = BINLOEDGE(h, h->GetNbinsX()) + BINWIDTH(h, h->GetNbinsX());
2667  h->GetXaxis()->SetRangeUser(x1, xmax);
2668  }
2669  if (txt == "YMax") {
2670  double ymin = h->GetMinimum();
2671  h->SetAxisRange(ymin, x1, "Y");
2672  }
2673  if (txt == "YMin") {
2674  double ymax = h->GetMaximum();
2675  h->SetAxisRange(x1, ymax, "Y");
2676  }
2677  }
2678  }
2679  }
2680  }
2681  found = str.find("AxisRange", found + 1);
2682  }
2683  }
2684 
2685  //-----------------------------
2686  void HanOutputFile::ratioplot(TCanvas* myC_upperpad, TH1* h, TH1* hRef, std::string display) {
2687  // this method creates two pads under a main canvas, upperpad with input canvas displayed, lower with ratio plot
2688  // Then it clears the input canvas and draws this newly created in input
2689  // I dont know if it is the best aproach,I used this method to minimize the changes on the main code
2690  if (display.find("RatioPad") == std::string::npos) return;
2691 
2692  unsigned int ww = myC_upperpad->GetWw();
2693  unsigned int wh = myC_upperpad->GetWh();
2694  std::string padname = "PAD";
2695  std::string padname_ratio = "PAD_main";
2696  auto myC_ratiopad = std::make_unique<TCanvas>(padname_ratio.c_str(), "myC_ratiopad", ww, wh);
2697  auto myC_main = std::make_unique<TCanvas>(padname.c_str(), "myC_main", ww, wh);
2698  myC_main->cd();
2699  // producing ratio histogram and plotting it on to myC_ratiopad
2700  myC_ratiopad->cd();
2701  myC_ratiopad->SetTopMargin(0);
2702  myC_ratiopad->SetLogx(display.find("LogX") != std::string::npos);
2703  // TH1F *clonehist=(TH1F*)h->Clone();
2704  // clonehist->Divide(hRef);
2705 
2709  TProfile* phRef = dynamic_cast<TProfile*>(hRef);
2710  TProfile* ph = dynamic_cast<TProfile*>(h);
2711  std::unique_ptr<TH1F> clonehist; // we will release this later, but use a unique_ptr in case we return early
2712  std::unique_ptr<TH1F> clonehistref;
2713  // transform if profiles
2714  if (ph != 0) {
2715  clonehist.reset((TH1F*) ph->ProjectionX());
2716  } else {
2717  clonehist.reset((TH1F*) h->Clone());
2718  if (!clonehist->GetSumw2()) {
2719  clonehist->Sumw2();
2720  }
2721  }
2722  if (phRef != 0) {
2723  clonehistref.reset((TH1F*) phRef->ProjectionX());
2724  } else {
2725  clonehistref.reset((TH1F*) hRef->Clone());
2726  if (!clonehistref->GetSumw2()) {
2727  clonehistref->Sumw2();
2728  }
2729  }
2730  if (!clonehist or !clonehistref) {
2731  return;
2732  }
2733  clonehist->SetBit(kCanDelete);
2734  clonehist->Divide(clonehistref.get());
2737 
2738  formatTH1(myC_ratiopad.get(), clonehist.get());
2739  clonehist->SetTitle("");
2740 
2741  // extract delta value from string that holds the draw options
2742  double delta = 0.75;
2743  if (display.find("delta(") != std::string::npos) {
2744  delta = std::stod(display.substr(display.find("delta(") + 6));
2745  }
2746  clonehist->SetAxisRange(1. - delta, 1. + delta, "Y");
2747 
2748  clonehist->GetYaxis()->SetNdivisions(3, true);
2749  clonehist->SetMarkerStyle(1);
2750  clonehist->Draw("E"); // plots into myC_ratiopad
2751  clonehist->GetXaxis()->SetTitleSize(0.11);
2752  clonehist->GetXaxis()->SetLabelSize(0.11);
2753  clonehist->GetYaxis()->SetTitleSize(0.11);
2754  clonehist->GetYaxis()->SetLabelSize(0.11);
2755  myC_main->cd(); // lowerPad and upperPad plotted into myC_main
2756  TPad* lowerPad = new TPad("lowerPad", "lowerPad", .005, .060, .995, .250); // deleted by myC_main
2757  lowerPad->SetTopMargin(0);
2758  lowerPad->SetFillStyle(0);
2759  lowerPad->Draw();
2760  TPad* upperPad = new TPad("upperPad", "upperPad", .005, .250, .995, .995); // deleted by myC_main
2761  upperPad->SetBottomMargin(0);
2762  upperPad->SetFillStyle(0);
2763  upperPad->Draw();
2764 
2765  lowerPad->cd();
2766  myC_ratiopad->DrawClonePad(); // clone contents of myC_ratiopad to lowerPad (will fix ownership later)
2767  // Draw y=1 lineon ratio plot
2768  TLine line;
2769  line.SetLineColor(kRed);
2770  line.SetLineWidth(1);
2771  // method belove might be a problem when axis range changed
2772  double xmin = clonehist->GetXaxis()->GetXmin();
2773  double xmax = clonehist->GetXaxis()->GetXmax();
2774  // double xmin = BINLOEDGE(clonehist, 1)-BINWIDTH(clonehist, 1);
2775  // double xmax = BINLOEDGE(clonehist, clonehist->GetNbinsX() ) + 2.0*BINWIDTH(clonehist, clonehist->GetNbinsX() ) ;
2776  line.DrawLine(xmin, 1, xmax, 1);
2777  upperPad->cd();
2778  myC_upperpad->SetBottomMargin(0);
2779  myC_upperpad->SetFillStyle(0);
2780  h->GetXaxis()->SetLabelSize(0.);
2781  h->GetXaxis()->SetTitleSize(0.);
2782  myC_upperpad->DrawClonePad(); // clone original canvas (i.e. main plot) into upperPad (will fix ownership later)
2783  myC_upperpad->cd();
2784  myC_upperpad->Clear(); // reset original canvas
2785  myC_main->DrawClonePad(); // clone contents of myC_main back into original canvas (will fix ownership shortly)
2786 
2787  std::ignore = clonehist.release(); // this will be deleted by lowerpad cleanup
2788  // At this point myC_main contains the original lowerPad and upperPad, which contain clones of the original canvas
2789  // and ownership of clonehist. Iterate one level down and mark contained objects as deleteable. This will delete
2790  // the pads, as well as clonehist.
2791  for (TObject* o : *(myC_main->GetListOfPrimitives())) {
2792  o->SetBit(kCanDelete);
2793  if (auto* o2 = dynamic_cast<TPad*>(o)) {
2794  for (auto* o3: *(o2->GetListOfPrimitives())) {
2795  if (!dynamic_cast<TFrame*>(o3)) {
2796  o3->SetBit(kCanDelete);
2797  }
2798  }
2799  }
2800  }
2801  // At this point myC_upperpad contains clones of all its objects, including the pads. None of them have pointers
2802  // outside of myC_upperpad and its contained cloned pads. Mark them all deleteable. The original plot will be
2803  // deleted
2804  // in the calling code.
2805  for (TObject* o : *(myC_upperpad->GetListOfPrimitives())) {
2806  o->SetBit(kCanDelete);
2807  if (auto* o2 = dynamic_cast<TPad*>(o)) {
2808  for (auto* o3: *(o2->GetListOfPrimitives())) {
2809  if (!dynamic_cast<TFrame*>(o3)) {
2810  o3->SetBit(kCanDelete);
2811  }
2812  }
2813  }
2814  }
2815  }
2816 
2817  void HanOutputFile::ratioplot2D(TCanvas* canvas_top, TH2* h2, TH2* h2Ref, std::string display) {
2818  if (display.find("Ref2DRatio") == std::string::npos && display.find("Ref2DSignif") == std::string::npos) return;
2819 
2820  auto canvas_bot =
2821  std::make_unique<TCanvas>("canvas_bottom", "canvas_bottom", canvas_top->GetWw(), canvas_top->GetWh());
2822  auto canvas_all = std::make_unique<TCanvas>("canvas_all", "canvas_all", canvas_top->GetWw(), canvas_top->GetWh());
2823 
2824  canvas_bot->cd();
2825  canvas_bot->SetTopMargin(0);
2826 
2827  h2Ref->Scale(h2->Integral() / h2Ref->Integral());
2828 
2829  TH2* comparison = (TH2*) (h2->Clone());
2830  comparison->Divide(h2, h2Ref, 1.0, 1.0);
2831  comparison->SetTitle("");
2832  formatTH2(canvas_bot.get(), comparison);
2833 
2834  if (display.find("Ref2DRatio") != std::string::npos) {
2835  comparison->GetZaxis()->SetTitle("ratio to ref.");
2836  comparison->SetAxisRange(0.0, 2.0, "Z");
2837  } else if (display.find("Ref2DSignif") != std::string::npos) {
2838  comparison->GetZaxis()->SetTitle("difference to ref. (#sigma)");
2839  comparison->SetAxisRange(-4.5, 4.5, "Z");
2840 
2841  double value_a = 0;
2842  double value_b = 0;
2843  double sigma_a = 0;
2844  double sigma_b = 0;
2845  double signif = 0;
2846 
2847  for (int binx = 0; binx <= comparison->GetNbinsX(); binx++) {
2848  for (int biny = 0; biny <= comparison->GetNbinsY(); biny++) {
2849  value_a = h2->GetBinContent(binx, biny);
2850  value_b = h2Ref->GetBinContent(binx, biny);
2851 
2852  sigma_a = h2->GetBinError(binx, biny);
2853  sigma_b = h2Ref->GetBinError(binx, biny);
2854 
2855  if (sigma_a == 0 && sigma_b == 0) signif = 0;
2856  else signif = (value_a - value_b) / sqrt((sigma_a * sigma_a + sigma_b * sigma_b));
2857 
2858  comparison->SetBinContent(binx, biny, signif);
2859  }
2860  }
2861  }
2862 
2863  comparison->Draw("colz");
2864 
2865  canvas_all->cd();
2866  TPad* pad_bot = new TPad("pad_bot", "pad_bot", 0.005, 0.060, 0.995, 0.550);
2867  TPad* pad_top = new TPad("pad_top", "pad_top", 0.005, 0.550, 0.995, 0.995);
2868 
2869  pad_bot->SetTopMargin(0);
2870  pad_top->SetBottomMargin(0);
2871 
2872  pad_bot->SetFillStyle(0);
2873  pad_top->SetFillStyle(0);
2874 
2875  pad_bot->Draw();
2876  pad_top->Draw();
2877 
2878  pad_bot->cd();
2879  canvas_bot->DrawClonePad();
2880 
2881  pad_top->cd();
2882  canvas_top->SetBottomMargin(0);
2883  canvas_top->SetFillStyle(0);
2884  h2->GetXaxis()->SetLabelSize(0.);
2885  h2->GetXaxis()->SetTitleSize(0.);
2886  canvas_top->DrawClonePad();
2887  canvas_top->cd();
2888  canvas_top->Clear();
2889 
2890  canvas_all->DrawClonePad();
2891  }
2892 
2893  //-----------------------------
2894  void HanOutputFile::polynomial(TCanvas* c, std::string str, TH1* h) {
2895  double xmin = h->GetXaxis()->GetXmin();
2896  double xmax = h->GetXaxis()->GetXmax();
2897 
2898  std::size_t found = str.find("polynomial(");
2899  while (found != std::string::npos) {
2900  std::size_t endpos = str.find_first_of(')', found + 1);
2901  std::cout << "found;" << found << " endpos;" << endpos << "count "
2902  << " \n";
2903  std::string inp_str = str.substr(found + 11, endpos - found - 11);
2904  std::size_t found1 = 0;
2905  std::size_t found2 = inp_str.find_first_of(',', found1);
2906  TF1* func = new TF1("func", "pol9", xmin, xmax);
2907  for (int j = 0; j < 10; j++) {
2908  std::string value_str = inp_str.substr(found1, found2 - found1);
2909  double value_double = std::strtod(value_str.c_str(), NULL);
2910  func->SetParameter(j, value_double);
2911  if (found2 == std::string::npos) {
2912  break;
2913  }
2914  found1 = found2 + 1;
2915  found2 = inp_str.find_first_of(',', found1);
2916  }
2917  func->SetNpx(1000);
2918  c->cd();
2919  func->Draw("SAME");
2920  found = str.find("polynomial(", found + 1);
2921  }
2922  }
2923 
2924  void HanOutputFile::displayExtra(TCanvas* c, const std::string& str) {
2925  std::size_t found = str.find("TLine");
2926  while (found != std::string::npos) {
2927  std::size_t found1 = str.find_first_of(')', found + 1);
2928  if (found1 != std::string::npos) {
2929  std::string coordinates = str.substr(found + 6, found1 - found - 6);
2930  bool NDC = false;
2931  if (found1 < str.size() - 3 && str.substr(found1 + 1, 3) == "NDC") {
2932  NDC = true;
2933  }
2934  found1 = coordinates.find_first_of(',');
2935  if (found1 != std::string::npos) {
2936  std::string cx1 = coordinates.substr(0, found1);
2937  double x1 = std::strtod(cx1.c_str(), NULL);
2938  std::size_t found2 = coordinates.find_first_of(',', found1 + 1);
2939  if (found2 != std::string::npos) {
2940  std::string cy1 = coordinates.substr(found1 + 1, found2 - found1 - 1);
2941  double y1 = std::strtod(cy1.c_str(), NULL);
2942  found1 = coordinates.find_first_of(',', found2 + 1);
2943  if (found1 != std::string::npos) {
2944  std::string cx2 = coordinates.substr(found2 + 1, found1 - found2 - 1);
2945  double x2 = std::strtod(cx2.c_str(), NULL);
2946  std::string cy2 = coordinates.substr(found1 + 1, coordinates.size());
2947  double y2 = std::strtod(cy2.c_str(), NULL);
2948  c->cd();
2949  TLine* L = new TLine;
2950  if (NDC) {
2951  if (x1 <= 1.0 && x1 >= 0.0 && x2 <= 1.0 && x2 >= 0.0 && y1 <= 1.0 && y1 >= 0.0 && y2 <= 1.0 &&
2952  y2 >= 0.0) {
2953  L->DrawLineNDC(x1, y1, x2, y2);
2954  }
2955  } else {
2956  L->DrawLine(x1, y1, x2, y2);
2957  }
2958  }
2959  }
2960  }
2961  }
2962  found = str.find("TLine", found + 1);
2963  }
2964 
2965  found = str.find("TText");
2966  while (found != std::string::npos) {
2967  std::string coordinates, cx1, cy1 = "";
2968  std::size_t found1 = str.find_first_of(')', found + 1);
2969  std::size_t found2 = str.find_first_of('\'', found + 1);
2970  if (found2 != std::string::npos) {
2971  found2 = str.find_first_of('\"', found2 + 1);
2972  if (found2 != std::string::npos && found1 < found2) {
2973  found1 = str.find_first_of(')', found2 + 1);
2974  }
2975  }
2976  if (found1 != std::string::npos) {
2977  coordinates = str.substr(found + 6, found1 - found - 6);
2978  bool NDC = false;
2979  if (found1 < str.size() - 3 && str.substr(found1 + 1, 3) == "NDC") {
2980  NDC = true;
2981  }
2982  found1 = coordinates.find_first_of(',');
2983  if (found1 != std::string::npos) {
2984  cx1 = coordinates.substr(0, found1);
2985  double x1 = std::strtod(cx1.c_str(), NULL);
2986  found2 = coordinates.find_first_of(',', found1 + 1);
2987  if (found2 != std::string::npos) {
2988  cy1 = coordinates.substr(found1 + 1, found2 - found1 - 1);
2989  double y1 = std::strtod(cy1.c_str(), NULL);
2990  std::string txt = coordinates.substr(found2 + 2, coordinates.size());
2991  txt.pop_back();
2992  c->cd();
2993  TText* T = new TText;
2994  if (NDC) {
2995  if (x1 <= 1.0 && x1 >= 0.0 && y1 <= 1.0 && y1 >= 0.0) {
2996  T->DrawTextNDC(x1, y1, txt.c_str());
2997  }
2998  } else {
2999  T->DrawText(x1, y1, txt.c_str());
3000  }
3001  }
3002  }
3003  }
3004  found = str.find("TText", found + 1);
3005  }
3006 
3007  found = str.find("TDota");
3008  while (found != std::string::npos) {
3009  std::size_t found1 = str.find_first_of(')', found + 1);
3010  if (found1 != std::string::npos) {
3011  std::string coordinates = str.substr(found + 6, found1 - found - 6);
3012  bool NDC = false;
3013  if (found1 < str.size() - 3 && str.substr(found1 + 1, 3) == "NDC") {
3014  NDC = true;
3015  }
3016  found1 = coordinates.find_first_of(',');
3017  if (found1 != std::string::npos) {
3018  std::string cx1 = coordinates.substr(0, found1);
3019  double x1 = std::strtod(cx1.c_str(), NULL);
3020  std::size_t found2 = coordinates.find_first_of(',', found1 + 1);
3021  if (found2 != std::string::npos) {
3022  std::string cy1 = coordinates.substr(found1 + 1, found2 - found1 - 1);
3023  double y1 = std::strtod(cy1.c_str(), NULL);
3024  found1 = coordinates.find_first_of(',', found2 + 1);
3025  if (found1 != std::string::npos) {
3026  std::string cx2 = coordinates.substr(found2 + 1, found1 - found2 - 1);
3027  double x2 = std::strtod(cx2.c_str(), NULL);
3028  std::string cy2 = coordinates.substr(found1 + 1, coordinates.size());
3029  double y2 = std::strtod(cy2.c_str(), NULL);
3030  c->cd();
3031  TLine* L = new TLine;
3032  L->SetLineStyle(2);
3033  if (NDC) {
3034  if (x1 <= 1.0 && x1 >= 0.0 && x2 <= 1.0 && x2 >= 0.0 && y1 <= 1.0 && y1 >= 0.0 && y2 <= 1.0 &&
3035  y2 >= 0.0) {
3036  L->DrawLineNDC(x1, y1, x2, y2);
3037  }
3038  } else {
3039  L->DrawLine(x1, y1, x2, y2);
3040  }
3041  }
3042  }
3043  }
3044  }
3045  found = str.find("TDota", found + 1);
3046  }
3047 
3048  found = str.find("TSize");
3049  while (found != std::string::npos) {
3050  std::string coordinates, cx1, cy1, txtsize = "";
3051  std::size_t found1 = str.find_first_of(')', found + 1);
3052  std::size_t found2 = str.find_first_of('\'', found + 1);
3053  if (found2 != std::string::npos) {
3054  found2 = str.find_first_of('\"', found2 + 1);
3055  if (found2 != std::string::npos && found1 < found2) {
3056  found1 = str.find_first_of(')', found2 + 1);
3057  }
3058  }
3059  if (found1 != std::string::npos) {
3060  coordinates = str.substr(found + 6, found1 - found - 6);
3061  bool NDC = false;
3062  if (found1 < str.size() - 3 && str.substr(found1 + 1, 3) == "NDC") {
3063  NDC = true;
3064  }
3065  found1 = coordinates.find_first_of(',');
3066  if (found1 != std::string::npos) {
3067  cx1 = coordinates.substr(0, found1);
3068  double x1 = std::strtod(cx1.c_str(), NULL);
3069  found2 = coordinates.find_first_of(',', found1 + 1);
3070  if (found2 != std::string::npos) {
3071  cy1 = coordinates.substr(found1 + 1, found2 - found1 - 1);
3072  double y1 = std::strtod(cy1.c_str(), NULL);
3073  std::size_t found3 = coordinates.find_first_of(',', found2 + 1);
3074  if (found3 != std::string::npos) {
3075  txtsize = coordinates.substr(found2 + 1, found3 - found2 - 1);
3076  double size = std::strtod(txtsize.c_str(), NULL);
3077  std::string txt = coordinates.substr(found3 + 2, coordinates.size());
3078  txt.pop_back();
3079  c->cd();
3080  TText* T = new TText;
3081  T->SetTextSize(size / 100);
3082  if (NDC) {
3083  if (x1 <= 1.0 && x1 >= 0.0 && y1 <= 1.0 && y1 >= 0.0) {
3084  T->DrawTextNDC(x1, y1, txt.c_str());
3085  }
3086  } else {
3087  T->DrawText(x1, y1, txt.c_str());
3088  }
3089  }
3090  }
3091  }
3092  }
3093  found = str.find("TSize", found + 1);
3094  }
3095  }
3096 
3097  void HanOutputFile::formatTH1(TCanvas* c, TH1* h) const {
3098  if (c == 0 || h == 0) return;
3099 
3100  c->SetLeftMargin(0.15);
3101  c->SetRightMargin(0.13);
3102  c->SetBottomMargin(0.15);
3103  c->SetTopMargin(0.12);
3104 
3105  h->SetStats(kFALSE);
3106  h->SetLabelSize(0.04, "X");
3107  h->SetLabelSize(0.04, "Y");
3108  h->SetLabelFont(62, "X");
3109  h->SetLabelFont(62, "Y");
3110  h->SetTitleSize(0.04, "X");
3111  h->SetTitleSize(0.04, "Y");
3112  h->GetXaxis()->SetTitleFont(62);
3113  h->GetXaxis()->SetTitleSize(0.04);
3114  h->GetYaxis()->SetTitleFont(62);
3115  h->GetYaxis()->SetTitleSize(0.04);
3116  h->SetMarkerStyle(20);
3117  h->SetMarkerSize(0.8);
3118 
3119  h->SetTitleOffset(1.5, "y");
3120  h->SetTitleOffset(0.9, "x");
3121 
3122  h->SetNdivisions(504, "X");
3123  h->SetNdivisions(504, "Y");
3124  }
3125 
3126  void HanOutputFile::formatTH2(TCanvas* c, TH2* h) const {
3127  if (c == 0 || h == 0) return;
3128 
3129  c->SetLeftMargin(0.15);
3130  c->SetRightMargin(0.13);
3131  c->SetBottomMargin(0.15);
3132  c->SetTopMargin(0.12);
3133 
3134  h->SetStats(kFALSE);
3135 
3136  h->SetLabelSize(0.04, "X");
3137  h->SetLabelSize(0.04, "Y");
3138  h->SetLabelSize(0.04, "Z");
3139  h->SetLabelFont(62, "X");
3140  h->SetLabelFont(62, "Y");
3141  h->SetLabelFont(62, "Z");
3142  h->SetTitleSize(0.04, "X");
3143  h->SetTitleSize(0.04, "Y");
3144  h->SetTitleSize(0.04, "Z");
3145  h->GetXaxis()->SetTitleFont(62);
3146  h->GetXaxis()->SetTitleSize(0.04);
3147  h->GetYaxis()->SetTitleFont(62);
3148  h->GetYaxis()->SetTitleSize(0.04);
3149 
3150  h->SetTitleOffset(1.5, "y");
3151  h->SetTitleOffset(0.9, "x");
3152 
3153  h->SetNdivisions(504, "X");
3154  h->SetNdivisions(504, "Y");
3155  }
3156 
3157  void HanOutputFile::formatTGraph(TCanvas* c, TGraph* g) const {
3158  if (c == 0 || g == 0) return;
3159 
3160  c->SetLeftMargin(0.15);
3161  c->SetRightMargin(0.13);
3162  c->SetBottomMargin(0.15);
3163  c->SetTopMargin(0.12);
3164 
3165  g->SetMarkerStyle(20);
3166  }
3167 
3168  void HanOutputFile::formatTEfficiency(TCanvas* c, TEfficiency* e) const {
3169  if (c == 0 || e == 0) return;
3170 
3171  c->SetLeftMargin(0.15);
3172  c->SetRightMargin(0.13);
3173  c->SetBottomMargin(0.15);
3174  c->SetTopMargin(0.12);
3175  }
3176 
3177  // *********************************************************************
3178  // Protected Methods
3179  // *********************************************************************
3180 
3183  // bool useRecursiveDelete = gROOT->MustClean();
3184  // gROOT->SetMustClean(false);
3185 
3186  delete m_file;
3187  delete m_style;
3188  m_file = 0;
3189  m_style = 0;
3190  m_indirMap.clear();
3191 
3192  DirToAssMap_t::const_iterator assessMapEnd = m_assessMap.end();
3193  for (DirToAssMap_t::const_iterator i = m_assessMap.begin(); i != assessMapEnd; ++i) {
3194  delete i->second;
3195  }
3196  m_assessMap.clear();
3197 
3198  // gROOT->SetMustClean(useRecursiveDelete);
3199  }
3200 
3201  bool HanOutputFile::writeToFile(const std::string& fname, const std::string& content) {
3202  std::ofstream outfile(fname);
3203  if (!outfile.is_open()) {
3204  std::cerr << "Error writing file to " << fname << std::endl;
3205  return false;
3206  }
3207  outfile << content;
3208  outfile.close();
3209  return true;
3210  }
3211 
3212  void HanOutputFile::convertToGraphics(int cnvsType, TCanvas* myC, std::string& json, TImage** img, char** x, int* y) {
3213  if (cnvsType & GENERATE_PNG) {
3214  if (img) getImageBuffer(img, myC, x, y);
3215  }
3216  if (cnvsType & GENERATE_JSON) {
3217  json = TBufferJSON::ConvertToJSON(myC);
3218  }
3219  }
3220 
3221  void HanOutputFile::convertToGraphics(int cnvsType, TCanvas* myC, const std::string& namePNG,
3222  const std::string& nameJSON) {
3223  if (cnvsType & GENERATE_PNG) {
3224  myC->SaveAs(namePNG.c_str());
3225  }
3226  if (cnvsType & GENERATE_JSON) {
3227  std::string json = std::string(TBufferJSON::ConvertToJSON(myC));
3228  writeToFile(nameJSON, json);
3229  }
3230  }
3231 
3233  int cnvsType, const std::string& pngfName, const std::string& pngContent, const std::string& jsonfName,
3234  const std::string& jsonfContent) {
3235  bool png = false;
3236  bool json = false;
3237 
3238  if (cnvsType & GENERATE_PNG) {
3239  png = writeToFile(pngfName, pngContent);
3240  }
3241  if (cnvsType & GENERATE_JSON) {
3242  json = writeToFile(jsonfName, jsonfContent);
3243  }
3244  return(png || json);
3245  }
3246 } // namespace dqutils
dqutils::HanOutputFile::formatTEfficiency
virtual void formatTEfficiency(TCanvas *c, TEfficiency *e) const
Definition: HanOutputFile.cxx:3168
dqutils::ATLAS_NOT_THREAD_SAFE
void getImageBuffer ATLAS_NOT_THREAD_SAFE(TImage **img, TCanvas *myC, char **x, int *y)
Definition: HanOutputFile.cxx:1130
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
dqutils::HanOutputFile::drawH1
virtual bool drawH1(TCanvas *canv, TH1 *hist, TH1 *reference, std::string &drawopt, std::string &display, std::string &AlgoName)
Definition: HanOutputFile.cxx:2436
ymin
double ymin
Definition: listroot.cxx:63
dqutils::HanOutputFile::stringListSystemPaths
virtual std::string stringListSystemPaths(std::string location)
Definition: HanOutputFile.cxx:721
checkFileSG.line
line
Definition: checkFileSG.py:75
dqutils::HanOutputFile::stringAllHistograms
virtual std::string stringAllHistograms()
Definition: HanOutputFile.cxx:772
get_generator_info.result
result
Definition: get_generator_info.py:21
dqutils::HanOutputFile::getHistogramPNG
virtual std::string getHistogramPNG(const std::string &nameHis, TDirectory *groupDir, bool drawRefs, const std::string &run_min_LB, const std::string &pathName)
Definition: HanOutputFile.cxx:1167
dqutils::HanOutputFile::saveHistogramToFileSuperimposed
virtual bool saveHistogramToFileSuperimposed(const std::string &nameHis, std::string location, TDirectory *groupDir1, TDirectory *groupDir2, bool drawRefs, const std::string &run_min_LB, const std::string &pathName, int cnvsType=1)
Definition: HanOutputFile.cxx:1953
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:126
dqutils::HanOutputFile::stringHistoAssessments
virtual std::string stringHistoAssessments()
Definition: HanOutputFile.cxx:766
dqutils::HanOutputFile::axisOption
virtual void axisOption(std::string str, TH1 *h)
Definition: HanOutputFile.cxx:2589
dqutils::HanOutputFile::getInfo
static std::string getInfo(const std::string &location, int file_version)
Definition: HanOutputFile.cxx:476
json
nlohmann::json json
Definition: HistogramDef.cxx:9
ClassImp
ClassImp(dqutils::HanOutputFile) namespace
Definition: HanOutputFile.cxx:51
rootconvert.fName
string fName
Definition: rootconvert.py:5
dqutils::HanOutputFile::getAllAssessments
static void getAllAssessments(AssMap_t &dirmap, TDirectory *dir)
Definition: HanOutputFile.cxx:249
dqutils::HanOutputFile::m_assessMap
DirToAssMap_t m_assessMap
Same Dim_indirMaprMap, but for files of version 2.
Definition: HanOutputFile.h:181
plotBeamSpotCompare.x2
x2
Definition: plotBeamSpotCompare.py:218
parse
std::map< std::string, std::string > parse(const std::string &list)
Definition: egammaLayerRecalibTool.cxx:983
dqutils::HanOutputFile::DirStrMap_t
std::map< std::string, TObject * > DirStrMap_t
Definition: HanOutputFile.h:41
skel.it
it
Definition: skel.GENtoEVGEN.py:423
dirname
std::string dirname(std::string name)
Definition: utils.cxx:200
dqutils::HanOutputFile::drawH2
virtual bool drawH2(TCanvas *canv, TH2 *hist, std::string &drawopt, std::string &display)
!!
Definition: HanOutputFile.cxx:2228
dqutils::HanOutputFile::ratioplot
virtual void ratioplot(TCanvas *myC_main, TH1 *h, TH1 *href, std::string str)
Definition: HanOutputFile.cxx:2686
dqutils::HanOutputFile::getNEntries
virtual double getNEntries(std::string location, std::string histname)
Definition: HanOutputFile.cxx:430
ReadCellNoiseFromCoolCompare.obj2
obj2
Definition: ReadCellNoiseFromCoolCompare.py:303
athena.value
value
Definition: athena.py:122
python.sizes.txt
string txt
Definition: sizes.py:141
dqutils::HanOutputFile::polynomial
virtual void polynomial(TCanvas *c, std::string str, TH1 *h)
Definition: HanOutputFile.cxx:2894
dqutils::HanOutputFile::getAllGroupDirs
static void getAllGroupDirs(DirMap_t &dirmap, TDirectory *dir, const std::string &dirName)
Definition: HanOutputFile.cxx:120
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
HanOutputFile.h
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
read_hist_ntuple.h1
h1
Definition: read_hist_ntuple.py:21
yodamerge_tmp.scale
scale
Definition: yodamerge_tmp.py:138
dqutils::HanOutputFile::setFile
virtual bool setFile(const std::string &fileName)
Clears all previous data and opens the file with the given name for analysis, returning a boolean ind...
Definition: HanOutputFile.cxx:632
x
#define x
dqutils::HanOutputFile::printHistoAssessments
virtual void printHistoAssessments()
Definition: HanOutputFile.cxx:719
dqi::DisableMustClean
Definition: HanUtils.h:30
dqutils::HanOutputFile::processJSON_ingetInfo
static std::string processJSON_ingetInfo(const nlohmann::ordered_json &j)
Definition: HanOutputFile.cxx:588
python.App.legend
legend
Definition: App.py:62
makeTRTBarrelCans.y1
tuple y1
Definition: makeTRTBarrelCans.py:15
dqutils::HanOutputFile::printAllDQGroups
virtual void printAllDQGroups()
Definition: HanOutputFile.cxx:670
module_driven_slicing.key2
key2
Definition: module_driven_slicing.py:159
m_file
std::unique_ptr< TFile > m_file
description: this is a custom writer for the old-school drivers that don't use an actual writer
Definition: OutputStreamData.cxx:52
dqutils::HanOutputFile::displayExtra
virtual void displayExtra(TCanvas *c, const std::string &str)
Definition: HanOutputFile.cxx:2924
dqutils::HanOutputFile::m_file
TFile * m_file
Definition: HanOutputFile.h:178
dqutils::HanOutputFile::containsKeyInJSON
static std::optional< std::string > containsKeyInJSON(const std::string &pathInJSON, const std::string &jsonName, const std::string &path_to_JSON)
Checks JSON file for a key (by its path)
Definition: HanOutputFile.cxx:383
dqutils::HanOutputFile::attachFits
virtual void attachFits(TH1 *hist, std::string &drawopt, std::string &display)
Definition: HanOutputFile.cxx:2294
grepfile.content
string content
Definition: grepfile.py:56
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
DiTauMassTools::ignore
void ignore(T &&)
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:54
dqutils::HanOutputFile::printAllDQAssessments
virtual void printAllDQAssessments()
Definition: HanOutputFile.cxx:717
dqutils::HanOutputFile
Definition: HanOutputFile.h:32
FortranAlgorithmOptions.fileName
fileName
Definition: FortranAlgorithmOptions.py:13
dqutils::HanOutputFile::getIndentation
static std::string getIndentation(const std::string &pathName, const std::string &leadingSpace="")
Definition: HanOutputFile.cxx:621
covarianceTool.pathName
pathName
Definition: covarianceTool.py:704
dqutils::HanOutputFile::GENERATE_JSON
static const int GENERATE_JSON
Definition: HanOutputFile.h:96
PixelAthClusterMonAlgCfg.histname
histname
Definition: PixelAthClusterMonAlgCfg.py:106
geometry_dat_to_json.indent
indent
Definition: geometry_dat_to_json.py:18
dqutils::HanOutputFile::saveAllHistograms
virtual int saveAllHistograms(const std::string &location, bool drawRefs, const std::string &run_min_LB, int cnvsType=1)
Definition: HanOutputFile.cxx:1080
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
ParseInputs.gDirectory
gDirectory
Definition: Final2012/ParseInputs.py:133
dqutils::HanOutputFile::formatTH2
virtual void formatTH2(TCanvas *c, TH2 *h) const
Definition: HanOutputFile.cxx:3126
lumiFormat.i
int i
Definition: lumiFormat.py:92
xmin
double xmin
Definition: listroot.cxx:60
dqutils::HanOutputFile::convertToGraphics
virtual void convertToGraphics(int cnvsType, TCanvas *myC, std::string &json, TImage **img=0, char **x=0, int *y=0)
Definition: HanOutputFile.cxx:3212
python.CaloCondTools.g
g
Definition: CaloCondTools.py:15
DetDescrDictionaryDict::it1
std::vector< HWIdentifier >::iterator it1
Definition: DetDescrDictionaryDict.h:17
HanUtils.h
dqutils::HanOutputFile::clearData
virtual void clearData()
Definition: HanOutputFile.cxx:3181
extractSporadic.h
list h
Definition: extractSporadic.py:97
python.sizes.location
string location
Definition: sizes.py:11
makeTRTBarrelCans.y2
tuple y2
Definition: makeTRTBarrelCans.py:18
dqutils::HanOutputFile::getHistogramJSON
virtual std::pair< std::string, std::string > getHistogramJSON(const std::string &nameHis, TDirectory *groupDir, bool drawRefs, const std::string &run_min_LB, const std::string &pathName)
Definition: HanOutputFile.cxx:1175
calibdata.exception
exception
Definition: calibdata.py:496
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
parseDir.wh
wh
Definition: parseDir.py:46
dqutils::HanOutputFile::writeToFile
virtual bool writeToFile(const std::string &fName, const std::string &content)
Definition: HanOutputFile.cxx:3201
dqutils::HanOutputFile::containsDir
static bool containsDir(std::string dirname, std::string maindir)
Definition: HanOutputFile.cxx:352
dqutils::HanOutputFile::formatTH1
virtual void formatTH1(TCanvas *c, TH1 *h) const
Definition: HanOutputFile.cxx:3097
SCT_Monitoring::disabled
@ disabled
Definition: SCT_MonitoringNumbers.h:60
dqutils::HanOutputFile::m_indirMap
DirMap_t m_indirMap
Definition: HanOutputFile.h:179
dqutils
Definition: CoolMdt.h:76
TH2
Definition: rootspy.cxx:373
pyroot.display
display
Definition: pyroot.py:44
dqutils::HanOutputFile::printDQGroupJSON
static void printDQGroupJSON(const nlohmann::json &j, const std::string &location, const char *path_to_file)
Print path - and name of Assessment, represented as JSON TObjString.
Definition: HanOutputFile.cxx:267
beamspotman.dir
string dir
Definition: beamspotman.py:623
dqutils::HanOutputFile::saveFile
virtual bool saveFile(int cnvsType, const std::string &pngfName, const std::string &pngContent, const std::string &jsonfName, const std::string &jsonfContent)
Definition: HanOutputFile.cxx:3232
dqutils::HanOutputFile::DirMap_t
std::map< std::string, TDirectory * > DirMap_t
Definition: HanOutputFile.h:40
dqutils::HanOutputFile::setupCanvas
virtual void setupCanvas(std::string &drawopt, std::string &display)
Definition: HanOutputFile.cxx:2270
dqutils::HanOutputFile::getAllGroupDirs_V2
static void getAllGroupDirs_V2(DirStrMap_t &dirstrmap, TObject *obj, const std::string &objName)
Same as getAllGroupDirs, but works with Version 2.3 files.
Definition: HanOutputFile.cxx:166
dqutils::HanOutputFile::streamHistoAssessments
virtual void streamHistoAssessments(std::ostream &o, bool streamAll)
Definition: HanOutputFile.cxx:906
BINWIDTH
#define BINWIDTH(h, n)
Definition: HanOutputFile.cxx:49
fitman.g2
g2
Definition: fitman.py:624
dqutils::HanOutputFile::formatTGraph
virtual void formatTGraph(TCanvas *c, TGraph *g) const
Definition: HanOutputFile.cxx:3157
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
dqutils::HanOutputFile::ratioplot2D
virtual void ratioplot2D(TCanvas *canvas, TH2 *h2, TH2 *h2Ref, std::string display)
Definition: HanOutputFile.cxx:2817
createCoolChannelIdFile.par
par
Definition: createCoolChannelIdFile.py:29
dqutils::HanOutputFile::m_indirstrMap
DirStrMap_t m_indirstrMap
Definition: HanOutputFile.h:180
TProfile
Definition: rootspy.cxx:515
dq_make_web_display.rv
def rv
Definition: dq_make_web_display.py:219
dqutils::HanOutputFile::GENERATE_PNG
static const int GENERATE_PNG
cnvsType: 1=pngOnly;2=jsonOnly;3=pngAndJson
Definition: HanOutputFile.h:95
dqutils::HanOutputFile::getHistogram
virtual std::pair< std::string, std::string > getHistogram(const std::string &nameHis, TDirectory *groupDir, bool drawRefs, const std::string &run_min_LB, const std::string &pathName, int cnvsType=1)
Definition: HanOutputFile.cxx:1183
python.changerun.o2
o2
Definition: changerun.py:45
BINLOEDGE
#define BINLOEDGE(h, n)
Definition: HanOutputFile.cxx:48
Rtt_histogram.n1
n1
Definition: Rtt_histogram.py:21
python.AthDsoLogger.fname
string fname
Definition: AthDsoLogger.py:67
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
y
#define y
h
TH1F
Definition: rootspy.cxx:320
CondAlgsOpts.found
int found
Definition: CondAlgsOpts.py:101
python.CaloScaleNoiseConfig.str
str
Definition: CaloScaleNoiseConfig.py:78
egammaEnergyPositionAllSamples::e2
double e2(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 2nd sampling
ref
const boost::regex ref(r_ef)
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
TH1
Definition: rootspy.cxx:268
dqutils::HanOutputFile::getFileVersion
virtual int getFileVersion()
Definition: HanOutputFile.cxx:642
dqutils::HanOutputFile::HanOutputFile
HanOutputFile()
Definition: HanOutputFile.cxx:90
dqutils::HanOutputFile::stringAllDQAssessments
virtual std::string stringAllDQAssessments()
Definition: HanOutputFile.cxx:760
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
dqutils::root_color_choices
std::vector< int > root_color_choices
Definition: HanOutputFile.cxx:86
dqutils::HanOutputFile::getStringName
static std::string getStringName(const std::string &location, int file_version)
Definition: HanOutputFile.cxx:290
xmax
double xmax
Definition: listroot.cxx:61
CxxUtils::atoi
int atoi(std::string_view str)
Helper functions to unpack numbers decoded in string into integers and doubles The strings are requir...
Definition: Control/CxxUtils/Root/StringUtils.cxx:85
dqutils::HanOutputFile::saveHistogramToFile
virtual bool saveHistogramToFile(const std::string &nameHis, std::string location, TDirectory *groupDir, bool drawRefs, const std::string &run_min_LB, const std::string &pathName, int cnvsType=1)
Definition: HanOutputFile.cxx:1142
dqutils::HanOutputFile::AssMap_t
std::map< std::string, std::string > AssMap_t
DirMap_t but For Version 2 files.
Definition: HanOutputFile.h:42
pickleTool.object
object
Definition: pickleTool.py:30
str
Definition: BTagTrackIpAccessor.cxx:11
merge.status
status
Definition: merge.py:17
dqutils::HanOutputFile::drawReference
virtual bool drawReference(TCanvas *canv, TH1 *hRef, TH1 *h, std::string &drawopt, std::string &display, std::string &AlgoName)
Definition: HanOutputFile.cxx:2473
dqutils::HanOutputFile::m_style
TStyle * m_style
Definition: HanOutputFile.h:182
python.LumiCalcRecover.subdir
subdir
Definition: LumiCalcRecover.py:25
dqutils::HanOutputFile::streamAllHistograms
virtual void streamAllHistograms(std::ostream &o, bool streamAll)
Definition: HanOutputFile.cxx:972
python.PyAthena.obj
obj
Definition: PyAthena.py:135
dqutils::HanOutputFile::~HanOutputFile
virtual ~HanOutputFile()
Definition: HanOutputFile.cxx:111
PrepareReferenceFile.outfile
outfile
Definition: PrepareReferenceFile.py:42
TileDCSDataPlotter.tt
tt
Definition: TileDCSDataPlotter.py:874
DeMoGenerateWWW.maindir
string maindir
Definition: DeMoGenerateWWW.py:15
python.compressB64.c
def c
Definition: compressB64.py:93
ymax
double ymax
Definition: listroot.cxx:64
read_hist_ntuple.f1
f1
Definition: read_hist_ntuple.py:4
CompareRootFiles.hist2
hist2
Definition: CompareRootFiles.py:37
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
dqutils::HanOutputFile::streamAllDQAssessments
virtual void streamAllDQAssessments(std::ostream &o, bool streamAll)
Definition: HanOutputFile.cxx:778
module_driven_slicing.key1
key1
Definition: module_driven_slicing.py:158