]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWG3/dielectron/AliDielectronCFdraw.cxx
deleting this class
[u/mrichter/AliRoot.git] / PWG3 / dielectron / AliDielectronCFdraw.cxx
index 5224839ad3bac9b6a84b9d96234c4d9cb0890698..28f458148551659fc331e7206bdf6489d2fc5234 100644 (file)
@@ -13,6 +13,8 @@
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/
 
+/* $Id$ */
+
 ///////////////////////////////////////////////////////////////////////////
 //       Dielectron Correction framework draw helper                     //
 //                                                                       //
 #include <TList.h>
 #include <TClass.h>
 #include <TObject.h>
+#include <TVirtualPS.h>
 #include <TFile.h>
 #include <TString.h>
 #include <TObjString.h>
+#include <TVectorD.h>
 #include <TMath.h>
 #include <TH1.h>
 #include <TH2.h>
@@ -57,7 +61,8 @@ ClassImp(AliDielectronCFdraw)
 AliDielectronCFdraw::AliDielectronCFdraw() :
   TNamed(),
   fCfContainer(0x0),
-  fEffGrid(0x0)
+  fEffGrid(0x0),
+  fVdata(0)
 {
   //
   // Ctor
@@ -68,7 +73,8 @@ AliDielectronCFdraw::AliDielectronCFdraw() :
 AliDielectronCFdraw::AliDielectronCFdraw(const char*name, const char* title) :
   TNamed(name,title),
   fCfContainer(0x0),
-  fEffGrid(0x0)
+  fEffGrid(0x0),
+  fVdata(0)
 {
   //
   // Named Ctor
@@ -80,7 +86,8 @@ AliDielectronCFdraw::AliDielectronCFdraw(const char*name, const char* title) :
 AliDielectronCFdraw::AliDielectronCFdraw(AliCFContainer *cont) :
   TNamed(cont->GetName(), cont->GetTitle()),
   fCfContainer(cont),
-  fEffGrid(new AliCFEffGrid("eff","eff",*cont))
+  fEffGrid(new AliCFEffGrid("eff","eff",*cont)),
+  fVdata(0)
 {
   //
   // directly set the CF container
@@ -92,7 +99,8 @@ AliDielectronCFdraw::AliDielectronCFdraw(AliCFContainer *cont) :
 AliDielectronCFdraw::AliDielectronCFdraw(const char* filename) :
   TNamed(),
   fCfContainer(0x0),
-  fEffGrid(0x0)
+  fEffGrid(0x0),
+  fVdata(0)
 {
   //
   // get CF container(s) from file 'filename'
@@ -113,14 +121,15 @@ void AliDielectronCFdraw::SetCFContainers(const TSeqCollection *arr)
   Int_t nstep=0;
   while ( (o=next()) ){
     AliCFContainer *cf=dynamic_cast<AliCFContainer*>(o);
-    if (!o) continue;
+    if (!cf) continue;
     nstep+=cf->GetNStep();
   }
+  if (nstep==0) return;
   Int_t nbins[1]={1};
   fCfContainer=new AliCFContainer(GetName(), GetTitle(), nstep, 1, nbins);
 
   //delete unneeded steps
-  for (Int_t istep=0; istep<nstep; ++istep) delete fCfContainer->GetGrid(istep);
+//   for (Int_t istep=0; istep<nstep; ++istep) delete fCfContainer->GetGrid(istep);
 
   //add step to the new container
   Int_t istep=0;
@@ -129,7 +138,7 @@ void AliDielectronCFdraw::SetCFContainers(const TSeqCollection *arr)
     if (!cf) continue;
     for (Int_t istepCurr=0; istepCurr<cf->GetNStep(); ++istepCurr){
       fCfContainer->SetGrid(istep, cf->GetGrid(istepCurr));
-      fCfContainer->SetStepTitle(istep,Form("%s: %s",cf->GetName(),cf->GetStepTitle(istepCurr)));
+      fCfContainer->SetStepTitle(istep,Form("%s, Pair: %s",cf->GetTitle(),cf->GetStepTitle(istepCurr)));
       ++istep;
     }
   }
@@ -146,19 +155,18 @@ void AliDielectronCFdraw::SetCFContainers(const char* filename)
 
   TFile f(filename);
   TList *l=f.GetListOfKeys();
-  Int_t entries=l->GetEntries();
-  if (entries==0) return;
-  
-  TKey *k=(TKey*)l->At(0);
-  if (!k) return;
-  TObject *o=k->ReadObj();
-  if (o->IsA()->InheritsFrom(TSeqCollection::Class())){
-    TSeqCollection *arr=static_cast<TSeqCollection*>(o);
-    SetCFContainers(arr);
-  } else if (o->IsA()==AliCFContainer::Class()){
-    fCfContainer=static_cast<AliCFContainer*>(o);
-    if (fEffGrid) delete fEffGrid;
-    fEffGrid=new AliCFEffGrid("eff","eff",*fCfContainer);
+  TIter nextKey(l);
+  TKey *k=0x0;
+  while ( (k=static_cast<TKey*>(nextKey())) ){
+    TObject *o=k->ReadObj();
+    if (o->IsA()->InheritsFrom(TSeqCollection::Class())){
+      TSeqCollection *arr=static_cast<TSeqCollection*>(o);
+      SetCFContainers(arr);
+    } else if (o->IsA()==AliCFContainer::Class()){
+      fCfContainer=static_cast<AliCFContainer*>(o);
+      if (fEffGrid) delete fEffGrid;
+      fEffGrid=new AliCFEffGrid("eff","eff",*fCfContainer);
+    }
   }
 }
 
@@ -174,14 +182,14 @@ void AliDielectronCFdraw::SetRangeUser(Int_t ivar, Double_t min, Double_t max, c
   if (arr->GetEntriesFast()==0){
     // all slices in case of 0 entries
     for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
-      fCfContainer->SetRangeUser(ivar,min,max,istep);
+      fCfContainer->GetGrid(istep)->SetRangeUser(ivar,min,max);
     }
   } else {
     TIter next(arr);
     TObjString *ostr=0x0;
     while ( (ostr=static_cast<TObjString*>(next())) ) {
       Int_t istep=ostr->GetString().Atoi();
-      fCfContainer->SetRangeUser(ivar,min,max,istep);
+      fCfContainer->GetGrid(istep)->SetRangeUser(ivar,min,max);
     }
   }
   delete arr;
@@ -199,23 +207,21 @@ void AliDielectronCFdraw::UnsetRangeUser(Int_t ivar, const char* slices)
   if (arr->GetEntriesFast()==0){
     // all slices in case of 0 entries
     for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
-      fCfContainer->SetRangeUser(ivar,fCfContainer->GetAxis(ivar,istep)->GetXmin(),
-                                 fCfContainer->GetAxis(ivar,istep)->GetXmax(),istep);
+      fCfContainer->GetAxis(ivar,istep)->SetRange(0,0);
     }
   } else {
     TIter next(arr);
     TObjString *ostr=0x0;
     while ( (ostr=static_cast<TObjString*>(next())) ) {
       Int_t istep=ostr->GetString().Atoi();
-      fCfContainer->SetRangeUser(ivar,fCfContainer->GetAxis(ivar,istep)->GetXmin(),
-                                 fCfContainer->GetAxis(ivar,istep)->GetXmax(),istep);
+      fCfContainer->GetAxis(ivar,istep)->SetRange(0,0);
     }
   }
   delete arr;
 }
 
 //________________________________________________________________
-void AliDielectronCFdraw::Draw(const Option_t* varnames, const char* slices, const char* opt)
+void AliDielectronCFdraw::Draw(const Option_t* varnames, const char* opt, const char* slices)
 {
   //
   // Draw 'variables' of 'slices'
@@ -236,7 +242,7 @@ void AliDielectronCFdraw::Draw(const Option_t* varnames, const char* slices, con
   TIter next(arrVars);
   TObjString *ostr=0x0;
   Int_t ivar[3]={-1,-1,-1};
-  for (Int_t i=0; i<entries; ++i){
+  for (Int_t i=entries-1; i>=0; --i){
     ostr=static_cast<TObjString*>(next());
     if (ostr->GetString().IsDigit()){
       ivar[i]=ostr->GetString().Atoi();
@@ -245,17 +251,7 @@ void AliDielectronCFdraw::Draw(const Option_t* varnames, const char* slices, con
     }
   }
 
-  switch (entries){
-  case 1:
-    Draw(ivar[0],slices,opt);
-    break;
-  case 2:
-    Draw(ivar[1],ivar[0],slices,opt);
-    break;
-  case 3:
-    Draw(ivar[2],ivar[1],ivar[0],slices,opt);
-    break;
-  }
+  Draw(ivar[0],ivar[1],ivar[2],opt,slices);
   delete arrVars;
 }
 
@@ -271,9 +267,8 @@ void AliDielectronCFdraw::Draw(Int_t var, const char* opt, const char* slices)
   // are drawn in each sub pad
   //
 
-  const Int_t ndim=1;
-  Int_t vars[ndim]={var};
-  TObjArray *arr=CollectHistosProj(ndim,vars,slices);
+  Int_t vars[3]={var,-1,-1};
+  TObjArray *arr=CollectHistosProj(vars,slices);
   Draw(arr,opt);
   delete arr; 
 }
@@ -284,9 +279,8 @@ void AliDielectronCFdraw::Draw(Int_t var0, Int_t var1, const char* opt, const ch
   //
   // Draw 2D case
   //
-  const Int_t ndim=2;
-  Int_t vars[ndim]={var0,var1};
-  TObjArray *arr=CollectHistosProj(ndim,vars,slices);
+  Int_t vars[3]={var0,var1,-1};
+  TObjArray *arr=CollectHistosProj(vars,slices);
   Draw(arr,opt);
   delete arr;
 }
@@ -297,19 +291,19 @@ void AliDielectronCFdraw::Draw(Int_t var0, Int_t var1, Int_t var2, const char* o
   //
   // Draw 3D case
   //
-  const Int_t ndim=3;
-  Int_t vars[ndim]={var0,var1,var2};
-  TObjArray *arr=CollectHistosProj(ndim,vars,slices);
+  Int_t vars[3]={var0,var1,var2};
+  TObjArray *arr=CollectHistosProj(vars,slices);
   Draw(arr,opt);
   delete arr;
 }
 
 //________________________________________________________________
-TObjArray* AliDielectronCFdraw::CollectHistosProj(Int_t dim, Int_t *vars, const char* slices)
+TObjArray* AliDielectronCFdraw::CollectHistosProj(const Int_t vars[3], const char* slices)
 {
   //
-  // Collect histos with 'dim'ension of the 'slices' separated by one of "':;'"
+  // Collect histos with up to 3 dimension of the 'slices' separated by one of "':;'"
   // in a TObjArray and return it
+  // if a dimension is not used it must be set to -1
   //
   TObjArray *arr=TString(slices).Tokenize(",:;");
   TObjArray *arrHists=0x0;
@@ -317,8 +311,10 @@ TObjArray* AliDielectronCFdraw::CollectHistosProj(Int_t dim, Int_t *vars, const
     // all slices in case of 0 entries
     arrHists=new TObjArray(fCfContainer->GetNStep());
     for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
-      TH1 *hproj=Project(dim,vars,istep);
-      hproj->SetName(fCfContainer->GetStepTitle(istep));
+      TH1 *hproj=Project(vars,istep);
+      if (!hproj) continue;
+      hproj->SetName(Form("proj_%02d",istep));
+      hproj->SetTitle(fCfContainer->GetStepTitle(istep));
       arrHists->Add(hproj);
     }
   } else {
@@ -327,8 +323,10 @@ TObjArray* AliDielectronCFdraw::CollectHistosProj(Int_t dim, Int_t *vars, const
     TObjString *ostr=0x0;
     while ( (ostr=static_cast<TObjString*>(next())) ) {
       Int_t istep=ostr->GetString().Atoi();
-      TH1 *hproj=Project(dim,vars,istep);
-      hproj->SetName(fCfContainer->GetStepTitle(istep));
+      TH1 *hproj=Project(vars,istep);
+      if (!hproj) continue;
+      hproj->SetName(Form("proj_%02d",istep));
+      hproj->SetTitle(fCfContainer->GetStepTitle(istep));
       arrHists->Add(hproj);
     }
   }
@@ -338,31 +336,49 @@ TObjArray* AliDielectronCFdraw::CollectHistosProj(Int_t dim, Int_t *vars, const
 }
 
 //________________________________________________________________
-TH1* AliDielectronCFdraw::Project(Int_t ndim, Int_t *vars, Int_t slice)
+TH1* AliDielectronCFdraw::Project(const Int_t *vars, Int_t slice)
 {
   //
-  // Do an nim projection
+  // Do an ndim projection
+  //
+  return fCfContainer->Project(slice,vars[0],vars[1],vars[2]);
+}
+
+//________________________________________________________________
+TH1* AliDielectronCFdraw::Project(const Option_t* var, Int_t slice)
+{
+  //
+  // translate variable names and do projection
   //
-  switch (ndim){
-  case 1:
-    return fCfContainer->Project(vars[0],slice);
-    break;
-  case 2:
-    return fCfContainer->Project(vars[0],vars[1],slice);
-    break;
-  case 3:
-    return fCfContainer->Project(vars[0],vars[1],vars[2],slice);
-    break;
+  TObjArray *arrVars=TString(var).Tokenize(":");
+  Int_t entries=arrVars->GetEntriesFast();
+  if (entries<1||entries>3){
+    AliError("Wrong number of variables, supported are 1 - 3 dimensions");
+    delete arrVars;
+    return 0x0;
   }
-  return 0x0;
+  
+  TObjString *ostr=0x0;
+  Int_t ivar[3]={-1,-1,-1};
+  for (Int_t i=entries-1; i>=0; --i){
+    ostr=static_cast<TObjString*>(arrVars->At(i));
+    if (ostr->GetString().IsDigit()){
+      ivar[i]=ostr->GetString().Atoi();
+    } else {
+      ivar[i]=fCfContainer->GetVar(ostr->GetName());
+    }
+  }
+  if (ivar[0]==-1) return 0x0;
+  delete arrVars;
+  return fCfContainer->Project(slice,ivar[0],ivar[1],ivar[2]);
 }
 
 //________________________________________________________________
-void AliDielectronCFdraw::DrawEfficiency(const char* varnames, const char* nominators, Int_t denominator, const char* opt)
+void AliDielectronCFdraw::DrawEfficiency(const char* varnames, const char* numerators, Int_t denominator, const char* opt)
 {
   //
   // plot efficiencies for variables. Variable may be up to 3 dim, separated by a ':'
-  // you may have several nominators, sparated by one of ',:;'
+  // you may have several numerators, sparated by one of ',:;'
   //
   
   TObjArray *arrVars=TString(varnames).Tokenize(":");
@@ -384,121 +400,161 @@ void AliDielectronCFdraw::DrawEfficiency(const char* varnames, const char* nomin
       ivar[i]=fCfContainer->GetVar(ostr->GetName());
     }
   }
+
+  Int_t type=0;
+  TString optStr(opt);
+  if (optStr.Contains("2")) type=1;
   
-  switch (entries){
-  case 1:
-    DrawEfficiency(ivar[0],nominators, denominator,opt);
-    break;
-  case 2:
-    DrawEfficiency(ivar[1],ivar[0], nominators, denominator,opt);
-    break;
-  case 3:
-    DrawEfficiency(ivar[2],ivar[1],ivar[0],nominators, denominator,opt);
-    break;
-  }
+  DrawEfficiency(ivar[2],ivar[1],ivar[0],numerators, denominator,opt,type);
   delete arrVars;
 }
 
 //________________________________________________________________
-void AliDielectronCFdraw::DrawEfficiency(Int_t var, const char* nominators, Int_t denominator, const char* opt)
+void AliDielectronCFdraw::DrawEfficiency(Int_t var, const char* numerators, Int_t denominator, const char* opt, Int_t type)
 {
   //
-  // Draw Efficiencies for all nominators
-  // nominators may be divided by and of ,;:
+  // Draw Efficiencies for all numerators
+  // numerators may be divided by and of ,;:
   //
   // if opt contains 'same' all histograms are drawn in the same pad
   // otherwise the pad will be divided in sub pads and the histograms
   // are drawn in each sub pad
   //
   
-  const Int_t ndim=1;
-  Int_t vars[ndim]={var};
-  TObjArray *arr=CollectHistosEff(ndim,vars,nominators,denominator);
-  Draw(arr,opt);
+  Int_t vars[3]={var,-1,-1};
+  TObjArray *arr=CollectHistosEff(vars,numerators,denominator,type);
+  TString drawOpt=opt;
+  drawOpt+="eff";
+  Draw(arr,drawOpt);
   delete arr;
 }
 
 //________________________________________________________________
-void AliDielectronCFdraw::DrawEfficiency(Int_t var0, Int_t var1, const char* nominators, Int_t denominator, const char* opt)
+void AliDielectronCFdraw::DrawEfficiency(Int_t var0, Int_t var1, const char* numerators, Int_t denominator, const char* opt, Int_t type)
 {
   //
   // Draw 2D case
   //
-  const Int_t ndim=2;
-  Int_t vars[ndim]={var0,var1};
-  TObjArray *arr=CollectHistosEff(ndim,vars,nominators,denominator);
-  Draw(arr,opt);
+  Int_t vars[3]={var0,var1,-1};
+  TObjArray *arr=CollectHistosEff(vars,numerators,denominator,type);
+  TString drawOpt=opt;
+  drawOpt+="eff";
+  Draw(arr,drawOpt);
   delete arr;
 }
 
 //________________________________________________________________
-void AliDielectronCFdraw::DrawEfficiency(Int_t var0, Int_t var1, Int_t var2, const char* nominators, Int_t denominator, const char* opt)
+void AliDielectronCFdraw::DrawEfficiency(Int_t var0, Int_t var1, Int_t var2, const char* numerators, Int_t denominator, const char* opt, Int_t type)
 {
   //
   // Draw 3D case
   //
-  const Int_t ndim=3;
-  Int_t vars[ndim]={var0,var1,var2};
-  TObjArray *arr=CollectHistosEff(ndim,vars,nominators,denominator);
-  Draw(arr,opt);
+  Int_t vars[3]={var0,var1,var2};
+  TObjArray *arr=CollectHistosEff(vars,numerators,denominator,type);
+  TString drawOpt=opt;
+  drawOpt+="eff";
+  Draw(arr,drawOpt);
   delete arr;
 }
 
 //________________________________________________________________
-TObjArray* AliDielectronCFdraw::CollectHistosEff(Int_t dim, Int_t *vars, const char* nominators, Int_t denominator)
+TObjArray* AliDielectronCFdraw::CollectHistosEff(const  Int_t vars[3], const char* numerators, Int_t denominator, Int_t type)
 {
   //
   // Collect histos with 'dim'ension of the 'slices' separated by one of "':;'"
   // in a TObjArray and return it
   //
-  TObjArray *arr=TString(nominators).Tokenize(",:;");
+  TObjArray *arr=TString(numerators).Tokenize(",:;");
   TObjArray *arrHists=0x0;
-  if (arr->GetEntriesFast()==0){
+
+  if (type==0){
+    if (arr->GetEntriesFast()==0){
     // all slices in case of 0 entries
-    arrHists=new TObjArray(fCfContainer->GetNStep());
-    for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
-      fEffGrid->CalculateEfficiency(istep,denominator);
-      TH1 *hproj=ProjectEff(dim,vars);
-      Float_t eff=fEffGrid->GetAverage();
-      hproj->SetName(Form("%s (%f)",fCfContainer->GetStepTitle(istep),eff));
-      arrHists->Add(hproj);
+      arrHists=new TObjArray(fCfContainer->GetNStep());
+      fVdata.ResizeTo(arrHists->GetSize());
+      for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
+        fEffGrid->CalculateEfficiency(istep,denominator);
+        TH1 *hproj=ProjectEff(vars);
+        if (!hproj) continue;
+        Float_t eff=fEffGrid->GetAverage();
+        fVdata(istep)=eff;
+        hproj->SetName(Form("eff_%02d/%02d",istep,denominator));
+        hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff));
+        arrHists->Add(hproj);
+      }
+    } else {
+      arrHists=new TObjArray(arr->GetEntriesFast());
+      TIter next(arr);
+      TObjString *ostr=0x0;
+      fVdata.ResizeTo(arrHists->GetSize());
+      Int_t count=0;
+      while ( (ostr=static_cast<TObjString*>(next())) ) {
+        Int_t istep=ostr->GetString().Atoi();
+        fEffGrid->CalculateEfficiency(istep,denominator);
+        TH1 *hproj=ProjectEff(vars);
+        if (!hproj) continue;
+        Float_t eff=fEffGrid->GetAverage();
+        fVdata(count++)=eff;
+        hproj->SetName(Form("eff_%02d/%02d",istep,denominator));
+        hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff));
+        arrHists->Add(hproj);
+      }
     }
-  } else {
-    arrHists=new TObjArray(arr->GetEntriesFast());
-    TIter next(arr);
-    TObjString *ostr=0x0;
-    while ( (ostr=static_cast<TObjString*>(next())) ) {
-      Int_t istep=ostr->GetString().Atoi();
-      fEffGrid->CalculateEfficiency(istep,denominator);
-      TH1 *hproj=ProjectEff(dim,vars);
-      Float_t eff=fEffGrid->GetAverage();
-      hproj->SetName(Form("%s (%f)",fCfContainer->GetStepTitle(istep),eff));
-      arrHists->Add(hproj);
+  }
+
+  //second approach
+  if (type==1){
+    TH1 *hDen=Project(vars,denominator);
+    Double_t entriesDen=hDen->GetEffectiveEntries();
+    if (arr->GetEntriesFast()==0){
+    // all slices in case of 0 entries
+      arrHists=new TObjArray(fCfContainer->GetNStep());
+      fVdata.ResizeTo(arrHists->GetSize());
+      for (Int_t istep=0; istep<fCfContainer->GetNStep(); ++istep){
+        TH1 *hproj=Project(vars,istep);
+        if (!hproj) continue;
+        Float_t eff=0;
+        if (entriesDen>0) eff=hproj->GetEffectiveEntries()/entriesDen;
+        fVdata(istep)=eff;
+        hproj->Divide(hproj,hDen,1,1,"B");
+        hproj->SetName(Form("eff_%02d/%02d",istep,denominator));
+        hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff));
+        arrHists->Add(hproj);
+      }
+    } else {
+      arrHists=new TObjArray(arr->GetEntriesFast());
+      fVdata.ResizeTo(arrHists->GetSize());
+      TIter next(arr);
+      TObjString *ostr=0x0;
+      Int_t count=0;
+      while ( (ostr=static_cast<TObjString*>(next())) ) {
+        Int_t istep=ostr->GetString().Atoi();
+        TH1 *hproj=Project(vars,istep);
+        if (!hproj) continue;
+        Float_t eff=0;
+        if (entriesDen>0) eff=hproj->GetEffectiveEntries()/entriesDen;
+        fVdata(count++)=eff;
+        hproj->Divide(hproj,hDen,1,1,"B");
+        hproj->SetName(Form("eff_%02d/%02d",istep,denominator));
+        hproj->SetTitle(Form("%s (%.3f)",fCfContainer->GetStepTitle(istep),eff));
+        arrHists->Add(hproj);
+      }
     }
+    delete hDen;
   }
-  delete arr;
   
+
+  delete arr;
   return arrHists;
 }
 
 //________________________________________________________________
-TH1* AliDielectronCFdraw::ProjectEff(Int_t ndim, Int_t *vars)
+TH1* AliDielectronCFdraw::ProjectEff(const Int_t vars[3])
 {
   //
   // Do an nim projection
   //
-  switch (ndim){
-  case 1:
-    return fEffGrid->Project(vars[0]);
-    break;
-  case 2:
-    return fEffGrid->Project(vars[0],vars[1]);
-    break;
-  case 3:
-    return fEffGrid->Project(vars[0],vars[1],vars[2]);
-    break;
-  }
-  return 0x0;
+  return fEffGrid->Project(vars[0],vars[1],vars[2]);
 }
 
 //________________________________________________________________
@@ -509,25 +565,33 @@ void AliDielectronCFdraw::Draw(const TObjArray *arr, const char* opt)
   //
   TString optStr(opt);
   optStr.ToLower();
-  Bool_t drawSame=optStr.Contains("same");
-  Bool_t optLeg=optStr.Contains("leg");
-  optStr.ReplaceAll("same","");
+  Bool_t drawSame     = optStr.Contains("same");
+  Bool_t drawSamePlus = optStr.Contains("same+");
+  Bool_t drawEff      = optStr.Contains("eff");
+  Bool_t optLeg       = optStr.Contains("leg");
+  Bool_t optScaleMax  = optStr.Contains("max");
+  
+  if (!drawSamePlus) optStr.ReplaceAll("same","");
+  
+  optStr.ReplaceAll("+","");
+  optStr.ReplaceAll("eff","");
+  optStr.ReplaceAll("leg","");
+  optStr.ReplaceAll("max","");
   
   if (!gPad) new TCanvas;
   
   Int_t nPads = arr->GetEntriesFast();
   if (nPads==0) return;
   
-  if (nPads==1){
-    arr->UncheckedAt(0)->Draw(optStr.Data());
-    return;
-  }
+//   if (nPads==1){
+//     arr->UncheckedAt(0)->Draw(optStr.Data());
+//     return;
+//   }
   
   TCanvas *c=gPad->GetCanvas();
-  c->Clear();
-  
+  if (!gVirtualPS&&!drawSamePlus&&!drawSame&&nPads>1) c->Clear();
   
-  if (!drawSame){
+  if (!drawSame&&nPads>1){
     //optimised division
     Int_t nCols = (Int_t)TMath::Ceil( TMath::Sqrt(nPads) );
     Int_t nRows = (Int_t)TMath::Ceil( (Double_t)nPads/(Double_t)nCols );
@@ -538,20 +602,77 @@ void AliDielectronCFdraw::Draw(const TObjArray *arr, const char* opt)
     }
   } else {
     TLegend *leg=0;
-    if (optLeg) leg=new TLegend(.8,.3,.99,.9);
+    if (drawSamePlus){
+      //find already existing legend to attach entries to it
+      TIter nextPrimitive(gPad->GetListOfPrimitives());
+      TObject *o=0x0;
+      while ((o=nextPrimitive())) if (o->IsA()==TLegend::Class()) leg=(TLegend*)o;
+    }
+    
+    if (optLeg&&!leg) leg=new TLegend(.2,.3,.99,.9);
+    Int_t addColor=0;
+    if (leg) addColor=leg->GetNRows();
+    Int_t offset=20;
+    if (nPads<7) offset=24;
     for (Int_t i=0; i<nPads; ++i){
-      if (i==1) optStr+="same";
+      if (i==1&&!drawSamePlus) optStr+="same";
       TH1 *hist=static_cast<TH1*>(arr->UncheckedAt(i));
-      hist->SetLineColor(i+1);
-      hist->SetMarkerColor(i+1);
+      hist->SetLineColor(i+1+addColor);
+      hist->SetLineWidth(2);
+      hist->SetMarkerColor(i+1+addColor);
+      hist->SetMarkerStyle(offset+i+addColor);
       hist->Draw(optStr.Data());
-      if (leg) leg->AddEntry(hist,hist->GetName(),"lp");
+      
+      if (drawEff&&i==0&&!drawSamePlus) {
+        hist->GetYaxis()->SetRangeUser(0,2);
+        hist->SetYTitle("Rec. Signal / Gen. Signal");
+      }
+      
+      if (leg) leg->AddEntry(hist,hist->GetTitle(),"lp");
     }
     if (leg){
       leg->SetFillColor(10);
-      leg->SetY1(.9-nPads*.05);
-      leg->Draw();
+      leg->SetY1(.9-leg->GetNRows()*.05);
+      leg->SetY1NDC(.9-leg->GetNRows()*.05);
+      leg->SetMargin(.1);
+      if (!drawSamePlus) leg->Draw();
+    }
+    if (optScaleMax){
+      TIter nextPrimitive(gPad->GetListOfPrimitives());
+      TObject *o=0x0;
+      TH1 *hfirst=0x0;
+      Float_t max=0;
+      while ((o=nextPrimitive())) if (o->InheritsFrom(TH1::Class())){
+        TH1 *h=(TH1*)o;
+        if (!hfirst) hfirst=h;
+        if (h->GetMaximum()>max) max=h->GetMaximum();
+      }
+      max*=1.1;
+      hfirst->SetMaximum(max);
     }
   }
   
 }
+
+//________________________________________________________________
+Double_t AliDielectronCFdraw::GetAverageEfficiency(Int_t numerator, Int_t denominator, Double_t &effErr)
+{
+  //
+  // Extract the mean efficiency of the numerator and denominator
+  //
+
+  //use variable 0 as default, since for the average it doesn't matter
+  TH1 *hDen=fCfContainer->Project(denominator,0);
+  Double_t entriesDen=hDen->GetEffectiveEntries();
+  TH1 *hproj=fCfContainer->Project(numerator,0);
+  if (!hproj) return -1.;
+  Double_t entriesNum=hproj->GetEffectiveEntries();
+  if (entriesDen<1||entriesNum<1) return -1;
+  
+  Double_t eff=-1.;
+  if (entriesDen>0) eff=entriesNum/entriesDen;
+  effErr=TMath::Sqrt(1./entriesNum+1./entriesDen)*eff;
+  delete hDen;
+  delete hproj;
+  return eff;
+}