]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGDQ/dielectron/AliDielectronCFdraw.cxx
Add INT1 and the TRD triggers S masks to the OADB for LHC13g
[u/mrichter/AliRoot.git] / PWGDQ / 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 <TClass.h>
38 #include <TObject.h>
39 #include <TVirtualPS.h>
40 #include <TFile.h>
41 #include <TString.h>
42 #include <TObjString.h>
43 #include <TVectorD.h>
44 #include <TMath.h>
45 #include <TH1.h>
46 #include <TH2.h>
47 #include <TH3.h>
48 #include <TPad.h>
49 #include <TCanvas.h>
50 #include <TLegend.h>
51 #include <AliCFEffGrid.h>
52
53 #include <AliLog.h>
54
55 #include "AliDielectronCFdraw.h"
56 #include "AliDielectron.h"
57
58 ClassImp(AliDielectronCFdraw)
59
60 AliDielectronCFdraw::AliDielectronCFdraw() :
61   TNamed(),
62   fCfContainer(0x0),
63   fEffGrid(0x0),
64   fVdata(0)
65 {
66   //
67   // Ctor
68   //
69 }
70
71 //________________________________________________________________
72 AliDielectronCFdraw::AliDielectronCFdraw(const char*name, const char* title) :
73   TNamed(name,title),
74   fCfContainer(0x0),
75   fEffGrid(0x0),
76   fVdata(0)
77 {
78   //
79   // Named Ctor
80   //
81   
82 }
83
84 //________________________________________________________________
85 AliDielectronCFdraw::AliDielectronCFdraw(AliCFContainer *cont) :
86   TNamed(cont->GetName(), cont->GetTitle()),
87   fCfContainer(cont),
88   fEffGrid(new AliCFEffGrid("eff","eff",*cont)),
89   fVdata(0)
90 {
91   //
92   // directly set the CF container
93   //
94
95 }
96
97 //________________________________________________________________
98 AliDielectronCFdraw::AliDielectronCFdraw(const char* filename) :
99   TNamed(),
100   fCfContainer(0x0),
101   fEffGrid(0x0),
102   fVdata(0)
103 {
104   //
105   // get CF container(s) from file 'filename'
106   //
107   SetCFContainers(filename);
108 }
109
110 //________________________________________________________________
111 AliDielectronCFdraw::~AliDielectronCFdraw()
112 {
113   //
114   // dtor
115   //
116   delete fCfContainer;
117   delete fEffGrid;
118 }
119
120 //________________________________________________________________
121 void AliDielectronCFdraw::SetCFContainers(const TSeqCollection *arr)
122 {
123   //
124   // Merge CF Container out of several containers
125   //
126
127   delete fCfContainer; fCfContainer=0x0;
128   delete fEffGrid; fEffGrid=0x0;
129   TIter next(arr);
130   TObject *o=0x0;
131
132   Int_t nstep=0;
133   while ( (o=next()) ){
134     AliCFContainer *cf=dynamic_cast<AliCFContainer*>(o);
135     if (!cf) continue;
136     nstep+=cf->GetNStep();
137   }
138   if (nstep==0) return;
139   Int_t nbins[1]={1};
140   fCfContainer=new AliCFContainer(GetName(), GetTitle(), nstep, 1, nbins);
141
142   //delete unneeded steps
143 //   for (Int_t istep=0; istep<nstep; ++istep) delete fCfContainer->GetGrid(istep);
144
145   //add step to the new container
146   Int_t istep=0;
147   for (Int_t icf=0; icf<arr->GetEntries(); ++icf){
148     AliCFContainer *cf=dynamic_cast<AliCFContainer*>(arr->At(icf));
149     if (!cf) continue;
150     for (Int_t istepCurr=0; istepCurr<cf->GetNStep(); ++istepCurr){
151       fCfContainer->SetGrid(istep, cf->GetGrid(istepCurr));
152       fCfContainer->SetStepTitle(istep,Form("%s, Pair: %s",cf->GetTitle(),cf->GetStepTitle(istepCurr)));
153       ++istep;
154     }
155   }
156   if (fEffGrid) delete fEffGrid;
157   fEffGrid=new AliCFEffGrid("eff","eff",*fCfContainer);
158 }
159
160 //________________________________________________________________
161 void AliDielectronCFdraw::SetCFContainers(const char* filename)
162 {
163   //
164   // get CF containers from file
165   //
166
167   TFile f(filename);
168   TList *l=f.GetListOfKeys();
169   TIter nextKey(l);
170   TKey *k=0x0;
171   while ( (k=static_cast<TKey*>(nextKey())) ){
172     TObject *o=k->ReadObj();
173     if (o->IsA()->InheritsFrom(TSeqCollection::Class())){
174       TSeqCollection *arr=static_cast<TSeqCollection*>(o);
175       SetCFContainers(arr);
176     } else if (o->IsA()==AliCFContainer::Class()){
177       fCfContainer=static_cast<AliCFContainer*>(o);
178       if (fEffGrid) delete fEffGrid;
179       fEffGrid=new AliCFEffGrid("eff","eff",*fCfContainer);
180     }
181   }
182 }
183
184 //________________________________________________________________
185 void AliDielectronCFdraw::SetRangeUser(Int_t ivar, Double_t min, Double_t max, const char* slices)
186 {
187   //
188   // Set range of cut steps defined in slices
189   // Steps may be separated by one the the characteres ,;:
190   //
191   if (ivar==-1) return;
192   TObjArray *arr=TString(slices).Tokenize(",:;");
193
194   if (arr->GetEntriesFast()==0){
195     // all slices in case of 0 entries
196     for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
197       fCfContainer->GetGrid(istep)->SetRangeUser(ivar,min,max);
198       fCfContainer->GetAxis(ivar,istep)->SetBit(TAxis::kAxisRange,1);
199     }
200   } else {
201     TIter next(arr);
202     TObjString *ostr=0x0;
203     while ( (ostr=static_cast<TObjString*>(next())) ) {
204       Int_t istep=ostr->GetString().Atoi();
205       fCfContainer->GetGrid(istep)->SetRangeUser(ivar,min,max);
206       fCfContainer->GetAxis(ivar,istep)->SetBit(TAxis::kAxisRange,1);
207     }
208   }
209   delete arr;
210 }
211
212 //________________________________________________________________
213 void AliDielectronCFdraw::SetRangeUser(const char* varname, Double_t min, Double_t max, const char* slices)
214 {
215   //
216   // Set range from variable name
217   //
218   Int_t ivar=fCfContainer->GetVar(varname);
219   if (ivar==-1){
220     AliFatal(Form("Variable '%s' not found",varname));
221     return;
222   }
223   SetRangeUser(ivar,min,max,slices);
224 }
225
226 //________________________________________________________________
227 void AliDielectronCFdraw::UnsetRangeUser(const char* varname, const char* slices)
228 {
229   //
230   // Unset range from variable name
231   //
232   Int_t ivar=fCfContainer->GetVar(varname);
233   if (ivar==-1){
234     AliFatal(Form("Variable '%s' not found",varname));
235     return;
236   }
237   UnsetRangeUser(ivar,slices);
238 }
239
240 //________________________________________________________________
241 void AliDielectronCFdraw::UnsetRangeUser(Int_t ivar, const char* slices)
242 {
243   //
244   // Unset range of cut steps defined in slices
245   // Steps may be separated by one the the characteres ,;:
246   //
247   if (ivar==-1) return;
248   TObjArray *arr=TString(slices).Tokenize(",:;");
249   
250   if (arr->GetEntriesFast()==0){
251     // all slices in case of 0 entries
252     for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
253       fCfContainer->GetAxis(ivar,istep)->SetRange(0,0);
254       fCfContainer->GetAxis(ivar,istep)->SetBit(TAxis::kAxisRange,0);
255     }
256   } else {
257     TIter next(arr);
258     TObjString *ostr=0x0;
259     while ( (ostr=static_cast<TObjString*>(next())) ) {
260       Int_t istep=ostr->GetString().Atoi();
261       fCfContainer->GetAxis(ivar,istep)->SetRange(0,0);
262       fCfContainer->GetAxis(ivar,istep)->SetBit(TAxis::kAxisRange,0);
263     }
264   }
265   delete arr;
266 }
267
268 //________________________________________________________________
269 void AliDielectronCFdraw::Draw(const Option_t* varnames, const char* opt, const char* slices)
270 {
271   //
272   // Draw 'variables' of 'slices'
273   // for multidimensional draw variables may be separated by a ':'
274   // slice numbers may be separated by any of ,:;
275   //
276   // variables may be called by either their name or number
277   //
278
279   TObjArray *arrVars=TString(varnames).Tokenize(":");
280   Int_t entries=arrVars->GetEntriesFast();
281   if (entries<1||entries>3){
282     AliError("Wrong number of variables, supported are 1 - 3 dimensions");
283     delete arrVars;
284     return;
285   }
286   
287   TIter next(arrVars);
288   TObjString *ostr=0x0;
289   Int_t ivar[3]={-1,-1,-1};
290   for (Int_t i=entries-1; i>=0; --i){
291     ostr=static_cast<TObjString*>(next());
292     if (ostr->GetString().IsDigit()){
293       ivar[i]=ostr->GetString().Atoi();
294     } else {
295       ivar[i]=fCfContainer->GetVar(ostr->GetName());
296     }
297   }
298
299   Draw(ivar[0],ivar[1],ivar[2],opt,slices);
300   delete arrVars;
301 }
302
303 //________________________________________________________________
304 TObjArray* AliDielectronCFdraw::CollectHistosProj(const Option_t* varnames, const char* slices)
305 {
306   //
307   // Collect histos with 'variables' of 'slices'
308   // for multidimensional histograms, variables may be separated by a ':'
309   // slice numbers may be separated by any of ,:;
310   //
311   // variables may be called by either their name or number
312   //
313   
314   TObjArray *arrVars=TString(varnames).Tokenize(":");
315   Int_t entries=arrVars->GetEntriesFast();
316   if (entries<1||entries>3){
317     AliError("Wrong number of variables, supported are 1 - 3 dimensions");
318     delete arrVars;
319     return 0x0;
320   }
321   
322   TIter next(arrVars);
323   TObjString *ostr=0x0;
324   Int_t ivar[3]={-1,-1,-1};
325   for (Int_t i=entries-1; i>=0; --i){
326     ostr=static_cast<TObjString*>(next());
327     if (ostr->GetString().IsDigit()){
328       ivar[i]=ostr->GetString().Atoi();
329     } else {
330       ivar[i]=fCfContainer->GetVar(ostr->GetName());
331     }
332   }
333   delete arrVars;
334   
335   return CollectHistosProj(ivar,slices);
336 }
337
338 //________________________________________________________________
339 void AliDielectronCFdraw::Draw(Int_t var, const char* opt, const char* slices)
340 {
341   //
342   // Draw variable var for all slices
343   // slices may be divided by and of ,;:
344   //
345   // if opt contains 'same' all histograms are drawn in the same pad
346   // otherwise the pad will be divided in sub pads and the histograms
347   // are drawn in each sub pad
348   //
349
350   Int_t vars[3]={var,-1,-1};
351   TObjArray *arr=CollectHistosProj(vars,slices);
352   Draw(arr,opt);
353   delete arr; 
354 }
355
356 //________________________________________________________________
357 void AliDielectronCFdraw::Draw(Int_t var0, Int_t var1, const char* opt, const char* slices)
358 {
359   //
360   // Draw 2D case
361   //
362   Int_t vars[3]={var0,var1,-1};
363   TObjArray *arr=CollectHistosProj(vars,slices);
364   Draw(arr,opt);
365   delete arr;
366 }
367
368 //________________________________________________________________
369 void AliDielectronCFdraw::Draw(Int_t var0, Int_t var1, Int_t var2, const char* opt, const char* slices)
370 {
371   //
372   // Draw 3D case
373   //
374   Int_t vars[3]={var0,var1,var2};
375   TObjArray *arr=CollectHistosProj(vars,slices);
376   Draw(arr,opt);
377   delete arr;
378 }
379
380 //________________________________________________________________
381 TObjArray* AliDielectronCFdraw::CollectHistosProj(const Int_t vars[3], const char* slices)
382 {
383   //
384   // Collect histos with up to 3 dimension of the 'slices' separated by one of "':;'"
385   // in a TObjArray and return it
386   // if a dimension is not used it must be set to -1
387   //
388   TObjArray *arr=TString(slices).Tokenize(",:;");
389   TObjArray *arrHists=0x0;
390   if (arr->GetEntriesFast()==0){
391     // all slices in case of 0 entries
392     arrHists=new TObjArray(fCfContainer->GetNStep());
393     for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
394       TH1 *hproj=Project(vars,istep);
395       if (!hproj) continue;
396       hproj->SetName(Form("proj_%02d",istep));
397       hproj->SetTitle(fCfContainer->GetStepTitle(istep));
398       arrHists->Add(hproj);
399     }
400   } else {
401     arrHists=new TObjArray(arr->GetEntriesFast());
402     TIter next(arr);
403     TObjString *ostr=0x0;
404     while ( (ostr=static_cast<TObjString*>(next())) ) {
405       Int_t istep=ostr->GetString().Atoi();
406       TH1 *hproj=Project(vars,istep);
407       if (!hproj) continue;
408       hproj->SetName(Form("proj_%02d",istep));
409       hproj->SetTitle(fCfContainer->GetStepTitle(istep));
410       arrHists->Add(hproj);
411     }
412   }
413   delete arr;
414
415   return arrHists;
416 }
417
418 //________________________________________________________________
419 TObjArray* AliDielectronCFdraw::CollectMinvProj(Int_t slice, ECollectType collect, TString var)
420 {
421   //
422   // Collect invariant mass spectra of step 'slice' for pair types
423   //
424   
425   TObjArray *arr = new TObjArray();
426   arr->SetOwner();
427   for (Int_t iType = 0; iType <= AliDielectron::kEv1PMRot; iType++) {
428
429     switch (iType) {
430       // same events
431       case AliDielectron::kEv1PP:
432       case AliDielectron::kEv1MM:
433         if(collect==kROT || collect==kME || collect==kMEOS) continue; break;
434         // mixed events
435       case AliDielectron::kEv1PEv2P:
436       case AliDielectron::kEv1MEv2M:
437         if(collect==kROT || collect==kSE || collect==kMEOS) continue; break;
438       case AliDielectron::kEv1MEv2P:
439       case AliDielectron::kEv1PEv2M:
440         if(collect==kROT || collect==kSE) continue; break;
441         // rotations
442       case AliDielectron::kEv1PMRot:
443         if(collect==kSE || collect==kME || collect==kMEOS) continue; break;
444         // unused
445       case AliDielectron::kEv2PP:
446       case AliDielectron::kEv2PM:
447       case AliDielectron::kEv2MM:
448         continue; break;
449     }
450     SetRangeUser("PairType",iType,iType,Form("%d",slice));
451     TH1 *hM=Project(var.Data(),slice);
452     hM->SetDirectory(0x0);
453     hM->SetNameTitle(Form("Minv_%d",iType),Form("M for type %d;M (GeV/c^{2})", iType));
454     arr->AddAt(hM,iType);
455   }
456   UnsetRangeUser("PairType",Form("%d",slice));
457   return arr;
458 }
459
460 //________________________________________________________________
461 TH1* AliDielectronCFdraw::Project(const Int_t *vars, Int_t slice)
462 {
463   //
464   // Do an ndim projection
465   //
466   return fCfContainer->Project(slice,vars[0],vars[1],vars[2]);
467 }
468
469 //________________________________________________________________
470 TH1* AliDielectronCFdraw::Project(const Option_t* var, Int_t slice)
471 {
472   //
473   // translate variable names and do projection
474   //
475   TObjArray *arrVars=TString(var).Tokenize(":");
476   Int_t entries=arrVars->GetEntriesFast();
477   if (entries<1||entries>3){
478     AliError("Wrong number of variables, supported are 1 - 3 dimensions");
479     delete arrVars;
480     return 0x0;
481   }
482
483   TIter next(arrVars);
484   TObjString *ostr=0x0;
485   Int_t ivar[3]={-1,-1,-1};
486   for (Int_t i=entries-1; i>=0; --i){
487     ostr=static_cast<TObjString*>(next());
488     if (ostr->GetString().IsDigit()){
489       ivar[i]=ostr->GetString().Atoi();
490     } else {
491       ivar[i]=fCfContainer->GetVar(ostr->GetName());
492     }
493   }
494   if (ivar[0]==-1) return 0x0;
495   delete arrVars;
496   return fCfContainer->Project(slice,ivar[0],ivar[1],ivar[2]);
497 }
498
499 //________________________________________________________________
500 void AliDielectronCFdraw::DrawEfficiency(const char* varnames, const char* numerators, Int_t denominator, const char* opt)
501 {
502   //
503   // plot efficiencies for variables. Variable may be up to 3 dim, separated by a ':'
504   // you may have several numerators, sparated by one of ',:;'
505   //
506   
507   TObjArray *arrVars=TString(varnames).Tokenize(":");
508   Int_t entries=arrVars->GetEntriesFast();
509   if (entries<1||entries>3){
510     AliError("Wrong number of variables, supported are 1 - 3 dimensions");
511     delete arrVars;
512     return;
513   }
514   
515   TIter next(arrVars);
516   TObjString *ostr=0x0;
517   Int_t ivar[3]={-1,-1,-1};
518   for (Int_t i=entries-1; i>=0; --i){
519     ostr=static_cast<TObjString*>(next());
520     if (ostr->GetString().IsDigit()){
521       ivar[i]=ostr->GetString().Atoi();
522     } else {
523       ivar[i]=fCfContainer->GetVar(ostr->GetName());
524     }
525   }
526
527   Int_t type=0;
528   TString optStr(opt);
529   if (optStr.Contains("2")) type=1;
530   
531   DrawEfficiency(ivar[0],ivar[1],ivar[2],numerators, denominator,opt,type);
532   delete arrVars;
533 }
534
535 //________________________________________________________________
536 void AliDielectronCFdraw::DrawEfficiency(Int_t var, const char* numerators, Int_t denominator, const char* opt, Int_t type)
537 {
538   //
539   // Draw Efficiencies for all numerators
540   // numerators may be divided by and of ,;:
541   //
542   // if opt contains 'same' all histograms are drawn in the same pad
543   // otherwise the pad will be divided in sub pads and the histograms
544   // are drawn in each sub pad
545   //
546   
547   Int_t vars[3]={var,-1,-1};
548   TObjArray *arr=CollectHistosEff(vars,numerators,denominator,type);
549   TString drawOpt=opt;
550   drawOpt+="eff";
551   Draw(arr,drawOpt);
552   delete arr;
553 }
554
555 //________________________________________________________________
556 void AliDielectronCFdraw::DrawEfficiency(Int_t var0, Int_t var1, const char* numerators, Int_t denominator, const char* opt, Int_t type)
557 {
558   //
559   // Draw 2D case
560   //
561   Int_t vars[3]={var0,var1,-1};
562   TObjArray *arr=CollectHistosEff(vars,numerators,denominator,type);
563   TString drawOpt=opt;
564   drawOpt+="eff";
565   Draw(arr,drawOpt);
566   delete arr;
567 }
568
569 //________________________________________________________________
570 void AliDielectronCFdraw::DrawEfficiency(Int_t var0, Int_t var1, Int_t var2, const char* numerators, Int_t denominator, const char* opt, Int_t type)
571 {
572   //
573   // Draw 3D case
574   //
575   Int_t vars[3]={var0,var1,var2};
576   TObjArray *arr=CollectHistosEff(vars,numerators,denominator,type);
577   TString drawOpt=opt;
578   drawOpt+="eff";
579   Draw(arr,drawOpt);
580   delete arr;
581 }
582
583 //________________________________________________________________
584 TObjArray* AliDielectronCFdraw::CollectHistosEff(const  Int_t vars[3], const char* numerators, Int_t denominator, Int_t type)
585 {
586   //
587   // Collect histos with 'dim'ension of the 'slices' separated by one of "':;'"
588   // in a TObjArray and return it
589   //
590   TObjArray *arr=TString(numerators).Tokenize(",:;");
591   TObjArray *arrHists=0x0;
592
593   if (type==0){
594     if (arr->GetEntriesFast()==0){
595     // all slices in case of 0 entries
596       arrHists=new TObjArray(fCfContainer->GetNStep());
597       fVdata.ResizeTo(arrHists->GetSize());
598       for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
599         fEffGrid->CalculateEfficiency(istep,denominator);
600         TH1 *hproj=ProjectEff(vars);
601         if (!hproj) continue;
602         Float_t eff=fEffGrid->GetAverage();
603         fVdata(istep)=eff;
604         hproj->SetName(Form("eff_%02d/%02d",istep,denominator));
605         hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff));
606         arrHists->Add(hproj);
607       }
608     } else {
609       arrHists=new TObjArray(arr->GetEntriesFast());
610       TIter next(arr);
611       TObjString *ostr=0x0;
612       fVdata.ResizeTo(arrHists->GetSize());
613       Int_t count=0;
614       while ( (ostr=static_cast<TObjString*>(next())) ) {
615         Int_t istep=ostr->GetString().Atoi();
616         fEffGrid->CalculateEfficiency(istep,denominator);
617         TH1 *hproj=ProjectEff(vars);
618         if (!hproj) continue;
619         Float_t eff=fEffGrid->GetAverage();
620         fVdata(count++)=eff;
621         hproj->SetName(Form("eff_%02d/%02d",istep,denominator));
622         hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff));
623         arrHists->Add(hproj);
624       }
625     }
626   }
627
628   //second approach
629   if (type==1){
630     TH1 *hDen=Project(vars,denominator);
631     Double_t entriesDen=hDen->GetEffectiveEntries();
632     if (arr->GetEntriesFast()==0){
633     // all slices in case of 0 entries
634       arrHists=new TObjArray(fCfContainer->GetNStep());
635       fVdata.ResizeTo(arrHists->GetSize());
636       for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
637         TH1 *hproj=Project(vars,istep);
638         if (!hproj) continue;
639         Float_t eff=0;
640         if (entriesDen>0) eff=hproj->GetEffectiveEntries()/entriesDen;
641         fVdata(istep)=eff;
642         hproj->Divide(hproj,hDen,1,1,"B");
643         hproj->SetName(Form("eff_%02d/%02d",istep,denominator));
644         hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff));
645         arrHists->Add(hproj);
646       }
647     } else {
648       arrHists=new TObjArray(arr->GetEntriesFast());
649       fVdata.ResizeTo(arrHists->GetSize());
650       TIter next(arr);
651       TObjString *ostr=0x0;
652       Int_t count=0;
653       while ( (ostr=static_cast<TObjString*>(next())) ) {
654         Int_t istep=ostr->GetString().Atoi();
655         TH1 *hproj=Project(vars,istep);
656         if (!hproj) continue;
657         Float_t eff=0;
658         if (entriesDen>0) eff=hproj->GetEffectiveEntries()/entriesDen;
659         fVdata(count++)=eff;
660         hproj->Divide(hproj,hDen,1,1,"B");
661         hproj->SetName(Form("eff_%02d/%02d",istep,denominator));
662         hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff));
663         arrHists->Add(hproj);
664       }
665     }
666     delete hDen;
667   }
668   
669
670   delete arr;
671   return arrHists;
672 }
673
674 //________________________________________________________________
675 TH1* AliDielectronCFdraw::ProjectEff(const Int_t vars[3])
676 {
677   //
678   // Do an nim projection
679   //
680   return fEffGrid->Project(vars[0],vars[1],vars[2]);
681 }
682
683 //________________________________________________________________
684 void AliDielectronCFdraw::Draw(const TObjArray *arr, const char* opt)
685 {
686   //
687   // draw all objects in arr
688   //
689   TString optStr(opt);
690   optStr.ToLower();
691   Bool_t drawSame     = optStr.Contains("same");
692   Bool_t drawSamePlus = optStr.Contains("same+");
693   Bool_t drawEff      = optStr.Contains("eff");
694   Bool_t optLeg       = optStr.Contains("leg");
695   Bool_t optScaleMax  = optStr.Contains("max");
696   
697   if (!drawSamePlus) optStr.ReplaceAll("same","");
698   
699   optStr.ReplaceAll("+","");
700   optStr.ReplaceAll("eff","");
701   optStr.ReplaceAll("leg","");
702   optStr.ReplaceAll("max","");
703   
704   if (!gPad) new TCanvas;
705   
706   Int_t nPads = arr->GetEntriesFast();
707   if (nPads==0) return;
708   
709 //   if (nPads==1){
710 //     arr->UncheckedAt(0)->Draw(optStr.Data());
711 //     return;
712 //   }
713   
714   TCanvas *c=gPad->GetCanvas();
715   if (!gVirtualPS&&!drawSamePlus&&!drawSame&&nPads>1) c->Clear();
716   
717   if (!drawSame&&nPads>1){
718     //optimised division
719     Int_t nCols = (Int_t)TMath::Ceil( TMath::Sqrt(nPads) );
720     Int_t nRows = (Int_t)TMath::Ceil( (Double_t)nPads/(Double_t)nCols );
721     c->Divide(nCols,nRows);
722     for (Int_t i=0; i<nPads; ++i){
723       c->cd(i+1);
724       arr->UncheckedAt(i)->Draw(optStr.Data());
725     }
726   } else {
727     TLegend *leg=0;
728     if (drawSamePlus){
729       //find already existing legend to attach entries to it
730       TIter nextPrimitive(gPad->GetListOfPrimitives());
731       TObject *o=0x0;
732       while ((o=nextPrimitive())) if (o->IsA()==TLegend::Class()) leg=(TLegend*)o;
733     }
734     
735     if (optLeg&&!leg) leg=new TLegend(.2,.3,.99,.9);
736     Int_t addColor=0;
737     if (leg) addColor=leg->GetNRows();
738     Int_t offset=20;
739     if (nPads<7) offset=24;
740     for (Int_t i=0; i<nPads; ++i){
741       if (i==1&&!drawSamePlus) optStr+="same";
742       TH1 *hist=static_cast<TH1*>(arr->UncheckedAt(i));
743       hist->SetLineColor(i+1+addColor);
744       hist->SetLineWidth(2);
745       hist->SetMarkerColor(i+1+addColor);
746       hist->SetMarkerStyle(offset+i+addColor);
747       hist->Draw(optStr.Data());
748       
749       if (drawEff&&i==0&&!drawSamePlus) {
750         hist->GetYaxis()->SetRangeUser(0,2);
751         hist->SetYTitle("Rec. Signal / Gen. Signal");
752       }
753       
754       if (leg) leg->AddEntry(hist,hist->GetTitle(),"lp");
755     }
756     if (leg){
757       leg->SetFillColor(10);
758       leg->SetY1(.9-leg->GetNRows()*.05);
759       leg->SetY1NDC(.9-leg->GetNRows()*.05);
760       leg->SetMargin(.1);
761       if (!drawSamePlus) leg->Draw();
762     }
763     if (optScaleMax){
764       TIter nextPrimitive(gPad->GetListOfPrimitives());
765       TObject *o=0x0;
766       TH1 *hfirst=0x0;
767       Float_t max=0;
768       while ((o=nextPrimitive())) if (o->InheritsFrom(TH1::Class())){
769         TH1 *h=(TH1*)o;
770         if (!hfirst) hfirst=h;
771         if (h->GetMaximum()>max) max=h->GetMaximum();
772       }
773       max*=1.1;
774       hfirst->SetMaximum(max);
775     }
776   }
777   
778 }
779
780 //________________________________________________________________
781 Double_t AliDielectronCFdraw::GetAverageEfficiency(Int_t numerator, Int_t denominator, Double_t &effErr)
782 {
783   //
784   // Extract the mean efficiency of the numerator and denominator
785   //
786
787   //use variable 0 as default, since for the average it doesn't matter
788   TH1 *hDen=fCfContainer->Project(denominator,0);
789   Double_t entriesDen=hDen->GetEffectiveEntries();
790   TH1 *hproj=fCfContainer->Project(numerator,0);
791   if (!hproj) return -1.;
792   Double_t entriesNum=hproj->GetEffectiveEntries();
793   if (entriesDen<1||entriesNum<1) return -1;
794   
795   Double_t eff=-1.;
796   if (entriesDen>0) eff=entriesNum/entriesDen;
797   effErr=TMath::Sqrt(1./entriesNum+1./entriesDen)*eff;
798   delete hDen;
799   delete hproj;
800   return eff;
801 }