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