EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Fun4AllHistoManager.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Fun4AllHistoManager.cc
1 #include "Fun4AllHistoManager.h"
2 
3 #include "TDirectoryHelper.h"
4 
5 #include <phool/phool.h>
6 #include <phool/recoConsts.h>
7 
8 #include <TFile.h>
9 #include <TH1.h>
10 #include <TNamed.h>
11 #include <TTree.h>
12 
13 #include <RVersion.h>
14 #if ROOT_VERSION_CODE >= ROOT_VERSION(5, 20, 0)
15 #define HAS_THNSPARSE 1
16 #include <THnSparse.h>
17 #endif
18 
19 #include <iomanip>
20 #include <iostream>
21 #include <sstream>
22 #include <utility> // for pair
23 
24 using namespace std;
25 
27  : Fun4AllBase(name)
28 {
29  return;
30 }
31 
33 {
34  while (Histo.begin() != Histo.end())
35  {
36  delete Histo.begin()->second;
37  Histo.erase(Histo.begin());
38  }
39  return;
40 }
41 
42 int Fun4AllHistoManager::dumpHistos(const string &filename, const string &openmode)
43 {
44  int iret = 0;
45  if (!filename.empty())
46  {
48  }
49  else
50  {
51  if (outfilename.empty())
52  {
54  ostringstream filnam;
55  int runnumber = -1;
56  if (rc->FlagExist("RUNNUMBER"))
57  {
58  runnumber = rc->get_IntFlag("RUNNUMBER");
59  }
60  // this will set the filename to the name of the manager
61  // add the runnumber in the std 10 digit format and
62  // end it with a .root extension
63  filnam << Name() << "-"
64  << setfill('0') << setw(10)
65  << runnumber << ".root";
66  outfilename = filnam.str();
67  }
68  }
69  cout << "Fun4AllHistoManager::dumpHistos() Writing root file: " << outfilename << endl;
70 
71  const int compress = 9;
72  ostringstream creator;
73  creator << "Created by " << Name();
74  TFile hfile(outfilename.c_str(), openmode.c_str(), creator.str().c_str(), compress);
75  if (!hfile.IsOpen())
76  {
77  cout << PHWHERE << " Could not open output file" << outfilename << endl;
78  return -1;
79  }
80 
81  map<const string, TNamed *>::const_iterator hiter;
82  for (hiter = Histo.begin(); hiter != Histo.end(); ++hiter)
83  {
84  const std::string &hname = hiter->first;
85  const TNamed *hptr = hiter->second;
86  if (Verbosity() > 0)
87  {
88  std::cout << PHWHERE << " Saving histo "
89  << hname
90  << std::endl;
91  }
92 
93  // Decode the string to see if it wants a directory
94  string::size_type pos = hname.find_last_of('/');
95  string dirname;
96  if (pos != string::npos) // string::npos is the result if search unsuccessful
97  {
98  dirname = hname.substr(0, pos);
99  }
100  else
101  {
102  dirname = "";
103  }
104 
105  if (Verbosity())
106  {
107  cout << " Histogram named " << hptr->GetName();
108  cout << " key " << hname;
109  if (dirname.size())
110  {
111  cout << " being saved to directory " << dirname;
112  }
113  cout << endl;
114  }
115 
116  if (dirname.size())
117  {
118  TDirectoryHelper::mkdir(&hfile, dirname.c_str());
119  hfile.cd(dirname.c_str());
120  }
121 
122  if (hptr)
123  {
124  int byteswritten = hptr->Write();
125  if (!byteswritten)
126  {
127  cout << PHWHERE << "Error saving histogram "
128  << hptr->GetName()
129  << endl;
130  iret = -2;
131  }
132  }
133  else
134  {
135  cout << PHWHERE << "dumpHistos : histogram "
136  << hname << " is a null pointer! Won't be saved."
137  << std::endl;
138  }
139  }
140  hfile.Close();
141  return iret;
142 }
143 
144 bool Fun4AllHistoManager::registerHisto(TNamed *h1d, const int replace)
145 {
146  return registerHisto(h1d->GetName(), h1d, replace);
147 }
148 
149 bool Fun4AllHistoManager::registerHisto(const string &hname, TNamed *h1d, const int replace)
150 {
151  map<const string, TNamed *>::const_iterator histoiter = Histo.find(hname);
152  if (histoiter != Histo.end() && replace == 0)
153  {
154  cerr << "Histogram " << hname << " already registered, I won't overwrite it" << endl;
155  cerr << "Use a different name and try again" << endl;
156  return false;
157  }
158 
159  string::size_type pos = hname.find_last_of('/');
160  string histoname = hname;
161  if (pos != string::npos) // okay someone wants damn TDirectories
162  {
163  histoname = hname.substr(pos + 1);
164  }
165  if (Verbosity() > 1)
166  {
167  if (histoname != h1d->GetName())
168  {
169  cout << PHWHERE << "Histogram " << h1d->GetName()
170  << " at " << h1d << " renamed to " << histoname << endl;
171  }
172  }
173  // this one did some very ugly mutilation to a const char *
174  // using a string seems to avoid the damage
175  h1d->SetName(histoname.c_str());
176  Histo[hname] = h1d;
177 
178  // reset directory for TTree
179  if (h1d->InheritsFrom("TTree"))
180  static_cast<TTree *>(h1d)->SetDirectory(0);
181 
182  // For histograms, enforce error calculation and propagation
183  if (h1d->InheritsFrom("TH1"))
184  static_cast<TH1 *>(h1d)->Sumw2();
185 
186  return true;
187 }
188 
189 int Fun4AllHistoManager::isHistoRegistered(const std::string &name) const
190 {
191  map<const string, TNamed *>::const_iterator histoiter = Histo.find(name);
192  if (histoiter != Histo.end())
193  {
194  return 1;
195  }
196  return 0;
197 }
198 
199 TNamed *
200 Fun4AllHistoManager::getHisto(const unsigned int ihisto) const
201 {
202  map<const string, TNamed *>::const_iterator histoiter = Histo.begin();
203  unsigned int size = Histo.size();
204  if (Verbosity() > 3)
205  {
206  cout << "Map contains " << size << " Elements" << endl;
207  }
208  if (ihisto < size)
209  {
210  for (unsigned int i = 0; i < ihisto; i++)
211  {
212  ++histoiter;
213  }
214  return histoiter->second;
215  }
216  else
217  {
218  cout << "Fun4AllHistoManager::getHisto: ERROR Invalid histogram number: "
219  << ihisto << ", maximum number is " << size << endl;
220  }
221  return nullptr;
222 }
223 
224 string
225 Fun4AllHistoManager::getHistoName(const unsigned int ihisto) const
226 {
227  map<const string, TNamed *>::const_iterator histoiter = Histo.begin();
228  unsigned int size = Histo.size();
229  if (Verbosity() > 3)
230  {
231  cout << "Map contains " << size << " Elements" << endl;
232  }
233  if (ihisto < size)
234  {
235  for (unsigned int i = 0; i < ihisto; i++)
236  {
237  ++histoiter;
238  }
239  return histoiter->first;
240  }
241  else
242  {
243  cout << "Fun4AllHistoManager::getHisto: ERROR Invalid histogram number: "
244  << ihisto << ", maximum number is " << size << endl;
245  }
246  return "";
247 }
248 
249 TNamed *
250 Fun4AllHistoManager::getHisto(const string &hname) const
251 {
252  map<const string, TNamed *>::const_iterator histoiter = Histo.find(hname);
253  if (histoiter != Histo.end())
254  {
255  return histoiter->second;
256  }
257  cout << "Fun4AllHistoManager::getHisto: ERROR Unknown Histogram " << hname
258  << ", The following are implemented: " << endl;
259  Print("ALL");
260  return nullptr;
261 }
262 
263 void Fun4AllHistoManager::Print(const string &what) const
264 {
265  if (what == "ALL" || what == "HISTOS")
266  {
267  // loop over the map and print out the content (name and location in memory)
268  cout << "--------------------------------------" << endl
269  << endl;
270  cout << "List of Histos in Fun4AllHistoManager "
271  << Name() << ":" << endl;
272 
273  map<const string, TNamed *>::const_iterator hiter;
274  for (hiter = Histo.begin(); hiter != Histo.end(); ++hiter)
275  {
276  cout << hiter->first << " is " << hiter->second << endl;
277  }
278  cout << endl;
279  }
280  return;
281 }
282 
284 {
285  map<const string, TNamed *>::const_iterator hiter;
286  for (hiter = Histo.begin(); hiter != Histo.end(); ++hiter)
287  {
288  TNamed *h = hiter->second;
289  if (h->InheritsFrom("TH1"))
290  (dynamic_cast<TH1 *>(h))->Reset();
291 #if HAS_THNSPARSE
292  else if (h->InheritsFrom("THnSparse"))
293  (dynamic_cast<THnSparse *>(h))->Reset();
294 #endif
295  }
296  return;
297 }