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
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
00097
00098
00099 folder->Add(fol);
00100 }
00101 else {
00102
00103
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
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
00139
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
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
00163
00164
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
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())) {
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
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
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
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
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;
00365 objects.push_back(obj);
00366 }
00367 return objects;
00368 }
00369
00370 vector<TFolder*> HistMan::GetSubFolders(const char* pathname){
00371
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;
00381 folders.push_back(folder);
00382 }
00383 return folders;
00384 }