//Author: C. Delaere //Original version: 31/05/2007 #include "TObject.h" #include "TKey.h" #include "TFile.h" #include "TString.h" #include "TH1.h" #include "TProfile.h" #include "TObjArray.h" #include "TObjString.h" #include "TDirectory.h" #include class mergeInfo { public: mergeInfo(TString basename, unsigned int n); virtual ~mergeInfo() { } virtual void merge(); private: virtual void scanDirectory(); virtual void copyProfile(TString path, TProfile* profile); virtual void createPath(TString path); TFile* input_; TFile* output_; TString basename_; unsigned int nInput_; }; mergeInfo::mergeInfo(TString basename, unsigned int n):basename_(basename),nInput_(n) { output_ = new TFile(basename+"_merged.root","RECREATE"); } void mergeInfo::merge() { if(!output_) return; TString num; for(unsigned int i=0; icd(); input_->cd("DQMData"); std::cout << "Merging data from file " << input_->GetName() << std::endl; scanDirectory(); input_->Close(); delete input_; } std::cout << "Saving..." << std::endl; output_->Write(output_->GetName(),TObject::kWriteDelete); output_->Close(); delete output_; output_ = NULL; } void mergeInfo::scanDirectory() { TIter next(gDirectory->GetListOfKeys()); TString filename = input_->GetName(); int offset = filename.Sizeof()+15; while (TKey *obj = (TKey*)next()) { TObject* o = obj->ReadObj(); // if it's a directory, enter if (strcmp(o->IsA()->GetName(),"TDirectory")==0) { gDirectory->cd(o->GetName()); scanDirectory(); gDirectory->cd(".."); } // if it's a TProfile, handle it if( strcmp(o->IsA()->GetName(),"TProfile")==0) { TProfile* p = (TProfile*) o; TString path = gDirectory->GetPath()+offset; copyProfile(path, p); } // else, ignore delete o; } } void mergeInfo::copyProfile(TString path, TProfile* profile) { TDirectory* sourceDir = gDirectory; // first check that the directory exist. If not, create it. if(!output_->GetDirectory(path)) createPath(path); output_->cd(path); // then look if there is a TProfile there. TProfile* p = (TProfile*)gDirectory->Get(profile->GetName()); if(p) { // then add the profile to the existing one p->Add(profile); } else { // then copy the profile here gDirectory->WriteTObject(profile); } sourceDir->cd(); } void mergeInfo::createPath(TString path) { TDirectory* startDir = gDirectory; // first split the path TObjArray* tokens = path.Tokenize("/"); output_->cd(); // start at the first level, and create if needed for(int i=0;iGetEntriesFast();++i) { TString subpath = ((TObjString*)tokens->At(i))->GetString(); if(!gDirectory->GetDirectory(subpath)) { gDirectory->mkdir(subpath); } gDirectory->cd(subpath); } delete tokens; startDir->cd(); }