+
+ if(nBatches==1){
+ Info("AliTRDpwg1Helper::MergeProd()", "Rename 1 merged file.");
+ gSystem->Exec(Form("mv merge/%d_%d_%s %s", level, first, mark, mark));
+ } else if(nBatches<=nBatch){
+ Info("AliTRDpwg1Helper::MergeProd()", Form("Merge %d files in 1 batch.", nBatches));
+ if(!gSystem->Exec(Form("aliroot -b -q \'$ALICE_ROOT/PWG1/TRD/macros/mergeBatch.C(\"%s\", \"%s\", %d, 0, kFALSE)\'", mark, lMERGE, nBatches))) return;
+ gSystem->Exec(Form("mv 0_%s %s", mark, mark));
+ } else {
+ level++;
+ Info("AliTRDpwg1Helper::MergeProd()", Form("Merge level %d.", level));
+ MergeProd(mark, lMERGE, nBatch, level);
+ }
+ gSystem->Exec(Form("rm -fv %s %s", lMERGE, lPURGE));
+}
+
+
+//______________________________________________________
+const Char_t* AliTRDpwg1Helper::MergeBatch(const Char_t *mark, const Char_t *files, const Int_t nfiles, const Int_t first, Bool_t kSVN, Bool_t kCLEAR)
+{
+// Merge files specified in the file list "files" by the token "mark".
+// The script will merge "nfiles" files starting from the "first" file.
+// If the file "svnInfo.log" is found together with the files to be merged it is copied locally
+// if option "kSVN". The input files are removed from disk if option "kCLEAR".
+//
+// On return the name of the merged file is return or NULL in case of failure.
+//
+ TObjArray arr(nfiles); arr.SetOwner(kTRUE);
+ TFileMerger fFM(kTRUE);
+ fFM.OutputFile(Form("%s/%d_%s", gSystem->ExpandPathName("$PWD"), first, mark));
+ Int_t iline(0), nbatch(0);
+ std::string filename;
+ std::ifstream file(files);
+ while(getline(file, filename)){
+ if(Int_t(filename.find(mark)) < 0) continue;
+ if(iline<first){
+ iline++;
+ continue;
+ }
+ if(kSVN){ // download SVN info for trending
+ if(gSystem->Exec(Form("if [ ! -f svnInfo.log ]; then cp -v %s/svnInfo.log %s; fi", Dirname(filename.c_str()), gSystem->ExpandPathName("$PWD"))) == 0) kSVN=kFALSE;
+ }
+ Info("AliTRDpwg1Helper::MergeBatch()", filename.c_str());
+ if(!fFM.AddFile(filename.c_str())) return NULL;
+ arr.Add(new TObjString(filename.c_str()));
+ nbatch++;
+ if(nbatch==nfiles) break;
+ }
+ if(!nbatch){
+ Warning("AliTRDpwg1Helper::MergeBatch()", "NOTHING TO MERGE"); return NULL;
+ } else {
+ Info("AliTRDpwg1Helper::MergeBatch()", "MERGING FILES[%d] START[%d] %s ... ", nbatch, first, ((nbatch<nfiles)?"INCOMPLETE":""));
+ }
+ if(!fFM.Merge()) return NULL;
+
+ if(kCLEAR){
+ for(Int_t ifile(0); ifile<arr.GetEntries(); ifile++){
+ gSystem->Exec(Form("rm -fv %s", ((TObjString*)arr.At(ifile))->GetString().Data()));
+ }
+ }
+ return fFM.GetOutputFileName();
+}
+
+//______________________________________________________
+const Char_t* AliTRDpwg1Helper::Basename(const char* filepath)
+{
+// Implementation of shell "basename" builtin
+ TString s(filepath);
+ Int_t idx(s.Last('/')+1);
+ s=s(idx, idx+100);
+ return s;
+}
+
+//______________________________________________________
+const Char_t* AliTRDpwg1Helper::Dirname(const char* filepath)
+{
+// Implementation of shell "dirname" builtin
+ TString s(filepath);
+ Int_t idx(s.Last('/'));
+ s=s(0, idx);
+ return s;