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