Add a draw class for the CORRFW (produces a warning, will be fixed
[u/mrichter/AliRoot.git] / PWG3 / dielectron / AliDielectronCFdraw.cxx
1 /*************************************************************************
2 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
7 * Permission to use, copy, modify and distribute this software and its   *
8 * documentation strictly for non-commercial purposes is hereby granted   *
9 * without fee, provided that the above copyright notice appears in all   *
10 * copies and that both the copyright notice and this permission notice   *
11 * appear in the supporting documentation. The authors make no claims     *
12 * about the suitability of this software for any purpose. It is          *
13 * provided "as is" without express or implied warranty.                  *
14 **************************************************************************/
15
16 ///////////////////////////////////////////////////////////////////////////
17 //       Dielectron Correction framework draw helper                     //
18 //                                                                       //
19 /*
20
21
22
23
24
25
26
27
28
29 */
30 //                                                                       //
31 ///////////////////////////////////////////////////////////////////////////
32
33 #include <TSeqCollection.h>
34 #include <TObjArray.h>
35 #include <TKey.h>
36 #include <TList.h>
37 #include <TObject.h>
38 #include <TFile.h>
39 #include <TString.h>
40 #include <TObjString.h>
41 #include <TMath.h>
42 #include <TH1.h>
43 #include <TH2.h>
44 #include <TH3.h>
45 #include <TPad.h>
46 #include <TCanvas.h>
47
48 #include <AliLog.h>
49
50 #include "AliDielectronCFdraw.h"
51
52 ClassImp(AliDielectronCFdraw)
53
54 AliDielectronCFdraw::AliDielectronCFdraw() :
55   TNamed(),
56   fCfContainer(0x0)
57 {
58   //
59   // Ctor
60   //
61 }
62
63 //________________________________________________________________
64 AliDielectronCFdraw::AliDielectronCFdraw(const char*name, const char* title) :
65   TNamed(name,title),
66   fCfContainer(0x0)
67 {
68   //
69   // Named Ctor
70   //
71   
72 }
73
74 //________________________________________________________________
75 void AliDielectronCFdraw::SetCFContainers(const TSeqCollection *arr)
76 {
77   //
78   // Merge CF Container out of several containers
79   //
80
81   TIter next(arr);
82   TObject *o=0x0;
83
84   Int_t nstep=0;
85   while ( (o=next()) ){
86     AliCFContainer *cf=dynamic_cast<AliCFContainer*>(o);
87     if (!o) continue;
88     nstep+=cf->GetNStep();
89   }
90   Int_t nbins[1]={1};
91   fCfContainer=new AliCFContainer(GetName(), GetTitle(), nstep, 1, nbins);
92
93   //delete unneeded steps
94   for (Int_t istep=0; istep<nstep; ++istep) delete fCfContainer->GetGrid(istep);
95
96   //add step to the new container
97   Int_t istep=0;
98   for (Int_t icf=0; icf<arr->GetEntries(); ++icf){
99     AliCFContainer *cf=dynamic_cast<AliCFContainer*>(arr->At(icf));
100     if (!cf) continue;
101     for (Int_t istepCurr=0; istepCurr<cf->GetNStep(); ++istepCurr){
102       fCfContainer->SetGrid(istep, cf->GetGrid(istepCurr));
103       fCfContainer->SetStepTitle(istep,Form("%s: %s",cf->GetName(),cf->GetStepTitle(istepCurr)));
104       ++istep;
105     }
106   }
107 }
108
109 //________________________________________________________________
110 void AliDielectronCFdraw::SetCFContainers(const char* filename)
111 {
112   //
113   // get CF containers from file
114   //
115
116   TFile f(filename);
117   TList *l=f.GetListOfKeys();
118   Int_t entries=l->GetEntries();
119   if (entries==0) return;
120   
121   TKey *k=(TKey*)l->At(0);
122   TSeqCollection *arr=dynamic_cast<TSeqCollection*>(k->ReadObj());
123   if (!arr) return;
124   
125   SetCFContainers(arr);
126 }
127
128 //________________________________________________________________
129 void AliDielectronCFdraw::SetRangeUser(Int_t ivar, Double_t min, Double_t max, const char* slices)
130 {
131   //
132   // Set range of cut steps defined in slices
133   // Steps may be separated by one the the characteres ,;:
134   //
135   TObjArray *arr=TString(slices).Tokenize(",:;");
136
137   if (arr->GetEntriesFast()==0){
138     // all slices in case of 0 entries
139     for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
140       fCfContainer->SetRangeUser(ivar,min,max,istep);
141     }
142   } else {
143     TIter next(arr);
144     TObjString *ostr=0x0;
145     while ( (ostr=static_cast<TObjString*>(next())) ) {
146       Int_t istep=ostr->GetString().Atoi();
147       fCfContainer->SetRangeUser(ivar,min,max,istep);
148     }
149   }
150   delete arr;
151 }
152
153 //________________________________________________________________
154 void AliDielectronCFdraw::UnsetRangeUser(Int_t ivar, const char* slices)
155 {
156   //
157   // Unset range of cut steps defined in slices
158   // Steps may be separated by one the the characteres ,;:
159   //
160   TObjArray *arr=TString(slices).Tokenize(",:;");
161   
162   if (arr->GetEntriesFast()==0){
163     // all slices in case of 0 entries
164     for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
165       fCfContainer->SetRangeUser(ivar,fCfContainer->GetAxis(ivar,istep)->GetXmin(),
166                                  fCfContainer->GetAxis(ivar,istep)->GetXmax(),istep);
167     }
168   } else {
169     TIter next(arr);
170     TObjString *ostr=0x0;
171     while ( (ostr=static_cast<TObjString*>(next())) ) {
172       Int_t istep=ostr->GetString().Atoi();
173       fCfContainer->SetRangeUser(ivar,fCfContainer->GetAxis(ivar,istep)->GetXmin(),
174                                  fCfContainer->GetAxis(ivar,istep)->GetXmax(),istep);
175     }
176   }
177   delete arr;
178 }
179
180 //________________________________________________________________
181 void AliDielectronCFdraw::Draw(const Option_t* varnames, const char* slices, const char* opt)
182 {
183   //
184   // Draw 'variables' of 'slices'
185   // for multidimensional draw variables may be separated by a ':'
186   // slice numbers may be separated by any of ,:;
187   //
188   // variables may be called by either their name or number
189   //
190
191   TObjArray *arrVars=TString(varnames).Tokenize(":");
192   Int_t entries=arrVars->GetEntriesFast();
193   if (entries<1||entries>3){
194     AliError("Wrong number of variables, supported are 1 - 3 dimensions");
195     delete arrVars;
196     return;
197   }
198   
199   TIter next(arrVars);
200   TObjString *ostr=0x0;
201   Int_t ivar[3]={-1,-1,-1};
202   for (Int_t i=0; i<entries; ++i){
203     ostr=static_cast<TObjString*>(next());
204     if (ostr->GetString().IsDigit()){
205       ivar[i]=ostr->GetString().Atoi();
206     } else {
207       ivar[i]=fCfContainer->GetVar(ostr->GetName());
208     }
209   }
210
211   switch (entries){
212   case 1:
213     Draw(ivar[0],slices,opt);
214     break;
215   case 2:
216     Draw(ivar[0],ivar[1],slices,opt);
217     break;
218   case 3:
219     Draw(ivar[0],ivar[1],ivar[2],slices,opt);
220     break;
221   }
222   delete arrVars;
223 }
224
225 //________________________________________________________________
226 void AliDielectronCFdraw::Draw(Int_t var, const char* opt, const char* slices)
227 {
228   //
229   // Draw variable var for all slices
230   // slices may be divided by and of ,;:
231   //
232   // if opt contains 'same' all histograms are drawn in the same pad
233   // otherwise the pad will be divided in sub pads and the histograms
234   // are drawn in each sub pad
235   //
236
237   const Int_t ndim=1;
238   Int_t vars[ndim]={var};
239   TObjArray *arr=CollectHistos(ndim,vars,slices);
240   Draw(arr,opt);
241   delete arr; 
242 }
243
244 //________________________________________________________________
245 void AliDielectronCFdraw::Draw(Int_t var0, Int_t var1, const char* opt, const char* slices)
246 {
247   //
248   // Draw 2D case
249   //
250   const Int_t ndim=2;
251   Int_t vars[ndim]={var0,var1};
252   TObjArray *arr=CollectHistos(ndim,vars,slices);
253   Draw(arr,opt);
254   delete arr;
255 }
256
257 //________________________________________________________________
258 void AliDielectronCFdraw::Draw(Int_t var0, Int_t var1, Int_t var2, const char* opt, const char* slices)
259 {
260   //
261   // Draw 3D case
262   //
263   const Int_t ndim=3;
264   Int_t vars[ndim]={var0,var1,var2};
265   TObjArray *arr=CollectHistos(ndim,vars,slices);
266   Draw(arr,opt);
267   delete arr;
268 }
269
270 //________________________________________________________________
271 void AliDielectronCFdraw::Draw(const TObjArray *arr, const char* opt)
272 {
273   //
274   // draw all objects in arr
275   //
276   TString optStr(opt);
277   optStr.ToLower();
278   Bool_t drawSame=optStr.Contains("same");
279   optStr.ReplaceAll("same","");
280   if (!gPad) new TCanvas;
281   TCanvas *c=gPad->GetCanvas();
282   c->Clear();
283   if (!drawSame){
284     //optimised division
285     Int_t nPads = arr->GetEntries();
286     Int_t nCols = (Int_t)TMath::Ceil( TMath::Sqrt(nPads) );
287     Int_t nRows = (Int_t)TMath::Ceil( (Double_t)nPads/(Double_t)nCols );
288     c->Divide(nCols,nRows);
289     for (Int_t i=0; i<nPads; ++i){
290       c->cd(i+1);
291       arr->UncheckedAt(i)->Draw(optStr.Data());
292     }
293   }
294 }
295
296 //________________________________________________________________
297 TObjArray* AliDielectronCFdraw::CollectHistos(Int_t dim, Int_t *vars, const char* slices)
298 {
299   //
300   // Collect histos with 'dim'ension of the 'slices' separated by one of "':;'"
301   // in a TObjArray and return it
302   //
303   TObjArray *arr=TString(slices).Tokenize(",:;");
304   TObjArray *arrHists=0x0;
305   if (arr->GetEntriesFast()==0){
306     // all slices in case of 0 entries
307     arrHists=new TObjArray(fCfContainer->GetNStep());
308     for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
309       arrHists->Add(Project(dim,vars,istep));
310     }
311   } else {
312     arrHists=new TObjArray(arr->GetEntriesFast());
313     TIter next(arr);
314     TObjString *ostr=0x0;
315     while ( (ostr=static_cast<TObjString*>(next())) ) {
316       Int_t istep=ostr->GetString().Atoi();
317       arrHists->Add(Project(dim,vars,istep));
318     }
319   }
320   delete arr;
321
322   return arrHists;
323 }
324
325 //________________________________________________________________
326 TH1* AliDielectronCFdraw::Project(Int_t ndim, Int_t *vars, Int_t slice)
327 {
328   //
329   // Do an nim projection
330   //
331   switch (ndim){
332   case 1:
333     return fCfContainer->Project(vars[0],slice);
334     break;
335   case 2:
336     return fCfContainer->Project(vars[0],vars[1],slice);
337     break;
338   case 3:
339     return fCfContainer->Project(vars[0],vars[1],vars[2],slice);
340     break;
341   }
342   return 0x0;
343 }
344