File indexing completed on 2025-08-06 08:17:18
0001 #include "TDirectoryHelper.h"
0002
0003 #include <TCollection.h> // for TIter
0004 #include <TDirectory.h>
0005 #include <TFile.h>
0006 #include <TH1.h>
0007 #include <TList.h> // for TList
0008 #include <TObject.h>
0009 #include <TROOT.h>
0010
0011 #include <algorithm> // for max
0012 #include <cassert>
0013 #include <cstddef> // for size_t
0014 #include <iostream>
0015 #include <memory> // for allocator_traits<>::value_type
0016 #include <string>
0017 #include <vector>
0018
0019
0020 void TDirectoryHelper::copyToFile(TDirectory* src, TFile* dest)
0021 {
0022 TDirectory* save = gDirectory;
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 if (!dest || !src)
0033 {
0034 return;
0035 }
0036
0037 if (!dest->IsWritable())
0038 {
0039 std::cout << "TDirectoryHelper::copyToFile : destination file is not "
0040 " writeable"
0041 << std::endl;
0042 return;
0043 }
0044
0045 duplicateDir(dest, src);
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084 save->cd();
0085 }
0086
0087
0088
0089 void TDirectoryHelper::duplicateDir(TDirectory* dest, TDirectory* source)
0090 {
0091 dest->cd();
0092
0093 TDirectory* newdir;
0094
0095
0096 newdir = static_cast<TDirectory*>(gDirectory->FindObject(source->GetName()));
0097
0098 if (!newdir)
0099 {
0100 newdir = dest->mkdir(source->GetName(), source->GetTitle());
0101 }
0102
0103 newdir->cd();
0104
0105 TIter next(source->GetList());
0106 TObject* obj;
0107
0108 while ((obj = next()))
0109 {
0110 TDirectory* dir = dynamic_cast<TDirectory*>(obj);
0111 if (dir)
0112 {
0113 duplicateDir(newdir, dir);
0114 }
0115 else
0116 {
0117 obj->Write();
0118 }
0119 }
0120 }
0121
0122
0123 bool TDirectoryHelper::mkpath(TDirectory* dir, const std::string& pathin)
0124 {
0125 static std::vector<std::string> paths;
0126
0127 splitPath(pathin, paths);
0128
0129 TDirectory* currentdir = dir;
0130
0131 for (auto& path : paths)
0132 {
0133 currentdir->cd();
0134
0135 currentdir = dynamic_cast<TDirectory*>(gDirectory->Get(path.c_str()));
0136 if (!currentdir)
0137 {
0138 currentdir = gDirectory->mkdir(path.c_str());
0139 assert(currentdir != nullptr);
0140 }
0141 }
0142
0143 return true;
0144 }
0145
0146
0147 TDirectory*
0148 TDirectoryHelper::mkdir(TDirectory* topDir,
0149 const std::string& path,
0150 std::vector<std::string>* titles)
0151 {
0152 TDirectory* save = gDirectory;
0153
0154 TDirectory* dir = topDir;
0155 TDirectory* tdir = dir;
0156
0157 if (topDir == nullptr)
0158 {
0159 gROOT->cd();
0160 tdir = gDirectory;
0161 }
0162
0163 dir = tdir;
0164
0165 dir->cd();
0166 std::vector<std::string> paths;
0167
0168 splitPath(path, paths);
0169
0170 for (size_t i = 0; i < paths.size(); i++)
0171 {
0172
0173 TDirectory* subdir = static_cast<TDirectory*>(dir->FindObject(paths[i].c_str()));
0174 if (subdir == nullptr)
0175 {
0176 if (titles && i < titles->size())
0177 {
0178 dir = dir->mkdir(paths[i].c_str(), (*titles)[i].c_str());
0179 }
0180 else
0181 {
0182 dir = dir->mkdir(paths[i].c_str());
0183 }
0184 }
0185 else
0186 {
0187 dir = subdir;
0188 }
0189 dir->cd();
0190 }
0191
0192 save->cd();
0193
0194 return dir;
0195 }
0196
0197
0198 bool TDirectoryHelper::pathIsInDir(const std::string& path, TDirectory* dir)
0199 {
0200
0201
0202
0203
0204
0205 TDirectory* dirsave = gDirectory;
0206
0207 static std::vector<std::string> paths;
0208
0209 paths.clear();
0210 splitPath(path, paths);
0211
0212 bool ok = true;
0213
0214 TDirectory* cdir = dir;
0215
0216 for (size_t i = 0; i < paths.size() && ok; i++)
0217 {
0218 cdir->cd();
0219
0220 cdir = dynamic_cast<TDirectory*>(cdir->Get(paths[i].c_str()));
0221 if (!cdir)
0222 {
0223 ok = false;
0224 }
0225 }
0226
0227 dirsave->cd();
0228
0229 return ok;
0230 }
0231
0232
0233 TH1* TDirectoryHelper::getHisto(TDirectory* dir, const std::string& histoname,
0234 const std::string& where)
0235 {
0236
0237
0238
0239 TH1* rv = nullptr;
0240
0241 bool ok = pathIsInDir(where, dir);
0242
0243 if (ok)
0244 {
0245
0246
0247
0248 ok = dir->cd(where.c_str());
0249 assert(ok == true);
0250 TObject* obj = gDirectory->Get(histoname.c_str());
0251 if (obj)
0252 {
0253 rv = dynamic_cast<TH1*>(obj);
0254 if (!rv)
0255 {
0256 std::cout << "GetHisto : object " << histoname << " is not a TH1" << std::endl;
0257 }
0258 }
0259 }
0260 return rv;
0261 }
0262
0263
0264 void TDirectoryHelper::splitPath(const std::string& path,
0265 std::vector<std::string>& paths)
0266 {
0267
0268
0269
0270 paths.clear();
0271
0272 std::string str = path;
0273
0274 if (str.empty())
0275 {
0276 return;
0277 }
0278
0279 std::vector<size_t> slashes_pos;
0280
0281 if (str[0] != '/')
0282 {
0283 str.insert(str.begin(), '/');
0284 }
0285
0286 if (str[str.size() - 1] != '/')
0287 {
0288 str.push_back('/');
0289 }
0290
0291 for (size_t i = 0; i < str.size(); i++)
0292 {
0293 if (str[i] == '/')
0294 {
0295 slashes_pos.push_back(i);
0296 }
0297 }
0298
0299 if (not slashes_pos.empty())
0300 {
0301 for (size_t i = 0; i < slashes_pos.size() - 1; i++)
0302 {
0303 paths.push_back(str.substr(slashes_pos[i] + 1,
0304 slashes_pos[i + 1] - slashes_pos[i] - 1));
0305 }
0306 }
0307 }