/search.css" rel="stylesheet" type="text/css"/> /search.js">
00001 #include "HistMan/HistMan.h" 00002 00003 #include <TSystem.h> 00004 #include <TKey.h> 00005 #include <TROOT.h> 00006 #include <TFile.h> 00007 #include <TH1.h> 00008 #include <TH2.h> 00009 #include <TProfile.h> 00010 #include <TTree.h> 00011 00012 #include <string> 00013 #include <vector> 00014 #include <iostream> 00015 #include <cassert> 00016 #include <algorithm> 00017 using namespace std; 00018 00019 //const char baseName[] = "HistMan"; 00020 const char baseName[] = "stats"; 00021 00022 vector<string> parse_path(const char* path) 00023 { 00024 vector<string> vs; 00025 string p(path); 00026 string::iterator it1=p.begin(), it2, done=p.end(); 00027 for (it2=find(p.begin(),done,'/'); it2 != done; it2=find(it1,done,'/')) { 00028 if (it1==it2) { 00029 ++it1; 00030 continue; 00031 } 00032 string dir(it1,it2); 00033 if (dir != ".") 00034 vs.push_back(dir); 00035 it1 = it2+1; 00036 } 00037 if (it1 != it2) { 00038 string dir(it1,it2); 00039 if (dir != ".") 00040 vs.push_back(string(it1,it2)); 00041 } 00042 return vs; 00043 } 00044 00045 TFolder& mkdir_p(TFolder& top, const char* path) 00046 { 00047 if (!path || path[0] == '\0') return top; 00048 00049 vector<string> vp = parse_path(path); 00050 TFolder* folder = ⊤ 00051 for (unsigned int ind=0; ind < vp.size(); ++ind) { 00052 const char* name = vp[ind].c_str(); 00053 TFolder* tmp = dynamic_cast<TFolder*>(folder->FindObject(name)); 00054 if (tmp) folder = tmp; 00055 else folder = folder->AddFolder(name,name); 00056 } 00057 return *folder; 00058 } 00059 00060 static int histcount = 0; 00061 HistMan::HistMan(TFolder* folder, bool own) 00062 : fFolder(folder) 00063 , fOwn(own) 00064 { 00065 if (!fFolder) { 00066 fFolder = new TFolder(Form("HistFolder%d",histcount), 00067 Form("Histogram Folder #%d",histcount)); 00068 } 00069 fFolder->SetOwner(true); 00070 } 00071 00072 HistMan::HistMan(const char* base_directory) 00073 { 00074 fFolder = &this->BaseFolder(); 00075 fFolder = &mkdir_p(*fFolder,base_directory); 00076 fOwn = false; 00077 fFolder->SetOwner(true); 00078 } 00079 00080 static TFolder* directory_to_folder(TDirectory& directory) 00081 { 00082 TFolder* folder = new TFolder(directory.GetName(),directory.GetName()); 00083 00084 TList *l = directory.GetListOfKeys(); 00085 if (!l) return folder; 00086 00087 TIter it(l->MakeIterator()); 00088 TObject *obj=0; 00089 while ( (obj=it()) ) { 00090 TKey* key = dynamic_cast<TKey*>(obj); 00091 assert(key); 00092 obj = directory.Get(key->GetName()); 00093 TDirectory* dir = dynamic_cast<TDirectory*>(obj); 00094 if (dir) { 00095 TFolder* fol = directory_to_folder(*dir); 00096 //cerr << "Adding folder " << fol->GetName() 00097 //<< " to folder " << folder->GetName() 00098 //<< " from directory " << dir->GetName() << endl; 00099 folder->Add(fol); 00100 } 00101 else { 00102 //cerr << "Adding object " << obj->GetName() 00103 //<< " to folder " << folder->GetName() << endl; 00104 folder->Add(obj); 00105 } 00106 } 00107 return folder; 00108 } 00109 00110 00111 00112 HistMan::HistMan(TFile& file, bool attach) 00113 { 00114 TDirectory* dir = dynamic_cast<TDirectory*>(file.Get(baseName)); 00115 if (!dir) { 00116 //cerr << "Failed to find HistMan folder in " << file.GetName() << endl; 00117 fFolder = &this->BaseFolder(); 00118 fFolder = &mkdir_p(*fFolder,""); 00119 fOwn = false; 00120 fFolder->SetOwner(true); 00121 return; 00122 } 00123 fFolder = directory_to_folder(*dir); 00124 if (attach) { 00125 fOwn = false; 00126 gROOT->Add(fFolder); 00127 } 00128 } 00129 00130 HistMan::HistMan(const char** file_list, const char** hist_list) 00131 { 00132 fFolder = &this->BaseFolder(); 00133 fFolder = &mkdir_p(*fFolder,""); 00134 fOwn = false; 00135 fFolder->SetOwner(true); 00136 // 00137 for (int ifile=0; file_list[ifile]; ++ifile){ 00138 // check first if there the file exists, if not, print out a 00139 // warning message and continue with the other files 00140 if (gSystem->AccessPathName(file_list[ifile])) { 00141 cout << "HistMan: Warning: file " << file_list[ifile] 00142 << " does not exist!" << endl; 00143 continue; 00144 } 00145 TFile file(file_list[ifile]); 00146 if (!file.IsOpen()) { 00147 cout << "HistMan: Warning: problems opening file " 00148 << file_list[ifile] << endl; 00149 continue; 00150 } 00151 HistMan hm(file,false); 00152 for (int ihist=0; hist_list[ihist]; ++ihist){ 00153 // Get a pointer to the histogram in the old file 00154 TH1* hold = hm.Get<TH1>(hist_list[ihist]); 00155 if (!hold) { 00156 cout << "HistMan: Warning: histogram named " 00157 << hist_list[ihist] << " does not exist in file " 00158 << file_list[ifile] << endl; 00159 continue; 00160 } 00161 00162 // try to get a pointer to the hitogram in the new 00163 // HistMan. If it exists, add the old histogram to it. I 00164 // it doesn't, adopt the old histo 00165 TH1* hnew = this->Get<TH1>(hist_list[ihist]); 00166 if (hnew) 00167 hnew->Add(hold); 00168 else{ 00169 string hname_fullp(hist_list[ihist]); 00170 string::size_type pos = hname_fullp.rfind("/"); 00171 string hname_path; 00172 if (pos < hname_fullp.length()) 00173 hname_path = hname_fullp.substr(0,pos); 00174 else 00175 hname_path = ""; 00176 00177 this->Adopt(hname_path.c_str(),dynamic_cast<TH1*>(hold->Clone())); 00178 } 00179 } 00180 file.Close(); 00181 } 00182 } 00183 00184 HistMan::~HistMan() 00185 { 00186 if (fOwn) { 00187 //cerr<< "HistMan::~HistMan: Deleting file\n"; 00188 delete fFolder; 00189 } 00190 fFolder = 0; 00191 } 00192 00193 TFolder& HistMan::BaseFolder() 00194 { 00195 TFolder* folder = dynamic_cast<TFolder*>(gROOT->FindObjectAny(baseName)); 00196 if (folder) return *folder; 00197 00198 folder = new TFolder(baseName,"Base Histogram Manager Folder"); 00199 gROOT->Add(folder); 00200 return *folder; 00201 } 00202 void HistMan::RegisterWithRoot() 00203 { 00204 if (!fOwn) return; 00205 fOwn = false; 00206 00207 TFolder& base = this->BaseFolder(); 00208 base.Add(fFolder); 00209 } 00210 00211 static void folder_to_directory(TFolder* folder, TDirectory& directory) 00212 { 00213 TDirectory*& prevdir = gDirectory, *dir = 0; 00214 00215 TObject* obj = directory.Get(folder->GetName()); 00216 if (obj) { 00217 dir = dynamic_cast<TDirectory*>(obj); 00218 if (!dir) { 00219 cerr << "Non-directory object \"" << folder->GetName() 00220 << "\" already in directory\n"; 00221 return; 00222 } 00223 } 00224 else 00225 dir = directory.mkdir(folder->GetName()); 00226 00227 dir->cd(); 00228 00229 TCollection* sf = folder->GetListOfFolders(); 00230 if (!sf) { 00231 prevdir->cd(); 00232 return; 00233 } 00234 00235 TIter it(sf->MakeIterator()); 00236 obj=0; 00237 while ( (obj=it()) ) { 00238 TFolder *fol = dynamic_cast<TFolder*>(obj); 00239 if (fol) folder_to_directory(fol,*dir); 00240 else { 00241 dir->cd(); 00242 obj->Write(); 00243 } 00244 } 00245 prevdir->cd(); 00246 } 00247 00248 void HistMan::WriteOut(TFile& file) 00249 { 00250 if (!fFolder) return; 00251 folder_to_directory(fFolder,file); 00252 } 00253 void HistMan::WriteOut(const char* filename) 00254 { 00255 TFile f(filename,"recreate"); 00256 this->WriteOut(f); 00257 f.Close(); 00258 } 00259 00260 00261 TObject* HistMan::Adopt(const char* dirpath, TObject* obj) 00262 { 00263 TH1* hist = dynamic_cast<TH1*>(obj); 00264 if (hist) 00265 hist->SetDirectory(0); 00266 TTree* tree = dynamic_cast<TTree*>(obj); 00267 if (tree) 00268 tree->SetDirectory(0); 00269 TFolder* folder = &mkdir_p(*fFolder,dirpath); 00270 if (folder->FindObject(obj->GetName())) { // FindObject(Object*) not implemented! 00271 cerr << "Object: " << dirpath << "/" 00272 << obj->GetName() << " already exists\n"; 00273 delete obj; 00274 return 0; 00275 } 00276 folder->Add(obj); 00277 00278 return obj; 00279 } 00280 bool HistMan::Fill1d(const char* pathname, Axis_t x, Stat_t w) 00281 { 00282 TObject* o = fFolder->FindObject(pathname); 00283 if (!o) o = fFolder->FindObjectAny(pathname); 00284 TH1* h = dynamic_cast<TH1*>(o); 00285 if (!h) { 00286 cerr << "Fill1d(\""<<pathname<<"\") failed lookup\n"; 00287 return false; 00288 } 00289 h->Fill(x,w); 00290 return true; 00291 } 00292 bool HistMan::Fill2d(const char* pathname, Axis_t x, Axis_t y, Stat_t w) 00293 { 00294 TObject* o = fFolder->FindObject(pathname); 00295 if (!o) o = fFolder->FindObjectAny(pathname); 00296 TH2* h = dynamic_cast<TH2*>(o); 00297 if (!h) { 00298 cerr << "Fill2d(\""<<pathname<<"\") failed lookup\n"; 00299 return false; 00300 } 00301 h->Fill(x,y,w); 00302 return true; 00303 } 00304 00305 bool HistMan::FillProfile(const char* pathname, Axis_t x, Axis_t y, Stat_t w) 00306 { 00307 TObject* o = fFolder->FindObject(pathname); 00308 if (!o) o = fFolder->FindObjectAny(pathname); 00309 TProfile* h = dynamic_cast<TProfile*>(o); 00310 if (!h) { 00311 cerr << "FillProfile(\""<<pathname<<"\") failed lookup\n"; 00312 return false; 00313 } 00314 h->Fill(x,y,w); 00315 return true; 00316 } 00317 00318 00319 TObject* HistMan::GetObject(const char* pathname){ 00320 TObject* obj = GetObjectOrFolder(pathname); 00321 if(!obj) return 0; 00322 // Don't return folders 00323 TFolder* f = dynamic_cast<TFolder*>(obj); 00324 if ( f ) return 0; 00325 return obj; 00326 } 00327 00328 TFolder* HistMan::GetFolder(const char* pathname){ 00329 TObject* obj = GetObjectOrFolder(pathname); 00330 if(!obj) return 0; 00331 // Only return folders 00332 TFolder* f = dynamic_cast<TFolder*>(obj); 00333 if ( !f ) return 0; 00334 return f; 00335 } 00336 00337 TObject* HistMan::GetObjectOrFolder(const char* pathname) 00338 { 00339 if (!fFolder) return 0; 00340 vector<string> path = parse_path(pathname); 00341 TFolder* folder = fFolder; 00342 for (size_t ind=0; ind < path.size(); ++ind) { 00343 //cerr << "Checking " << path[ind] << endl; 00344 TObject* obj = folder->FindObject(path[ind].c_str()); 00345 if( !obj ) return 0; 00346 if( ind == (path.size()-1) ) return obj; 00347 TFolder* f = dynamic_cast<TFolder*>(obj); 00348 if ( !f ) return 0; 00349 folder = f; 00350 } 00351 return folder; 00352 } 00353 00354 vector<TObject*> HistMan::GetObjects(const char* pathname){ 00355 // Return the list of Objects (non-folders) in this folder 00356 vector<TObject*> objects; 00357 TFolder* currentFolder = this->GetFolder(pathname); 00358 if(!currentFolder) return objects; 00359 TCollection* contents = currentFolder->GetListOfFolders(); 00360 TIter next(contents); 00361 TObject* obj = 0; 00362 while( (obj = next()) ){ 00363 TFolder* folder = dynamic_cast<TFolder*>(obj); 00364 if(folder) continue; // Ignore sub-folders 00365 objects.push_back(obj); 00366 } 00367 return objects; 00368 } 00369 00370 vector<TFolder*> HistMan::GetSubFolders(const char* pathname){ 00371 // Return the list of sub-folders in this folder 00372 vector<TFolder*> folders; 00373 TFolder* currentFolder = this->GetFolder(pathname); 00374 if(!currentFolder) return folders; 00375 TCollection* contents = currentFolder->GetListOfFolders(); 00376 TIter next(contents); 00377 TObject* obj = 0; 00378 while( (obj = next()) ){ 00379 TFolder* folder = dynamic_cast<TFolder*>(obj); 00380 if(!folder) continue; // Ignore non-folders 00381 folders.push_back(folder); 00382 } 00383 return folders; 00384 }