Back to home page

sPhenix code displayed by LXR

 
 

    


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   // We basically have two cases here to consider, depending
0025   // on whether (1) or not (2) a TFile was opened prior to calling
0026   // the PhotonHistogrammer ctor.
0027   // 1. Nothing special to do, all the TDirectory structure
0028   //    is already attached to the correct file.
0029   // 2. We have to "duplicate" the TDirectory structure into
0030   //    the newly opened file and save the HistogramCollection(s) there.
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   //       list<TDirectory*> mothers;
0048 
0049   //       TDirectory* mother = fDir;
0050 
0051   //       while ( (mother = dynamic_cast<TDirectory*>(mother->GetMother()) ) )
0052   //    {
0053   //      std::string motherName = mother->GetName();
0054   //      if (motherName != "Rint" )
0055   //        {
0056   //          mothers.push_front(mother);
0057   //        }
0058   //    }
0059 
0060   //       TDirectory* currentDir = save;
0061 
0062   //       list<TDirectory*>::const_iterator it;
0063 
0064   //       for ( it = mothers.begin(); it != mothers.end() ; it++ )
0065   //    {
0066 
0067   //      TDirectory* dir;
0068   //      if ( (dir=(TDirectory*)currentDir->FindObject((*it)->GetName()) ))
0069   //        {
0070   //          currentDir = dir;
0071   //        }
0072   //      else
0073   //        {
0074   //          currentDir = currentDir->mkdir((*it)->GetName(),
0075   //                         (*it)->GetTitle());
0076   //        }
0077   //    }
0078 
0079   //       TDirectoryHelper::duplicateDir
0080   //    ((TDirectory*)save->FindObject(mothers.back()->GetName()),fDir);
0081 
0082   //     }
0083 
0084   save->cd();
0085 }
0086 
0087 //_____________________________________________________________________________
0088 // NOLINTNEXTLINE(misc-no-recursion)
0089 void TDirectoryHelper::duplicateDir(TDirectory* dest, TDirectory* source)
0090 {
0091   dest->cd();
0092 
0093   TDirectory* newdir;
0094 
0095   // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
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     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-static-cast-downcast)
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   // This is to avoid annoying ROOT message when a directory does not exist
0201   // in Cd(), so we provide this small method to check whereas
0202   // a path exists under a directory, but without issuing error message
0203   // in case of failure (just returning false in this case).
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   // Try to find histogram named histoname into directory dir, under
0237   // path=where (where e.g. = "/Cut##/OK/C#/V#").
0238 
0239   TH1* rv = nullptr;
0240 
0241   bool ok = pathIsInDir(where, dir);
0242 
0243   if (ok)
0244   {
0245     // Path is in dir, we can safely (i.e. without getting ROOT error message
0246     // on stdout) cd into it.
0247     //    dir->cd();
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   // Given a path e.g. /Cut##/OK/C#/V#, will return
0268   // a vector of string with Cut#,
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 }