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