]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGPP/TRD/AliTRDpwgppHelper.cxx
on Proof dont delete the output objects in the destructor
[u/mrichter/AliRoot.git] / PWGPP / TRD / AliTRDpwgppHelper.cxx
1 ////////////////////////////////////////////////////////////////////////////
2 //                                                                        //
3 //  Helper class for PWGPP TRD train                                       //
4 //                                                                        //
5 //  Authors:                                                              //
6 //    Markus Fasel <M.Fasel@gsi.de>                                       //
7 //                                                                        //
8 ////////////////////////////////////////////////////////////////////////////
9
10 #include "TError.h"
11 #include <Rtypes.h>
12 #include <TMath.h>
13 #include <TObjArray.h>
14 #include <TObjString.h>
15 #include <TFileMerger.h>
16 #include <TRandom.h>
17 #include <TString.h>
18 #include <TSystem.h>
19
20 #include <string>
21 #include <cstring>
22 #include <fstream>
23
24 #include "AliTRDpwgppHelper.h"
25
26 const Char_t * AliTRDpwgppHelper::fgkTRDtaskClassName[AliTRDpwgppHelper::kNTRDTASKS] = {
27   "AliTRDcheckESD"
28   ,"AliTRDinfoGen"
29   ,"AliTRDcheckDET"
30   ,"AliTRDefficiency"
31   ,"AliTRDresolution"
32   ,"AliTRDcheckPID"
33   ,"AliTRDv0Monitor"
34   ,"AliTRDcheckTRK"
35   ,"AliTRDcalibration"
36   ,"AliTRDefficiencyMC"
37   ,"AliTRDalignmentTask"
38   ,"AliTRDpidRefMaker"
39   ,"AliTRDclusterResolution"
40   ,"AliTRDmultiplicity"
41 };
42
43 const Char_t * AliTRDpwgppHelper::fgkTRDtaskOpt[AliTRDpwgppHelper::kNTRDTASKS+1] = {
44   "ESD"
45   ,"GEN"
46   ,"DET"
47   ,"EFF"
48   ,"RES"
49   ,"PID"
50   ,"V0"
51   ,"TRK"
52   ,"CAL"
53   ,"EFFC"
54   ,"ALGN"
55   ,"PIDR"
56   ,"CLRES"
57   ,"MULT"
58   ,"ALL"
59 };
60
61 //______________________________________________________
62 Bool_t AliTRDpwgppHelper::DoTask(Int_t idx, Int_t map)
63 {
64   return TESTBIT(map, idx);
65 }
66
67 //______________________________________________________
68 Int_t AliTRDpwgppHelper::ParseOptions(const Char_t *trd)
69 {
70 // Parse space separated options.
71 // Possible options are:
72 //      "ALL" : [default] all performance (no calibration) tasks
73 // ------- Performance tasks ----------
74 //     "ESD"  : Basic TRD Detector checks on ESD only (no TRD tracks analysed)
75 //     "DET"  : Basic TRD Detector checks
76 //     "RES"  : TRD tracking Resolution
77 //     "EFF"  : TRD Tracking Efficiency
78 //     "PID"  : TRD PID - pion efficiency
79 //     "V0"   : monitor V0 performance for use in TRD PID calibration
80 // ------- Calibration tasks ----------
81 //     "TRK"  : multidimensional tracking performance resolution
82 //     "EFFC" : TRD Tracking Efficiency Combined (barrel + stand alone) - only in case of simulations
83 //     "MULT"  : TRD single track selection
84 //     "CLRES": clusters Resolution
85 //     "CAL"  : TRD calibration
86 //     "ALGN" : TRD alignment
87 //     "PIDR" : TRD PID - reference data
88 // ------- SPECIAL OPTIONS -----------
89 //     "NOFR" : Data set does not have AliESDfriends.root
90 //     "NOMC" : Data set does not have Monte Carlo Informations (default have MC),
91
92   Int_t fSteerTask = 0;
93   TObjArray *tasksArray = TString(trd).Tokenize(" ");
94   for(Int_t isel = 0; isel < tasksArray->GetEntriesFast(); isel++){
95     TString s = (dynamic_cast<TObjString *>(tasksArray->UncheckedAt(isel)))->String();
96     if(s.CompareTo("ALL") == 0){
97       for(Int_t itask = 0; itask < kNTRDQATASKS; itask++) SETBIT(fSteerTask, itask);
98       continue;
99     } else if(s.CompareTo("NOMC") == 0 || s.CompareTo("NOFR") == 0){
100       continue; // taken care by special functions
101     } else { 
102       Bool_t foundOpt = kFALSE;  
103       for(Int_t itask = 0; itask < kNTRDTASKS; itask++){
104         if(s.CompareTo(fgkTRDtaskOpt[itask]) != 0) continue;
105         SETBIT(fSteerTask, itask); 
106         if(itask>1) SETBIT(fSteerTask, kInfoGen);
107         foundOpt = kTRUE;
108         break;
109       }
110       if(!foundOpt) Warning("AliTRDpwgppHelper::ParseOptions()", "TRD task %s not implemented (yet).", s.Data());
111     }
112   }
113   tasksArray->Delete(); delete tasksArray;
114
115   // extra rules for calibration tasks
116 //  if(TESTBIT(fSteerTask, kCheckTRK)) SETBIT(fSteerTask, kResolution);
117   if(TESTBIT(fSteerTask, kCalibration)) SETBIT(fSteerTask, kCheckDET);
118   if(TESTBIT(fSteerTask, kMultiplicity)) SETBIT(fSteerTask, kEfficiency);
119   if(TESTBIT(fSteerTask, kEfficiencyMC)) SETBIT(fSteerTask, kEfficiency);
120   if(TESTBIT(fSteerTask, kClErrParam)) SETBIT(fSteerTask, kResolution);
121   if(TESTBIT(fSteerTask, kAlignment)) SETBIT(fSteerTask, kResolution);
122   if(TESTBIT(fSteerTask, kPIDRefMaker)) SETBIT(fSteerTask, kCheckPID);
123   if(TESTBIT(fSteerTask, kV0Monitor)) SETBIT(fSteerTask, kCheckPID);
124
125   return fSteerTask;
126
127 }
128
129 //______________________________________________________
130 void AliTRDpwgppHelper::MergeProd(const Char_t *mark, const Char_t *files, const Int_t nBatch, Int_t level)
131 {
132 // Recursively merge files named "mark" from list in "files" in groups of "nBatch" files.
133 // parameter "level" is used to index recurent calls of this function.
134
135   Char_t lMERGE[8]; snprintf(lMERGE, 8, "%04d.lst", (Int_t)gRandom->Uniform(9999.));
136   Char_t lPURGE[8]; snprintf(lPURGE, 8, "%04d.lst", (Int_t)gRandom->Uniform(9999.));
137
138   // purge file list
139   std::string filename;
140   std::ifstream file(files);
141   Int_t iline(0);
142   while(getline(file, filename)){
143     if(Int_t(filename.find(mark)) < 0) continue;
144     gSystem->Exec(Form("echo %s >> %s", filename.c_str(), lPURGE));
145     iline++;
146   }
147   Int_t nBatches=Int_t(TMath::Ceil(Double_t(iline)/nBatch));
148   Info("MergeProd()", "Merge %d files in %d batches.", iline, nBatches);
149
150   Int_t first(0);
151   for(Int_t ibatch(0); ibatch<nBatches; ibatch++){
152     first = ibatch*nBatch;
153     if(gSystem->Exec(Form("aliroot -b -q \'$ALICE_ROOT/PWGPP/TRD/macros/mergeBatch.C(\"%s\", \"%s\", %d, %d)\'", mark, lPURGE, nBatch, first))) continue;
154     gSystem->Exec(Form("mv %d_%s merge/%d_%d_%s", first, mark, level, first, mark));
155     gSystem->Exec(Form("echo %s/merge/%d_%d_%s >> %s", gSystem->ExpandPathName("$PWD"), level, first, mark, lMERGE));
156   }
157
158   if(nBatches==1){
159     Info("AliTRDpwgppHelper::MergeProd()", "Rename 1 merged file.");
160     gSystem->Exec(Form("mv merge/%d_%d_%s %s", level, first, mark, mark));
161   } else if(nBatches<=nBatch){
162     Info("AliTRDpwgppHelper::MergeProd()", "Merge %d files in 1 batch.", nBatches);
163     if(!gSystem->Exec(Form("aliroot -b -q \'$ALICE_ROOT/PWGPP/TRD/macros/mergeBatch.C(\"%s\", \"%s\", %d, 0, kFALSE)\'", mark, lMERGE, nBatches))) return;
164     gSystem->Exec(Form("mv 0_%s %s", mark, mark));
165   } else {
166     level++;
167     Info("AliTRDpwgppHelper::MergeProd()", "Merge level %d.", level);
168     MergeProd(mark, lMERGE, nBatch, level);
169   }
170   gSystem->Exec(Form("rm -fv %s %s", lMERGE, lPURGE));
171 }
172
173
174 //______________________________________________________
175 Int_t AliTRDpwgppHelper::MergeBatch(const Char_t *mark, const Char_t *files, const Int_t nfiles, const Int_t first, Bool_t kSVN, Bool_t kCLEAR)
176 {
177 // Merge files specified in the file list "files" by the token "mark".
178 // The script will merge "nfiles" files starting from the "first" file.
179 // If the file "svnInfo.log" is found together with the files to be merged it is copied locally
180 // if option "kSVN". The input files are removed from disk if option "kCLEAR".
181 //
182 // On return the name of the merged file is return or NULL in case of failure.
183 //
184   TObjArray arr(nfiles); arr.SetOwner(kTRUE);
185   TFileMerger fFM(kTRUE);
186   fFM.OutputFile(Form("%s/%d_%s",  gSystem->ExpandPathName("$PWD"), first, mark));
187   Int_t iline(0), nbatch(0);
188   std::string filename;
189   std::ifstream file(files);
190   while(getline(file, filename)){
191     if(Int_t(filename.find(mark)) < 0) continue;
192     if(iline<first){
193       iline++;
194       continue;
195     }
196     if(kSVN){ // download SVN info for trending
197       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;
198     }
199     Info("AliTRDpwgppHelper::MergeBatch()", "%s", filename.c_str());
200     if(!fFM.AddFile(filename.c_str())) return NULL;
201     arr.Add(new TObjString(filename.c_str()));
202     nbatch++;
203     if(nbatch==nfiles) break;
204   }
205   if(!nbatch){
206     Warning("AliTRDpwgppHelper::MergeBatch()", "NOTHING TO MERGE"); return NULL;
207   } else {
208     Info("AliTRDpwgppHelper::MergeBatch()", "MERGING FILES[%d] START[%d] %s ... ", nbatch, first, ((nbatch<nfiles)?"INCOMPLETE":""));
209   }
210   if(!fFM.Merge()){
211     Info("AliTRDpwgppHelper::MergeBatch()", "Failed [%s]", fFM.GetOutputFileName());
212     return 1;
213   }
214   Info("AliTRDpwgppHelper::MergeBatch()", "Done [%s]", fFM.GetOutputFileName());
215
216   if(kCLEAR){
217     for(Int_t ifile(0); ifile<arr.GetEntries(); ifile++){
218       gSystem->Exec(Form("rm -fv %s", ((TObjString*)arr.At(ifile))->GetString().Data()));
219     }
220   }
221   return 0;
222 }
223
224 //______________________________________________________
225 const Char_t* AliTRDpwgppHelper::Basename(const char* filepath)
226 {
227 // Implementation of shell "basename" builtin
228   TString s(filepath);
229   Int_t idx(s.Last('/')+1);
230   s=s(idx, idx+100);
231   return s;
232 }
233
234 //______________________________________________________
235 const Char_t* AliTRDpwgppHelper::Dirname(const char* filepath)
236 {
237 // Implementation of shell "dirname" builtin
238   TString s(filepath);
239   Int_t idx(s.Last('/'));
240   s=s(0, idx);
241   return s;
242 }
243
244 //______________________________________________________
245 Int_t AliTRDpwgppHelper::GetTaskIndex(const Char_t *name)
246 {
247 //  Give index in TRD train of task class "name"
248   for(Int_t it(0); it<kNTRDTASKS; it++){
249     if(strcmp(fgkTRDtaskClassName[it], name)==0) return it;
250   }
251   return -1;
252 }
253
254 //______________________________________________________
255 Bool_t AliTRDpwgppHelper::HasReadMCData(const Char_t *opt)
256 {
257 // Use MC data option
258   return !(Bool_t)strstr(opt, "NOMC");
259 }
260
261 //____________________________________________
262 Bool_t AliTRDpwgppHelper::HasReadFriendData(const Char_t *opt)
263 {
264 // Use friends data option
265   return !(Bool_t)strstr(opt, "NOFR");
266 }
267