]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - CORRFW/AliCFContainer.cxx
updated merging function (Michele)
[u/mrichter/AliRoot.git] / CORRFW / AliCFContainer.cxx
index dbe12a8501f8854826a53ff6d07b5bc9f1657e57..9467c82d4d71724b5a52446f29aba14788038b5e 100644 (file)
@@ -1,9 +1,22 @@
 /* $Id$ */
-
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
 //--------------------------------------------------------------------//
 //                                                                    //
-// AliCFContainer Class                                           //
-// Class to accumulate data on an N-dimensional grids, at different    //
+// AliCFContainer Class                                               //
+// Class to accumulate data on an N-dimensional grids, at different   //
 // selection stages. To be used as an input to get corrections for    //
 // Reconstruction & Trigger efficiency                                // 
 //                                                                    //
@@ -12,9 +25,9 @@
 //
 //
 #include <AliLog.h>
-#include "AliCFGrid.h"
+#include "AliCFGridSparse.h"
 #include "AliCFContainer.h"
-
+#include "TAxis.h"
 //____________________________________________________________________
 ClassImp(AliCFContainer)
 
@@ -38,36 +51,35 @@ AliCFContainer::AliCFContainer(const Char_t* name, const Char_t* title) :
 }
 
 //____________________________________________________________________
-AliCFContainer::AliCFContainer(const Char_t* name, const Char_t* title,const Int_t nSelSteps, const Int_t nVarIn, const Int_t * nBinIn, const Float_t *binLimitsIn) :  
-  AliCFFrame(name,title,nVarIn,nBinIn,binLimitsIn),
-  fNStep(0),
+AliCFContainer::AliCFContainer(const Char_t* name, const Char_t* title, const Int_t nSelSteps, const Int_t nVarIn, const Int_t* nBinIn) :  
+  AliCFFrame(name,title),
+  fNStep(nSelSteps),
   fGrid(0x0)
 {
   //
   // main constructor
   //
 
-  // The selection steps
-  fNStep=nSelSteps;
-
   // The grids 
-  fGrid = new AliCFGrid*[fNStep]; //the grids at the various selection steps
-  char gname[30];
-  for(Int_t istep=0;istep<fNStep;istep++){
+  fGrid = new AliCFGridSparse*[fNStep]; //the grids at the various selection steps
+  char gname[100];
+  for (Int_t istep=0; istep<fNStep; istep++) {
     sprintf(gname,"%s%s%i",GetName(),"_SelStep", istep);
-    fGrid[istep] = new AliCFGrid(gname,title,nVarIn,nBinIn,binLimitsIn); 
+    fGrid[istep] = new AliCFGridSparse(gname,title,nVarIn,nBinIn);
+    fGrid[istep]->SumW2();
   }
+  AliInfo(Form("Grids created for %d steps required  \n =>  Don't forget to set the bin limits !!",fNStep));
 }
 //____________________________________________________________________
-AliCFContainer::AliCFContainer(const AliCFContainer& c) : 
-  AliCFFrame(),
+AliCFContainer::AliCFContainer(const AliCFContainer& c) :
+  AliCFFrame(c.fName,c.fTitle),
   fNStep(0),
   fGrid(0x0)
 {
   //
   // copy constructor
   //
-  ((AliCFContainer &)c).Copy(*this);
+  c.Copy(*this);
 }
 //____________________________________________________________________
 AliCFContainer::~AliCFContainer()
@@ -75,8 +87,7 @@ AliCFContainer::~AliCFContainer()
   //
   // destructor
   //
-  if(fGrid)delete [] fGrid;
-
+  if (fGrid) delete [] fGrid;
 }
 //____________________________________________________________________
 AliCFContainer &AliCFContainer::operator=(const AliCFContainer &c)
@@ -84,89 +95,207 @@ AliCFContainer &AliCFContainer::operator=(const AliCFContainer &c)
   //
   // assigment operator
   //
-  if (this != &c)
-    ((AliCFContainer &) c).Copy(*this);
+  if (this != &c) c.Copy(*this);
   return *this;
 } 
-//____________________________________________________________________
-void AliCFContainer::SetBinLimits(Int_t varindex, Float_t *array)
-{
-  //
-  // setting the arrays containing the bin limits 
-  //
-  Int_t nbins=fNVarBins[varindex]+1;
-  for(Int_t i=0;i<nbins;i++){
-    fVarBinLimits[fOffset[varindex]+i] =array[i];
-  } 
-  for(Int_t istep=0;istep<fNStep;istep++){
-    fGrid[istep]->SetBinLimits(varindex,array);
-  }
-} 
+
 //____________________________________________________________________
 void AliCFContainer::Copy(TObject& c) const
 {
   //
   // copy function
   //
+  AliCFFrame::Copy(c);
   AliCFContainer& target = (AliCFContainer &) c;
-  target.fNStep=fNStep;
-  target.fNVar=fNVar;
-  target.fNDim=fNDim;
-  target.fNVarBinLimits=fNVarBinLimits;
-  if (fNVarBins)
-    target.fNVarBins = fNVarBins;
-  if (fVarBinLimits)
-    target.fVarBinLimits = fVarBinLimits;
-  if (fGrid)
-    target.fGrid = fGrid;
-    for(Int_t istep=0;istep<fNStep;istep++){
-      for(Int_t iel=0;iel<fNDim;iel++){
-       target.fGrid[istep]->SetElement(iel,fGrid[istep]->GetElement(iel));
-      } 
-    }  
+  target.fNStep = fNStep;
+  target.fGrid  = new AliCFGridSparse*[fNStep];
+  for (Int_t iStep=0; iStep<fNStep; iStep++) {
+    if (fGrid[iStep])  target.fGrid[iStep] = new AliCFGridSparse(*(fGrid[iStep]));
+  }
 }
+
 //____________________________________________________________________
-void AliCFContainer::Fill(Float_t *var, Int_t istep, Float_t weight)
+void AliCFContainer::Fill(const Double_t *var, Int_t istep, Double_t weight)
 {
   //
   // Fills the grid at selection step istep for a set of values of the 
   // input variables, with a given weight (by default w=1)
   //
+  if(istep >= fNStep || istep < 0){
+    AliError("Non-existent selection step, grid was not filled");
+    return;
+  }
   fGrid[istep]->Fill(var,weight);
 }
 //___________________________________________________________________
-TH1F *AliCFContainer::ShowProjection(Int_t ivar, Int_t istep) const
+TH1D *AliCFContainer::Project(Int_t ivar, Int_t istep) const
 {
   //
   // returns 1-D projection along variable ivar at selection step istep
   //
+  if(istep >= fNStep || istep < 0){
+    AliError("Non-existent selection step, return NULL");
+    return 0x0;
+  }
+  if(ivar >= GetNVar() || ivar < 0){
+    AliError("Non-existent variable, return NULL");
+    return 0x0;
+  }
+
   return fGrid[istep]->Project(ivar);
 }
 //___________________________________________________________________
-TH2F *AliCFContainer::ShowProjection(Int_t ivar1, Int_t ivar2, Int_t istep) const
+TH2D *AliCFContainer::Project(Int_t ivar1, Int_t ivar2, Int_t istep) const
 {
   //
   // returns 2-D projection along variables ivar1,ivar2 at selection step istep
   //
+  if(istep >= fNStep || istep < 0){
+    AliError("Non-existent selection step, return NULL");
+    return 0x0;
+  }
+  if(ivar1 >= GetNVar() || ivar1 < 0 || ivar2 >= GetNVar() || ivar2 < 0){
+    AliError("Non-existent variable, return NULL");
+    return 0x0;
+  }
+
   return fGrid[istep]->Project(ivar1,ivar2);
 }
 //___________________________________________________________________
-TH3F *AliCFContainer::ShowProjection(Int_t ivar1, Int_t ivar2, Int_t ivar3, Int_t istep) const
+TH3D *AliCFContainer::Project(Int_t ivar1, Int_t ivar2, Int_t ivar3, Int_t istep) const
 {
   //
   // returns 3-D projection along variables ivar1,ivar2,ivar3 
   // at selection step istep
   //
+  if(istep >= fNStep || istep < 0){
+    AliError("Non-existent selection step, return NULL");
+    return 0x0;
+  }
+  if(ivar1 >= GetNVar() || ivar1 < 0 || 
+     ivar2 >= GetNVar() || ivar2 < 0 ||
+     ivar3 >= GetNVar() || ivar3 < 0 ) {
+    AliError("Non-existent variable, return NULL");
+    return 0x0;
+  }
+
   return fGrid[istep]->Project(ivar1,ivar2,ivar3);
 }
 //___________________________________________________________________
-TH1F *AliCFContainer::ShowSlice(Int_t ivar, Float_t *varMin, Float_t* varMax, Int_t istep) const
+TH1D *AliCFContainer::ShowSlice(Int_t ivar, const Double_t *varMin, const Double_t* varMax, Int_t istep, Bool_t useBins) const
 {
   //
   // Make a slice along variable ivar at selection level istep in range [varMin,varMax]
+  // If useBins=true, varMin and varMax are taken as bin numbers
+  //
+  if(istep >= fNStep || istep < 0){
+    AliError("Non-existent selection step, return NULL");
+    return 0x0;
+  }
+  if (ivar >= GetNVar() || ivar < 0) {
+    AliError("Non-existent variable, return NULL");
+    return 0x0;
+  }
+  return (TH1D*)fGrid[istep]->Slice(ivar,varMin,varMax,useBins);
+}
+//___________________________________________________________________
+TH2D *AliCFContainer::ShowSlice(Int_t ivar1, Int_t ivar2, const Double_t *varMin, const Double_t* varMax, Int_t istep, Bool_t useBins) const
+{
+  //
+  // Make a slice along variables ivar1 and ivar2 at selection level istep in range [varMin,varMax]
+  // If useBins=true, varMin and varMax are taken as bin numbers
+  //
+  if(istep >= fNStep || istep < 0){
+    AliError("Non-existent selection step, return NULL");
+    return 0x0;
+  }
+  if (ivar1 >= GetNVar() || ivar1 < 0 || ivar2 >= GetNVar() || ivar2 < 0) {
+    AliError("Non-existent variable, return NULL");
+    return 0x0;
+  }
+  return (TH2D*)fGrid[istep]->Slice(ivar1,ivar2,varMin,varMax,useBins);
+}
+//___________________________________________________________________
+TH3D *AliCFContainer::ShowSlice(Int_t ivar1, Int_t ivar2, Int_t ivar3, const Double_t *varMin, const Double_t* varMax, Int_t istep, Bool_t useBins) const
+{
+  //
+  // Make a slice along variables ivar1, ivar2and ivar3 at selection level istep in range [varMin,varMax]
+  // If useBins=true, varMin and varMax are taken as bin numbers
+  //
+  if(istep >= fNStep || istep < 0){
+    AliError("Non-existent selection step, return NULL");
+    return 0x0;
+  }
+  if (ivar1 >= GetNVar() || ivar1 < 0 || ivar2 >= GetNVar() || ivar2 < 0 || ivar3 >= GetNVar() || ivar3 < 0) {
+    AliError("Non-existent variable, return NULL");
+    return 0x0;
+  }
+  return (TH3D*)fGrid[istep]->Slice(ivar1,ivar2,ivar3,varMin,varMax,useBins);
+}
+//____________________________________________________________________
+AliCFContainer* AliCFContainer::MakeSlice(Int_t nVars, const Int_t* vars, const Double_t* varMin, const Double_t* varMax, Bool_t useBins) const
+{
+  //
+  // Makes a slice along the "nVars" variables defined in the array "vars[nVars]" for all the container steps.
+  // The ranges of ALL the container variables must be defined in the array varMin[GetNVar()] and varMax[GetNVar()]
+  // The function returns a new container of nVars variables.
+  // If useBins=true, varMin and varMax are taken as bin numbers
+  //
+  Int_t* steps = new Int_t[fNStep];
+  for (Int_t iStep=0;iStep<fNStep;iStep++) steps[iStep]=iStep;
+  AliCFContainer* out = MakeSlice(nVars,vars,varMin,varMax,fNStep,steps,useBins);
+  delete [] steps ;
+  return out;
+}
+
+//____________________________________________________________________
+AliCFContainer* AliCFContainer::MakeSlice(Int_t nVars, const Int_t* vars, const Double_t* varMin, const Double_t* varMax, Int_t nSteps, const Int_t* steps, Bool_t useBins) const
+{
   //
-  return (TH1F*)fGrid[istep]->Slice(ivar,varMin,varMax);
+  // Makes a slice along the "nVars" variables defined in the array "vars[nVars]" for the given "nSteps" defined in "steps[nSteps]".
+  // The ranges of ALL the container variables must be defined in the array varMin[GetNVar()] and varMax[GetNVar()]
+  // The function returns a new container of nVars variables.
+  // If useBins=true, varMin and varMax are taken as bin numbers
+  //
+
+  if (nVars < 1 || nVars > GetNVar())   AliError("Bad number of dimensions required for the slice");
+  if (nSteps< 1 || nSteps> fNStep)  AliError("Bad number of steps required for the slice");
+
+  AliInfo(Form("Making a slice in %d dimension(s)",nVars));
+
+  // create the output grids
+  AliCFGridSparse** grids = new AliCFGridSparse*[nSteps] ;
+  for (Int_t iStep=0; iStep<nSteps; iStep++) grids[iStep] = fGrid[steps[iStep]]->Project(nVars,vars,varMin,varMax,useBins);
+  
+  TAxis ** axis = new TAxis*[nVars];
+  for (Int_t iVar=0; iVar<nVars; iVar++) axis[iVar] = ((AliCFGridSparse*)grids[0])->GetGrid()->GetAxis(iVar); //same axis for every grid
+
+  //define new binning for new container
+  Int_t* bins=new Int_t[nVars];
+  for (Int_t iVar=0; iVar<nVars; iVar++) bins[iVar] = axis[iVar]->GetNbins();
+
+  AliCFContainer* out = new AliCFContainer(fName,fTitle,nSteps,nVars,bins);
+
+  //set the bin limits
+  for (Int_t iVar=0; iVar<nVars; iVar++) {
+    Int_t nBins = bins[iVar];
+    Double_t *array = new Double_t[nBins+1];
+    for (Int_t iBin=1; iBin<=nBins; iBin++) {
+      array[iBin-1] = axis[iVar]->GetBinLowEdge(iBin);
+    }
+    array[nBins] = axis[iVar]->GetBinUpEdge(nBins);
+    out->SetBinLimits(iVar,array);
+    delete [] array;
+  }
+
+  //set grid for the given steps
+  for (Int_t iStep=0; iStep<nSteps; iStep++) out->SetGrid(iStep,grids[iStep]);
+
+  delete [] bins;
+  delete [] axis ;
+  return out;
 }
+
 //____________________________________________________________________
 Long64_t AliCFContainer::Merge(TCollection* list)
 {
@@ -196,82 +325,145 @@ Long64_t AliCFContainer::Merge(TCollection* list)
 }
 
 //____________________________________________________________________
-void AliCFContainer::Add(AliCFContainer* aContainerToAdd, Float_t c)
+void AliCFContainer::Add(const AliCFContainer* aContainerToAdd, Double_t c)
 {
   //
   //add the content of container aContainerToAdd to the current one
   //
-
-  if(aContainerToAdd->GetNStep()!=fNStep)AliError("Different number of steps, cannot add the containers");
-  if(aContainerToAdd->GetNVar()!=fNVar)AliError("Different number of variables, cannot add the containers");
-  if(aContainerToAdd->GetNDim()!=fNDim)AliError("Different number of dimensions, cannot add the containers!");
-  
-  for(Int_t istep=0;istep<fNStep;istep++){
+  if ((aContainerToAdd->GetNStep()      != fNStep)          ||
+      (aContainerToAdd->GetNVar()       != GetNVar())       ||
+      (aContainerToAdd->GetNBinsTotal() != GetNBinsTotal()))
+    {
+      AliError("Different number of steps/sensitive variables/grid elements: cannot add the containers");
+      return;
+    }
+  for (Int_t istep=0; istep<fNStep; istep++) {
     fGrid[istep]->Add(aContainerToAdd->GetGrid(istep),c);
   }
 }
 //____________________________________________________________________
-Float_t AliCFContainer::GetOverFlows( Int_t ivar, Int_t istep) const {
+Float_t AliCFContainer::GetOverFlows( Int_t ivar, Int_t istep, Bool_t exclusive) const {
   //
   // Get overflows in variable var at selection level istep
+  // Set 'exclusive' to true for an exclusive check on variable ivar
   //
-  return fGrid[istep]->GetOverFlows(ivar);
-} 
-//____________________________________________________________________
-Float_t AliCFContainer::GetOverFlows( Int_t istep) const {
-  //
-  // Get overflows in variable var at selection level istep
-  //
-  return fGrid[istep]->GetOverFlows();
-} 
-//____________________________________________________________________
-Float_t AliCFContainer::GetUnderFlows( Int_t ivar, Int_t istep) const {
-  //
-  // Get overflows in variable var at selection level istep
-  //
-  return fGrid[istep]->GetUnderFlows(ivar);
+  if(istep >= fNStep || istep < 0){
+    AliError("Non-existent selection step, return -1");
+    return -1.;
+  }
+  return fGrid[istep]->GetOverFlows(ivar,exclusive);
 } 
 //____________________________________________________________________
-Float_t AliCFContainer::GetUnderFlows( Int_t istep) const {
+Float_t AliCFContainer::GetUnderFlows( Int_t ivar, Int_t istep, Bool_t exclusive) const {
   //
-  // Get overflows in variable var at selection level istep
+  // Get underflows in variable var at selection level istep
+  // Set 'exclusive' to true for an exclusive check on variable ivar
   //
-  return fGrid[istep]->GetUnderFlows();
+  if(istep >= fNStep || istep < 0){
+    AliError("Non-existent selection step, return -1");
+    return -1.;
+  }
+  return fGrid[istep]->GetUnderFlows(ivar,exclusive);
 } 
 //____________________________________________________________________
-Float_t AliCFContainer::GetEntries( Int_t istep) const {
+Float_t AliCFContainer::GetEntries(Int_t istep) const {
   //
-  // Get overflows in variable var at selection level istep
+  // Get total entries in variable var at selection level istep
   //
+  if(istep >= fNStep || istep < 0){
+    AliError("Non-existent selection step, return -1");
+    return -1.;
+  }
   return fGrid[istep]->GetEntries();
 } 
-//____________________________________________________________________
-Int_t AliCFContainer::GetEmptyBins( Int_t istep) const {
-  //
-  // Get overflows in variable var at selection level istep
-  //
-  return fGrid[istep]->GetEmptyBins();
-} 
-//____________________________________________________________________
-Int_t AliCFContainer::GetEmptyBins( Int_t istep, Float_t *varMin, Float_t* varMax) const {
+// //____________________________________________________________________
+// Int_t AliCFContainer::GetEmptyBins(Int_t istep) const {
+//   //
+//   // Get empty bins in variable var at selection level istep
+//   //
+//   if(istep >= fNStep || istep < 0){
+//     AliError("Non-existent selection step, return -1");
+//     return -1;
+//   }
+//   return fGrid[istep]->GetEmptyBins();
+// } 
+// //____________________________________________________________________
+// Int_t AliCFContainer::GetEmptyBins( Int_t istep, Double_t *varMin, Double_t* varMax) const {
+//   //
+//   // Get empty bins in a range in variable var at selection level istep
+//   //
+//   if(istep >= fNStep || istep < 0){
+//     AliError("Non-existent selection step, return -1");
+//     return -1;
+//   }
+//   return fGrid[istep]->GetEmptyBins(varMin,varMax);
+// } 
+//_____________________________________________________________________
+Double_t AliCFContainer::GetIntegral( Int_t istep) const 
+{
   //
-  // Get overflows in variable var at selection level istep
+  // Get Integral over the grid at selection level istep
   //
-  return fGrid[istep]->GetEmptyBins(varMin,varMax);
-} 
+  if(istep >= fNStep || istep < 0){
+    AliError("Non-existent selection step, return -1");
+    return -1.;
+  }
+  return fGrid[istep]->GetIntegral();
+}
+//_____________________________________________________________________
+// Double_t AliCFContainer::GetIntegral( Int_t istep, Double_t *varMin, Double_t* varMax ) const 
+// {
+//   //
+//   // Get Integral over the grid in a range at selection level istep
+//   //
+//   if(istep >= fNStep || istep < 0){
+//     AliError("Non-existent selection step, return -1");
+//     return -1.;
+//   }
+//   return fGrid[istep]->GetIntegral(varMin,varMax);
+// }
 //_____________________________________________________________________
-Float_t AliCFContainer::GetIntegral( Int_t istep) const 
+void AliCFContainer::SetRangeUser(Int_t ivar, Double_t varMin, Double_t varMax, Int_t istep) 
 {
   //
-  // Get Integral at selection level istep
+  // set axis range at step istep
   //
-  return fGrid[istep]->GetIntegral();
+  if (istep >= fNStep || istep < 0){
+    AliError("Non-existent selection step");
+    return ;
+  }
+  if (ivar >= GetNVar() || ivar < 0){
+    AliError("Non-existent selection var");
+    return ;
+  }
+  fGrid[istep]->SetRangeUser(ivar,varMin,varMax);
 }
+
 //_____________________________________________________________________
-Float_t AliCFContainer::GetIntegral( Int_t istep, Float_t *varMin, Float_t* varMax ) const 
+void AliCFContainer::SetRangeUser(Double_t* varMin, Double_t* varMax, Int_t istep) 
 {
   //
-  // Get Integral at selection level istep
+  // set all axis ranges at step istep according to varMin and varMax values
   //
-  return fGrid[istep]->GetIntegral(varMin,varMax);
+  if (istep >= fNStep || istep < 0){
+    AliError("Non-existent selection step");
+    return ;
+  }
+  ((AliCFGridSparse*)fGrid[istep])->SetRangeUser(varMin,varMax);
+}
+
+//_____________________________________________________________________
+void AliCFContainer::Print(const Option_t*) const {
+  AliInfo("====================================================================================");
+  AliInfo(Form("AliCFContainer : name = %s   title = %s",GetName(),GetTitle()));
+  AliInfo(Form("number of steps \t %d",GetNStep()));
+  for (Int_t iStep=0;iStep<GetNStep();iStep++) AliInfo(Form("step %d \t -> %s",iStep,GetStepTitle(iStep)));
+  AliInfo(Form("number of variables \t %d",GetNVar()));
+  for (Int_t iVar=0;iVar<GetNVar();iVar++) {
+    Double_t *binLimits = new Double_t[GetNBins(iVar)+1];
+    GetBinLimits(iVar,binLimits);
+    AliInfo(Form("variable %d \t -> %s : %d bins in [%f,%f]",iVar,GetVarTitle(iVar),GetNBins(iVar),binLimits[0],binLimits[GetNBins(iVar)]));
+    delete binLimits;
+  }
+  AliInfo("====================================================================================");
 }