ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TDirectoryHelper.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file TDirectoryHelper.cc
1 #include "TDirectoryHelper.h"
2 
3 #include <TCollection.h> // for TIter
4 #include <TDirectory.h>
5 #include <TFile.h>
6 #include <TH1.h>
7 #include <TList.h> // for TList
8 #include <TObject.h>
9 #include <TROOT.h>
10 
11 #include <algorithm> // for max
12 #include <cassert>
13 #include <cstddef> // for size_t
14 #include <iostream>
15 #include <memory> // for allocator_traits<>::value_type
16 #include <string>
17 #include <vector>
18 
19 using namespace std;
20 
21 //_____________________________________________________________________________
22 void TDirectoryHelper::copyToFile(TDirectory* src, TFile* dest)
23 {
24  TDirectory* save = gDirectory;
25 
26  // We basically have two cases here to consider, depending
27  // on whether (1) or not (2) a TFile was opened prior to calling
28  // the PhotonHistogrammer ctor.
29  // 1. Nothing special to do, all the TDirectory structure
30  // is already attached to the correct file.
31  // 2. We have to "duplicate" the TDirectory structure into
32  // the newly opened file and save the HistogramCollection(s) there.
33 
34  if (!dest || !src)
35  {
36  return;
37  }
38 
39  if (!dest->IsWritable())
40  {
41  cerr << "TDirectoryHelper::copyToFile : destination file is not "
42  " writeable"
43  << endl;
44  return;
45  }
46 
47  duplicateDir(dest, src);
48 
49  // list<TDirectory*> mothers;
50 
51  // TDirectory* mother = fDir;
52 
53  // while ( (mother = dynamic_cast<TDirectory*>(mother->GetMother()) ) )
54  // {
55  // std::string motherName = mother->GetName();
56  // if (motherName != "Rint" )
57  // {
58  // mothers.push_front(mother);
59  // }
60  // }
61 
62  // TDirectory* currentDir = save;
63 
64  // list<TDirectory*>::const_iterator it;
65 
66  // for ( it = mothers.begin(); it != mothers.end() ; it++ )
67  // {
68 
69  // TDirectory* dir;
70  // if ( (dir=(TDirectory*)currentDir->FindObject((*it)->GetName()) ))
71  // {
72  // currentDir = dir;
73  // }
74  // else
75  // {
76  // currentDir = currentDir->mkdir((*it)->GetName(),
77  // (*it)->GetTitle());
78  // }
79  // }
80 
81  // TDirectoryHelper::duplicateDir
82  // ((TDirectory*)save->FindObject(mothers.back()->GetName()),fDir);
83 
84  // }
85 
86  save->cd();
87 }
88 
89 //_____________________________________________________________________________
90 void TDirectoryHelper::duplicateDir(TDirectory* dest, TDirectory* source)
91 {
92  dest->cd();
93 
94  TDirectory* newdir;
95 
96  newdir = static_cast<TDirectory*>(gDirectory->FindObject(source->GetName()));
97 
98  if (!newdir)
99  {
100  newdir = dest->mkdir(source->GetName(), source->GetTitle());
101  }
102 
103  newdir->cd();
104 
105  TIter next(source->GetList());
106  TObject* obj;
107 
108  while ((obj = next()))
109  {
110  TDirectory* dir = dynamic_cast<TDirectory*>(obj);
111  if (dir)
112  {
113  duplicateDir(newdir, dir);
114  }
115  else
116  {
117  obj->Write();
118  }
119  }
120 }
121 
122 //_____________________________________________________________________________
123 bool TDirectoryHelper::mkpath(TDirectory* dir, const string& path)
124 {
125  static vector<string> paths;
126 
127  splitPath(path, paths);
128 
129  TDirectory* currentdir = dir;
130 
131  for (size_t i = 0; i < paths.size(); i++)
132  {
133  currentdir->cd();
134 
135  currentdir = dynamic_cast<TDirectory*>(gDirectory->Get(paths[i].c_str()));
136  if (!currentdir)
137  {
138  currentdir = gDirectory->mkdir(paths[i].c_str());
139  assert(currentdir != 0);
140  }
141  }
142 
143  return true;
144 }
145 
146 //_____________________________________________________________________________
147 TDirectory*
148 TDirectoryHelper::mkdir(TDirectory* topDir,
149  const string& path,
150  std::vector<std::string>* titles)
151 {
152  TDirectory* save = gDirectory;
153 
154  TDirectory* dir = topDir;
155  TDirectory* tdir = dir;
156 
157  if (topDir == 0)
158  {
159  gROOT->cd();
160  tdir = gDirectory;
161  }
162 
163  dir = tdir;
164 
165  dir->cd();
166  std::vector<std::string> paths;
167 
168  splitPath(path, paths);
169 
170  for (size_t i = 0; i < paths.size(); i++)
171  {
172  TDirectory* subdir = static_cast<TDirectory*>(dir->FindObject(paths[i].c_str()));
173  if (subdir == 0)
174  {
175  if (titles && i < titles->size())
176  {
177  dir = dir->mkdir(paths[i].c_str(), (*titles)[i].c_str());
178  }
179  else
180  {
181  dir = dir->mkdir(paths[i].c_str());
182  }
183  }
184  else
185  {
186  dir = subdir;
187  }
188  dir->cd();
189  }
190 
191  save->cd();
192 
193  return dir;
194 }
195 
196 //_____________________________________________________________________________
197 bool TDirectoryHelper::pathIsInDir(const string& path, TDirectory* dir)
198 {
199  // This is to avoid annoying ROOT message when a directory does not exist
200  // in Cd(), so we provide this small method to check whereas
201  // a path exists under a directory, but without issuing error message
202  // in case of failure (just returning false in this case).
203 
204  TDirectory* dirsave = gDirectory;
205 
206  static std::vector<string> paths;
207 
208  paths.clear();
209  splitPath(path, paths);
210 
211  bool ok = true;
212 
213  TDirectory* cdir = dir;
214 
215  for (size_t i = 0; i < paths.size() && ok; i++)
216  {
217  cdir->cd();
218 
219  cdir = dynamic_cast<TDirectory*>(cdir->Get(paths[i].c_str()));
220  if (!cdir)
221  {
222  ok = false;
223  }
224  }
225 
226  dirsave->cd();
227 
228  return ok;
229 }
230 
231 //_____________________________________________________________________________
232 TH1* TDirectoryHelper::getHisto(TDirectory* dir, const string& histoname,
233  const string& where)
234 {
235  // Try to find histogram named histoname into directory dir, under
236  // path=where (where e.g. = "/Cut##/OK/C#/V#").
237 
238  TH1* rv = 0;
239 
240  bool ok = pathIsInDir(where, dir);
241 
242  if (ok)
243  {
244  // Path is in dir, we can safely (i.e. without getting ROOT error message
245  // on stdout) cd into it.
246  // dir->cd();
247  ok = dir->cd(where.c_str());
248  assert(ok == true);
249  TObject* obj = gDirectory->Get(histoname.c_str());
250  if (obj)
251  {
252  rv = dynamic_cast<TH1*>(obj);
253  if (!rv)
254  {
255  cerr << "GetHisto : object " << histoname << " is not a TH1" << endl;
256  }
257  }
258  }
259  return rv;
260 }
261 
262 //_____________________________________________________________________________
263 void TDirectoryHelper::splitPath(const string& path,
264  std::vector<std::string>& paths)
265 {
266  // Given a path e.g. /Cut##/OK/C#/V#, will return
267  // a vector of string with Cut#,
268 
269  paths.clear();
270 
271  std::string str = path;
272 
273  if (str.empty())
274  {
275  return;
276  }
277 
278  std::vector<size_t> slashes_pos;
279 
280  if (str[0] != '/')
281  {
282  str.insert(str.begin(), '/');
283  }
284 
285  if (str[str.size() - 1] != '/')
286  {
287  str.push_back('/');
288  }
289 
290  for (size_t i = 0; i < str.size(); i++)
291  {
292  if (str[i] == '/')
293  {
294  slashes_pos.push_back(i);
295  }
296  }
297 
298  if (not slashes_pos.empty())
299  {
300  for (size_t i = 0; i < slashes_pos.size() - 1; i++)
301  {
302  paths.push_back(str.substr(slashes_pos[i] + 1,
303  slashes_pos[i + 1] - slashes_pos[i] - 1));
304  }
305  }
306 }