This commit was generated by cvs2svn to compensate for changes in r23278,
authorhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 10 Jan 2008 09:58:27 +0000 (09:58 +0000)
committerhristov <hristov@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 10 Jan 2008 09:58:27 +0000 (09:58 +0000)
which included commits to RCS files with non-trunk default branches.

45 files changed:
CORRFW/AliCFAcceptanceCuts.cxx [new file with mode: 0644]
CORRFW/AliCFAcceptanceCuts.h [new file with mode: 0644]
CORRFW/AliCFContainer.cxx [new file with mode: 0644]
CORRFW/AliCFContainer.h [new file with mode: 0644]
CORRFW/AliCFCutBase.cxx [new file with mode: 0644]
CORRFW/AliCFCutBase.h [new file with mode: 0644]
CORRFW/AliCFDataGrid.cxx [new file with mode: 0644]
CORRFW/AliCFDataGrid.h [new file with mode: 0644]
CORRFW/AliCFEffGrid.cxx [new file with mode: 0644]
CORRFW/AliCFEffGrid.h [new file with mode: 0644]
CORRFW/AliCFEventClassCuts.cxx [new file with mode: 0644]
CORRFW/AliCFEventClassCuts.h [new file with mode: 0644]
CORRFW/AliCFEventGenCuts.cxx [new file with mode: 0644]
CORRFW/AliCFEventGenCuts.h [new file with mode: 0644]
CORRFW/AliCFEventRecCuts.cxx [new file with mode: 0644]
CORRFW/AliCFEventRecCuts.h [new file with mode: 0644]
CORRFW/AliCFFrame.cxx [new file with mode: 0644]
CORRFW/AliCFFrame.h [new file with mode: 0644]
CORRFW/AliCFGrid.cxx [new file with mode: 0644]
CORRFW/AliCFGrid.h [new file with mode: 0644]
CORRFW/AliCFManager.cxx [new file with mode: 0644]
CORRFW/AliCFManager.h [new file with mode: 0644]
CORRFW/AliCFParticleGenCuts.cxx [new file with mode: 0644]
CORRFW/AliCFParticleGenCuts.h [new file with mode: 0644]
CORRFW/AliCFSingleTrackTask.C [new file with mode: 0644]
CORRFW/AliCFSingleTrackTask.cxx [new file with mode: 0644]
CORRFW/AliCFSingleTrackTask.h [new file with mode: 0644]
CORRFW/AliCFTrackCutPid.cxx [new file with mode: 0644]
CORRFW/AliCFTrackCutPid.h [new file with mode: 0644]
CORRFW/AliCFTrackIsPrimaryCuts.cxx [new file with mode: 0644]
CORRFW/AliCFTrackIsPrimaryCuts.h [new file with mode: 0644]
CORRFW/AliCFTrackKineCuts.cxx [new file with mode: 0644]
CORRFW/AliCFTrackKineCuts.h [new file with mode: 0644]
CORRFW/AliCFTrackQualityCuts.cxx [new file with mode: 0644]
CORRFW/AliCFTrackQualityCuts.h [new file with mode: 0644]
CORRFW/CORRFWLinkDef.h [new file with mode: 0644]
CORRFW/Makefile [new file with mode: 0644]
CORRFW/Makefile.arch [new file with mode: 0644]
CORRFW/PROOF-INF.CORRFW/BUILD.sh [new file with mode: 0755]
CORRFW/PROOF-INF.CORRFW/SETUP.C [new file with mode: 0644]
CORRFW/libCORRFW.pkg [new file with mode: 0644]
CORRFW/test/AliCFSingleTrackTask.C [new file with mode: 0644]
CORRFW/test/AliCFSingleTrackTask.cxx [new file with mode: 0644]
CORRFW/test/AliCFSingleTrackTask.h [new file with mode: 0644]
CORRFW/test/wn.xml [new file with mode: 0644]

diff --git a/CORRFW/AliCFAcceptanceCuts.cxx b/CORRFW/AliCFAcceptanceCuts.cxx
new file mode 100644 (file)
index 0000000..5f6d873
--- /dev/null
@@ -0,0 +1,157 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+//          ----   CORRECTION FRAMEWORK   ----
+// AliCFAcceptanceCuts implementation
+// Class to cut on the number of AliTrackReference's 
+// for each detector
+///////////////////////////////////////////////////////////////////////////
+// author : R. Vernet (renaud.vernet@cern.ch)
+///////////////////////////////////////////////////////////////////////////
+
+#include "AliLog.h"
+#include "AliMCParticle.h"
+#include "AliCFAcceptanceCuts.h"
+
+ClassImp(AliCFAcceptanceCuts)
+
+//______________________________
+AliCFAcceptanceCuts::AliCFAcceptanceCuts() : 
+  AliCFCutBase(),
+  fMCInfo(0x0),
+  fMinNHitITS(0),
+  fMinNHitTPC(0),
+  fMinNHitTRD(0),
+  fMinNHitTOF(0),
+  fMinNHitMUON(0)
+
+{
+  //
+  //ctor
+  //
+}
+
+//______________________________
+AliCFAcceptanceCuts::AliCFAcceptanceCuts(const Char_t* name, const Char_t* title) : 
+  AliCFCutBase(name,title),
+  fMCInfo(0x0),
+  fMinNHitITS(0),
+  fMinNHitTPC(0),
+  fMinNHitTRD(0),
+  fMinNHitTOF(0),
+  fMinNHitMUON(0)
+{
+  //
+  //ctor
+  //
+}
+
+//______________________________
+AliCFAcceptanceCuts::AliCFAcceptanceCuts(const AliCFAcceptanceCuts& c) : 
+  AliCFCutBase(c),
+  fMCInfo(c.fMCInfo),
+  fMinNHitITS(c.fMinNHitITS),
+  fMinNHitTPC(c.fMinNHitTPC),
+  fMinNHitTRD(c.fMinNHitTRD),
+  fMinNHitTOF(c.fMinNHitTOF),
+  fMinNHitMUON(c.fMinNHitMUON)
+{
+  //
+  //copy ctor
+  //
+}
+
+//______________________________
+AliCFAcceptanceCuts& AliCFAcceptanceCuts::operator=(const AliCFAcceptanceCuts& c)
+{
+  //
+  // Assignment operator
+  //
+  if (this != &c) {
+    AliCFCutBase::operator=(c) ;
+    fMCInfo=c.fMCInfo;
+    fMinNHitITS=c.fMinNHitITS;
+    fMinNHitTPC=c.fMinNHitTPC;
+    fMinNHitTRD=c.fMinNHitTRD;
+    fMinNHitTOF=c.fMinNHitTOF;
+    fMinNHitMUON=c.fMinNHitMUON;
+  }
+  return *this ;
+}
+
+//______________________________
+Bool_t AliCFAcceptanceCuts::IsSelected(TObject* obj) {
+  //
+  // checks the number of track references associated to 'obj'
+  // 'obj' must be an AliMCParticle
+  //
+
+  if (!obj) return kFALSE ;
+
+  TString className(obj->ClassName());
+  if (className.CompareTo("AliMCParticle") != 0) {
+    AliError("obj must point to a AliMCParticle !");
+    return kFALSE ;
+  }
+
+  AliMCParticle* part = (AliMCParticle*) obj ;
+  if(!part) return kFALSE;
+
+  Int_t nHitsITS=0, nHitsTPC=0, nHitsTRD=0, nHitsTOF=0, nHitsMUON=0 ;
+  for (Int_t iTrackRef=0; iTrackRef<part->GetNumberOfTrackReferences(); iTrackRef++) {
+    AliTrackReference * trackRef = part->GetTrackReference(iTrackRef);
+    if(trackRef){
+      Int_t detectorId = trackRef->DetectorId();
+      switch(detectorId) {
+      case AliTrackReference::kITS  : nHitsITS++  ; break ;
+      case AliTrackReference::kTPC  : nHitsTPC++  ; break ;
+      case AliTrackReference::kTRD  : nHitsTRD++  ; break ;
+      case AliTrackReference::kTOF  : nHitsTOF++  ; break ;
+      case AliTrackReference::kMUON : nHitsMUON++ ; break ;
+      default : break ;
+      }
+    }
+  }
+  
+  if (nHitsITS  < fMinNHitITS  ) return kFALSE;
+  if (nHitsTPC  < fMinNHitTPC  ) return kFALSE;
+  if (nHitsTRD  < fMinNHitTRD  ) return kFALSE;
+  if (nHitsTOF  < fMinNHitTOF  ) return kFALSE;
+  if (nHitsMUON < fMinNHitMUON ) return kFALSE;
+
+
+  return kTRUE ;
+}
+
+
+void AliCFAcceptanceCuts::SetEvtInfo(TObject* mcInfo) {
+  //
+  // Sets pointer to MC event information (AliMCEventHandler)
+  //
+
+  if (!mcInfo) {
+    AliError("Pointer to MC Event Handler is null !");
+    return;
+  }
+  
+  TString className(mcInfo->ClassName());
+  if (className.CompareTo("AliMCEventHandler") != 0) {
+    AliError("argument must point to an AliMCEventHandler !");
+    return ;
+  }
+  
+  fMCInfo = (AliMCEventHandler*) mcInfo ;
+}
diff --git a/CORRFW/AliCFAcceptanceCuts.h b/CORRFW/AliCFAcceptanceCuts.h
new file mode 100644 (file)
index 0000000..0b2904a
--- /dev/null
@@ -0,0 +1,61 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+
+///////////////////////////////////////////////////////////////////////////
+//          ----   CORRECTION FRAMEWORK   ----
+// AliCFAcceptanceCuts implementation
+// Class to cut on the number of AliTrackReference's 
+// for each detector
+///////////////////////////////////////////////////////////////////////////
+// author : R. Vernet (renaud.vernet@cern.ch)
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef ALICFACCEPTANCECUTS_H
+#define ALICFACCEPTANCECUTS_H
+
+#include "AliCFCutBase.h"
+
+class AliMCEventHandler;
+
+class AliCFAcceptanceCuts : public AliCFCutBase
+{
+ public :
+  AliCFAcceptanceCuts() ;
+  AliCFAcceptanceCuts(const Char_t* name, const Char_t* title) ;
+  AliCFAcceptanceCuts(const AliCFAcceptanceCuts& c) ;
+  AliCFAcceptanceCuts& operator=(const AliCFAcceptanceCuts& c) ;
+  virtual ~AliCFAcceptanceCuts() { };
+  virtual Bool_t IsSelected(TObject* obj) ;   
+  virtual void   SetEvtInfo(TObject* mcInfo) ;
+  void SetMinNHitITS (Int_t nhits) {fMinNHitITS=nhits;} 
+  void SetMinNHitTPC (Int_t nhits) {fMinNHitTPC=nhits;} 
+  void SetMinNHitTRD (Int_t nhits) {fMinNHitTRD=nhits;} 
+  void SetMinNHitTOF (Int_t nhits) {fMinNHitTOF=nhits;} 
+  void SetMinNHitMUON(Int_t nhits) {fMinNHitMUON=nhits;}
+
+ protected:
+  AliMCEventHandler *fMCInfo;   // pointer to MC Information
+  Int_t      fMinNHitITS ;      // min number of track references in ITS 
+  Int_t      fMinNHitTPC ;      // min number of track references in TPC 
+  Int_t      fMinNHitTRD ;      // min number of track references in TRD 
+  Int_t      fMinNHitTOF ;      // min number of track references in TOF 
+  Int_t      fMinNHitMUON ;     // min number of track references in MUON
+  
+  ClassDef(AliCFAcceptanceCuts,1);
+};
+
+#endif
diff --git a/CORRFW/AliCFContainer.cxx b/CORRFW/AliCFContainer.cxx
new file mode 100644 (file)
index 0000000..dbe12a8
--- /dev/null
@@ -0,0 +1,277 @@
+/* $Id$ */
+
+//--------------------------------------------------------------------//
+//                                                                    //
+// 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                                // 
+//                                                                    //
+// -- Author : S.Arcelli                                              //
+//--------------------------------------------------------------------//
+//
+//
+#include <AliLog.h>
+#include "AliCFGrid.h"
+#include "AliCFContainer.h"
+
+//____________________________________________________________________
+ClassImp(AliCFContainer)
+
+//____________________________________________________________________
+AliCFContainer::AliCFContainer() : 
+  AliCFFrame(),
+  fNStep(0),
+  fGrid(0x0)
+{
+  //
+  // default constructor
+  //
+}
+//____________________________________________________________________
+AliCFContainer::AliCFContainer(const Char_t* name, const Char_t* title) : 
+  AliCFFrame(name,title),
+  fNStep(0),
+  fGrid(0x0)
+{
+  // default constructor
+}
+
+//____________________________________________________________________
+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),
+  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++){
+    sprintf(gname,"%s%s%i",GetName(),"_SelStep", istep);
+    fGrid[istep] = new AliCFGrid(gname,title,nVarIn,nBinIn,binLimitsIn); 
+  }
+}
+//____________________________________________________________________
+AliCFContainer::AliCFContainer(const AliCFContainer& c) : 
+  AliCFFrame(),
+  fNStep(0),
+  fGrid(0x0)
+{
+  //
+  // copy constructor
+  //
+  ((AliCFContainer &)c).Copy(*this);
+}
+//____________________________________________________________________
+AliCFContainer::~AliCFContainer()
+{
+  //
+  // destructor
+  //
+  if(fGrid)delete [] fGrid;
+
+}
+//____________________________________________________________________
+AliCFContainer &AliCFContainer::operator=(const AliCFContainer &c)
+{
+  //
+  // assigment operator
+  //
+  if (this != &c)
+    ((AliCFContainer &) 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
+  //
+  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));
+      } 
+    }  
+}
+//____________________________________________________________________
+void AliCFContainer::Fill(Float_t *var, Int_t istep, Float_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)
+  //
+  fGrid[istep]->Fill(var,weight);
+}
+//___________________________________________________________________
+TH1F *AliCFContainer::ShowProjection(Int_t ivar, Int_t istep) const
+{
+  //
+  // returns 1-D projection along variable ivar at selection step istep
+  //
+  return fGrid[istep]->Project(ivar);
+}
+//___________________________________________________________________
+TH2F *AliCFContainer::ShowProjection(Int_t ivar1, Int_t ivar2, Int_t istep) const
+{
+  //
+  // returns 2-D projection along variables ivar1,ivar2 at selection step istep
+  //
+  return fGrid[istep]->Project(ivar1,ivar2);
+}
+//___________________________________________________________________
+TH3F *AliCFContainer::ShowProjection(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
+  //
+  return fGrid[istep]->Project(ivar1,ivar2,ivar3);
+}
+//___________________________________________________________________
+TH1F *AliCFContainer::ShowSlice(Int_t ivar, Float_t *varMin, Float_t* varMax, Int_t istep) const
+{
+  //
+  // Make a slice along variable ivar at selection level istep in range [varMin,varMax]
+  //
+  return (TH1F*)fGrid[istep]->Slice(ivar,varMin,varMax);
+}
+//____________________________________________________________________
+Long64_t AliCFContainer::Merge(TCollection* list)
+{
+  // Merge a list of AliCorrection objects with this (needed for
+  // PROOF). 
+  // Returns the number of merged objects (including this).
+
+  if (!list)
+    return 0;
+  
+  if (list->IsEmpty())
+    return 1;
+
+  TIterator* iter = list->MakeIterator();
+  TObject* obj;
+  
+  Int_t count = 0;
+  while ((obj = iter->Next())) {
+    AliCFContainer* entry = dynamic_cast<AliCFContainer*> (obj);
+    if (entry == 0) 
+      continue;
+    this->Add(entry);
+    count++;
+  }
+
+  return count+1;
+}
+
+//____________________________________________________________________
+void AliCFContainer::Add(AliCFContainer* aContainerToAdd, Float_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++){
+    fGrid[istep]->Add(aContainerToAdd->GetGrid(istep),c);
+  }
+}
+//____________________________________________________________________
+Float_t AliCFContainer::GetOverFlows( Int_t ivar, Int_t istep) const {
+  //
+  // Get overflows in variable var at selection level istep
+  //
+  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);
+} 
+//____________________________________________________________________
+Float_t AliCFContainer::GetUnderFlows( Int_t istep) const {
+  //
+  // Get overflows in variable var at selection level istep
+  //
+  return fGrid[istep]->GetUnderFlows();
+} 
+//____________________________________________________________________
+Float_t AliCFContainer::GetEntries( Int_t istep) const {
+  //
+  // Get overflows in variable var at selection level istep
+  //
+  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 {
+  //
+  // Get overflows in variable var at selection level istep
+  //
+  return fGrid[istep]->GetEmptyBins(varMin,varMax);
+} 
+//_____________________________________________________________________
+Float_t AliCFContainer::GetIntegral( Int_t istep) const 
+{
+  //
+  // Get Integral at selection level istep
+  //
+  return fGrid[istep]->GetIntegral();
+}
+//_____________________________________________________________________
+Float_t AliCFContainer::GetIntegral( Int_t istep, Float_t *varMin, Float_t* varMax ) const 
+{
+  //
+  // Get Integral at selection level istep
+  //
+  return fGrid[istep]->GetIntegral(varMin,varMax);
+}
diff --git a/CORRFW/AliCFContainer.h b/CORRFW/AliCFContainer.h
new file mode 100644 (file)
index 0000000..14d8d7f
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef ALICFCONTAINER_H
+#define ALICFCONTAINER_H
+
+/* $Id$ */
+
+//--------------------------------------------------------------------//
+//                                                                    //
+// AliCFContainer Class                                               //
+// Class to handle input data for correction Framework                // 
+//                                                                    //
+//--------------------------------------------------------------------//
+
+#include "AliCFFrame.h"
+
+class TH1F;
+class TH2F;
+class TH3F;
+class AliCFGrid;
+
+class AliCFContainer : public AliCFFrame
+{
+ public:
+  AliCFContainer();
+  AliCFContainer(const Char_t* name,const Char_t* title);
+  AliCFContainer(const Char_t* name, const Char_t* title,const Int_t nSelStep, const Int_t nVarIn, const Int_t* nBinIn, const Float_t  *binLimitsIn=0);
+  AliCFContainer(const AliCFContainer& c);
+  
+  virtual ~AliCFContainer();
+  AliCFContainer& operator=(const AliCFContainer& corr);
+  virtual Int_t GetNStep() const {return fNStep;};
+  virtual void  SetBinLimits(Int_t varindex, Float_t * array);
+  virtual void  Fill(Float_t *var, Int_t istep, Float_t weight=1.);
+
+  virtual Float_t GetOverFlows(Int_t var,Int_t istep) const;
+  virtual Float_t GetUnderFlows(Int_t var,Int_t istep)const ;
+  virtual Float_t GetOverFlows(Int_t istep)const ;
+  virtual Float_t GetUnderFlows(Int_t istep)const ;
+  virtual Float_t GetEntries(Int_t istep)const ;
+  virtual Int_t   GetEmptyBins(Int_t istep)const ;
+  virtual Int_t   GetEmptyBins(Int_t istep, Float_t *varMin,Float_t *varMax) const ;
+  virtual Float_t GetIntegral(Int_t istep) const ;
+  virtual Float_t GetIntegral(Int_t istep, Float_t *varMin,Float_t *varMax) const ;
+  //basic operations
+
+  virtual void Copy(TObject& c) const;
+  virtual void Add(AliCFContainer* aContainerToAdd, Float_t c=1.);
+  virtual Long64_t Merge(TCollection* list);
+
+  virtual TH1F* ShowProjection( Int_t ivar, Int_t istep) const;
+  virtual TH2F* ShowProjection( Int_t ivar1, Int_t ivar2, Int_t istep) const;
+  virtual TH3F* ShowProjection( Int_t ivar1, Int_t ivar2,Int_t ivar3, Int_t istep) const;
+  virtual TH1F* ShowSlice( Int_t ivar, Float_t *varMin, Float_t *varMax, Int_t istep) const;
+  virtual AliCFGrid * GetGrid(Int_t istep) const {return fGrid[istep];};
+  
+ private:
+  Int_t    fNStep; //number of selection steps
+  AliCFGrid **fGrid;//[fNStep]
+  
+  ClassDef(AliCFContainer,1);
+};
+    
+#endif
+
diff --git a/CORRFW/AliCFCutBase.cxx b/CORRFW/AliCFCutBase.cxx
new file mode 100644 (file)
index 0000000..0037bb7
--- /dev/null
@@ -0,0 +1,56 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/ 
+// Base class for selection classes for the correction framework. 
+// Inherits from AliAnalysisCuts. It includes additional methods 
+// to export QA histograms & study the cut statistics & correlations 
+// through the bitmap of the cuts embedded in each class, if needed
+// Author S.Arcelli
+// silvia.Arcelli@cern.ch
+
+#include "AliCFCutBase.h"
+
+
+ClassImp(AliCFCutBase)
+
+
+//___________________________________________________________________________
+AliCFCutBase::AliCFCutBase():
+  AliAnalysisCuts(),
+  fIsQAOn(kFALSE)
+{
+  //
+  // Default constructor
+  //
+}
+
+//___________________________________________________________________________
+AliCFCutBase::AliCFCutBase(const char* name, const char* title):
+  AliAnalysisCuts(name, title),
+  fIsQAOn(kFALSE)
+{
+  //
+  // Constructor
+  //
+}
+
+//___________________________________________________________________________
+AliCFCutBase::AliCFCutBase(const AliCFCutBase& obj):
+  AliAnalysisCuts(obj),
+  fIsQAOn(obj.fIsQAOn)
+{
+  //
+  // Copy Constructor
+  //
+}
diff --git a/CORRFW/AliCFCutBase.h b/CORRFW/AliCFCutBase.h
new file mode 100644 (file)
index 0000000..4b53ae2
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef ALICFCUTBASE_H
+#define ALICFCUTBASE_H
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+// Base class for selecton classes for the correction framework 
+// Inherits from AliAnalysisCuts. It includes additional methods to handle QA 
+// histograms and if needed, study the cut statistics & correlations 
+// Author S.Arcelli
+// silvia.Arcelli@cern.ch
+
+#include <AliAnalysisCuts.h>
+class TBits;
+class TList;
+//___________________________________________________________________________
+class AliCFCutBase : public AliAnalysisCuts
+{
+ public:
+  AliCFCutBase(); //default ctor
+  AliCFCutBase(const char* name, const char* title); //ctor
+  AliCFCutBase(const AliCFCutBase& obj); //copy ctor  
+  virtual ~AliCFCutBase() {;} //dtor
+  virtual Bool_t IsQAOn() const {return fIsQAOn;}; //QA flag getter
+  virtual void SetQAOn(Bool_t flagQA) {fIsQAOn=flagQA;}; //QA flag setter
+  virtual void FillHistogramsBeforeCuts(TObject* ) {;}; //QA histos
+  virtual void FillHistogramsAfterCuts(TObject* ) {;}; //QA histos
+  virtual void DefineHistograms(){;}; //QA histos
+  virtual void AddQAHistograms(TList*) const {;}; //QA Histos
+  virtual void GetBitMap(TObject*, TBits*){;} //selection bitmap
+  virtual void SetEvtInfo(TObject *) {;}; //Pass pointer to event-level info
+  protected:
+  Bool_t fIsQAOn;//qa checking on/off
+ private:
+  ClassDef(AliCFCutBase, 1); // Base class for Correction Framework Cuts
+};
+#endif
diff --git a/CORRFW/AliCFDataGrid.cxx b/CORRFW/AliCFDataGrid.cxx
new file mode 100644 (file)
index 0000000..d57398b
--- /dev/null
@@ -0,0 +1,207 @@
+/* $Id$ */
+
+//--------------------------------------------------------------------//
+//                                                                    //
+// AliCFDataGrid Class                                        //
+// Class to handle observed data and correct them                     // 
+//                                                                    //
+// -- Author : S.Arcelli                                              //
+//                                                                    //
+//                                                                    //
+//                                                                    //
+//--------------------------------------------------------------------//
+//
+//
+#include <TROOT.h>
+#include <TMath.h>
+#include <TFile.h>
+#include <AliLog.h>
+#include "AliCFDataGrid.h"
+
+//____________________________________________________________________
+ClassImp(AliCFDataGrid)
+
+//____________________________________________________________________
+AliCFDataGrid::AliCFDataGrid() : 
+  AliCFGrid(),
+  fSelData(-1),
+  fContainer(0x0)
+{
+  //
+  // default constructor
+  //
+  SumW2(); //errors saved
+}
+
+//____________________________________________________________________
+AliCFDataGrid::AliCFDataGrid(const Char_t* name,const Char_t* title) : 
+  AliCFGrid(name,title),
+  fSelData(-1),
+  fContainer(0x0)
+{
+  //
+  // default constructor
+  //
+  SumW2(); //errors saved
+}
+
+//____________________________________________________________________
+AliCFDataGrid::AliCFDataGrid(const Char_t* name, const Char_t* title, const Int_t nVarIn, const Int_t * nBinIn, const Float_t *binLimitsIn) :  
+  AliCFGrid(name,title,nVarIn,nBinIn,binLimitsIn),
+  fSelData(-1),
+  fContainer(0x0)
+{
+  //
+  // main constructor
+  //
+  SumW2();// errors saved
+}
+//____________________________________________________________________
+AliCFDataGrid::AliCFDataGrid(const Char_t* name, const Char_t* title, const AliCFContainer &c) :  
+  AliCFGrid(name,title,c.GetNVar(),c.GetNBins(),c.GetBinLimits()),
+  fSelData(-1),
+  fContainer(0x0)
+{
+  //
+  // main constructor
+  //
+  SumW2();
+   //assign the container;
+  fContainer=&c;
+
+}
+//____________________________________________________________________
+AliCFDataGrid::AliCFDataGrid(const AliCFDataGrid& data) :   AliCFGrid(),
+  fSelData(-1),
+  fContainer(0x0)
+{
+  //
+  // copy constructor
+  //
+  ((AliCFDataGrid &)data).Copy(*this);
+}
+
+//____________________________________________________________________
+AliCFDataGrid::~AliCFDataGrid()
+{
+  //
+  // destructor
+  //
+}
+//____________________________________________________________________
+AliCFDataGrid &AliCFDataGrid::operator=(const AliCFDataGrid &c)
+{
+  //
+  // assigment operator
+  //
+  if (this != &c)
+    ((AliCFDataGrid &) c).Copy(*this);
+  return *this;
+} 
+//____________________________________________________________________
+
+void AliCFDataGrid::SetMeasured(Int_t istep)
+{
+  //
+  // Deposit observed data over the grid
+  //
+  Int_t nEmptyBins=0;
+  fSelData=istep;
+  //Initially, set the corrected data to the measured data
+  for(Int_t i=0;i<fNDim;i++){
+    Float_t meas=fContainer->GetGrid(fSelData)->GetElement(i);
+    Float_t dmeas=fContainer->GetGrid(fSelData)->GetElementError(i);
+    SetElement(i,meas);
+    SetElementError(i,dmeas);
+    if(meas <=0)nEmptyBins++;
+  }
+  fNentriesTot=fNDim;
+  AliInfo(Form("retrieving measured data from Container %s at selection step %i: %i empty bins were found.",fContainer->GetName(),fSelData,nEmptyBins));
+} 
+//____________________________________________________________________
+void AliCFDataGrid::ApplyEffCorrection(const AliCFEffGrid &c)
+{
+
+  //
+  // Apply the efficiency correction
+  //
+  if(c.GetNVar()!=fNVar){
+    AliInfo("Different number of variables, cannot apply correction");
+    return;
+  }
+  if(c.GetNDim()!=fNDim){
+    AliInfo("Different number of dimension, cannot apply correction");
+    return;
+  }
+
+  //Get the data
+  Int_t ncorr=0;    
+  Int_t nnocorr=0;    
+  Float_t eff,deff,unc,dunc,corr,dcorr;
+  //Apply the correction
+  for(Int_t i=0;i<fNDim;i++){
+    eff =c.GetElement(i);    
+    deff =TMath::Sqrt(c.GetElementError(i));    
+    unc =GetElement(i);    
+    dunc =TMath::Sqrt(GetElementError(i));    
+    if(eff>0 && unc>0){      
+      ncorr++;
+      corr=unc/eff;
+      dcorr=TMath::Sqrt(dunc*dunc/unc/unc+deff*deff/eff/eff)*corr;
+      SetElement(i,corr);
+      SetElementError(i,dcorr*dcorr);
+      
+    } else{
+      if(unc>0)nnocorr++;
+      SetElement(i,0);
+      SetElementError(i,0);
+    }
+  }
+  AliInfo(Form("correction applied for %i cells in correction matrix of Container %s, having entries in Data Container %s.",ncorr,c.GetName(),GetName()));
+  AliInfo(Form("No correction applied for %i empty bins in correction matrix of Container %s, having entries in Data Container %s. Their content in the corrected data container was set to zero",nnocorr,c.GetName(),GetName()));
+}
+//____________________________________________________________________
+void AliCFDataGrid::ApplyBGCorrection(const AliCFDataGrid &c)
+{
+
+  //
+  // Apply correction for background
+  //
+  if(c.GetNVar()!=fNVar){
+    AliInfo("Different number of variables, cannot apply correction");
+    return;
+  }
+  if(c.GetNDim()!=fNDim){
+    AliInfo("Different number of dimension, cannot apply correction");
+    return;
+  }
+
+  //Get the data
+  Float_t bkg,dbkg,unc,dunc,corr,dcorr;
+
+  //Apply the correction
+
+  for(Int_t i=0;i<fNDim;i++){
+    bkg =c.GetElement(i);    
+    dbkg =TMath::Sqrt(c.GetElementError(i));    
+    unc =GetElement(i);    
+    dunc =TMath::Sqrt(GetElementError(i));    
+    corr=unc-bkg;
+    dcorr=TMath::Sqrt(unc+bkg); //stats only, check this
+    SetElement(i,corr);
+    SetElementError(i,dcorr*dcorr);
+      
+  }
+}
+
+//____________________________________________________________________
+void AliCFDataGrid::Copy(TObject& eff) const
+{
+  // copy function
+
+  Copy(eff);
+  AliCFDataGrid& target = (AliCFDataGrid &) eff;
+  target.fContainer=fContainer;
+  target.fSelData=fSelData;
+
+}
diff --git a/CORRFW/AliCFDataGrid.h b/CORRFW/AliCFDataGrid.h
new file mode 100644 (file)
index 0000000..e748a44
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef ALICFDATAGRID_H
+#define ALICFDATAGRID_H
+
+/* $Id$ */
+
+//--------------------------------------------------------------------//
+//                                                                    //
+// AliCFDataGrid Class                                             //
+// Class to handle observed data and correct them                     // 
+//                                                                    //
+//--------------------------------------------------------------------//
+
+#include "AliCFGrid.h"
+#include "AliCFEffGrid.h"
+#include "AliCFContainer.h"
+#include <TNamed.h>
+#include <TTree.h>
+#include <TH1F.h>
+#include <TH2F.h>
+#include <TH3F.h>
+
+class AliCFDataGrid : public AliCFGrid
+{
+ public:
+  AliCFDataGrid();
+  AliCFDataGrid(const Char_t* name,const Char_t* title);
+  AliCFDataGrid(const Char_t* name,const Char_t* title, const Int_t nVarIn, const Int_t* nBinIn, const Float_t  *binLimitsIn=0);
+  AliCFDataGrid(const Char_t* name,const Char_t* title,const AliCFContainer &c);
+  AliCFDataGrid(const AliCFDataGrid& c);
+  
+  virtual ~AliCFDataGrid();
+  AliCFDataGrid& operator=(const AliCFDataGrid& c);
+  virtual Int_t GetSelDataStep() const {return fSelData;};
+
+  // Methods for handling/correcting data 
+
+  virtual void  SetMeasured(Int_t istep);
+  virtual const AliCFGrid*  GetData() {return fContainer->GetGrid(fSelData);};
+  virtual void  ApplyEffCorrection(const AliCFEffGrid &eff);
+  virtual void  ApplyBGCorrection(const AliCFDataGrid &c);
+  virtual void  SetContainer(const AliCFContainer &c) {fContainer=&c;};
+
+  //basic operations
+  virtual void   Copy(TObject& data) const;
+  
+ private:
+  Int_t fSelData; //sel step of the observed data 
+  const AliCFContainer *fContainer; //pointer to the input data Container
+  ClassDef(AliCFDataGrid,1);
+};
+    
+#endif
+
diff --git a/CORRFW/AliCFEffGrid.cxx b/CORRFW/AliCFEffGrid.cxx
new file mode 100644 (file)
index 0000000..26b07d2
--- /dev/null
@@ -0,0 +1,314 @@
+/* $Id$ */
+
+//--------------------------------------------------------------------//
+//                                                                    //
+// AliCFEffGrid Class                                              //
+// Class to handle efficiency grids                                   // 
+//                                                                    //
+// -- Author : S.Arcelli                                              //
+//                                                                    //
+//                                                                    //
+//                                                                    //
+//--------------------------------------------------------------------//
+//
+//
+#include <TROOT.h>
+#include <TMath.h>
+#include <TFile.h>
+#include <AliLog.h>
+#include "AliCFEffGrid.h"
+
+//____________________________________________________________________
+ClassImp(AliCFEffGrid)
+
+//____________________________________________________________________
+AliCFEffGrid::AliCFEffGrid() : 
+  AliCFGrid(),
+  fContainer(0x0),
+  fSelNum(-1),
+  fSelDen(-1)
+{
+  //
+  // default constructor
+  //
+}
+
+//____________________________________________________________________
+AliCFEffGrid::AliCFEffGrid(const Char_t* name, const Char_t* title, const Int_t nVarIn, const Int_t * nBinIn, const Float_t *binLimitsIn) :  
+  AliCFGrid(name,title,nVarIn,nBinIn,binLimitsIn),
+  fContainer(0x0),
+  fSelNum(-1),
+  fSelDen(-1)
+{
+  //
+  // ctor
+  //
+  SumW2();
+}
+//____________________________________________________________________
+AliCFEffGrid::AliCFEffGrid(const Char_t* name, const Char_t* title, const AliCFContainer &c) :  
+  AliCFGrid(name,title,c.GetNVar(),c.GetNBins(),c.GetBinLimits()),
+  fContainer(0x0),
+  fSelNum(-1),
+  fSelDen(-1)
+{
+  //
+  // main constructor
+  //
+  SumW2();
+  //assign the container;
+  fContainer=&c;
+}
+//____________________________________________________________________
+AliCFEffGrid::AliCFEffGrid(const AliCFEffGrid& eff) :   AliCFGrid(),
+  fContainer(0x0),
+  fSelNum(-1),
+  fSelDen(-1)
+{
+  //
+  // copy constructor
+  //
+  ((AliCFEffGrid &)eff).Copy(*this);
+}
+
+//____________________________________________________________________
+AliCFEffGrid::~AliCFEffGrid()
+{
+  //
+  // destructor
+  //
+}
+
+//____________________________________________________________________
+AliCFEffGrid &AliCFEffGrid::operator=(const AliCFEffGrid &eff)
+{
+  //
+  // assigment operator
+  //
+  if (this != &eff)
+    ((AliCFEffGrid &) eff).Copy(*this);
+  return *this;
+} 
+//____________________________________________________________________
+
+void AliCFEffGrid::CalculateEfficiency(Int_t istep1,Int_t istep2)
+{
+  //
+  // Calculate the efficiency matrix and its error between selection
+  // Steps istep1 and istep2
+  //
+
+  fSelNum=istep1;
+  fSelDen=istep2;
+  AliCFGrid *num=fContainer->GetGrid(fSelNum);
+  AliCFGrid *den=fContainer->GetGrid(fSelDen);
+  num->SumW2();
+  den->SumW2();
+  this->Divide(num,den,1.,1.,"B");
+
+  Int_t nEmptyBinsNum=0;
+  Int_t nEmptyBinsNumAndDen=0;
+  for(Int_t iel=0;iel<fNDim;iel++){
+    if(den->GetElement(iel)>0){
+      if(num->GetElement(iel)==0)nEmptyBinsNum++; //num==0,den!=0
+      }
+    else{
+      nEmptyBinsNumAndDen++;
+    }
+  }    
+  // Some monitoring printout:
+  AliInfo(Form("Efficiency calculated for steps %i and %i: %i empty bins in the numerator && !denominator and %i empty bins in numerator && denominator were found.",fSelNum,fSelDen,nEmptyBinsNumAndDen,nEmptyBinsNum));
+  AliInfo(Form("The correction map contains %i empty bins ",nEmptyBinsNum+nEmptyBinsNumAndDen));
+} 
+//_____________________________________________________________________
+Float_t AliCFEffGrid::GetAverage() const 
+{
+  //
+  // Get the average efficiency 
+  //
+
+  Float_t val=0;
+  Float_t valnum=0;
+  Float_t valden=0;
+  for(Int_t i=0;i<fNDim;i++){
+    valnum+=fContainer->GetGrid(fSelNum)->GetElement(i);
+    valden+=fContainer->GetGrid(fSelDen)->GetElement(i);
+  }
+  if(valden>0)val=valnum/valden;
+  AliInfo(Form(" The Average Efficiency = %f ",val)); 
+
+  return val;
+} 
+//_____________________________________________________________________
+Float_t AliCFEffGrid::GetAverage(Float_t *varMin, Float_t* varMax ) const 
+{
+  //
+  // Get ave efficiency in a range
+  //
+
+
+  Float_t val=0;
+  Int_t *indexMin = new Int_t[fNVar];
+  Int_t *indexMax = new Int_t[fNVar];
+  Int_t *index    = new Int_t[fNVar];
+  
+  //Find out the min and max bins
+  
+  for(Int_t i=0;i<fNVar;i++){
+    Float_t xmin=varMin[i]; // the min values  
+    Float_t xmax=varMax[i]; // the max values  
+    Int_t nbins=fNVarBins[i]+1;
+    Float_t *bins=new Float_t[nbins];
+    for(Int_t ibin =0;ibin<nbins;ibin++){
+      bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
+    }
+    indexMin[i] = TMath::BinarySearch(nbins,bins,xmin);
+    indexMax[i] = TMath::BinarySearch(nbins,bins,xmax);
+    if(xmax>=bins[nbins-1]){
+      indexMax[i]=indexMax[i]-1;
+    }  
+    delete [] bins;
+  }
+  
+  Float_t valnum=0;
+  Float_t valden=0;
+  for(Int_t i=0;i<fNDim;i++){
+    for (Int_t j=0;j<fNVar;j++)index[j]=GetBinIndex(j,i);
+    Bool_t isIn=kTRUE;
+    for (Int_t j=0;j<fNVar;j++){
+      if(!(index[j]>=indexMin[j] && index[j]<=indexMax[j]))isIn=kFALSE;   
+    }
+    if(isIn){
+      valnum+=fContainer->GetGrid(fSelNum)->GetElement(i);
+      valden+=fContainer->GetGrid(fSelDen)->GetElement(i);
+    }
+  } 
+  delete [] index;
+  delete [] indexMin;
+  delete [] indexMax;
+  if(valden>0)val=valnum/valden;
+  AliInfo(Form(" the Average Efficiency = %f ",val)); 
+  return val;
+} 
+//____________________________________________________________________
+void AliCFEffGrid::Copy(TObject& eff) const
+{
+  //
+  // copy function
+  //
+  Copy(eff);
+  AliCFEffGrid& target = (AliCFEffGrid &) eff;
+  
+  target.fSelNum=fSelNum; 
+  target.fSelDen=fSelDen; 
+  if(fContainer)
+    target.fContainer=fContainer;
+}
+//___________________________________________________________________
+TH1F *AliCFEffGrid::Project(Int_t ivar) const
+{
+  //
+  // Make a 1D projection along variable ivar 
+  //
+  TH1F *proj1D=0;
+  Int_t nbins =fNVarBins[ivar];
+  Float_t *bins = new Float_t[nbins+1];    
+  for(Int_t ibin =0;ibin<nbins+1;ibin++){
+    bins[ibin] = fVarBinLimits[ibin+fOffset[ivar]];
+  }
+  
+  char pname[30];
+  sprintf(pname,"%s%s%i%i%s%i",GetName(),"_SelStep",fSelNum,fSelDen,"_proj1D_var", ivar);
+  char htitle[30];
+  sprintf(htitle,"%s%s%i%i%s%i",GetName(),"_SelStep",fSelNum,fSelDen,"_proj1D_var", ivar);
+  
+  if(!proj1D){
+    proj1D =new TH1F(pname,htitle, nbins, bins);
+  }  
+  
+  proj1D->Divide(fContainer->GetGrid(fSelNum)->Project(ivar),fContainer->GetGrid(fSelDen)->Project(ivar),1.,1.,"B");
+  
+  delete [] bins; 
+  return proj1D;
+} 
+//___________________________________________________________________
+TH2F *AliCFEffGrid::Project(Int_t ivar1,Int_t ivar2) const
+{
+  //
+  // Make a 2D projection along variable ivar1,ivar2 
+  //
+  TH2F *proj2D=0;
+
+  Int_t nbins1 =fNVarBins[ivar1];
+  Float_t *bins1 = new Float_t[nbins1+1];    
+  Int_t nbins2 =fNVarBins[ivar2];
+  Float_t *bins2 = new Float_t[nbins2+1];    
+  for(Int_t ibin1 =0;ibin1<nbins1+1;ibin1++){
+    bins1[ibin1] = fVarBinLimits[ibin1+fOffset[ivar1]];
+  }
+  for(Int_t ibin2 =0;ibin2<nbins2+1;ibin2++){
+    bins2[ibin2] = fVarBinLimits[ibin2+fOffset[ivar2]];
+  }
+  
+  char pname[30];
+  sprintf(pname,"%s%s%i%i%s%i%i",GetName(),"_SelStep",fSelNum,fSelDen,"_proj2D_var", ivar1,ivar2);
+  char htitle[30];
+  sprintf(htitle,"%s%s%i%i%s%i%i",GetName(),"_SelStep",fSelNum,fSelDen,"_proj2D_var",ivar1,ivar2);
+  
+  if(!proj2D){
+    proj2D =new TH2F(pname,htitle, nbins1,bins1,nbins2,bins2);
+  }  
+  
+  proj2D->Divide(fContainer->GetGrid(fSelNum)->Project(ivar1,ivar2),fContainer->GetGrid(fSelDen)->Project(ivar1,ivar2),1.,1.,"B");
+  
+  delete [] bins1;
+  delete [] bins2; 
+  return proj2D;
+} 
+//___________________________________________________________________
+TH3F *AliCFEffGrid::Project(Int_t ivar1, Int_t ivar2, Int_t ivar3) const
+{
+  //
+  // Make a 3D projection along variable ivar1,ivar2,ivar3 
+  //
+
+  TH3F *proj3D=0;
+
+  Int_t nbins1 =fNVarBins[ivar1];
+  Int_t nbins2 =fNVarBins[ivar2];
+  Int_t nbins3 =fNVarBins[ivar3];
+  
+  Float_t *bins1 = new Float_t[nbins1+1];         
+  Float_t *bins2 = new Float_t[nbins2+1];     
+  Float_t *bins3 = new Float_t[nbins3+1];     
+  
+  for(Int_t ibin =0;ibin<nbins1+1;ibin++){
+    bins1[ibin] = fVarBinLimits[ibin+fOffset[ivar1]];
+  }
+  for(Int_t ibin =0;ibin<nbins2+1;ibin++){
+    bins2[ibin] = fVarBinLimits[ibin+fOffset[ivar2]];
+  }
+  for(Int_t ibin =0;ibin<nbins3+1;ibin++){
+    bins3[ibin] = fVarBinLimits[ibin+fOffset[ivar3]];
+  }
+  
+  char pname[30];
+  sprintf(pname,"%s%s%i%i%s%i%i%i",GetName(),"_SelStep",fSelNum,fSelDen,"_proj3D_var",ivar1,ivar2,ivar3);
+  char htitle[30];
+  sprintf(htitle,"%s%s%i%i%s%i%i%i",GetName(),"_SelStep",fSelNum,fSelDen,"_proj3D_var",ivar1,ivar2,ivar3);
+   
+  
+  if(!proj3D){
+    proj3D =new TH3F(pname,htitle, nbins1, bins1,nbins2,bins2,nbins3,bins3);
+  }  
+  
+  proj3D->Divide(fContainer->GetGrid(fSelNum)->Project(ivar1,ivar2,ivar3),fContainer->GetGrid(fSelDen)->Project(ivar1,ivar2,ivar3),1.,1.,"B");
+  
+  delete [] bins1;
+  delete [] bins2;
+  delete [] bins3; 
+  
+  return proj3D;
+} 
diff --git a/CORRFW/AliCFEffGrid.h b/CORRFW/AliCFEffGrid.h
new file mode 100644 (file)
index 0000000..d1a6786
--- /dev/null
@@ -0,0 +1,58 @@
+#ifndef ALICFEFFGRID_H
+#define ALICFEFFGRID_H
+
+/* $Id$ */
+
+//--------------------------------------------------------------------//
+//                                                                    //
+// AliCFEffGrid Class                                              //
+// Class to handle efficiency grids                                   // 
+//                                                                    //
+//--------------------------------------------------------------------//
+
+#include "AliCFGrid.h"
+#include "AliCFContainer.h"
+#include <TNamed.h>
+#include <TTree.h>
+#include <TH1F.h>
+#include <TH2F.h>
+#include <TH3F.h>
+
+class AliCFEffGrid : public AliCFGrid
+{
+ public:
+  AliCFEffGrid();
+  AliCFEffGrid(const Char_t* name,const Char_t* title, const Int_t nVarIn, const Int_t* nBinIn, const Float_t  *binLimitsIn=0);
+  AliCFEffGrid(const Char_t* name,const Char_t* title,const AliCFContainer &c);
+  AliCFEffGrid(const AliCFEffGrid& eff);
+  
+  virtual ~AliCFEffGrid();
+  AliCFEffGrid& operator=(const AliCFEffGrid& eff);
+  virtual Float_t GetAverage() const ;
+  virtual Float_t GetAverage(Float_t *varMin,Float_t *varMax) const ;
+  virtual Int_t GetSelNumStep() const {return fSelNum;};
+  virtual Int_t GetSelDenStep() const {return fSelDen;};
+  virtual TH1F* Project( Int_t ivar) const;
+  virtual TH2F* Project( Int_t ivar1, Int_t ivar2) const;
+  virtual TH3F* Project( Int_t ivar1, Int_t ivar2,Int_t ivar3) const;
+
+  //Efficiency calculation
+  virtual void  CalculateEfficiency(Int_t istep1, Int_t istep2);
+  virtual const AliCFGrid*  GetNum() {return fContainer->GetGrid(fSelNum);};
+  virtual const AliCFGrid*  GetDen() {return fContainer->GetGrid(fSelDen);};
+  virtual void  SetContainer(const AliCFContainer &c) {fContainer=&c;};
+
+  //basic operations
+  virtual void Copy(TObject& eff) const;
+  
+ private:
+  const    AliCFContainer *fContainer; //pointer to the input AliContainer
+  Int_t fSelNum; //numerator selection step
+  Int_t fSelDen; //denominator selection step
+  
+  ClassDef(AliCFEffGrid,1);
+};
+    
+#endif
+
diff --git a/CORRFW/AliCFEventClassCuts.cxx b/CORRFW/AliCFEventClassCuts.cxx
new file mode 100644 (file)
index 0000000..f770359
--- /dev/null
@@ -0,0 +1,580 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+// To select on the Event Class: look at the Trigger mask and the ZDC info.
+// Only pp-running trigger types implemented so far
+// handles all masks for the trigger description
+// and some general combinations like MB1,MB2,MB3
+// The argument of IsSelected member function (passed object) is cast into 
+// an AliVEvent, but cuts have a true meaning only for AliESD(AOD)Event 
+// type objects.
+// The class derives from AliCFCutBase
+// Author:S.Arcelli Silvia.Arcelli@cern.ch
+//
+//
+#include "TH1F.h"
+#include "TList.h"
+#include "AliLog.h"
+#include "TMath.h"
+#include "AliVEvent.h"
+#include "AliCFEventClassCuts.h"
+ClassImp(AliCFEventClassCuts) 
+//____________________________________________________________________
+AliCFEventClassCuts::AliCFEventClassCuts() : 
+  AliCFCutBase(),
+  fTriggerType(0),
+  fTriggerAND(kFALSE),
+  fZDCN1EnergyMin(-1.e99),  
+  fZDCP1EnergyMin(-1.e99),  
+  fZDCN2EnergyMin(-1.e99),  
+  fZDCP2EnergyMin(-1.e99),  
+  fZDCEM1EnergyMin(-1.e99),  
+  fZDCEM2EnergyMin(-1.e99),  
+  fZDCN1EnergyMax(1.e99),  
+  fZDCP1EnergyMax(1.e99),  
+  fZDCN2EnergyMax(1.e99),  
+  fZDCP2EnergyMax(1.e99),  
+  fZDCEM1EnergyMax(1.e99),  
+  fZDCEM2EnergyMax(1.e99),
+  fBitMap(0x0),
+  fhNBinsTrigger(0),
+  fhBinLimTrigger(0),
+  fhNBinsZDCEnN1(0),
+  fhBinLimZDCEnN1(0),
+  fhNBinsZDCEnP1(0),
+  fhBinLimZDCEnP1(0),
+  fhNBinsZDCEnN2(0),
+  fhBinLimZDCEnN2(0),
+  fhNBinsZDCEnP2(0),
+  fhBinLimZDCEnP2(0),
+  fhNBinsZDCEnEM1(0),
+  fhBinLimZDCEnEM1(0),
+  fhNBinsZDCEnEM2(0),
+  fhBinLimZDCEnEM2(0)
+{
+  //
+  //ctor
+  //  
+
+  fBitMap=new TBits(0);
+  Initialise();
+}
+//____________________________________________________________________
+AliCFEventClassCuts::AliCFEventClassCuts(Char_t* name, Char_t* title) : 
+  AliCFCutBase(name,title),
+  fTriggerType(0),
+  fTriggerAND(kFALSE),
+  fZDCN1EnergyMin(-1.e99),  
+  fZDCP1EnergyMin(-1.e99),  
+  fZDCN2EnergyMin(-1.e99),  
+  fZDCP2EnergyMin(-1.e99),  
+  fZDCEM1EnergyMin(-1.e99),  
+  fZDCEM2EnergyMin(-1.e99),  
+  fZDCN1EnergyMax(1.e99),  
+  fZDCP1EnergyMax(1.e99),  
+  fZDCN2EnergyMax(1.e99),  
+  fZDCP2EnergyMax(1.e99),  
+  fZDCEM1EnergyMax(1.e99),  
+  fZDCEM2EnergyMax(1.e99), 
+  fBitMap(0x0),
+  fhNBinsTrigger(0),
+  fhBinLimTrigger(0),
+  fhNBinsZDCEnN1(0),
+  fhBinLimZDCEnN1(0),
+  fhNBinsZDCEnP1(0),
+  fhBinLimZDCEnP1(0),
+  fhNBinsZDCEnN2(0),
+  fhBinLimZDCEnN2(0),
+  fhNBinsZDCEnP2(0),
+  fhBinLimZDCEnP2(0),
+  fhNBinsZDCEnEM1(0),
+  fhBinLimZDCEnEM1(0),
+  fhNBinsZDCEnEM2(0),
+  fhBinLimZDCEnEM2(0)
+{
+  //
+  //ctor
+  //
+  fBitMap=new TBits(0);
+  Initialise();
+ }
+//____________________________________________________________________
+AliCFEventClassCuts::AliCFEventClassCuts(const AliCFEventClassCuts& c) : 
+  AliCFCutBase(c),
+  fTriggerType(c.fTriggerType),
+  fTriggerAND(c.fTriggerAND),
+  fZDCN1EnergyMin(c.fZDCN1EnergyMin),  
+  fZDCP1EnergyMin(c.fZDCP1EnergyMin),  
+  fZDCN2EnergyMin(c.fZDCN2EnergyMin),  
+  fZDCP2EnergyMin(c.fZDCP2EnergyMin),  
+  fZDCEM1EnergyMin(c.fZDCEM1EnergyMin),  
+  fZDCEM2EnergyMin(c.fZDCEM2EnergyMin),  
+  fZDCN1EnergyMax(c.fZDCN1EnergyMax),  
+  fZDCP1EnergyMax(c.fZDCP1EnergyMax),  
+  fZDCN2EnergyMax(c.fZDCN2EnergyMax),  
+  fZDCP2EnergyMax(c.fZDCP2EnergyMax),  
+  fZDCEM1EnergyMax(c.fZDCEM1EnergyMax), 
+  fZDCEM2EnergyMax(c.fZDCEM2EnergyMax),
+  fBitMap(c.fBitMap),
+  fhNBinsTrigger(c.fhNBinsTrigger),
+  fhBinLimTrigger(c.fhBinLimTrigger ),
+  fhNBinsZDCEnN1(c.fhNBinsZDCEnN1),
+  fhBinLimZDCEnN1(c.fhBinLimZDCEnN1),
+  fhNBinsZDCEnP1(c.fhNBinsZDCEnP1),
+  fhBinLimZDCEnP1(c.fhBinLimZDCEnP1),
+  fhNBinsZDCEnN2(c.fhNBinsZDCEnN2),
+  fhBinLimZDCEnN2(c.fhBinLimZDCEnN2),
+  fhNBinsZDCEnP2(c.fhNBinsZDCEnP2),
+  fhBinLimZDCEnP2(c.fhBinLimZDCEnP2),
+  fhNBinsZDCEnEM1(c.fhNBinsZDCEnEM1),
+  fhBinLimZDCEnEM1(c.fhBinLimZDCEnEM1),
+  fhNBinsZDCEnEM2(c.fhNBinsZDCEnEM2),
+  fhBinLimZDCEnEM2(c.fhBinLimZDCEnEM2)
+
+{
+  //
+  //copy constructor
+  //
+}
+//____________________________________________________________________
+AliCFEventClassCuts& AliCFEventClassCuts::operator=(const AliCFEventClassCuts& c){
+  //
+  // Assignment operator
+  //
+  if (this != &c) {
+    AliCFCutBase::operator=(c) ;
+    fTriggerType = c.fTriggerType ;
+    fTriggerAND = c.fTriggerAND ;
+    fZDCN1EnergyMin = c.fZDCN1EnergyMin;  
+    fZDCP1EnergyMin = c.fZDCP1EnergyMin;  
+    fZDCN2EnergyMin = c.fZDCN2EnergyMin;  
+    fZDCP2EnergyMin = c.fZDCP2EnergyMin;  
+    fZDCEM1EnergyMin = c.fZDCEM1EnergyMin;  
+    fZDCEM2EnergyMin = c.fZDCEM2EnergyMin;  
+    fZDCN1EnergyMax = c.fZDCN1EnergyMax;  
+    fZDCP1EnergyMax = c.fZDCP1EnergyMax;  
+    fZDCN2EnergyMax = c.fZDCN2EnergyMax;  
+    fZDCP2EnergyMax = c.fZDCP2EnergyMax;  
+    fZDCEM1EnergyMax = c.fZDCEM1EnergyMax;  
+    fZDCEM2EnergyMax = c.fZDCEM2EnergyMax;  
+    fBitMap          = c.fBitMap;
+    fhNBinsTrigger = c.fhNBinsTrigger;
+    fhBinLimTrigger = c.fhBinLimTrigger ;
+    fhNBinsZDCEnN1 = c.fhNBinsZDCEnN1;
+    fhBinLimZDCEnN1 = c.fhBinLimZDCEnN1;
+    fhNBinsZDCEnP1 = c.fhNBinsZDCEnP1;
+    fhBinLimZDCEnP1 = c.fhBinLimZDCEnP1;
+    fhNBinsZDCEnN2 = c.fhNBinsZDCEnN2;
+    fhBinLimZDCEnN2 = c.fhBinLimZDCEnN2;
+    fhNBinsZDCEnP2 = c.fhNBinsZDCEnP2;
+    fhBinLimZDCEnP2 = c.fhBinLimZDCEnP2;
+    fhNBinsZDCEnEM1 = c.fhNBinsZDCEnEM1;
+    fhBinLimZDCEnEM1 = c.fhBinLimZDCEnEM1;
+    fhNBinsZDCEnEM2 = c.fhNBinsZDCEnEM2;
+    fhBinLimZDCEnEM2 = c.fhBinLimZDCEnEM2;
+  }
+
+
+  for (Int_t i=0; i<c.kNCuts; i++){
+    for (Int_t j=0; j<c.kNStepQA; j++){
+      if(c.fhQA[i][j]) fhQA[i][j] = (TH1F*)c.fhQA[i][j]->Clone();
+    }
+  }
+
+  return *this ;
+}
+
+//____________________________________________________________________
+AliCFEventClassCuts::~AliCFEventClassCuts()
+{
+  //
+  // destructor
+  //
+  for (Int_t i=0; i<kNCuts; i++){
+    for (Int_t j=0; j<kNStepQA; j++){
+      if(fhQA[i][j]) delete fhQA[i][j];
+    }
+  }
+
+  if(fBitMap)delete fBitMap;
+  if(fhBinLimTrigger)delete fhBinLimTrigger;
+  if(fhBinLimZDCEnN1)delete fhBinLimZDCEnN1;
+  if(fhBinLimZDCEnP1)delete fhBinLimZDCEnP1;
+  if(fhBinLimZDCEnN2)delete fhBinLimZDCEnN2;
+  if(fhBinLimZDCEnP2)delete fhBinLimZDCEnP2;
+  if(fhBinLimZDCEnEM1)delete fhBinLimZDCEnEM1;
+  if(fhBinLimZDCEnEM2)delete fhBinLimZDCEnEM2;
+
+}
+//__________________________________________________________________________________
+void AliCFEventClassCuts::Init() {
+  //
+  // initialises all histograms and the TList which holds the histograms
+  //
+  if(fIsQAOn)
+    DefineHistograms();
+}
+//__________________________________________________________________________________
+//__________________________________________________________________________________
+void AliCFEventClassCuts::Initialise()
+{
+  //
+  //initialization
+  //
+
+  //
+  // sets pointers to histos to zero
+  //
+
+  for(Int_t i=0; i<kNCuts; i++){
+    for(Int_t j =0; j<kNStepQA; j++){
+      fhQA[i][j]=0x0;
+    }
+  }
+
+  //set default bin number/ranges for QA histograms
+
+  SetHistogramBins(kTrigger,23,-0.5,22.5);
+  SetHistogramBins(kZDCEnergyN1,800,-500,7500);
+  SetHistogramBins(kZDCEnergyP1,800,-500,7500);
+  SetHistogramBins(kZDCEnergyN2,800,-500,7500);
+  SetHistogramBins(kZDCEnergyP2,800,-500,7500);
+  SetHistogramBins(kZDCEnergyEM1,800,-500,7500);
+  SetHistogramBins(kZDCEnergyEM2,800,-500,7500);
+
+}
+//____________________________________________________________________
+Bool_t AliCFEventClassCuts::IsSelected(TObject* obj) {
+  //
+  //Check if the requested cuts are passed
+  //
+
+  TBits* bitmap = SelectionBitMap(obj);
+
+  Bool_t isSelected = kTRUE;
+
+  for (UInt_t icut=0; icut<bitmap->GetNbits();icut++)
+       if(!bitmap->TestBitNumber(icut)) isSelected = kFALSE;
+
+  return isSelected;
+}
+
+//____________________________________________________________________
+TBits *AliCFEventClassCuts::SelectionBitMap(TObject* obj) {
+  //
+  //cut on trigger type (just pp running trigger types implemented so far)
+  //and on the energy observed in the ZDC. The argument is cast into 
+  //an AliVEvent, but has true meaning only for AliESDEvent type objects.
+  //Check if the requested cuts are passed and return a bitmap
+  //
+
+  for(Int_t j=0;j<kNCuts;j++)fBitMap->SetBitNumber(j,kFALSE);
+  AliVEvent* esd = dynamic_cast<AliVEvent *>(obj);
+  if (!esd ) return fBitMap ;
+
+
+  //now start checking the cuts
+  //first assume the event will be accepted: 
+  for(Int_t j=0;j<kNCuts;j++)fBitMap->SetBitNumber(j,kTRUE);
+
+
+  //Check the trigger:
+
+  //look at the Trigger mask in current event
+  TBits *triggerBitMap=new TBits(0);
+  TriggerBitMap(esd,triggerBitMap); 
+  //now compare to what was requested as a Trigger:  
+  if(fTriggerType.GetNbits()>0)fBitMap->SetBitNumber(0,kFALSE); //trigger required, initialize to false
+  for(Int_t j=0;j<kNTriggers+kNTriggersMB;j++){
+    if(fTriggerType.TestBitNumber(j)){
+      if(!fTriggerAND){
+       if(triggerBitMap->TestBitNumber(j) == fTriggerType.TestBitNumber(j)){
+         fBitMap->SetBitNumber(0,kTRUE); 
+
+         break;// @least one requested bit fired, ok
+       }
+      }else{
+       if(!triggerBitMap->TestBitNumber(j)){
+         break;
+       }       
+      }
+    }
+  }
+  
+  delete triggerBitMap;
+  //Then, cut on the energy observed in the ZDC 
+  
+  if( esd->GetZDCN1Energy()<fZDCN1EnergyMin || esd->GetZDCN1Energy()>fZDCN1EnergyMax)fBitMap->SetBitNumber(1,kFALSE); 
+  if( esd->GetZDCP1Energy()<fZDCP1EnergyMin || esd->GetZDCP1Energy()>fZDCP1EnergyMax)fBitMap->SetBitNumber(2,kFALSE); 
+  if( esd->GetZDCN2Energy()<fZDCN2EnergyMin || esd->GetZDCN2Energy()>fZDCN2EnergyMax)fBitMap->SetBitNumber(3,kFALSE);
+  if( esd->GetZDCP2Energy()<fZDCP2EnergyMin || esd->GetZDCP2Energy()>fZDCP2EnergyMax)fBitMap->SetBitNumber(4,kFALSE); 
+  if( esd->GetZDCEMEnergy(0)<fZDCEM1EnergyMin || esd->GetZDCEMEnergy(0)>fZDCEM1EnergyMax)fBitMap->SetBitNumber(5,kFALSE); 
+  if( esd->GetZDCEMEnergy(1)<fZDCEM2EnergyMin || esd->GetZDCEMEnergy(1)>fZDCEM2EnergyMax)fBitMap->SetBitNumber(6,kFALSE); 
+  return fBitMap;
+
+}
+//_____________________________________________________________________________
+Bool_t AliCFEventClassCuts::IsTriggered(AliVEvent* ev, TriggerType trigger) {
+  //
+  //look at the Trigger mask in current event
+  TBits *triggerBitMap=new TBits(0);
+  TriggerBitMap(ev,triggerBitMap); 
+  Bool_t isTriggered=kFALSE;  
+  if(triggerBitMap->TestBitNumber(trigger))isTriggered=kTRUE;
+  delete triggerBitMap;
+  return isTriggered;
+
+}
+//_____________________________________________________________________________
+void AliCFEventClassCuts::TriggerBitMap(AliVEvent* ev, TBits *bitmapT ) {
+  //
+
+  for(Int_t itrig=0;itrig<kNTriggers+kNTriggersMB;itrig++)bitmapT->SetBitNumber(itrig,kFALSE);
+  if (!ev ) return;
+
+  ULong64_t triggerMask = ev->GetTriggerMask();
+  //run over the different triggers in the mask, and check which bits have fired    
+  for(Int_t itrig=0;itrig<kNTriggers;itrig++){
+    bitmapT->SetBitNumber(itrig,kFALSE);
+    if (triggerMask&(0x1 <<itrig)){
+      bitmapT->SetBitNumber(itrig,kTRUE);
+    }
+  }
+
+  //Trigger combinations, Minimum bias triggers
+
+  //MB1 case: (GFO || V0OR) && !BG
+  if((bitmapT->TestBitNumber(5) || (bitmapT->TestBitNumber(0) || bitmapT->TestBitNumber(1))) && !bitmapT->TestBitNumber(2)) bitmapT->SetBitNumber(17,kTRUE); 
+  //MB2 case: (GFO && V0OR) && !BG
+  if((bitmapT->TestBitNumber(5) && (bitmapT->TestBitNumber(0) || bitmapT->TestBitNumber(1))) && !bitmapT->TestBitNumber(2)) bitmapT->SetBitNumber(18,kTRUE); 
+
+  //MB3 case : (GFO && V0AND) && !BG
+  if((bitmapT->TestBitNumber(5) && (bitmapT->TestBitNumber(0) && bitmapT->TestBitNumber(1))) && !bitmapT->TestBitNumber(2)) bitmapT->SetBitNumber(19,kTRUE); 
+
+  //MB4 case: (GFO || V0AND) && !BG
+  if((bitmapT->TestBitNumber(5) || (bitmapT->TestBitNumber(0) && bitmapT->TestBitNumber(1))) &&  !bitmapT->TestBitNumber(2)) bitmapT->SetBitNumber(20,kTRUE); 
+
+  //MB5 case:: GFO && !BG
+  if(bitmapT->TestBitNumber(5) && !bitmapT->TestBitNumber(2)) bitmapT->SetBitNumber(21,kTRUE); 
+
+  return;
+} 
+//__________________________________________________________________________________
+void AliCFEventClassCuts::GetBitMap(TObject* obj, TBits* bitmap){
+  //
+  // retrieve the pointer to the bitmap
+  //
+
+  bitmap = SelectionBitMap(obj);
+
+}
+//__________________________________________________________________________________
+void AliCFEventClassCuts::SetHistogramBins(Int_t index, Int_t nbins, Double_t *bins)
+{
+  //
+  // QA histogram axis parameters
+  // variable bin size:user inputs nbins and the vector of bin limits
+  //
+
+  switch(index){
+  case kTrigger:
+    fhNBinsTrigger=nbins;
+    fhBinLimTrigger=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimTrigger[i]=bins[i];
+    break;
+    
+  case kZDCEnergyN1:
+    fhNBinsZDCEnN1=nbins;
+    fhBinLimZDCEnN1=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimZDCEnN1[i]=bins[i];
+    break;
+
+  case kZDCEnergyP1:
+    fhNBinsZDCEnP1=nbins;
+    fhBinLimZDCEnP1=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimZDCEnP1[i]=bins[i];
+    break;
+
+  case kZDCEnergyN2:
+    fhNBinsZDCEnN2=nbins;
+    fhBinLimZDCEnN2=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimZDCEnN2[i]=bins[i];
+    break;
+
+  case kZDCEnergyP2:
+    fhNBinsZDCEnP2=nbins;
+    fhBinLimZDCEnP2=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimZDCEnP2[i]=bins[i];
+    break;
+
+  case kZDCEnergyEM1:
+    fhNBinsZDCEnEM1=nbins;
+    fhBinLimZDCEnEM1=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimZDCEnEM1[i]=bins[i];
+    break;
+
+  case kZDCEnergyEM2:
+    fhNBinsZDCEnEM2=nbins;
+    fhBinLimZDCEnEM2=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimZDCEnEM2[i]=bins[i];
+    break;
+
+  }
+
+}
+//__________________________________________________________________________________
+void AliCFEventClassCuts::SetHistogramBins(Int_t index, Int_t nbins, Double_t xmin, Double_t xmax)
+{
+  //
+  // QA histogram axis parameters
+  // fixed bin size: user inputs nbins, xmin and xmax
+  //
+  switch(index){
+  case kTrigger:
+    fhNBinsTrigger=nbins;
+    fhBinLimTrigger=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimTrigger[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kZDCEnergyN1:
+    fhNBinsZDCEnN1=nbins;
+    fhBinLimZDCEnN1=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimZDCEnN1[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+
+  case kZDCEnergyP1:
+    fhNBinsZDCEnP1=nbins;
+    fhBinLimZDCEnP1=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimZDCEnP1[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+
+  case kZDCEnergyN2:
+    fhNBinsZDCEnN2=nbins;
+    fhBinLimZDCEnN2=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimZDCEnN2[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+
+  case kZDCEnergyP2:
+    fhNBinsZDCEnP2=nbins;
+    fhBinLimZDCEnP2=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimZDCEnP2[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+
+  case kZDCEnergyEM1:
+    fhNBinsZDCEnEM1=nbins;
+    fhBinLimZDCEnEM1=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimZDCEnEM1[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+
+  case kZDCEnergyEM2:
+    fhNBinsZDCEnEM2=nbins;
+    fhBinLimZDCEnEM2=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimZDCEnEM2[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+  }
+}
+//__________________________________________________________________________________
+ void AliCFEventClassCuts::DefineHistograms() {
+  //
+  // histograms for cut variables
+  //
+  Int_t color = 2;
+
+  if(!fIsQAOn) {
+    AliInfo(Form("Nn QA histos requested, Please first set the QA flag on!"));
+    return;
+  }  
+  
+  // book QA histograms
+
+  Char_t str[256];
+  for (Int_t i=0; i<kNStepQA; i++) {
+    if (i==0) sprintf(str," ");
+    else sprintf(str,"_cut");
+
+    fhQA[kTrigger][i]  = new  TH1F(Form("%s_TriggerBits%s",GetName(),str),                     "",fhNBinsTrigger,fhBinLimTrigger);
+    fhQA[kZDCEnergyN1][i]      = new  TH1F(Form("%s_ZDC_Energy_N1%s",GetName(),str),           "",fhNBinsZDCEnN1,fhBinLimZDCEnN1);
+    fhQA[kZDCEnergyP1][i]      = new  TH1F(Form("%s_ZDC_Energy_P1%s",GetName(),str),           "",fhNBinsZDCEnP1,fhBinLimZDCEnP1);
+    fhQA[kZDCEnergyN2][i]      = new  TH1F(Form("%s_ZDC_Energy_N2%s",GetName(),str),           "",fhNBinsZDCEnN2,fhBinLimZDCEnN2);
+    fhQA[kZDCEnergyP2][i]      = new  TH1F(Form("%s_ZDC_Energy_P2%s",GetName(),str),           "",fhNBinsZDCEnP2,fhBinLimZDCEnP2);
+    fhQA[kZDCEnergyEM1][i]     = new  TH1F(Form("%s_ZDC_Energy_EM1%s",GetName(),str),          "",fhNBinsZDCEnEM1,fhBinLimZDCEnEM1);
+    fhQA[kZDCEnergyEM2][i]     = new  TH1F(Form("%s_ZDC_Energy_EM2%s",GetName(),str),          "",fhNBinsZDCEnEM2,fhBinLimZDCEnEM2);
+
+
+    fhQA[kTrigger][i]          ->SetXTitle("Trigger Bits");
+    fhQA[kZDCEnergyN1][i]      ->SetXTitle("ZDC Energy N1 (GeV)");
+    fhQA[kZDCEnergyP1][i]      ->SetXTitle("ZDC Energy P1 (GeV)");
+    fhQA[kZDCEnergyN2][i]      ->SetXTitle("ZDC Energy N2 (GeV)");
+    fhQA[kZDCEnergyP2][i]      ->SetXTitle("ZDC Energy P2 (GeV)");
+    fhQA[kZDCEnergyEM1][i]     ->SetXTitle("ZDC Energy EM1 (GeV)");
+    fhQA[kZDCEnergyEM2][i]     ->SetXTitle("ZDC Energy EM2 (GeV)");
+
+  }
+
+  for(Int_t i=0; i<kNCuts; i++) fhQA[i][1]->SetLineColor(color);
+
+}
+//__________________________________________________________________________________
+void AliCFEventClassCuts::FillHistograms(TObject* obj, Bool_t b)
+{
+  //
+  // fill the QA histograms
+  //
+  if(!fIsQAOn) return;
+
+  // cast TObject into VParticle
+  AliVEvent* esd = dynamic_cast<AliVEvent *>(obj);
+  if (!esd ) return  ;
+
+  // index = 0: fill histograms before cuts
+  // index = 1: fill histograms after cuts
+  Int_t index = -1;
+  index = ((b) ? 1 : 0);
+
+
+  //look at the Trigger mask in current event
+  TBits *triggerBitMap=new TBits(0);
+  TriggerBitMap(esd, triggerBitMap); 
+  
+  //trigger Mask
+  for(Int_t itrig=0;itrig<kNTriggers+kNTriggersMB;itrig++){
+    if(triggerBitMap->TestBitNumber(itrig)){
+      fhQA[kTrigger][index]->Fill(itrig);
+    }
+  }   
+
+  delete triggerBitMap;
+
+  //ZDC Quantities
+  fhQA[kZDCEnergyN1][index]->Fill(esd->GetZDCN1Energy());
+  fhQA[kZDCEnergyP1][index]->Fill(esd->GetZDCP1Energy());
+  fhQA[kZDCEnergyN2][index]->Fill(esd->GetZDCN2Energy());
+  fhQA[kZDCEnergyP2][index]->Fill(esd->GetZDCP2Energy());
+  fhQA[kZDCEnergyEM1][index]->Fill(esd->GetZDCEMEnergy(0));
+  fhQA[kZDCEnergyEM2][index]->Fill(esd->GetZDCEMEnergy(1));
+
+}
+//__________________________________________________________________________________
+void AliCFEventClassCuts::AddQAHistograms(TList *list) const {
+  //
+  // saves the histograms in a TList
+  //
+  if(!fIsQAOn) return;  
+
+  for (Int_t j=0; j<kNStepQA; j++) {
+    for(Int_t i=0; i<kNCuts; i++)
+       list->Add(fhQA[i][j]);
+  }
+}
diff --git a/CORRFW/AliCFEventClassCuts.h b/CORRFW/AliCFEventClassCuts.h
new file mode 100644 (file)
index 0000000..fcdd4c3
--- /dev/null
@@ -0,0 +1,158 @@
+#ifndef ALICFEVENTCLASSCUTS_H
+#define ALICFEVENTCLASSCUTS_H
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+// Cut on the type of Event Class: for the moment 
+// the Trigger (pp running configurations) 
+// and requirements on the energy observed in the ZDC are implemented
+// The argument of IsSelected member function (passed object) is cast into 
+// an AliVEvent, although conditions are meaningful only for AliESD(AOD)Event 
+// type objects.
+// The class derives from AliCFCutBase
+// Author:S.Arcelli Silvia.Arcelli@cern.ch
+
+#include "AliCFCutBase.h"
+#include "TBits.h"
+class TH1F;
+class AliVEvent;
+//____________________________________________________________________________
+class AliCFEventClassCuts: public AliCFCutBase 
+{
+ public :
+  AliCFEventClassCuts() ;
+  AliCFEventClassCuts(Char_t* name, Char_t* title) ;
+  AliCFEventClassCuts(const AliCFEventClassCuts& c) ;
+  AliCFEventClassCuts& operator=(const AliCFEventClassCuts& c) ;
+  ~AliCFEventClassCuts();
+  Bool_t IsSelected(TObject* obj);
+  void Init();
+  void GetBitMap(TObject *obj,  TBits *bitmap);
+  void AddQAHistograms(TList *list) const;
+
+  //Association to The Trigger bits in the mask. 
+  //They correspond to the PP running descriptor as in 
+  //STEER/createTriggerDescriptor_pp.C plus five MB Trigger combinations
+  enum TriggerType { 
+    kVZEROLeft=0,kVZERORight,kVZEROBeamGas,
+    kSTARTAL0,kSTARTCL0,
+    kITSSPDGFOL0,kITSSPDHMultL0,
+    kMUSingleLPtL0,kMUUnlikeLPtL0,kMUUnlikeHPtL0,kMULikeLPtL0,kMULikeHPtL0,
+    kMB,kTOFMB,
+    kMUSingleMB,kMUUnLikeLPtMB,kMULikeLPtMB,
+    kMB1,kMB2,kMB3,kMB4,kMB5
+  }; 
+
+  
+  enum{kTrigger=0,
+        kZDCEnergyN1,
+        kZDCEnergyP1,
+        kZDCEnergyN2,
+        kZDCEnergyP2,
+        kZDCEnergyEM1,
+        kZDCEnergyEM2,
+        kNTriggers=17,
+        kNTriggersMB=5,
+        kNCuts=7,
+         kNStepQA=2
+        };
+
+  
+//static checker for trigger bits
+  static Bool_t IsTriggered(AliVEvent *ev, TriggerType trigger=kMB1); 
+
+  void   SetTriggerType(TriggerType trigger=kMB1) { fTriggerType.SetBitNumber(trigger,kTRUE);} // Set requested trigger bits
+  TBits  GetTriggerType() const { return fTriggerType;} // get Triggers bits which were requested
+  void  SetTriggersInAND( Bool_t flag){fTriggerAND=flag;} // request Trigger bits in .AND.
+
+  void  SetZDCN1EnergyCut(Double_t min,Double_t max){fZDCN1EnergyMin=min; fZDCN1EnergyMax=max;} // ZDC energy cuts
+  void  SetZDCN2EnergyCut(Double_t min,Double_t max){fZDCN2EnergyMin=min; fZDCN2EnergyMax=max;} // ZDC energy cuts
+  void  SetZDCP1EnergyCut(Double_t min,Double_t max){fZDCP1EnergyMin=min; fZDCP1EnergyMax=max;} // ZDC energy cuts
+  void  SetZDCP2EnergyCut(Double_t min,Double_t max){fZDCP2EnergyMin=min; fZDCP2EnergyMax=max;} // ZDC energy cuts  
+  void  SetZDCEM1EnergyCut(Double_t min,Double_t max){fZDCEM1EnergyMin=min; fZDCEM1EnergyMax=max;} // ZDC energy cuts
+  void  SetZDCEM2EnergyCut(Double_t min,Double_t max){fZDCEM2EnergyMin=min; fZDCEM2EnergyMax=max;} // ZDC energy cuts
+
+  Double_t  GetZDCN1EnergyCutMin() const {return fZDCN1EnergyMin;};//ZDC N1 energy min
+  Double_t  GetZDCN2EnergyCutMin() const {return fZDCN2EnergyMin;};//ZDC N2 Emin
+  Double_t  GetZDCP1EnergyCutMin() const {return fZDCP1EnergyMin;};//ZDC P1 Emin
+  Double_t  GetZDCP2EnergyCutMin() const {return fZDCP2EnergyMin;};//ZDC P2 Emin
+  Double_t  GetZDCEM1EnergyCutMin() const {return fZDCEM1EnergyMin;};//ZDC EM1 Emin
+  Double_t  GetZDCEM2EnergyCutMin() const {return fZDCEM2EnergyMin;};//ZDC EM2 Emin
+
+  Double_t  GetZDCN1EnergyCutMax() const {return fZDCN1EnergyMax;};//ZDC N1 Emax
+  Double_t  GetZDCN2EnergyCutMax() const {return fZDCN2EnergyMax;};//ZDC N2 Emax
+  Double_t  GetZDCP1EnergyCutMax() const {return fZDCP1EnergyMax;};//ZDC P1 Emax
+  Double_t  GetZDCP2EnergyCutMax() const {return fZDCP2EnergyMax;};//ZDC P2 Emax
+  Double_t  GetZDCEM1EnergyCutMax() const {return fZDCEM1EnergyMax;};//ZDC EM1 Emax
+  Double_t  GetZDCEM2EnergyCutMax() const {return fZDCEM2EnergyMax;};//ZDC EM2 Emax
+
+
+  // QA histograms
+  void FillHistogramsBeforeCuts(TObject* obj) {return FillHistograms(obj,kFALSE);}
+  void FillHistogramsAfterCuts(TObject* obj)  {return FillHistograms(obj,kTRUE);}
+  // QA histogram setter
+  // please use indices from the enumeration below
+  void SetHistogramBins(Int_t index, Int_t nbins, Double_t *bins);
+  void SetHistogramBins(Int_t index, Int_t nbins, Double_t xmin, Double_t xmax);
+
+ private:
+  TBits* SelectionBitMap(TObject* obj);
+  static void TriggerBitMap(AliVEvent* ev,TBits *bitmapT);
+  void DefineHistograms();             // books histograms and TList
+  void Initialise();                   // sets everything to 0
+  void FillHistograms(TObject* obj, Bool_t b);
+
+  TBits fTriggerType ; //The type of trigger to be checked
+  Bool_t fTriggerAND; //Flag to ak for .AND of all the requested trigger bits (.or.is default)
+  Double_t fZDCN1EnergyMin;  //Min Energy in ZDCN1
+  Double_t fZDCP1EnergyMin;  //Min Energy in ZDCP1
+  Double_t fZDCN2EnergyMin;  //Min Energy in ZDCN2
+  Double_t fZDCP2EnergyMin;  //Min Energy in ZDCP2
+  Double_t fZDCEM1EnergyMin; //Min Energy in ZDCEM1
+  Double_t fZDCEM2EnergyMin; //Min Energy in ZDCEM2
+  Double_t fZDCN1EnergyMax;  //Max Energy in ZDCN1
+  Double_t fZDCP1EnergyMax;  //Max Energy in ZDCP1
+  Double_t fZDCN2EnergyMax;  //Max Energy in ZDCN2
+  Double_t fZDCP2EnergyMax;  //Max Energy in ZDCP2
+  Double_t fZDCEM1EnergyMax; //Max Energy in ZDCEM1
+  Double_t fZDCEM2EnergyMax; //Max Energy in ZDCEM2
+
+  TBits *fBitMap ; //cut mask
+  TH1F* fhQA[kNCuts][kNStepQA];                // QA Histograms
+  //QA Histogram parameters
+
+  Int_t fhNBinsTrigger;//size of array of bin limits, Trigger Mask
+  Double_t *fhBinLimTrigger;//[fhNBinsTrigger] bin limits, Trigger Mask
+
+  Int_t fhNBinsZDCEnN1;//size of array of bin limits, Energy in ZDC N1
+  Double_t *fhBinLimZDCEnN1;//[fhNBinsZDCEnN1] bin limits, Energy in ZDC N1
+
+  Int_t fhNBinsZDCEnP1;//size of array of bin limits, Energy in ZDC P1
+  Double_t *fhBinLimZDCEnP1;//[fhNBinsZDCEnP1] bin limits, Energy in ZDC P1
+
+  Int_t fhNBinsZDCEnN2;//size of array of bin limits, Energy in ZDC N2
+  Double_t *fhBinLimZDCEnN2;//[fhNBinsZDCEnN2] bin limits, Energy in ZDC N2
+
+  Int_t fhNBinsZDCEnP2;//size of array of bin limits, Energy in ZDC P2
+  Double_t *fhBinLimZDCEnP2;//[fhNBinsZDCEnP2] bin limits, Energy in ZDC P2
+
+  Int_t fhNBinsZDCEnEM1;//size of array of bin limits, Energy in ZDC EM1
+  Double_t *fhBinLimZDCEnEM1;//[fhNBinsZDCEnEM1] bin limits, Energy in ZDC EM1
+
+  Int_t fhNBinsZDCEnEM2;//size of array of bin limits, Energy in ZDC EM2
+  Double_t *fhBinLimZDCEnEM2;//[fhNBinsZDCEnEM1] bin limits, Energy in ZDC EM2
+  ClassDef(AliCFEventClassCuts,1);
+};
+#endif
diff --git a/CORRFW/AliCFEventGenCuts.cxx b/CORRFW/AliCFEventGenCuts.cxx
new file mode 100644 (file)
index 0000000..e03e321
--- /dev/null
@@ -0,0 +1,286 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+// Cut on the Event at generator level: for the moment just 
+// the requirements on the MB process type, number of tracks and on 
+// the 3-D vertex position are implemented
+// The argument of IsSelected member function (passed object) is cast into 
+// an AliMCEvent. In the future may be modified to use AliVEvent interface
+// and include more cut variables.
+// The class derives from AliCFCutBase
+// Author:S.Arcelli Silvia.Arcelli@cern.ch
+
+#include "TBits.h"
+#include "TList.h"
+#include "AliLog.h"
+#include "AliMCEvent.h"
+#include <AliGenEventHeader.h>
+#include <AliGenPythiaEventHeader.h>
+#include <AliGenCocktailEventHeader.h>
+#include "AliCFEventGenCuts.h"
+
+ClassImp(AliCFEventGenCuts) 
+//____________________________________________________________________
+AliCFEventGenCuts::AliCFEventGenCuts() : 
+  AliCFCutBase(),
+  fMBProcessType(-1),
+  fNTracksMin(-1),
+  fNTracksMax(100000),
+  fRequireVtxCuts(kFALSE),
+  fVtxXMax(1.e99),
+  fVtxYMax(1.e99),
+  fVtxZMax(1.e99),
+  fVtxXMin(-1.e99),
+  fVtxYMin(-1.e99),
+  fVtxZMin(-1.e99),
+  fBitMap(0x0)
+{
+  //
+  //ctor
+  //
+  fBitMap=new TBits(0);
+}
+//____________________________________________________________________
+AliCFEventGenCuts::AliCFEventGenCuts(Char_t* name, Char_t* title) : 
+  AliCFCutBase(name,title),
+  fMBProcessType(-1),
+  fNTracksMin(-1),
+  fNTracksMax(100000),
+  fRequireVtxCuts(kFALSE),
+  fVtxXMax(1.e99),
+  fVtxYMax(1.e99),
+  fVtxZMax(1.e99),
+  fVtxXMin(-1.e99),
+  fVtxYMin(-1.e99),
+  fVtxZMin(-1.e99),
+  fBitMap(0x0)
+ {
+  //
+  //ctor
+  //
+  fBitMap=new TBits(0);
+ }
+//____________________________________________________________________
+AliCFEventGenCuts::AliCFEventGenCuts(const AliCFEventGenCuts& c) : 
+  AliCFCutBase(c),
+  fMBProcessType(c.fMBProcessType),
+  fNTracksMin(c.fNTracksMin),
+  fNTracksMax(c.fNTracksMax),
+  fRequireVtxCuts(c.fRequireVtxCuts),
+  fVtxXMax(c.fVtxXMax),
+  fVtxYMax(c.fVtxYMax),
+  fVtxZMax(c.fVtxZMax),
+  fVtxXMin(c.fVtxXMin),
+  fVtxYMin(c.fVtxYMin),
+  fVtxZMin(c.fVtxZMin),
+  fBitMap(c.fBitMap)
+{
+  //
+  //copy constructor
+  //
+}
+//____________________________________________________________________
+AliCFEventGenCuts::~AliCFEventGenCuts() {
+  //
+  //dtor
+  //
+
+  if(fBitMap)delete fBitMap;
+}
+//____________________________________________________________________
+AliCFEventGenCuts& AliCFEventGenCuts::operator=(const AliCFEventGenCuts& c)
+{
+  //
+  // Assignment operator
+  //
+  if (this != &c) {
+    AliCFCutBase::operator=(c) ;
+    fMBProcessType=c.fMBProcessType;
+    fNTracksMin=c.fNTracksMin;
+    fNTracksMax=c.fNTracksMax;
+    fRequireVtxCuts=c.fRequireVtxCuts;
+    fVtxXMax=c.fVtxXMax;
+    fVtxYMax=c.fVtxYMax;
+    fVtxZMax=c.fVtxZMax;
+    fVtxXMin=c.fVtxXMin;
+    fVtxYMin=c.fVtxYMin;
+    fVtxZMin=c.fVtxZMin;
+    fBitMap=c.fBitMap;
+  }
+  return *this ;
+}
+//____________________________________________________________________
+Bool_t AliCFEventGenCuts::IsSelected(TObject* obj) {
+  //
+  //Check if the requested cuts are passed
+  //
+
+  TBits *bitmap = SelectionBitMap(obj);
+
+  Bool_t isSelected = kTRUE;
+
+  for (UInt_t icut=0; icut<bitmap->GetNbits();icut++)
+       if(!bitmap->TestBitNumber(icut)) isSelected = kFALSE;
+
+  return isSelected;
+
+}
+
+//____________________________________________________________________
+TBits * AliCFEventGenCuts::SelectionBitMap(TObject* obj){
+  //
+  //cut on the MB process type, the number of charged and neutral 
+  //tracks and on the event vertex. So far specific to AliMCEvents
+  //
+
+  //Check if the requested cuts are passed and return a bitmap
+  for(Int_t j=0;j<kNCuts;j++)fBitMap->SetBitNumber(j,kFALSE);
+  AliMCEvent* ev = dynamic_cast<AliMCEvent *>(obj);
+  if ( !ev ) return fBitMap ;
+  AliGenEventHeader*genHeader = ev->GenEventHeader();  
+
+
+  fBitMap->SetBitNumber(0,kTRUE);
+  if(fMBProcessType>-1){
+    Int_t process=MBProcessType(genHeader);
+    if(process==-1){
+      AliInfo(Form(" not a pythia event, not checking on the process type"));
+    }else{
+
+      switch (fMBProcessType)  {
+      case kND:
+       {
+         if (!( process!=92 && process!=93 && process!=94))
+           fBitMap->SetBitNumber(0,kFALSE);
+         break;
+       }
+      case kSD:
+       {
+         if (!( process==92 || process==93))
+           fBitMap->SetBitNumber(0,kFALSE);
+         break;
+       }
+      case kDD:
+       {
+         if (!( process==94))
+           fBitMap->SetBitNumber(0,kFALSE);
+         break;
+       }
+      }
+    }
+  }
+
+
+  //Number of charged+neutral tracks:
+  Int_t nTracks = ev->GetNumberOfTracks();
+  fBitMap->SetBitNumber(1,kTRUE); //assume it is ok...
+  if(nTracks<fNTracksMin || nTracks>fNTracksMax)
+    fBitMap->SetBitNumber(1,kFALSE); 
+
+  //now check the vertex cuts
+  for(Int_t j=2;j<kNCuts;j++)fBitMap->SetBitNumber(j,kTRUE);
+
+  TArrayF vtxPos(3);
+  genHeader->PrimaryVertex(vtxPos);    
+
+  if(fRequireVtxCuts){
+    // Apply the cut
+    if (vtxPos[0]>fVtxXMax || vtxPos[0]<fVtxXMin)
+      fBitMap->SetBitNumber(2,kFALSE); 
+    if (vtxPos[1]>fVtxYMax || vtxPos[1]<fVtxYMin)
+      fBitMap->SetBitNumber(3,kFALSE); 
+    if (vtxPos[2]>fVtxZMax || vtxPos[2]<fVtxZMin)
+      fBitMap->SetBitNumber(4,kFALSE); 
+  }  
+  return fBitMap;
+}
+
+ //______________________________________________________________________
+Bool_t AliCFEventGenCuts::IsMBProcessType(Int_t isel, TObject *obj){
+  //
+  //returns the type of MB process (if pythia events)
+  //
+
+  AliMCEvent* ev = dynamic_cast<AliMCEvent *>(obj);
+  if ( !ev ) return kFALSE ;
+
+  AliGenEventHeader*genHeader = ev->GenEventHeader();  
+
+  Int_t process=MBProcessType(genHeader);
+
+  switch (isel)  {
+  case kND: //Non Diffractive: Actually what is checked is ALL -SD -DD
+    {
+      if ( process!=92 && process!=93 && process!=94)
+       return kTRUE;
+    }
+  case kSD: //Single Diffractive
+    {
+      if ( process==92 || process==93)
+       return kTRUE;
+    }
+  case kDD: //Double Diffractive
+    {
+      if ( process==94)
+       return kTRUE;
+    }
+  }
+
+  return kFALSE;     
+}
+ //_____________________________________________________________________________
+Int_t AliCFEventGenCuts::MBProcessType(AliGenEventHeader *genHeader) {
+
+  //get the MB process type: if we are not dealing with pythia stuff, 
+  //return -1 and we do not apply the cut
+  //
+
+  // can only read pythia headers, either directly or from cocktalil header
+  AliGenPythiaEventHeader* pythiaGenHeader = dynamic_cast<AliGenPythiaEventHeader*>(genHeader);
+
+  if (!pythiaGenHeader) {
+
+    AliGenCocktailEventHeader* genCocktailHeader = dynamic_cast<AliGenCocktailEventHeader*>(genHeader);
+    if (!genCocktailHeader) {
+      return -1;
+    }
+
+    TList* headerList = genCocktailHeader->GetHeaders();
+    if (!headerList) {
+      return -1;
+    }
+
+    for (Int_t i=0; i<headerList->GetEntries(); i++) {
+      pythiaGenHeader = dynamic_cast<AliGenPythiaEventHeader*>(headerList->At(i));
+      if (pythiaGenHeader)
+        break;
+    }
+
+    if (!pythiaGenHeader) {
+      return -1;
+    }
+  }
+  
+  Int_t process=pythiaGenHeader->ProcessType();
+  return process;
+}
+//_____________________________________________________________________________
+void  AliCFEventGenCuts::GetBitMap(TObject* obj, TBits *bitmap){
+  //
+  // retrieve the pointer to the bitmap
+  //
+  bitmap=SelectionBitMap(obj);
+
+}
diff --git a/CORRFW/AliCFEventGenCuts.h b/CORRFW/AliCFEventGenCuts.h
new file mode 100644 (file)
index 0000000..5a8813b
--- /dev/null
@@ -0,0 +1,97 @@
+
+#ifndef ALICFEVENTGENCUTS_H
+#define ALICFEVENTGENCUTS_H
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+// Cut on the Event at generator level: for the moment just
+// the requirements on the MB process type, on the number of charged tracks 
+// and on the vertex 3-D position are implemented
+// The argument of IsSelected member function (passed object) is cast into 
+// an AliMCEvent. In the future may be modified to use AliVEvent interface
+// and to include more cut variables.
+// The class derives from AliCFCutBase
+// Author:S.Arcelli Silvia.Arcelli@cern.ch
+
+
+#include "AliCFCutBase.h"
+#include "AliGenEventHeader.h"
+class TBits;
+class AliEventGenHeader;
+//____________________________________________________________________________
+class AliCFEventGenCuts: public AliCFCutBase 
+{
+ public :
+  AliCFEventGenCuts() ;
+  AliCFEventGenCuts(Char_t* name, Char_t* title) ;
+  AliCFEventGenCuts(const AliCFEventGenCuts& c) ;
+  AliCFEventGenCuts& operator=(const AliCFEventGenCuts& c) ;
+  ~AliCFEventGenCuts();
+  void GetBitMap(TObject *obj, TBits *bitmap);
+  Bool_t IsSelected(TObject* obj);
+  void Init(){;};
+  static Bool_t IsMBProcessType(Int_t isel, TObject *obj);
+
+  //number of embedded cuts
+  enum{kNCuts=5};
+
+  //Label the MB MC processes
+  enum PrType { 
+   kND, kSD, kDD 
+  }; 
+
+  void   SetMBProcessType(PrType process = kND) {fMBProcessType=process;} // cut values setter
+  Int_t  GetMBProcessType()const {return fMBProcessType;} // cut values getter
+
+
+
+  void SetNTracksCut(Int_t xMin=-1, Int_t xMax=1000000) {fNTracksMin=xMin; fNTracksMax=xMax;} // cut values setter
+
+  void SetRequireVtxCuts(Bool_t vtx=kFALSE) {fRequireVtxCuts=vtx;} // cut values setter
+  void SetVertexXCut(Double_t xMin=-1.e99, Double_t xMax=1.e99) { fVtxXMin=xMin; fVtxXMax=xMax;} // cut values setter
+  void SetVertexYCut(Double_t yMin=-1.e99, Double_t yMax=1.e99) { fVtxYMin=yMin; fVtxYMax=yMax;} // cut values setter
+  void SetVertexZCut(Double_t zMin=-1.e99, Double_t zMax=1.e99) { fVtxZMin=zMin; fVtxZMax=zMax;} // cut values setter
+
+  Int_t    GetNTracksMin() const {return fNTracksMin;} // cut values getter
+  Int_t    GetNTracksMax() const {return fNTracksMax;} // cut values getter
+  Bool_t   GetRequireVtxCuts() const {return fRequireVtxCuts;} // cut value getter
+  Double_t GetVertexXMax() const {return fVtxXMax;} // cut values getter
+  Double_t GetVertexYMax() const {return fVtxYMax;} // cut values getter
+  Double_t GetVertexZMax() const {return fVtxZMax;} // cut values getter
+  Double_t GetVertexXMin() const {return fVtxXMin;} // cut values getter
+  Double_t GetVertexYMin() const {return fVtxYMin;} // cut values getter
+  Double_t GetVertexZMin() const {return fVtxZMin;} // cut values getter
+  
+
+ private:
+  TBits * SelectionBitMap(TObject* obj);
+  static Int_t MBProcessType(AliGenEventHeader *genHeader); 
+  
+  Int_t fMBProcessType ; //the type of selected MB process 
+  Int_t fNTracksMin; //minimum number of particles in the event
+  Int_t fNTracksMax; //maximum number of particles in the event
+  Bool_t fRequireVtxCuts ; //The type of trigger to be checked
+  Double_t fVtxXMax ; //X vertex position, maximum value
+  Double_t fVtxYMax ; //Y vertex position, maximum value 
+  Double_t fVtxZMax ; //Z vertex position, maximum value
+  Double_t fVtxXMin ; //X vertex position, minimum value
+  Double_t fVtxYMin ; //Y vertex position, minimum value
+  Double_t fVtxZMin ; //Z vertex position, minimum value
+
+  TBits *fBitMap ; //cut mask
+
+  ClassDef(AliCFEventGenCuts,1);
+};
+
+#endif
diff --git a/CORRFW/AliCFEventRecCuts.cxx b/CORRFW/AliCFEventRecCuts.cxx
new file mode 100644 (file)
index 0000000..b3db0e6
--- /dev/null
@@ -0,0 +1,215 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+// Cut on the Event at reconstructed level: for the moment 
+// the requirements on the number of charged tracks and on 
+// the vertex position and resolution are implemented
+// The argument of IsSelected member function (passed object) is cast into 
+// an AliESDEvent. In the future may be modified to use AliVEvent interface
+// and include more cut variables.
+// The class derives from AliCFCutBase
+// Author:S.Arcelli Silvia.Arcelli@cern.ch
+//
+//
+#include "TBits.h"
+#include "AliLog.h"
+#include "AliESDEvent.h"
+#include "AliESDVertex.h"
+#include "AliCFEventRecCuts.h"
+ClassImp(AliCFEventRecCuts) 
+//____________________________________________________________________
+AliCFEventRecCuts::AliCFEventRecCuts() : 
+  AliCFCutBase(),
+  fNTracksMin(-1),
+  fNTracksMax(1000000),
+  fRequireVtxCuts(kFALSE),
+  fVtxXMax(1.e99),
+  fVtxYMax(1.e99),
+  fVtxZMax(1.e99),
+  fVtxXMin(-1.e99),
+  fVtxYMin(-1.e99),
+  fVtxZMin(-1.e99),
+  fVtxXResMax(1.e99),
+  fVtxYResMax(1.e99),
+  fVtxZResMax(1.e99),
+  fBitMap(0x0)
+{
+  //
+  //ctor
+  //
+  fBitMap=new TBits(0);
+}
+//____________________________________________________________________
+AliCFEventRecCuts::AliCFEventRecCuts(Char_t* name, Char_t* title) : 
+  AliCFCutBase(name,title),
+  fNTracksMin(-1),
+  fNTracksMax(1000000),
+  fRequireVtxCuts(kFALSE),
+  fVtxXMax(1.e99),
+  fVtxYMax(1.e99),
+  fVtxZMax(1.e99),
+  fVtxXMin(-1.e99),
+  fVtxYMin(-1.e99),
+  fVtxZMin(-1.e99),
+  fVtxXResMax(1.e99),
+  fVtxYResMax(1.e99),
+  fVtxZResMax(1.e99),
+  fBitMap(0x0)
+ {
+  //
+  //ctor
+  //
+  fBitMap=new TBits(0);
+ }
+//____________________________________________________________________
+AliCFEventRecCuts::AliCFEventRecCuts(const AliCFEventRecCuts& c) : 
+  AliCFCutBase(c),
+  fNTracksMin(c.fNTracksMin),
+  fNTracksMax(c.fNTracksMax),
+  fRequireVtxCuts(c.fRequireVtxCuts),
+  fVtxXMax(c.fVtxXMax),
+  fVtxYMax(c.fVtxYMax),
+  fVtxZMax(c.fVtxZMax),
+  fVtxXMin(c.fVtxXMin),
+  fVtxYMin(c.fVtxYMin),
+  fVtxZMin(c.fVtxZMin),
+  fVtxXResMax(c.fVtxXResMax),
+  fVtxYResMax(c.fVtxYResMax),
+  fVtxZResMax(c.fVtxZResMax),
+  fBitMap(c.fBitMap)
+{
+  //
+  //copy constructor
+  //
+}
+//____________________________________________________________________
+AliCFEventRecCuts::~AliCFEventRecCuts() {
+  //
+  //dtor
+  //
+
+  if(fBitMap)delete fBitMap;
+}
+//____________________________________________________________________
+AliCFEventRecCuts& AliCFEventRecCuts::operator=(const AliCFEventRecCuts& c)
+{
+  //
+  // Assignment operator
+  //
+  if (this != &c) {
+    AliCFCutBase::operator=(c) ;
+    fNTracksMin=c.fNTracksMin;
+    fNTracksMax=c.fNTracksMax;
+    fRequireVtxCuts=c.fRequireVtxCuts;
+    fVtxXMax=c.fVtxXMax;
+    fVtxYMax=c.fVtxYMax;
+    fVtxZMax=c.fVtxZMax;
+    fVtxXMin=c.fVtxXMin;
+    fVtxYMin=c.fVtxYMin;
+    fVtxZMin=c.fVtxZMin;
+    fVtxXResMax=c.fVtxXResMax;
+    fVtxYResMax=c.fVtxYResMax;
+    fVtxZResMax=c.fVtxZResMax;
+    fBitMap=c.fBitMap;
+  }
+  return *this ;
+}
+//____________________________________________________________________
+Bool_t AliCFEventRecCuts::IsSelected(TObject* obj) {
+  //
+  //Check if the requested cuts are passed
+  //
+
+  TBits *bitmap = SelectionBitMap(obj);
+
+  Bool_t isSelected = kTRUE;
+
+  for (UInt_t icut=0; icut<bitmap->GetNbits();icut++)
+       if(!bitmap->TestBitNumber(icut)) isSelected = kFALSE;
+
+  return isSelected;
+
+}
+
+//____________________________________________________________________
+TBits *AliCFEventRecCuts::SelectionBitMap(TObject* obj) {
+  //
+  //cut on the number of charged tracks and on the event vertex.
+  //so far specific to AliESDEvents
+  //
+
+  //Check if the requested cuts are passed and return a bitmap
+  for(Int_t j=0;j<kNCuts;j++)fBitMap->SetBitNumber(j,kFALSE);
+  AliESDEvent* esd = dynamic_cast<AliESDEvent *>(obj);
+  if ( !esd ) return fBitMap ;
+
+  //now start checking the cuts,
+  //first assume the event will be accepted: 
+  for(Int_t j=0;j<kNCuts;j++)fBitMap->SetBitNumber(j,kTRUE);
+
+  //Number of charged tracks:
+  Int_t nTracks = esd->GetNumberOfTracks();
+  if(nTracks<fNTracksMin || nTracks>fNTracksMax)
+    fBitMap->SetBitNumber(0,kFALSE); 
+  
+  if(fRequireVtxCuts){
+    const AliESDVertex* vtxESD = esd->GetVertex();
+    if(!vtxESD){
+      for(Int_t j=1;j<kNCuts;j++)fBitMap->SetBitNumber(j,kFALSE); 
+      return fBitMap;
+    }
+    // Require the vertex to have been reconstructed successfully
+    if (strcmp(vtxESD->GetName(), "default")==0){
+      AliWarning(Form(" No reconstructed vertex found, skip event"));    
+      for(Int_t j=1;j<kNCuts;j++)fBitMap->SetBitNumber(j,kFALSE); 
+      return fBitMap;
+    }    
+    // Pick up the position and uncertainties
+    
+    Double_t vtxPos[3];
+    vtxPos[0] = vtxESD->GetXv();
+    vtxPos[1] = vtxESD->GetYv();
+    vtxPos[2] = vtxESD->GetZv();
+    
+    Double_t vtxRes[3];
+    vtxRes[0] = vtxESD->GetXRes();
+    vtxRes[1] = vtxESD->GetYRes();
+    vtxRes[2] = vtxESD->GetZRes();
+    // Apply the cut
+    
+    if (vtxPos[0]>fVtxXMax || vtxPos[0]<fVtxXMin)
+      fBitMap->SetBitNumber(1,kFALSE); 
+    if (vtxPos[1]>fVtxYMax || vtxPos[1]<fVtxYMin)
+      fBitMap->SetBitNumber(2,kFALSE); 
+    if (vtxPos[2]>fVtxZMax || vtxPos[2]<fVtxZMin)
+      fBitMap->SetBitNumber(3,kFALSE); 
+    if (vtxRes[0]==0 || vtxRes[0]>fVtxXResMax)
+      fBitMap->SetBitNumber(4,kFALSE); 
+    if (vtxRes[1]==0 || vtxRes[1]>fVtxYResMax)
+      fBitMap->SetBitNumber(5,kFALSE); 
+    if (vtxRes[2]==0 || vtxRes[2]>fVtxZResMax)
+      fBitMap->SetBitNumber(6,kFALSE); 
+  }  
+  return fBitMap;
+}
+//__________________________________________________________________________________
+void AliCFEventRecCuts::GetBitMap(TObject* obj, TBits *bitmap) {
+  //
+  // retrieve the pointer to the bitmap
+  //
+  bitmap = SelectionBitMap(obj);
+
+}
diff --git a/CORRFW/AliCFEventRecCuts.h b/CORRFW/AliCFEventRecCuts.h
new file mode 100644 (file)
index 0000000..bc3364a
--- /dev/null
@@ -0,0 +1,89 @@
+#ifndef ALICFEVENTRECCUTS_H
+#define ALICFEVENTRECCUTS_H
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+// Cut on the Event at reconstructed level: for the moment 
+// just the requirements on the number of charged tracks and on 
+// the vertex position and resolution are implemented
+// The argument of IsSelected member function (passed object) is cast into 
+// an AliESDEvent. In the future may be modified to use AliVEvent interface
+// and include more cut variables.
+// The class derives from AliCFCutBase
+// Author:S.Arcelli Silvia.Arcelli@cern.ch
+
+
+#include "AliCFCutBase.h"
+class TBits;
+//_____________________________________________________________________________
+class AliCFEventRecCuts: public AliCFCutBase 
+{
+ public :
+  AliCFEventRecCuts() ;
+  AliCFEventRecCuts(Char_t* name, Char_t* title) ;
+  AliCFEventRecCuts(const AliCFEventRecCuts& c) ;
+  AliCFEventRecCuts& operator=(const AliCFEventRecCuts& c) ;
+  ~AliCFEventRecCuts();
+  void GetBitMap(TObject *obj, TBits*bitmap);
+  Bool_t IsSelected(TObject* obj);
+  void Init(){;};
+
+  enum{kNCuts=7};
+
+  void SetNTracksCut(Int_t xMin=-1, Int_t xMax=1000000) {fNTracksMin=xMin; fNTracksMax=xMax;} // cut values setter
+
+  void SetRequireVtxCuts(Bool_t vtx=kFALSE) {fRequireVtxCuts=vtx;} // cut values setter
+  void SetVertexXCut(Double_t xMin=-1.e99, Double_t xMax=1.e99) { fVtxXMin=xMin; fVtxXMax=xMax;} // cut values setter
+  void SetVertexYCut(Double_t yMin=-1.e99, Double_t yMax=1.e99) { fVtxYMin=yMin; fVtxYMax=yMax;} // cut values setter
+  void SetVertexZCut(Double_t zMin=-1.e99, Double_t zMax=1.e99) { fVtxZMin=zMin; fVtxZMax=zMax;} // cut values setter
+
+  void SetVertexXResCut(Double_t xMax=1.e99) {fVtxXResMax=xMax;} // cut values setter
+  void SetVertexYResCut(Double_t yMax=1.e99){fVtxYResMax=yMax;} // cut values setter
+  void SetVertexZResCut(Double_t zMax=1.e99){fVtxZResMax=zMax;} // cut values setter
+
+  Int_t    GetNTracksMin() const {return fNTracksMin;} // cut values getter
+  Int_t    GetNTracksMax() const {return fNTracksMax;} // cut values getter
+  Bool_t   GetRequireVtxCuts() const {return fRequireVtxCuts;} // cut value getter
+  Double_t GetVertexXMax() const {return fVtxXMax;} // cut values getter
+  Double_t GetVertexYMax() const {return fVtxYMax;} // cut values getter
+  Double_t GetVertexZMax() const {return fVtxZMax;} // cut values getter
+  Double_t GetVertexXMin() const {return fVtxXMin;} // cut values getter
+  Double_t GetVertexYMin() const {return fVtxYMin;} // cut values getter
+  Double_t GetVertexZMin() const {return fVtxZMin;} // cut values getter
+  Double_t GetVertexXResMax() const {return fVtxXResMax;} // cut values getter
+  Double_t GetVertexYResMax() const {return fVtxYResMax;} // cut values getter
+  Double_t GetVertexZResMax() const {return fVtxZResMax;} // cut values getter
+  
+ private:
+  TBits *SelectionBitMap(TObject* obj);
+  Int_t fNTracksMin; //minimum number of esd tracks
+  Int_t fNTracksMax; //maximum number of esd tracks
+  Bool_t fRequireVtxCuts ; //The type of trigger to be checked
+  Double_t fVtxXMax ; //X vertex position, maximum value
+  Double_t fVtxYMax ; //Y vertex position, maximum value 
+  Double_t fVtxZMax ; //Z vertex position, maximum value
+  Double_t fVtxXMin ; //X vertex position, minimum value
+  Double_t fVtxYMin ; //Y vertex position, minimum value
+  Double_t fVtxZMin ; //Z vertex position, minimum value
+  Double_t fVtxXResMax ;//Maximum value of sigma_vtx in X
+  Double_t fVtxYResMax ;//Maximum value of sigma_vtx in X
+  Double_t fVtxZResMax ;//Maximum value of sigma_vtx in X
+
+
+  TBits *fBitMap ; //cut mask
+
+  ClassDef(AliCFEventRecCuts,1);
+};
+
+#endif
diff --git a/CORRFW/AliCFFrame.cxx b/CORRFW/AliCFFrame.cxx
new file mode 100644 (file)
index 0000000..cdb4a5a
--- /dev/null
@@ -0,0 +1,304 @@
+/* $Id$ */
+
+//--------------------------------------------------------------------//
+//                                                                    //
+// AliCFFrame Class                                                 //
+// Class to accumulate data on an N-dimensional grid, to be used      //
+// as input to get corrections for Reconstruction & Trigger efficiency// 
+//                                                                    //
+// -- Author : S.Arcelli                                              //
+// Still to be done:                                                  //
+// --Implement methods to merge cells                                 //
+// --Interpolate among bins in a range                                // 
+//--------------------------------------------------------------------//
+//
+//
+
+#include "TSystem.h"
+#include <TFile.h>
+#include <AliLog.h>
+#include "AliCFFrame.h"
+
+//____________________________________________________________________
+ClassImp(AliCFFrame)
+
+//____________________________________________________________________
+AliCFFrame::AliCFFrame() : 
+  TNamed(),
+  fNVar(0),
+  fNDim(0),
+  fNVarBinLimits(0),
+  fNVarBins(0x0),
+  fIndex(0x0),
+  fProduct(0x0),
+  fOffset(0x0),
+  fVarBinLimits(0x0)
+{
+  // default constructor
+}
+//____________________________________________________________________
+AliCFFrame::AliCFFrame(const Char_t* name, const Char_t* title) : 
+  TNamed(name,title),
+  fNVar(0),
+  fNDim(0),
+  fNVarBinLimits(0),
+  fNVarBins(0x0),
+  fIndex(0x0),
+  fProduct(0x0),
+  fOffset(0x0),
+  fVarBinLimits(0x0)
+{
+  // named constructor
+}
+//____________________________________________________________________
+AliCFFrame::AliCFFrame(const Char_t* name, const Char_t* title, const Int_t nVarIn, const Int_t * nBinIn, const Float_t *binLimitsIn) :  
+  TNamed(name,title),
+  fNVar(0),
+  fNDim(0),
+  fNVarBinLimits(0),
+  fNVarBins(0x0),
+  fIndex(0x0),
+  fProduct(0x0),
+  fOffset(0x0),
+  fVarBinLimits(0x0)
+{
+  //
+  // main constructor
+  //
+
+  //the number of variables on the grid
+  fNVar=nVarIn;
+
+  // the binning in each variable
+  fNVarBins= new Int_t[fNVar];
+
+  fIndex= new Int_t[fNVar];
+
+  Int_t ndimTot=1;
+  Int_t nbinTot=0;
+
+
+  //Calculate total number of elements and bins...
+
+  for(Int_t i=0;i<fNVar;i++){
+    fNVarBins[i]=nBinIn[i];
+    ndimTot*=nBinIn[i];
+    nbinTot+=(nBinIn[i]+1);
+  } 
+
+
+  //total number of elements
+
+  fNDim=ndimTot;
+
+  fOffset= new Int_t[fNVar];
+  fProduct= new Int_t[fNVar];
+
+  for(Int_t ivar=0;ivar<fNVar;ivar++){
+    Int_t offset=0;
+    for(Int_t i =0;i<ivar;i++)offset+=(fNVarBins[i]+1);      
+    fOffset[ivar]=offset;
+    Int_t prod=1;
+    for(Int_t i=0;i<ivar;i++)prod*=fNVarBins[i];
+    fProduct[ivar]=prod;
+  }
+
+  //The bin limits
+
+  fNVarBinLimits=nbinTot;
+  fVarBinLimits=new Float_t[fNVarBinLimits];
+  if(binLimitsIn){
+    for(Int_t i=0;i<fNVarBinLimits;i++){
+      fVarBinLimits[i] =binLimitsIn[i];
+    } 
+  }
+}
+//____________________________________________________________________
+AliCFFrame::AliCFFrame(const AliCFFrame& c) : 
+  TNamed(),
+  fNVar(0),
+  fNDim(0),
+  fNVarBinLimits(0),
+  fNVarBins(0x0),
+  fIndex(0x0),
+  fProduct(0x0),
+  fOffset(0x0),
+  fVarBinLimits(0x0)
+{
+  //
+  // copy constructor
+  //
+  ((AliCFFrame &)c).Copy(*this);
+}
+//____________________________________________________________________
+AliCFFrame::~AliCFFrame()
+{
+  //
+  // destructor
+  //
+  if(fNVarBins)delete [] fNVarBins;
+  if(fVarBinLimits)delete [] fVarBinLimits;
+  if(fIndex)delete [] fIndex;
+  if(fProduct)delete [] fProduct;
+  if(fOffset)delete [] fOffset;
+
+}
+//____________________________________________________________________
+AliCFFrame &AliCFFrame::operator=(const AliCFFrame &c)
+{
+  //
+  // assigment operator
+  //
+  if (this != &c)
+    ((AliCFFrame &) c).Copy(*this);
+  return *this;
+} 
+//____________________________________________________________________
+void AliCFFrame::SetBinLimits(Int_t ivar, Float_t *array)
+{
+  //
+  // setting the arrays containing the bin limits 
+  //
+  Int_t nbins=fNVarBins[ivar]+1;
+  for(Int_t i=0;i<nbins;i++){
+    fVarBinLimits[fOffset[ivar]+i] =array[i];
+  } 
+} 
+//____________________________________________________________________
+void AliCFFrame::GetBinLimits(Int_t ivar, Float_t *array) const
+{
+  //
+  // getting the arrays containing the bin limits 
+  //
+  Int_t nbins=fNVarBins[ivar]+1;
+  for(Int_t i=0;i<nbins;i++){
+    array[i]=fVarBinLimits[fOffset[ivar]+i];
+  } 
+} 
+//____________________________________________________________________
+Int_t AliCFFrame::GetBinIndex(Int_t *ibin) const
+{
+  //
+  // getting the element number on the grid for a given set of bin indeces 
+  //
+  Int_t ind=ibin[fNVar-1];
+  for(Int_t i=fNVar-1;i>0;i--){
+    ind=ibin[i-1]+ind*fNVarBins[i-1]; 
+  }
+  return ind;
+} 
+//____________________________________________________________________
+Int_t AliCFFrame::GetBinIndex(Int_t ivar, Int_t ind) const
+{
+  //
+  // getting the bin index on a given dim. ivar for a given element ind on the grid
+  //
+  Int_t index=-1;
+  for(Int_t i=fNVar-1;i>=0;i--){
+    index=ind/fProduct[i];
+    fIndex[i]=index;
+    ind-=index*fProduct[i];
+  }
+  
+  index=fIndex[ivar];
+  return index;
+}
+//____________________________________________________________________
+void AliCFFrame::GetBinIndex(Int_t ind, Int_t *bins ) const
+{
+  //
+  // getting the set of bin indeces for a given element ind on the grid
+  //
+  Int_t index=-1;
+  for(Int_t i=fNVar-1;i>=0;i--){
+    index=ind/fProduct[i];
+    bins[i]=index;
+    ind-=index*fProduct[i];
+  }
+  return;
+}
+//____________________________________________________________________
+Float_t AliCFFrame::GetBinCenter(Int_t ivar, Int_t ibin) const
+{
+  //
+  // getting the bin center of a given bin ibin on the dim. (axis) ivar
+  //
+  Float_t binMin=fVarBinLimits[fOffset[ivar]+ibin];
+  Float_t binMax=fVarBinLimits[fOffset[ivar]+ibin+1];
+  Float_t val=0.5*(binMin+binMax);
+  return val;
+}
+//____________________________________________________________________
+void AliCFFrame::GetBinCenter(Int_t *ibin, Float_t *binCenter) const
+{
+  //
+  // gives the centers of the N-dim bin identified by a set of bin indeces 
+  // invar
+  //
+  for(Int_t i=0;i<fNVar;i++){
+    binCenter[i]=GetBinCenter(i,ibin[i]);
+  }
+} 
+//____________________________________________________________________
+void AliCFFrame::Copy(TObject& c) const
+{
+  //
+  // copy function
+  //
+  AliCFFrame& target = (AliCFFrame &) c;
+
+  target.fNVar=fNVar;
+  target.fNDim=fNDim;
+  target.fNVarBinLimits=fNVarBinLimits;
+  if (fNVarBins)
+    target.fNVarBins = fNVarBins;
+  if (fVarBinLimits)
+    target.fVarBinLimits = fVarBinLimits;
+  if (fProduct)
+    target.fProduct = fProduct;
+  if (fOffset)
+    target.fOffset = fOffset;  
+}
+//____________________________________________________________________
+void AliCFFrame::PrintBinLimits()
+{
+  //
+  // printing the array containing the bin limits 
+  //
+  for(Int_t i=0;i<fNVarBinLimits;i++){
+    AliInfo(Form("bin limit index %i is: %f",i, fVarBinLimits[i]));
+  } 
+} 
+//____________________________________________________________________
+void AliCFFrame::PrintNBins()
+{
+  //
+  // printing the array containing the # of bins  
+  //
+  for(Int_t i=0;i<fNVar;i++){
+    AliInfo(Form("bins in var %i are: %i",i, fNVarBins[i]));
+  } 
+} 
+//____________________________________________________________________
+void AliCFFrame::Save(const Char_t *outfile) const
+{
+  //
+  // Save the grid to a root file
+  //
+
+  const char *dirname = "./";
+  TString filename = outfile;
+  TFile *file=0x0;
+  if((gSystem->FindFile(dirname,filename))!=NULL){
+      file = new TFile( outfile,"UPDATE");
+  }
+  else{
+    file = new TFile( outfile,"RECREATE");
+  } 
+  file->cd();
+  //write the object to a file
+  this->Write(GetName(),TObject::kSingleKey);
+  file->Close();
+  delete file;
+}
diff --git a/CORRFW/AliCFFrame.h b/CORRFW/AliCFFrame.h
new file mode 100644 (file)
index 0000000..615e0b5
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef ALICFFRAME_H
+#define ALICFFRAME_H
+
+/* $Id$ */
+
+//--------------------------------------------------------------------//
+//                                                                    //
+// AliCFFrame.cxx Class                                               //
+// Class to handle input data for correction Framework                // 
+//                                                                    //
+//--------------------------------------------------------------------//
+
+#include <TNamed.h>
+class TCollection;
+class AliCFFrame : public TNamed
+{
+ public:
+  AliCFFrame();
+  AliCFFrame(const Char_t* name,const Char_t* title);
+  AliCFFrame(const Char_t* name, const Char_t* title, const Int_t nVarIn, const Int_t* nBinIn, const Float_t  *binLimitsIn=0);
+  AliCFFrame(const AliCFFrame & c);
+  
+  virtual ~AliCFFrame();
+  AliCFFrame& operator=(const AliCFFrame& corr);
+  virtual void  PrintBinLimits();
+  virtual void  PrintNBins();
+  virtual void  SetBinLimits(Int_t ivar, Float_t * array);
+  virtual void  GetBinLimits(Int_t ivar, Float_t * array) const;
+  virtual Int_t GetBinIndex(Int_t *ibin) const;
+  virtual void  GetBinIndex(Int_t iel, Int_t *ibin) const;
+  virtual Int_t GetBinIndex(Int_t ivar, Int_t ind) const;
+  virtual Int_t GetNDim() const {return fNDim;};
+  virtual Int_t GetNVar() const {return fNVar;};
+  virtual Int_t GetNBins(Int_t ivar) const {return fNVarBins[ivar];};
+  virtual Int_t GetNBinLimits() const {return fNVarBinLimits;};
+  virtual Int_t   *GetNBins() const {return fNVarBins;};
+  virtual void    GetBinCenter(Int_t *ibin, Float_t *binCenter) const;
+  virtual Float_t *GetBinLimits() const {return fVarBinLimits;};
+  virtual Float_t GetBinCenter(Int_t ivar,Int_t ibin) const;
+
+  //basic operations
+
+  virtual void Copy(TObject& c) const;
+  virtual void Save(const Char_t *outfile) const;
+  
+ protected:
+  Int_t    fNVar; //number of variables in the grid
+  Int_t    fNDim; //Overall number of elements in the grid
+  Int_t    fNVarBinLimits; //total number of bin limits
+  Int_t    *fNVarBins; //[fNVar] size of the grid in each dimension (binning)
+  Int_t    *fIndex;//[fNVar] current N-dim index on the grid
+  Int_t    *fProduct;//[fNVar] current N-dim index on the grid
+  Int_t    *fOffset;//[fNVar] current N-dim index on the grid
+  Float_t  *fVarBinLimits;//[fNVarBinLimits] array defining the binLimits
+
+  
+  ClassDef(AliCFFrame,1);
+};
+    
+#endif
+
diff --git a/CORRFW/AliCFGrid.cxx b/CORRFW/AliCFGrid.cxx
new file mode 100644 (file)
index 0000000..f137840
--- /dev/null
@@ -0,0 +1,1365 @@
+/* $Id$ */
+
+//--------------------------------------------------------------------//
+//                                                                    //
+// AliCFGrid Class                                                 //
+// Class to accumulate data on an N-dimensional grid, to be used      //
+// as input to get corrections for Reconstruction & Trigger efficiency// 
+//                                                                    //
+// -- Author : S.Arcelli                                              //
+// Still to be done:                                                  //
+// --Implement methods to merge cells                                 //
+// --Interpolate among bins in a range                                // 
+//--------------------------------------------------------------------//
+//
+//
+#include <AliLog.h>
+#include "AliCFGrid.h"
+#include "TMath.h"
+#include "TROOT.h"
+#include "TH1F.h"
+#include "TH2F.h"
+#include "TH3F.h"
+
+//____________________________________________________________________
+ClassImp(AliCFGrid)
+
+//____________________________________________________________________
+AliCFGrid::AliCFGrid() : 
+  AliCFFrame(),
+  fSumW2(kFALSE),
+  fNunflTot(0),
+  fNovflTot(0),
+  fNentriesTot(0),
+  fNunfl(0x0),
+  fNovfl(0x0),
+  fData(0x0),
+  fErr2(0x0)
+{
+  // default constructor
+}
+//____________________________________________________________________
+AliCFGrid::AliCFGrid(const Char_t* name, const Char_t* title) : 
+  AliCFFrame(name,title),
+  fSumW2(kFALSE),
+  fNunflTot(0),
+  fNovflTot(0),
+  fNentriesTot(0),
+  fNunfl(0x0),
+  fNovfl(0x0),
+  fData(0x0),
+  fErr2(0x0)
+{
+  // default constructor
+}
+
+//____________________________________________________________________
+AliCFGrid::AliCFGrid(const Char_t* name, const Char_t* title, const Int_t nVarIn, const Int_t * nBinIn, const Float_t *binLimitsIn) :  
+  AliCFFrame(name,title,nVarIn,nBinIn,binLimitsIn),
+  fSumW2(kFALSE),
+  fNunflTot(0),
+  fNovflTot(0),
+  fNentriesTot(0),
+  fNunfl(0x0),
+  fNovfl(0x0),
+  fData(0x0),
+  fErr2(0x0)
+{
+  //
+  // main constructor
+  //
+
+
+  //The underflows
+  fNunfl=new Float_t[fNVar];
+  fNovfl= new Float_t[fNVar];
+
+
+  // the grid
+  fData = new Float_t[fNDim]; //num
+
+  //Initialization
+  for(Int_t i = 0;i<fNDim;i++)fData[i]=0;
+
+  fNunflTot =0;
+  fNovflTot =0;
+  fNentriesTot =0;
+  for(Int_t j=0;j<fNVar;j++){
+    fNunfl[j] =0;
+    fNovfl[j] =0;
+  }
+}
+
+//____________________________________________________________________
+AliCFGrid::AliCFGrid(const AliCFGrid& c) : 
+  AliCFFrame(),
+  fSumW2(kFALSE),
+  fNunflTot(0),
+  fNovflTot(0),
+  fNentriesTot(0),
+  fNunfl(0x0),
+  fNovfl(0x0),
+  fData(0x0),
+  fErr2(0x0)
+{
+  //
+  // copy constructor
+  //
+  ((AliCFGrid &)c).Copy(*this);
+}
+
+//____________________________________________________________________
+AliCFGrid::~AliCFGrid()
+{
+  //
+  // destructor
+  //
+  delete fData;
+  if(fSumW2)delete fErr2;
+  delete fNunfl;
+  delete fNovfl;
+
+}
+
+//____________________________________________________________________
+AliCFGrid &AliCFGrid::operator=(const AliCFGrid &c)
+{
+  //
+  // assigment operator
+  //
+  if (this != &c)
+    ((AliCFGrid &) c).Copy(*this);
+  return *this;
+} 
+//____________________________________________________________________
+Float_t AliCFGrid::GetElement(Int_t bin) const
+{
+  //
+  // Returns grid element bin
+  //
+  if(bin>=fNDim){
+    AliInfo(Form(" element index outside the grid, return -1"));
+    return -1.;
+  }
+  return fData[bin];
+}
+//____________________________________________________________________
+Float_t AliCFGrid::GetElement(Int_t *bin) const
+{
+ //
+  // Get the content in a bin corresponding to a set of bin indexes
+  //
+    Int_t ind =GetBinIndex(bin);
+    return GetElement(ind);
+}  
+//____________________________________________________________________
+Float_t AliCFGrid::GetElement(Float_t *var) const
+{
+  //
+  // Get the content in a bin corresponding to a set of input variables
+  //
+  Int_t unfl=0;  
+  Int_t ovfl=0;  
+  for(Int_t i=0;i<fNVar;i++){
+    Int_t nbins=fNVarBins[i]+1;
+    Float_t *bins=new Float_t[nbins];
+    for(Int_t ibin =0;ibin<nbins;ibin++){
+     bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
+    }
+
+    fIndex[i] = TMath::BinarySearch(nbins,bins,var[i]);
+
+    //underflows
+
+    if(var[i] < bins[0]){
+      unfl=1;
+    }
+
+    //overflows
+
+    if(var[i] > bins[nbins-1]){
+      ovfl=1;
+    }
+    delete [] bins;
+  }
+
+  if(!(ovfl==1 || unfl==1)){
+    return GetElement(fIndex);
+  }
+  else{
+    AliInfo(Form(" input variables outside the grid, return -1"));
+    return -1.;
+  }
+} 
+//____________________________________________________________________
+Float_t AliCFGrid::GetElementError(Int_t iel) const
+{
+  //
+  // Return the squared error on grid element iel
+  //
+  if(iel>=fNDim){
+    AliInfo(Form(" element index outside the grid, return -1"));
+    return -1.;
+  }
+  if(fSumW2)return fErr2[iel];
+  return fData[iel];
+}
+//____________________________________________________________________
+Float_t AliCFGrid::GetElementError(Int_t *bin) const
+{
+  //
+  // Get the squared error in a bin corresponding to a set of bin indeces
+  //
+    Int_t ind =GetBinIndex(bin);
+    return GetElementError(ind);
+
+}
+//____________________________________________________________________
+Float_t AliCFGrid::GetElementError(Float_t *var) const
+{
+  //
+  // Get the squared error in a bin corresponding to a set of input variables
+  //
+  Int_t unfl=0;  
+  Int_t ovfl=0;  
+  for(Int_t i=0;i<fNVar;i++){
+    Int_t nbins=fNVarBins[i]+1;
+    Float_t *bins=new Float_t[nbins];
+    for(Int_t ibin =0;ibin<nbins;ibin++){
+     bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
+    }
+
+    fIndex[i] = TMath::BinarySearch(nbins,bins,var[i]);
+    //underflows
+
+    if(var[i] < bins[0]){
+      unfl=1;
+    }
+
+    //overflows
+
+    if(var[i] > bins[nbins-1]){
+      ovfl=1;
+    }
+    delete [] bins;
+  }
+
+  if(!(ovfl==1 || unfl==1)){
+    return GetElementError(fIndex);
+  }
+  else{
+    AliInfo(Form(" input variables outside the grid, return -1"));
+    return -1.;
+  }
+} 
+//____________________________________________________________________
+void AliCFGrid::SetElement(Int_t iel, Float_t val)
+{
+  //
+  // Sets grid element iel to val
+  //
+  if(iel>=fNDim){
+    AliInfo(Form(" element index outside the grid, no value set"));
+  }else {
+    fData[iel]=val;
+  }
+}
+//____________________________________________________________________
+void AliCFGrid::SetElement(Int_t *bin, Float_t val)
+{
+  //
+  // Sets grid element of bin indeces bin to val
+  //
+    Int_t ind =GetBinIndex(bin);
+    SetElement(ind,val);
+}
+//____________________________________________________________________
+void AliCFGrid::SetElement(Float_t *var, Float_t val) 
+{
+  //
+  // Set the content in a bin to value val corresponding to a set of input variables
+  //
+  Int_t unfl=0;  
+  Int_t ovfl=0;  
+  for(Int_t i=0;i<fNVar;i++){
+    Int_t nbins=fNVarBins[i]+1;
+    Float_t *bins=new Float_t[nbins];
+    for(Int_t ibin =0;ibin<nbins;ibin++){
+     bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
+    }
+
+    fIndex[i] = TMath::BinarySearch(nbins,bins,var[i]);
+    //underflows
+
+    if(var[i] < bins[0]){
+      unfl=1;
+    }
+
+    //overflows
+
+    if(var[i] > bins[nbins-1]){
+      ovfl=1;
+    }
+    delete [] bins;
+  }
+
+  if(!(ovfl==1 || unfl==1)){
+    SetElement(fIndex,val);
+  }
+  else{
+    AliInfo(Form(" input variables outside the grid, no value set"));
+  }
+} 
+//____________________________________________________________________
+void AliCFGrid::SetElementError(Int_t iel, Float_t val) 
+{
+  //
+  // Set squared error to val on grid element iel
+  //
+  if(iel>=fNDim){
+    AliInfo(Form(" element index outside the grid, no value set"));
+    return;
+  }
+  if(!fErr2)SumW2();
+  fErr2[iel]=val;   
+}
+//____________________________________________________________________
+void AliCFGrid::SetElementError(Int_t *bin, Float_t val) 
+{
+  //
+  // Set squared error to val on grid element of bin indeces bin
+  //
+    Int_t ind =GetBinIndex(bin);
+    SetElementError(ind,val);
+}
+//____________________________________________________________________
+void AliCFGrid::SetElementError(Float_t *var, Float_t val)
+{
+  //
+  // Set squared error to val in a bin corresponding to a set of input variables
+  //
+  Int_t unfl=0;  
+  Int_t ovfl=0;  
+  for(Int_t i=0;i<fNVar;i++){
+    Int_t nbins=fNVarBins[i]+1;
+    Float_t *bins=new Float_t[nbins];
+    for(Int_t ibin =0;ibin<nbins;ibin++){
+     bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
+    }
+
+    fIndex[i] = TMath::BinarySearch(nbins,bins,var[i]);
+    //underflows
+
+    if(var[i] < bins[0]){
+      unfl=1;
+    }
+
+    //overflows
+
+    if(var[i] > bins[nbins-1]){
+      ovfl=1;
+    }
+    delete [] bins;
+  }
+
+  if(!(ovfl==1 || unfl==1)){
+    SetElementError(fIndex,val);
+  }
+  else{
+    AliInfo(Form(" input variables outside the grid, no value set"));
+  }
+} 
+//____________________________________________________________________
+void AliCFGrid::Scale(Int_t iel, Float_t *fact)
+{
+  //
+  //scale content of a certain cell by (positive) fact (with error)
+  //
+  if(iel>=fNDim){
+    AliInfo(Form(" element index outside the grid, no scaling"));
+    return;
+  }
+  Float_t el,del,elsc,delsc;  
+  if(GetElement(iel)>0 && fact[0]>0){
+    el=GetElement(iel);
+    del=TMath::Sqrt(GetElementError(iel));
+    elsc=el*fact[0];
+    delsc=TMath::Sqrt(del*del/el/el
+                   +fact[1]*fact[1]/fact[0]/fact[0])
+      *elsc;
+    SetElement(iel,elsc);
+    if(fSumW2)SetElementError(iel,delsc*elsc);
+  }
+}
+//____________________________________________________________________
+void AliCFGrid::Scale(Int_t *bin, Float_t *fact)
+{
+  //
+  //scale content of a certain cell by (positive) fact (with error)
+  //
+  Int_t iel=GetBinIndex(bin);
+  Scale(iel,fact);
+}
+//____________________________________________________________________
+void AliCFGrid::Scale(Float_t *var, Float_t *fact) 
+{
+  //
+  //scale content of a certain cell by (positive) fact (with error)
+  //
+  Int_t unfl=0;  
+  Int_t ovfl=0;  
+  for(Int_t i=0;i<fNVar;i++){
+    Int_t nbins=fNVarBins[i]+1;
+    Float_t *bins=new Float_t[nbins];
+    for(Int_t ibin =0;ibin<nbins;ibin++){
+     bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
+    }
+
+    fIndex[i] = TMath::BinarySearch(nbins,bins,var[i]);
+    //underflows
+
+    if(var[i] < bins[0]){
+      unfl=1;
+    }
+
+    //overflows
+
+    if(var[i] > bins[nbins-1]){
+      ovfl=1;
+    }
+    delete [] bins;
+  }
+
+  if(!(ovfl==1 || unfl==1)){
+    Int_t iel=GetBinIndex(fIndex);
+    Scale(iel,fact);
+  }
+  else{
+    AliInfo(Form(" input variables outside the grid, no scaling done"));
+  }
+}
+//____________________________________________________________________
+void AliCFGrid::Scale( Float_t *fact) 
+{
+  //
+  //scale contents of the whole grid by fact
+  //
+  for(Int_t iel=0;iel<fNDim;iel++){
+    Scale(iel,fact);
+  }
+}
+//____________________________________________________________________
+void AliCFGrid::Fill(Float_t *var, Float_t weight)
+{
+
+  //
+  // Fill the grid,
+  // given a set of values of the input variable, 
+  // with weight (by default w=1)
+  //
+
+  Int_t unfl=0;  
+  Int_t ovfl=0;  
+  for(Int_t i=0;i<fNVar;i++){
+    Int_t nbins=fNVarBins[i]+1;
+    Float_t *bins=new Float_t[nbins];
+    for(Int_t ibin =0;ibin<nbins;ibin++){
+     bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
+    }
+
+    fIndex[i] = TMath::BinarySearch(nbins,bins,var[i]);
+    //underflows
+
+    if(var[i] < bins[0]){
+      unfl=1;
+      fNunfl[i]++;
+    }
+
+    //overflows
+
+    if(var[i] > bins[nbins-1]){
+      ovfl=1;
+      fNovfl[i]++;
+    }
+    delete [] bins;
+  }
+
+  // Total number of entries, overflows and underflows
+
+  fNentriesTot++;
+  if(unfl)fNunflTot++;
+  if(ovfl)fNovflTot++;
+
+  //if not ovfl/unfl, fill the element  
+  if(!(ovfl==1 || unfl==1)){
+    Int_t ind =GetBinIndex(fIndex);
+    fData[ind]+=weight;
+    if(fSumW2)fErr2[ind]+=(weight*weight);
+  }
+} 
+//____________________________________________________________________
+Float_t AliCFGrid::GetOverFlows( Int_t ivar) const {
+  //
+  // Get overflows in variable var 
+  //
+  return fNovfl[ivar];
+} 
+//____________________________________________________________________
+Float_t AliCFGrid::GetOverFlows() const {
+  //
+  // Get overflows 
+  //
+  return fNovflTot;
+} 
+//____________________________________________________________________
+Float_t AliCFGrid::GetUnderFlows( Int_t ivar) const {
+  //
+  // Get overflows in variable var 
+  //
+  return fNunfl[ivar];
+} 
+//____________________________________________________________________
+Float_t AliCFGrid::GetUnderFlows() const {
+  //
+  // Get overflows 
+  //
+  return fNunflTot;
+} 
+//____________________________________________________________________
+Float_t AliCFGrid::GetEntries( ) const {
+  //
+  // Get total entries (in grid + over/underflows) 
+  //
+  return fNentriesTot;
+} 
+//____________________________________________________________________
+Int_t AliCFGrid::GetEmptyBins() const {
+  //
+  // Get empty bins 
+  //
+  Int_t val=0;
+  for(Int_t i=0;i<fNDim;i++){
+    if(fData[i]<=0)val++;     
+  }
+  return val;
+} 
+//_____________________________________________________________________
+Int_t AliCFGrid::GetEmptyBins( Float_t *varMin, Float_t* varMax ) const 
+{
+  //
+  // Get empty bins in a range
+  //
+
+  Int_t *indexMin=new Int_t[fNVar];
+  Int_t *indexMax=new Int_t[fNVar];
+
+  //Find out the min and max bins
+
+  for(Int_t i=0;i<fNVar;i++){
+    Float_t xmin=varMin[i]; // the min values  
+    Float_t xmax=varMax[i]; // the min values  
+    Int_t nbins=fNVarBins[i]+1;
+    Float_t *bins=new Float_t[nbins];
+    for(Int_t ibin =0;ibin<nbins;ibin++){
+     bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
+    }
+    indexMin[i] = TMath::BinarySearch(nbins,bins,xmin);
+    indexMax[i] = TMath::BinarySearch(nbins,bins,xmax);
+    if(xmax>=bins[nbins-1]){
+      indexMax[i]=indexMax[i]-1;
+    }  
+    delete [] bins;
+  }
+
+  Int_t val=0;
+  for(Int_t i=0;i<fNDim;i++){
+    for (Int_t j=0;j<fNVar;j++)fIndex[j]=GetBinIndex(j,i);
+    Bool_t isIn=kTRUE;
+    for (Int_t j=0;j<fNVar;j++){
+      if(!(fIndex[j]>=indexMin[j] && fIndex[j]<=indexMax[j]))isIn=kFALSE;   
+    }
+    if(isIn && fData[i]<=0)val++;     
+  }
+  AliInfo(Form(" the empty bins = %i ",val)); 
+
+  delete [] indexMin;
+  delete [] indexMax;
+  return val;
+} 
+//____________________________________________________________________
+Int_t AliCFGrid::CheckEfficiencyStats(Float_t thr) const
+{
+  //
+  // Count the cells below a certain threshold
+  //
+  Int_t ncellsLow=0;
+  for(Int_t i=0;i<fNDim;i++){
+    if(GetElement(i)<thr)ncellsLow++;
+  }
+  return ncellsLow;
+}
+//_____________________________________________________________________
+Float_t AliCFGrid::GetIntegral() const 
+{
+  //
+  // Get full Integral
+  //
+  Float_t val=0;
+  for(Int_t i=0;i<fNDim;i++){
+    val+=fData[i];     
+  }
+  return val;  
+} 
+//_____________________________________________________________________
+Float_t AliCFGrid::GetIntegral(Int_t *binMin, Int_t* binMax ) const 
+{
+  //
+  // Get Integral in a range of bin indeces (extremes included)
+  //
+
+  Float_t val=0;
+  for(Int_t i=0;i<fNVar;i++){
+    if((binMin[i]<0) || (binMax[i]>=fNVarBins[i]) || (binMin[i]>binMax[i])){
+      AliInfo(Form(" Bin indeces in variable %i outside allowed range or in reverse order, please check!", i));
+      return val;
+    }
+  }
+  val=GetSum(0,binMin,binMax);
+  return val;
+} 
+//_____________________________________________________________________
+Float_t AliCFGrid::GetIntegral(Float_t *varMin, Float_t* varMax ) const 
+{
+  //
+  // Get Integral in a range (extremes included)
+  //
+
+  Int_t *indexMin=new Int_t[fNVar];
+  Int_t *indexMax=new Int_t[fNVar];
+
+  //Find out the min and max bins
+
+  for(Int_t i=0;i<fNVar;i++){
+    Float_t xmin=varMin[i]; // the min values  
+    Float_t xmax=varMax[i]; // the min values  
+    Int_t nbins=fNVarBins[i]+1;
+    Float_t *bins=new Float_t[nbins];
+    for(Int_t ibin =0;ibin<nbins;ibin++){
+     bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
+    }
+    indexMin[i] = TMath::BinarySearch(nbins,bins,xmin);
+    indexMax[i] = TMath::BinarySearch(nbins,bins,xmax);
+    if(xmax>=bins[nbins-1]){
+      indexMax[i]=indexMax[i]-1;
+    }  
+    delete [] bins;
+  }
+
+  Float_t val=GetIntegral(indexMin,indexMax);
+
+  delete [] indexMin;
+  delete [] indexMax;
+
+  return val;
+} 
+//___________________________________________________________________
+TH1F *AliCFGrid::Project(Int_t ivar) const
+{
+  //
+  // Make a 1D projection along variable ivar 
+
+
+  Int_t nbins =fNVarBins[ivar];
+  Float_t *bins = new Float_t[nbins+1];    
+  for (Int_t i=0;i<=fNVar;i++){
+  }
+  for(Int_t ibin =0;ibin<nbins+1;ibin++){
+    bins[ibin] = fVarBinLimits[ibin+fOffset[ivar]];
+  }
+
+  char pname[40];
+  sprintf(pname,"%s%s_%i",GetName(),"_proj1D_var", ivar);
+  char htitle[40];
+  sprintf(htitle,"%s%s_%i",GetName(),"_proj1D_var", ivar);
+
+  TH1F *proj1D=0;
+
+  //check if a projection with identical name exist
+  TObject *obj = gROOT->FindObject(pname);
+  if (obj && obj->InheritsFrom("TH1F")) {
+    proj1D = (TH1F*)obj;
+    proj1D->Reset();
+  }
+
+  if(!proj1D){
+    proj1D =new TH1F(pname,htitle, nbins, bins);
+  }  
+
+  delete [] bins;
+  Float_t sum=0;
+  Float_t *data= new Float_t[nbins];
+  Float_t *err= new Float_t[nbins];
+  
+  for(Int_t ibin=0;ibin<nbins;ibin++)data[ibin]=0;
+  for(Int_t ibin=0;ibin<nbins;ibin++)err[ibin]=0;
+  for(Int_t iel=0;iel<fNDim;iel++){
+      data[GetBinIndex(ivar,iel)]+=fData[iel];
+      if(fSumW2)err[GetBinIndex(ivar,iel)]+=fErr2[iel];
+  }
+
+  for(Int_t ibin =0;ibin<nbins;ibin++){
+    proj1D->SetBinContent(ibin+1,data[ibin]);
+    proj1D->SetBinError(ibin+1,TMath::Sqrt(data[ibin]));
+    if(fSumW2)proj1D->SetBinError(ibin+1,TMath::Sqrt(err[ibin]));
+    sum+=data[ibin];
+  }
+
+  delete [] data;
+  delete [] err;
+  proj1D->SetBinContent(nbins+1,GetOverFlows(ivar));
+  proj1D->SetBinContent(0,GetUnderFlows(ivar));
+  proj1D->SetEntries(GetEntries());
+  return proj1D;
+} 
+
+//___________________________________________________________________
+TH2F *AliCFGrid::Project(Int_t ivar1, Int_t ivar2) const
+{
+  //
+  // Make a 2D projection along variable ivar 
+
+  Int_t nbins1 =fNVarBins[ivar1];
+  Int_t nbins2 =fNVarBins[ivar2];
+
+  Float_t *bins1 = new Float_t[nbins1+1];         
+  Float_t *bins2 = new Float_t[nbins2+1];     
+
+  for(Int_t ibin =0;ibin<nbins1+1;ibin++){
+    bins1[ibin] = fVarBinLimits[ibin+fOffset[ivar1]];
+  }
+  for(Int_t ibin =0;ibin<nbins2+1;ibin++){
+    bins2[ibin] = fVarBinLimits[ibin+fOffset[ivar2]];
+  }
+
+  char pname[40];
+  sprintf(pname,"%s%s_%i_%i",GetName(),"_proj2D_var",ivar1,ivar2);
+  char htitle[40];
+  sprintf(htitle,"%s%s_%i_%i",GetName(),"_proj2D_var",ivar1,ivar2);
+
+  TH2F *proj2D=0;
+
+  //check if a projection with identical name exist
+  TObject *obj = gROOT->FindObject(pname);
+  if (obj && obj->InheritsFrom("TH2F")) {
+    proj2D = (TH2F*)obj;
+    proj2D->Reset();
+  }
+
+  if(!proj2D){
+    proj2D =new TH2F(pname,htitle, nbins1, bins1,nbins2,bins2);
+  }  
+
+  delete [] bins1;
+  delete [] bins2;
+
+
+  Float_t sum=0;
+  Float_t **data=new Float_t*[nbins1];
+  Float_t *data2=new Float_t[nbins1*nbins2];
+  Float_t **err=new Float_t*[nbins1];
+  Float_t *err2=new Float_t[nbins1*nbins2];
+  for(Int_t i=0;i<nbins1;i++)data[i] = data2+i*nbins2;
+  for(Int_t i=0;i<nbins1;i++)err[i] = err2+i*nbins2;
+
+  for(Int_t ibin1 =0;ibin1<nbins1;ibin1++){
+    for(Int_t ibin2 =0;ibin2<nbins2;ibin2++){
+      data[ibin1][ibin2]=0;
+      err[ibin1][ibin2]=0;
+    }
+  }
+
+  for(Int_t iel=0;iel<fNDim;iel++){
+    data[GetBinIndex(ivar1,iel)][GetBinIndex(ivar2,iel)]+=fData[iel];
+    if(fSumW2)err[GetBinIndex(ivar1,iel)][GetBinIndex(ivar2,iel)]+=fErr2[iel];
+  }
+
+  for(Int_t ibin1 =0;ibin1<nbins1;ibin1++){
+    for(Int_t ibin2 =0;ibin2<nbins2;ibin2++){
+      proj2D->SetBinContent(ibin1+1,ibin2+1,data[ibin1][ibin2]);
+      proj2D->SetBinError(ibin1+1,ibin2+1,TMath::Sqrt(data[ibin1][ibin2]));
+      if(fSumW2)proj2D->SetBinError(ibin1+1,ibin2+1,TMath::Sqrt(err[ibin1][ibin2]));
+      sum+=data[ibin1][ibin2];
+    }
+
+  } 
+  delete data;
+  delete data2;
+  delete err;
+  delete err2;
+  proj2D->SetBinContent(0,nbins2/2,GetUnderFlows(ivar1));
+  proj2D->SetBinContent(nbins1+1,nbins2/2,GetOverFlows(ivar1));
+  proj2D->SetBinContent(nbins1/2,0,GetUnderFlows(ivar2));
+  proj2D->SetBinContent(nbins1/2,nbins2+1,GetOverFlows(ivar2));
+  proj2D->SetEntries(GetEntries());
+  return proj2D;
+} 
+//___________________________________________________________________
+TH3F *AliCFGrid::Project(Int_t ivar1, Int_t ivar2, Int_t ivar3) const
+{
+  //
+  // Make a 3D projection along variable ivar 
+
+  Int_t nbins1 =fNVarBins[ivar1];
+  Int_t nbins2 =fNVarBins[ivar2];
+  Int_t nbins3 =fNVarBins[ivar3];
+
+  Float_t *bins1 = new Float_t[nbins1+1];         
+  Float_t *bins2 = new Float_t[nbins2+1];     
+  Float_t *bins3 = new Float_t[nbins3+1];     
+
+  for(Int_t ibin =0;ibin<nbins1+1;ibin++){
+    bins1[ibin] = fVarBinLimits[ibin+fOffset[ivar1]];
+  }
+  for(Int_t ibin =0;ibin<nbins2+1;ibin++){
+    bins2[ibin] = fVarBinLimits[ibin+fOffset[ivar2]];
+  }
+  for(Int_t ibin =0;ibin<nbins3+1;ibin++){
+    bins3[ibin] = fVarBinLimits[ibin+fOffset[ivar3]];
+  }
+
+  char pname[40];
+  sprintf(pname,"%s%s_%i_%i_%i",GetName(),"_proj3D_var",ivar1,ivar2,ivar3);
+  char htitle[40];
+  sprintf(htitle,"%s%s_%i_%i_%i",GetName(),"_proj3D_var",ivar1,ivar2,ivar3);
+
+  TH3F *proj3D=0;
+
+  //check if a projection with identical name exist
+  TObject *obj = gROOT->FindObject(pname);
+  if (obj && obj->InheritsFrom("TH3F")) {
+    proj3D = (TH3F*)obj;
+    proj3D->Reset();
+  }
+
+  if(!proj3D){
+    proj3D =new TH3F(pname,htitle, nbins1,bins1,nbins2,bins2,nbins3,bins3);
+  }  
+
+  delete [] bins1;
+  delete [] bins2;
+  delete [] bins3;
+
+
+  Float_t sum=0;
+  Float_t ***data=new Float_t**[nbins1];
+  Float_t **data2=new Float_t*[nbins1*nbins2];
+  Float_t *data3=new Float_t[nbins1*nbins2*nbins3];
+  Float_t ***err=new Float_t**[nbins1];
+  Float_t **err2=new Float_t*[nbins1*nbins2];
+  Float_t *err3=new Float_t[nbins1*nbins2*nbins3];
+  for(Int_t i=0;i<nbins1;i++)data[i] = data2+i*nbins2;
+  for(Int_t i=0;i<nbins1;i++)err[i] = err2+i*nbins2;
+  for(Int_t i=0;i<nbins1;i++){
+    for(Int_t j=0;j<nbins2;j++){
+      data[i][j] = data3+i*nbins2*nbins3+j*nbins3;
+      err[i][j] = err3+i*nbins2*nbins3+j*nbins3;
+    }
+  }
+  for(Int_t ibin1 =0;ibin1<nbins1;ibin1++){
+    for(Int_t ibin2 =0;ibin2<nbins2;ibin2++){
+      for(Int_t ibin3 =0;ibin3<nbins3;ibin3++){
+       data[ibin1][ibin2][ibin3]=0;
+       err[ibin1][ibin2][ibin3]=0;
+      }
+    }
+  }
+  
+  for(Int_t iel=0;iel<fNDim;iel++){
+    data[GetBinIndex(ivar1,iel)][GetBinIndex(ivar2,iel)][GetBinIndex(ivar3,iel)]+=fData[iel];
+    if(fSumW2)err[GetBinIndex(ivar1,iel)][GetBinIndex(ivar2,iel)][GetBinIndex(ivar3,iel)]+=fErr2[iel];
+  }
+
+  for(Int_t ibin1 =0;ibin1<nbins1;ibin1++){
+    for(Int_t ibin2 =0;ibin2<nbins2;ibin2++){
+      for(Int_t ibin3 =0;ibin3<nbins3;ibin3++){
+       proj3D->SetBinContent(ibin1+1,ibin2+1,ibin3+1,data[ibin1][ibin2][ibin3]);
+       proj3D->SetBinError(ibin1+1,ibin2+1,ibin3+1,TMath::Sqrt(data[ibin1][ibin2][ibin3]));
+       if(fSumW2)proj3D->SetBinError(ibin1+1,ibin2+1,ibin3+1,TMath::Sqrt(err[ibin1][ibin2][ibin3]));
+       sum+=data[ibin1][ibin2][ibin3];
+      }
+    }
+  } 
+
+  delete data;
+  delete data2;
+  delete data3;
+  delete err;
+  delete err2;
+  delete err3;
+  proj3D->SetEntries(GetEntries());
+  return proj3D;
+} 
+
+//___________________________________________________________________
+TH1F *AliCFGrid::Slice(Int_t ivar, Float_t *varMin, Float_t* varMax) const
+{
+  //
+  // Make a slice along variable ivar in range [varMin,varMax]
+
+
+  Int_t nbins =fNVarBins[ivar];
+  Float_t *bins = new Float_t[nbins+1];    
+  for (Int_t i=0;i<=fNVar;i++){
+  }
+  for(Int_t ibin =0;ibin<nbins+1;ibin++){
+    bins[ibin] = fVarBinLimits[ibin+fOffset[ivar]];
+  }
+
+  char pname[40];
+  sprintf(pname,"%s%s_%i",GetName(),"_proj1D_var", ivar);
+  char htitle[40];
+  sprintf(htitle,"%s%s_%i",GetName(),"_proj1D_var", ivar);
+
+  TH1F *proj1D=0;
+
+  //check if a projection with identical name exist
+  TObject *obj = gROOT->FindObject(pname);
+  if (obj && obj->InheritsFrom("TH1F")) {
+    proj1D = (TH1F*)obj;
+    proj1D->Reset();
+  }
+
+  if(!proj1D){
+    proj1D =new TH1F(pname,htitle, nbins, bins);
+  }  
+
+  delete [] bins;
+
+
+  Int_t *indexMin=new Int_t[fNVar];
+  Int_t *indexMax=new Int_t[fNVar];
+
+
+  //Find out the min and max bins
+
+  for(Int_t i=0;i<fNVar;i++){
+    Float_t xmin=varMin[i]; // the min values  
+    Float_t xmax=varMax[i]; // the min values  
+    Int_t nbins=fNVarBins[i]+1;
+    Float_t *bins=new Float_t[nbins];
+    for(Int_t ibin =0;ibin<nbins;ibin++){
+     bins[ibin] = fVarBinLimits[ibin+fOffset[i]];
+    }
+    indexMin[i] = TMath::BinarySearch(nbins,bins,xmin);
+    indexMax[i] = TMath::BinarySearch(nbins,bins,xmax);
+    if(xmax>=bins[nbins-1]){
+      indexMax[i]=indexMax[i]-1;
+    }  
+    delete [] bins;
+  }
+
+  Float_t sum=0;
+  Float_t *data= new Float_t[nbins];
+  for(Int_t ibin=0;ibin<nbins;ibin++)data[ibin]=0;
+
+  Int_t *index= new Int_t[fNVar];
+  Int_t ielmin=GetBinIndex(indexMin);
+  Int_t ielmax=GetBinIndex(indexMax);
+  for(Int_t iel=ielmin;iel<=ielmax;iel++){
+    GetBinIndex(iel,index);
+    Bool_t isIn=kTRUE;
+    for (Int_t j=0;j<fNVar;j++){
+      if(!(index[j]>=indexMin[j] && index[j]<=indexMax[j]))isIn=kFALSE;   
+      break;
+    }
+    if(isIn)data[GetBinIndex(ivar,iel)]+=fData[iel];
+  }
+
+  delete [] index;
+
+
+  for(Int_t ibin =0;ibin<nbins;ibin++){
+    proj1D->SetBinContent(ibin+1,data[ibin]);
+    proj1D->SetBinError(ibin+1,TMath::Sqrt(data[ibin]));
+    sum+=data[ibin];
+  }
+
+  delete [] data;
+
+  proj1D->SetEntries(sum);
+  return proj1D;
+} 
+
+//____________________________________________________________________
+Long64_t AliCFGrid::Merge(TCollection* list)
+{
+  // Merge a list of AliCorrection objects with this (needed for
+  // PROOF). 
+  // Returns the number of merged objects (including this).
+
+  if (!list)
+    return 0;
+  
+  if (list->IsEmpty())
+    return 1;
+
+  TIterator* iter = list->MakeIterator();
+  TObject* obj;
+  
+  Int_t count = 0;
+  while ((obj = iter->Next())) {
+    AliCFGrid* entry = dynamic_cast<AliCFGrid*> (obj);
+    if (entry == 0) 
+      continue;
+    this->Add(entry);
+    count++;
+  }
+
+  return count+1;
+}
+
+//____________________________________________________________________
+void AliCFGrid::Add(AliCFGrid* aGrid, Float_t c)
+{
+  //
+  //add aGrid to the current one
+  //
+
+  if(aGrid->GetNVar()!=fNVar){
+    AliInfo("Different number of variables, cannot add the grids");
+    return;
+  } 
+  if(aGrid->GetNDim()!=fNDim){
+    AliInfo("Different number of dimensions, cannot add the grids!");
+    return;
+  } 
+  
+  if(!fSumW2  && aGrid->GetSumW2())SumW2();
+
+  for(Int_t iel=0;iel<fNDim;iel++){
+    fData[iel]+=(c*aGrid->GetElement(iel));
+    if(fSumW2){
+      Float_t err=TMath::Sqrt(aGrid->GetElementError(iel));  
+      fErr2[iel]+=c*c*err*err;
+    }
+  }
+
+  //Add entries, overflows and underflows
+
+  fNentriesTot+= c*aGrid->GetEntries();
+  fNunflTot+= c*aGrid->GetUnderFlows();
+  fNovflTot+= c*aGrid->GetOverFlows();
+  for(Int_t j=0;j<fNVar;j++){
+    fNunfl[j]+= c*aGrid->GetUnderFlows(j);
+    fNovfl[j]+= c*aGrid->GetUnderFlows(j);
+  }
+}
+//____________________________________________________________________
+void AliCFGrid::Add(AliCFGrid* aGrid1, AliCFGrid* aGrid2, Float_t c1,Float_t c2)
+{
+  //
+  //add aGrid1 and aGrid2
+  //
+
+  if(fNVar!=aGrid1->GetNVar()|| fNVar!=aGrid2->GetNVar()){
+    AliInfo("Different number of variables, cannot add the grids");
+    return;
+  } 
+  if(fNDim!=aGrid1->GetNDim()|| fNDim!=aGrid2->GetNDim()){
+    AliInfo("Different number of dimensions, cannot add the grids!");
+    return;
+  } 
+  
+  if(!fSumW2  && (aGrid1->GetSumW2() || aGrid2->GetSumW2()))SumW2();
+
+  Float_t cont1,cont2,err1,err2;  
+
+  for(Int_t iel=0;iel<fNDim;iel++){
+    cont1=aGrid1->GetElement(iel);
+    cont2=aGrid2->GetElement(iel);
+    SetElement(iel,c1*cont1+c2*cont2);
+    if(fSumW2){
+      err1=TMath::Sqrt(aGrid1->GetElementError(iel));
+      err2=TMath::Sqrt(aGrid2->GetElementError(iel));
+      SetElementError(iel,c1*c1*err1*err1+c2*c2*err2*err2);
+    }
+  }
+
+  //Add entries, overflows and underflows
+
+  fNentriesTot= c1*aGrid1->GetEntries()+c2*aGrid2->GetEntries();
+  fNunflTot= c1*aGrid1->GetUnderFlows()+c2*aGrid2->GetUnderFlows();
+  fNovflTot= c1*aGrid1->GetOverFlows()+c2*aGrid2->GetOverFlows();
+  for(Int_t j=0;j<fNVar;j++){
+    fNunfl[j]= c1*aGrid1->GetUnderFlows(j)+c2*aGrid2->GetUnderFlows(j);
+    fNovfl[j]= c1*aGrid1->GetUnderFlows(j)+c2*aGrid2->GetUnderFlows(j);
+  }
+}
+//____________________________________________________________________
+void AliCFGrid::Multiply(AliCFGrid* aGrid, Float_t c)
+{
+  //
+  //multiply grid aGrid by the current one
+  //
+
+  if(aGrid->GetNVar()!=fNVar){
+    AliInfo("Different number of variables, cannot multiply the grids");
+    return;
+  } 
+  if(aGrid->GetNDim()!=fNDim){
+    AliInfo("Different number of dimensions, cannot multiply the grids!");
+    return;
+  } 
+  
+  if(!fSumW2  && aGrid->GetSumW2())SumW2();
+  
+  Float_t cont1,cont2,err1,err2;  
+
+  for(Int_t iel=0;iel<fNDim;iel++){
+    cont1=GetElement(iel);  
+    cont2=c*aGrid->GetElement(iel);  
+    SetElement(iel,cont1*cont2);
+    if(fSumW2){
+      err1=TMath::Sqrt(GetElementError(iel));  
+      err2=TMath::Sqrt(aGrid->GetElementError(iel));  
+      SetElementError(iel,c*c*(cont2*cont2*err1*err1+cont1*cont1*err2*err2));
+    }
+  }
+
+  //Set entries to the number of bins, preserve original overflows and underflows
+
+  fNentriesTot=fNDim;
+  fNunflTot=GetUnderFlows();
+  fNovflTot=GetOverFlows();
+  for(Int_t j=0;j<fNVar;j++){
+    fNunfl[j]= GetUnderFlows(j);
+    fNovfl[j]= GetUnderFlows(j);
+  }
+}
+//____________________________________________________________________
+void AliCFGrid::Multiply(AliCFGrid* aGrid1,AliCFGrid* aGrid2, Float_t c1,Float_t c2)
+{
+  //
+  //multiply grids aGrid1 and aGrid2
+  //
+
+  if(fNVar!=aGrid1->GetNVar()|| fNVar!=aGrid2->GetNVar()){
+    AliInfo("Different number of variables, cannot multiply the grids");
+    return;
+  } 
+  if(fNDim!=aGrid1->GetNDim()|| fNDim!=aGrid2->GetNDim()){
+    AliInfo("Different number of dimensions, cannot multiply the grids!");
+    return;
+  } 
+  
+  if(!fSumW2  && (aGrid1->GetSumW2() || aGrid2->GetSumW2()))SumW2();
+
+  Float_t cont1,cont2,err1,err2;  
+  for(Int_t iel=0;iel<fNDim;iel++){
+    cont1=c1*aGrid1->GetElement(iel);  
+    cont2=c2*aGrid2->GetElement(iel);  
+    SetElement(iel,cont1*cont2);
+    if(fSumW2){
+      err1=TMath::Sqrt(aGrid1->GetElementError(iel));  
+      err2=TMath::Sqrt(aGrid2->GetElementError(iel));  
+      SetElementError(iel,c1*c1*c2*c2*(cont2*cont2*err1*err1+cont1*cont1*err2*err2));
+    }
+  }
+
+  //Set entries to the number of bins, preserve original overflows and underflows
+
+  fNentriesTot=fNDim;
+  fNunflTot=GetUnderFlows();
+  fNovflTot=GetOverFlows();
+  for(Int_t j=0;j<fNVar;j++){
+    fNunfl[j]= GetUnderFlows(j);
+    fNovfl[j]= GetUnderFlows(j);
+  }
+}
+//____________________________________________________________________
+void AliCFGrid::Divide(AliCFGrid* aGrid, Float_t c, Option_t *option)
+{
+  //
+  //divide current grid by grid aGrid
+  //
+
+  TString opt = option;
+  opt.ToUpper();
+
+  if(aGrid->GetNVar()!=fNVar){
+    AliInfo("Different number of variables, cannot divide the grids");
+    return;
+  } 
+  if(aGrid->GetNDim()!=fNDim){
+    AliInfo("Different number of dimensions, cannot divide the grids!");
+    return;
+  } 
+ if(!c){AliInfo(Form("c is %f, cannot divide!",c)); return;} 
+  
+  if(!fSumW2  && aGrid->GetSumW2())SumW2();
+
+  Float_t cont1,cont2,err1,err2,r,den;
+  for(Int_t iel=0;iel<fNDim;iel++){
+    cont1=GetElement(iel);  
+    cont2=aGrid->GetElement(iel);
+    if(cont2)SetElement(iel,cont1/(c*cont2));
+    else SetElement(iel,0);
+    if(fSumW2){
+      err1=TMath::Sqrt(GetElementError(iel));  
+      err2=TMath::Sqrt(aGrid->GetElementError(iel));  
+      if(!cont2){SetElementError(iel,0.); continue;}
+      if (opt.Contains("B")){
+       if(cont1!=cont2){
+         r=cont1/cont2;            
+         SetElementError(iel,TMath::Abs(((1-2.*r)*err1*err1+r*r*err2*err2)/(cont2*cont2)));
+       }else{
+         SetElementError(iel,0.);
+       }
+      }else{
+        den=cont2*cont2*cont2*c*c;
+       SetElementError(iel,(cont2*cont2*err1*err1+cont1*cont1*err2*err2)/den);
+      }
+    }
+  }
+
+  //Set entries to the number of bins, preserve original overflows and underflows
+
+  fNentriesTot=fNDim;
+  fNunflTot=GetUnderFlows();
+  fNovflTot=GetOverFlows();
+  for(Int_t j=0;j<fNVar;j++){
+    fNunfl[j]= GetUnderFlows(j);
+    fNovfl[j]= GetUnderFlows(j);
+  }
+}
+//____________________________________________________________________
+void AliCFGrid::Divide(AliCFGrid* aGrid1, AliCFGrid* aGrid2, Float_t c1,Float_t c2, Option_t *option)
+{
+  //
+  //divide grids aGrid1,aGrid2
+  //
+
+  TString opt = option;
+  opt.ToUpper();
+
+  if(fNVar!=aGrid1->GetNVar()|| fNVar!=aGrid2->GetNVar()){
+    AliInfo("Different number of variables, cannot divide the grids");
+    return;
+  }
+  if(fNDim!=aGrid1->GetNDim()|| fNDim!=aGrid2->GetNDim()){
+    AliInfo("Different number of dimensions, cannot divide the grids!");
+    return;
+  }
+  if(!c2){AliInfo(Form("c2 is %f, cannot divide!",c2)); return;} 
+  
+  if(!fSumW2  && (aGrid1->GetSumW2() || aGrid2->GetSumW2()))SumW2();
+
+  Float_t cont1,cont2,err1,err2,r,den;
+  for(Int_t iel=0;iel<fNDim;iel++){
+    cont1=aGrid1->GetElement(iel);  
+    cont2=aGrid2->GetElement(iel);  
+    if(cont2)SetElement(iel,c1*cont1/(c2*cont2));
+    else SetElement(iel,0);
+     if(fSumW2){
+      err1=TMath::Sqrt(aGrid1->GetElementError(iel));  
+      err2=TMath::Sqrt(aGrid2->GetElementError(iel));  
+      if(!cont2){SetElementError(iel,0.); continue;}
+      if (opt.Contains("B")){
+       if(cont1!=cont2){
+         r=cont1/cont2;            
+         SetElementError(iel,TMath::Abs(((1.-2.*r)*err1*err1+r*r*err2*err2)/(cont2*cont2)));
+       }else{
+         SetElementError(iel,0.);
+       }
+      }else{
+        den=cont2*cont2*cont2*cont2*c2*c2;
+       SetElementError(iel,c1*c1*(cont2*cont2*err1*err1+cont1*cont1*err2*err2)/den);
+      }
+    }
+  }
+
+  //Set entries to the number of bins, preserve original overflows and underflows
+
+  fNentriesTot=fNDim;
+  fNunflTot=GetUnderFlows();
+  fNovflTot=GetOverFlows();
+  for(Int_t j=0;j<fNVar;j++){
+    fNunfl[j]= GetUnderFlows(j);
+    fNovfl[j]= GetUnderFlows(j);
+  }
+}
+//____________________________________________________________________
+void AliCFGrid::SumW2()
+{
+  //
+  //set calculation of the squared sum of the weighted entries
+  //
+  if(!fSumW2){
+    fErr2=new Float_t [fNDim];
+    //init....
+    for(Int_t iel=0;iel<fNDim;iel++){
+      fErr2[iel]=fData[iel];
+    }
+  }
+
+  fSumW2=kTRUE;
+}
+//_____________________________________________________________________
+Float_t AliCFGrid::GetSum(Int_t ivar, Int_t *binMin, Int_t* binMax) const 
+{
+  //
+  // recursively add over nested loops.... 
+  //
+  static Float_t val;
+  if(ivar==0)val=0.;
+  for(Int_t ibin=binMin[ivar];ibin<=binMax[ivar];ibin++){
+    fIndex[ivar]=ibin;
+    if(ivar<fNVar-1) {
+      val=GetSum(ivar+1,binMin,binMax);
+    }
+    else {
+      Int_t iel=GetBinIndex(fIndex);
+      val+=fData[iel];
+    }
+  }
+
+  return val;
+}
+//____________________________________________________________________
+void AliCFGrid::Copy(TObject& c) const
+{
+  //
+  // copy function
+  //
+  AliCFGrid& target = (AliCFGrid &) c;
+
+  target.fNVar=fNVar;
+  target.fNDim=fNDim;
+  target.fSumW2=fSumW2;
+  target.fNVarBinLimits=fNVarBinLimits;
+  target.fNunflTot = fNunflTot;
+  target.fNovflTot = fNovflTot;
+  target.fNentriesTot = fNentriesTot;
+  if (fNVarBins)
+    target.fNVarBins = fNVarBins;
+  if (fVarBinLimits)
+    target.fVarBinLimits = fVarBinLimits;
+  if (fNunfl)
+    target.fNunfl = fNunfl;
+  if (fNunfl)
+    target.fNunfl = fNunfl;
+  if (fNovfl)
+    target.fNovfl = fNovfl;
+  if (fProduct)
+    target.fProduct = fProduct;
+  if (fOffset)
+    target.fOffset = fOffset;
+  if (fData)
+    target.fData = fData;
+  if (fErr2)
+    target.fErr2 = fErr2;
+  
+}
diff --git a/CORRFW/AliCFGrid.h b/CORRFW/AliCFGrid.h
new file mode 100644 (file)
index 0000000..06b4fd2
--- /dev/null
@@ -0,0 +1,93 @@
+#ifndef ALICFGRID_H
+#define ALICFGRID_H
+
+/* $Id$ */
+
+//--------------------------------------------------------------------//
+//                                                                    //
+// AliCFGrid.cxx Class                                                //
+// Class to handle N-dim maps for the correction Framework            // 
+//                                                                    //
+//--------------------------------------------------------------------//
+
+#include "AliCFFrame.h"
+
+class TH1F;
+class TH2F;
+class TH3F;
+
+class AliCFGrid : public AliCFFrame
+{
+ public:
+  AliCFGrid();
+  AliCFGrid(const Char_t* name,const Char_t* title);
+  AliCFGrid(const Char_t* name, const Char_t* title, const Int_t nVarIn, const Int_t* nBinIn, const Float_t  *binLimitsIn=0);
+  AliCFGrid(const AliCFGrid & c);
+  
+  virtual ~AliCFGrid();
+  AliCFGrid& operator=(const AliCFGrid& corr);
+  virtual void  Fill(Float_t *var, Float_t weight=1.);
+  virtual Float_t GetOverFlows(Int_t var) const;
+  virtual Float_t GetUnderFlows(Int_t var)const ;
+  virtual Float_t GetOverFlows()const ;
+  virtual Float_t GetUnderFlows()const ;
+  virtual Float_t GetEntries()const ;
+  virtual Int_t GetEmptyBins()const ;
+  virtual Int_t CheckEfficiencyStats(Float_t thr) const;
+  virtual Int_t GetSumW2()const {return fSumW2;};
+  virtual Float_t GetElement(Int_t iel)const; 
+  virtual Float_t GetElement(Int_t *bin)const; 
+  virtual Float_t GetElement(Float_t *var)const; 
+  virtual Float_t GetElementError(Int_t iel)const; 
+  virtual Float_t GetElementError(Int_t *bin)const; 
+  virtual Float_t GetElementError(Float_t *var)const; 
+  virtual void SetElement(Int_t iel, Float_t val); 
+  virtual void SetElement(Int_t *bin, Float_t val); 
+  virtual void SetElement(Float_t *var, Float_t val); 
+  virtual void SetElementError(Int_t iel, Float_t val); 
+  virtual void SetElementError(Int_t *bin, Float_t val); 
+  virtual void SetElementError(Float_t *var, Float_t val); 
+  virtual void Scale(Int_t iel, Float_t *fact); 
+  virtual void Scale(Int_t* bin, Float_t *fact); 
+  virtual void Scale(Float_t* var, Float_t *fact); 
+  virtual void Scale(Float_t *fact); // To normalize MC to int lumi, for ex. 
+  virtual Int_t GetEmptyBins(Float_t *varMin,Float_t *varMax) const ;
+  virtual Float_t GetIntegral() const ;
+  virtual Float_t GetIntegral(Int_t *binMin,Int_t *binMax) const ;
+  virtual Float_t GetIntegral(Float_t *varMin,Float_t *varMax) const ;
+  virtual TH1F* Project( Int_t ivar) const;
+  virtual TH2F* Project( Int_t ivar1, Int_t ivar2) const;
+  virtual TH3F* Project( Int_t ivar1, Int_t ivar2,Int_t ivar3) const;
+  virtual TH1F* Slice( Int_t ivar, Float_t *varMin, Float_t *varMax) const;
+  virtual Float_t GetSum(Int_t ivar, Int_t *binMin, Int_t* binMax) const; 
+
+  //basic operations
+
+  virtual void SumW2();
+  virtual void Copy(TObject& c) const;
+  virtual void Add(AliCFGrid* aGrid, Float_t c=1.);
+  virtual void Add(AliCFGrid* aGrid1 ,AliCFGrid* aGrid2, Float_t c1=1.,Float_t c2=1.);
+  virtual void Multiply(AliCFGrid* aGrid, Float_t c=1.);
+  virtual void Multiply(AliCFGrid* aGrid1,AliCFGrid* aGrid2, Float_t c1=1.,Float_t c2=1.);
+  virtual void Divide(AliCFGrid* aGrid, Float_t c=1.,Option_t *option=0);
+  virtual void Divide(AliCFGrid* aGrid1, AliCFGrid* aGrid2, Float_t c1=1., Float_t c2=1.,Option_t *option=0);
+  virtual Long64_t Merge(TCollection* list);
+
+  
+ protected:
+  Bool_t   fSumW2;//flag to check if calculation of squared weights enabled
+  Float_t  fNunflTot;//Total number of underflows
+  Float_t  fNovflTot;//Total number of underflows
+  Float_t  fNentriesTot;//Total number of entries 
+  Float_t  *fNunfl;//[fNVar] underflows in each dimension
+  Float_t  *fNovfl;//[fNVar] overflows in each dimension
+
+  Float_t  *fData;//[fNDim] The data Container
+  Float_t  *fErr2;//[fNDim] The squared weights Container (only with SumW2)
+
+  
+  ClassDef(AliCFGrid,1);
+};
+    
+#endif
+
diff --git a/CORRFW/AliCFManager.cxx b/CORRFW/AliCFManager.cxx
new file mode 100644 (file)
index 0000000..069aa05
--- /dev/null
@@ -0,0 +1,337 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+///////////////////////////////////////////////////////////////////////////
+// The class AliCFManager is designed to handle inside the 
+// task the basic components for a particle-level correction of single 
+// particle analysis
+// The class provides methods to set lists of cuts and to loop over them 
+// for several different selection steps to be then used for
+// efficiency calculation.
+// prototype version by S.Arcelli silvia.arcelli@cern.ch
+///////////////////////////////////////////////////////////////////////////
+#include "TBits.h"
+#include "TList.h"
+#include "TH1.h"
+#include "AliLog.h"
+#include "AliCFCutBase.h"
+#include "AliCFManager.h"
+
+ClassImp(AliCFManager)
+
+//_____________________________________________________________________________
+AliCFManager::AliCFManager() : 
+  TNamed(),
+  fEvtContainer(0x0),
+  fPartContainer(0x0),
+  fhQABits(0x0)
+
+{ 
+  //
+  // ctor
+  //
+  for(Int_t i=0;i<kNEvtSel;i++)fEvtCutList[i]=0x0;
+  for(Int_t i=0;i<kNPartSel;i++)fPartCutList[i]=0x0;
+  fhQABits=new TBits(0);
+}
+//_____________________________________________________________________________
+AliCFManager::AliCFManager(Char_t* name, Char_t* title) : 
+  TNamed(name,title),
+  fEvtContainer(0x0),
+  fPartContainer(0x0),
+  fhQABits(0x0)
+ { 
+   //
+   // ctor
+   //
+  for(Int_t i=0;i<kNEvtSel;i++)fEvtCutList[i]=0x0;
+  for(Int_t i=0;i<kNPartSel;i++)fPartCutList[i]=0x0;
+  fhQABits=new TBits(0);
+}
+//_____________________________________________________________________________
+AliCFManager::AliCFManager(const AliCFManager& c) : 
+  TNamed(c),
+  fEvtContainer(c.fEvtContainer),
+  fPartContainer(c.fPartContainer),
+  fhQABits(c.fhQABits)
+ { 
+   //
+   //copy ctor
+   //
+  for(Int_t i=0;i<kNEvtSel;i++)fEvtCutList[i]=c.fEvtCutList[i];
+  for(Int_t i=0;i<kNPartSel;i++)fPartCutList[i]=c.fPartCutList[i];
+ }
+//_____________________________________________________________________________
+AliCFManager& AliCFManager::operator=(const AliCFManager& c)
+{
+  //
+  // Assignment operator
+  //
+  if (this != &c) {
+    TNamed::operator=(c) ;
+  }
+
+  this->fEvtContainer=c.fEvtContainer;
+  this->fPartContainer=c.fPartContainer;
+  this->fhQABits=c.fhQABits;
+  for(Int_t i=0;i<kNEvtSel;i++)this->fEvtCutList[i]=c.fEvtCutList[i];
+  for(Int_t i=0;i<kNPartSel;i++)this->fPartCutList[i]=c.fPartCutList[i];
+  return *this ;
+}
+
+//_____________________________________________________________________________
+AliCFManager::~AliCFManager() {
+   //
+   //dtor
+   //
+  if(fhQABits) delete fhQABits;
+}
+
+//_____________________________________________________________________________
+Bool_t AliCFManager::CheckParticleCuts(Int_t isel, TObject *obj, const TString  &selcuts) const {
+  //
+  // check whether object obj passes particle-level selection isel
+  //
+
+  if(isel>=kNPartSel){
+    AliWarning(Form("Selection index out of Range! isel=%i, max. number of selections= %i", isel,kNPartSel));
+      return kTRUE;
+  }
+  if(!fPartCutList[isel])return kTRUE;
+  TObjArrayIter iter(fPartCutList[isel]);
+  AliCFCutBase *cut = 0;
+  while ( (cut = (AliCFCutBase*)iter.Next()) ) {
+    TString cutName=cut->GetName();
+    Bool_t checkCut=CompareStrings(cutName,selcuts);
+    if(checkCut && !cut->IsSelected(obj)) return kFALSE;   
+  }
+  return kTRUE;
+}
+
+//_____________________________________________________________________________
+Bool_t AliCFManager::CheckEventCuts(Int_t isel, TObject *obj, const TString  &selcuts) const{
+  //
+  // check whether object obj passes event-level selection isel
+  //
+
+  if(isel>=kNEvtSel){
+    AliWarning(Form("Selection index out of Range! isel=%i, max. number of selections= %i", isel,kNEvtSel));
+      return kTRUE;
+  }
+  if(!fEvtCutList[isel])return kTRUE;
+  TObjArrayIter iter(fEvtCutList[isel]);
+  AliCFCutBase *cut = 0;
+  while ( (cut = (AliCFCutBase*)iter.Next()) ) {
+    TString cutName=cut->GetName();
+    Bool_t checkCut=CompareStrings(cutName,selcuts);
+    if(checkCut && !cut->IsSelected(obj)) return kFALSE;   
+  }
+  return kTRUE;
+}
+
+//_____________________________________________________________________________
+void AliCFManager::FillQABeforeParticleCuts(Int_t isel, TObject *obj) const{
+  //
+  // Fill QA histos before cuts at particle selection level isel are applied
+  //
+
+  if(isel>=kNPartSel){
+    AliWarning(Form("Selection index out of Range! isel=%i, max. number of selections= %i", isel,kNPartSel));
+      return;
+  }
+  if(!fPartCutList[isel])return;
+
+  TObjArrayIter iter(fPartCutList[isel]);
+  AliCFCutBase *cut = 0;
+  while ( (cut = (AliCFCutBase*)iter.Next()) ) {
+    if(cut->IsQAOn())cut->FillHistogramsBeforeCuts(obj);   
+  }
+}
+//_____________________________________________________________________________
+void AliCFManager::FillQAAfterParticleCuts(Int_t isel, TObject *obj) const{
+  //
+  // Fill QA histos after cuts at particle selection level isel are applied
+  //
+  if(isel>=kNPartSel){
+    AliWarning(Form("Selection index out of Range! isel=%i, max. number of selections= %i", isel,kNPartSel));
+      return;
+  }
+  if(!fPartCutList[isel])return;
+
+  TObjArrayIter iter(fPartCutList[isel]);
+  AliCFCutBase *cut = 0;
+  while ( (cut = (AliCFCutBase*)iter.Next()) ) {
+    if(cut->IsQAOn())cut->FillHistogramsAfterCuts(obj);   
+  }
+}
+
+//_____________________________________________________________________________
+void AliCFManager::FillQABeforeEventCuts(Int_t isel, TObject *obj) const{
+  //
+  // Fill QA histos before cuts at event selection level isel are applied
+  //
+
+  if(isel>=kNEvtSel){
+    AliWarning(Form("Selection index out of Range! isel=%i, max. number of selections= %i", isel,kNEvtSel));
+      return;
+  }
+  if(!fEvtCutList[isel])return;
+
+  TObjArrayIter iter(fEvtCutList[isel]);
+  AliCFCutBase *cut = 0;
+  while ( (cut = (AliCFCutBase*)iter.Next()) ) {
+    if(cut->IsQAOn())cut->FillHistogramsBeforeCuts(obj);   
+  }
+}
+
+//_____________________________________________________________________________
+void AliCFManager::FillQAAfterEventCuts(Int_t isel, TObject *obj) const{
+  //
+  // Fill QA histos after cuts at event selection level isel are applied
+  //
+
+  if(isel>=kNEvtSel){
+    AliWarning(Form("Selection index out of Range! isel=%i, max. number of selections= %i", isel,kNEvtSel));
+      return;
+  }
+  if(!fEvtCutList[isel])return;
+
+  TObjArrayIter iter(fEvtCutList[isel]);
+  AliCFCutBase *cut = 0;
+  while ( (cut = (AliCFCutBase*)iter.Next()) ) {
+    if(cut->IsQAOn())cut->FillHistogramsAfterCuts(obj);   
+  }
+}
+
+//_____________________________________________________________________________
+void AliCFManager::AddQAHistosToList(TList *list) const {
+  //
+  // Add to list the full list of QA histograms to be written to the output
+  //
+
+  for(Int_t isel=0;isel<kNPartSel; isel++){
+    if(!fPartCutList[isel])continue;  
+    TObjArrayIter iter(fPartCutList[isel]);
+    AliCFCutBase *cut = 0;
+    while ( (cut = (AliCFCutBase*)iter.Next()) ) {
+      if(cut->IsQAOn())cut->AddQAHistograms(list);     
+    }
+  }  
+
+  //Event-level cuts QA
+
+  for(Int_t isel=0;isel<kNEvtSel; isel++){
+    if(!fEvtCutList[isel])continue;  
+    TObjArrayIter iter(fEvtCutList[isel]);
+    AliCFCutBase *cut = 0;
+    while ( (cut = (AliCFCutBase*)iter.Next()) ) {
+      if(cut->IsQAOn())cut->AddQAHistograms(list);
+    }
+  }    
+}
+//_____________________________________________________________________________
+TBits* AliCFManager::GetQAParticleSelBits(Int_t isel, TObject *obj) {
+  //
+  // Get the full list of QA histograms to be written to the output
+  //
+
+  fhQABits->Clear(); //reset the list
+  
+  //Particle-level cuts QA
+
+  if(fPartCutList[isel]){  
+    TObjArrayIter iter(fPartCutList[isel]);
+    AliCFCutBase *cut = 0;
+    while ( (cut = (AliCFCutBase*)iter.Next()) ) {
+      if(cut->IsQAOn()){
+       TBits *qalist=new TBits(0);
+       cut->GetBitMap(obj,qalist);
+       for(UInt_t icut=0;icut<qalist->GetNbits();icut++){
+         fhQABits->SetBitNumber(icut,qalist->TestBitNumber(icut));    
+       }
+       delete qalist;
+      }
+    }    
+  }
+
+  return fhQABits;
+
+}
+
+//_____________________________________________________________________________
+void  AliCFManager::SetEventInfo(TObject *obj) const {
+
+  //Particle level cuts
+
+  for(Int_t isel=0;isel<kNPartSel; isel++){
+    if(!fPartCutList[isel])continue;  
+    TObjArrayIter iter(fPartCutList[isel]);
+    AliCFCutBase *cut = 0;
+    while ( (cut = (AliCFCutBase*)iter.Next()) ) {
+      cut->SetEvtInfo(obj);
+    }    
+  }
+  
+  //Event level cuts 
+
+  for(Int_t isel=0;isel<kNEvtSel; isel++){
+    if(!fEvtCutList[isel])continue;  
+    TObjArrayIter iter(fEvtCutList[isel]);
+    AliCFCutBase *cut = 0;
+    while ( (cut = (AliCFCutBase*)iter.Next()) ) {
+      cut->SetEvtInfo(obj);
+    }    
+  }
+}
+//_____________________________________________________________________________
+void  AliCFManager::InitQAHistos() const {
+
+  //Particle level cuts
+
+  for(Int_t isel=0;isel<kNPartSel; isel++){
+    if(!fPartCutList[isel])continue;  
+    TObjArrayIter iter(fPartCutList[isel]);
+    AliCFCutBase *cut = 0;
+    while ( (cut = (AliCFCutBase*)iter.Next()) ) {
+      if(cut->IsQAOn())cut->Init();
+    }    
+  }
+  
+  //Event level cuts 
+
+  for(Int_t isel=0;isel<kNEvtSel; isel++){
+    if(!fEvtCutList[isel])continue;  
+    TObjArrayIter iter(fEvtCutList[isel]);
+    AliCFCutBase *cut = 0;
+    while ( (cut = (AliCFCutBase*)iter.Next()) ) {
+      if(cut->IsQAOn())cut->Init();
+    }    
+  }
+}
+
+//_____________________________________________________________________________
+Bool_t AliCFManager::CompareStrings(const TString  &cutname,const TString  &selcuts) const{
+  //
+  // compare two strings
+  //
+
+  if(selcuts.Contains("all"))return kTRUE;
+  if ( selcuts.CompareTo(cutname) == 0 ||
+       selcuts.BeginsWith(cutname+" ") ||
+       selcuts.EndsWith(" "+cutname) ||
+       selcuts.Contains(" "+cutname+" "))  return kTRUE; 
+  return kFALSE;
+}
+
+
diff --git a/CORRFW/AliCFManager.h b/CORRFW/AliCFManager.h
new file mode 100644 (file)
index 0000000..f2a1619
--- /dev/null
@@ -0,0 +1,134 @@
+#ifndef ALICFMANAGER_H
+#define ALICFMANAGER_H
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+// Prototype class helping the user to handle event & particle-level 
+// selections/correction containers inside the Analysis job
+// Author:S.Arcelli. Silvia.Arcelli@cern.ch 
+
+#include "TNamed.h"
+
+class TObject;
+class TList;
+class TBits;
+class AliCFContainer ;
+class AliMCEventHandler ;
+class AliGenEventHeader ;
+//____________________________________________________________________________
+class AliCFManager : public TNamed 
+{
+ public :
+  AliCFManager() ;
+  AliCFManager(Char_t* name, Char_t* title) ;
+  AliCFManager(const AliCFManager& c) ;
+  AliCFManager& operator=(const AliCFManager& c) ;
+  virtual ~AliCFManager();
+
+  //
+  //Currently foreseen selection steps for event-level cuts:
+  //generator, trigger, reconstruction
+  //
+  enum{
+    kEvtGenCuts=0,
+      kEvtTrigCuts,
+      kEvtRecCuts,
+      kNEvtSel=3
+      };
+
+  //
+  //Currently foreseen selection steps for particle-level cuts:
+  //generator, acceptance, reconstruction, user selection
+  //
+
+  enum{
+      kPartGenCuts=0,
+      kPartAccCuts,
+      kPartRecCuts,
+      kPartSelCuts,
+      kNPartSel=4
+      };
+
+  //
+  // Setters:
+  //
+  //pass the pointer to the correction container
+  virtual void SetEventContainer(AliCFContainer* c) {fEvtContainer=c;} ; 
+
+  //pass the pointer to the correction container
+  virtual void SetParticleContainer(AliCFContainer* c) {fPartContainer=c;} ; 
+
+  //Setter for event-level selection cut list at selection step isel
+  virtual void SetEventCutsList(Int_t isel, TObjArray* array) {fEvtCutList[isel]=array;} ; 
+
+  //Setter for particle-level selection cut list at selection step isel
+  virtual void SetParticleCutsList(Int_t isel, TObjArray* array) {fPartCutList[isel]=array;} ; 
+
+
+  //
+  //Getters
+  //
+  // pointer to the Event-level correction container
+  virtual AliCFContainer* GetEventContainer() const {return fEvtContainer;} ; 
+
+  // pointer to the Particle-level correction container
+  virtual AliCFContainer* GetParticleContainer() const {return fPartContainer;} ; 
+
+  //pointer to the event-level cut list for event selection step isel
+  virtual TObjArray* GetEventCutsList(Int_t isel) const {return fEvtCutList[isel];};
+
+//pointer to the particle-level cut list for particle selection step isel
+  virtual TObjArray* GetParticleCutsList(Int_t isel) const {return fPartCutList[isel];};
+  
+
+  //Pass the pointer to obj to the selections (used to access MC/rec global
+  //event info when requested
+  virtual void SetEventInfo(TObject *obj) const;
+
+  //Cut Checkers: by default *all* the cuts of a given input list is checked 
+  //(.and. of all cuts), but the user can select a subsample of cuts in the 
+  //list via the string argument selcuts
+  virtual Bool_t CheckEventCuts(Int_t isel, TObject *obj, const TString &selcuts="all") const;
+  virtual Bool_t CheckParticleCuts(Int_t isel, TObject *obj, const TString &selcuts="all") const;
+
+  virtual void FillQABeforeEventCuts(Int_t isel, TObject *obj) const;
+  virtual void FillQAAfterEventCuts(Int_t isel, TObject *obj) const;
+  virtual void FillQABeforeParticleCuts(Int_t isel, TObject *obj) const;
+  virtual void FillQAAfterParticleCuts(Int_t isel, TObject *obj) const;
+
+  virtual void InitQAHistos() const;//init QA histograms
+  virtual TBits*  GetQAParticleSelBits(Int_t isel, TObject *obj);//get cut mask
+  virtual void AddQAHistosToList(TList *list) const; //put the QA histos in TList
+  
+  
+ private:
+
+  //the correction grid
+  AliCFContainer *fEvtContainer; //ptr to Evt-Level correction container
+  //the correction grid
+  AliCFContainer *fPartContainer; //ptr to Particle-level correction container
+  //Evt-Level Selections
+  TObjArray *fEvtCutList[kNEvtSel]; //arrays of cuts: gen,trig,rec-level
+  //Particle-level selections
+  TObjArray *fPartCutList[kNPartSel]; //arrays of cuts: gen,acceptance,rec,sel-level
+  TBits *fhQABits; // Global list of Cuts' QA BitMaps
+
+  Bool_t CompareStrings(const TString  &cutname,const TString  &selcuts) const;
+
+  ClassDef(AliCFManager,1);
+};
+
+
+#endif
diff --git a/CORRFW/AliCFParticleGenCuts.cxx b/CORRFW/AliCFParticleGenCuts.cxx
new file mode 100644 (file)
index 0000000..df4d0f8
--- /dev/null
@@ -0,0 +1,287 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+////////////////////////////////////////////////////////////////////////////
+//          ----   CORRECTION FRAMEWORK   ----
+// class AliCFParticleGenCuts implementation
+// Using this class a user may define selections relative to 
+// MC particle (AliMCParticle) using generation-level information.
+////////////////////////////////////////////////////////////////////////////
+// author : R. Vernet (renaud.vernet@cern.ch)
+////////////////////////////////////////////////////////////////////////////
+
+#include "AliLog.h"
+#include "AliCFParticleGenCuts.h"
+#include "TParticle.h"
+#include "TParticlePDG.h"
+#include "AliMCEventHandler.h"
+#include "AliMCEvent.h"
+#include "TObject.h"
+#include "AliStack.h"
+
+ClassImp(AliCFParticleGenCuts)
+
+//______________________________
+AliCFParticleGenCuts::AliCFParticleGenCuts() : 
+  AliCFCutBase(),
+  fMCInfo(0x0),
+  fRequireIsCharged(0),
+  fRequireIsPrimary(0),
+  fRequireIsSecondary(0),
+  fRequirePdgCode(0),
+  fPdgCode(0),
+  fProdVtxXMin (-1.e+09),
+  fProdVtxYMin (-1.e+09),
+  fProdVtxZMin (-1.e+09),
+  fProdVtxXMax ( 1.e+09),
+  fProdVtxYMax ( 1.e+09),
+  fProdVtxZMax ( 1.e+09),
+  fDecayVtxXMin(-1.e+09),
+  fDecayVtxYMin(-1.e+09),
+  fDecayVtxZMin(-1.e+09),
+  fDecayVtxXMax( 1.e+09),
+  fDecayVtxYMax( 1.e+09),
+  fDecayVtxZMax( 1.e+09),
+  fDecayLengthMin(0),
+  fDecayLengthMax(1.e+09),
+  fDecayRxyMin(0),
+  fDecayRxyMax(1.e+09)
+{
+  //
+  //ctor
+  //
+}
+
+//______________________________
+AliCFParticleGenCuts::AliCFParticleGenCuts(const Char_t* name, const Char_t* title) : 
+  AliCFCutBase(name,title),
+  fMCInfo(0x0),
+  fRequireIsCharged(0),
+  fRequireIsPrimary(0),
+  fRequireIsSecondary(0),
+  fRequirePdgCode(0),
+  fPdgCode(0),
+  fProdVtxXMin (-1.e+09),
+  fProdVtxYMin (-1.e+09),
+  fProdVtxZMin (-1.e+09),
+  fProdVtxXMax ( 1.e+09),
+  fProdVtxYMax ( 1.e+09),
+  fProdVtxZMax ( 1.e+09),
+  fDecayVtxXMin(-1.e+09),
+  fDecayVtxYMin(-1.e+09),
+  fDecayVtxZMin(-1.e+09),
+  fDecayVtxXMax( 1.e+09),
+  fDecayVtxYMax( 1.e+09),
+  fDecayVtxZMax( 1.e+09),
+  fDecayLengthMin(0),
+  fDecayLengthMax(1.e+09),
+  fDecayRxyMin(0),
+  fDecayRxyMax(1.e+09)
+{
+  //
+  //ctor
+  //
+}
+
+//______________________________
+AliCFParticleGenCuts::AliCFParticleGenCuts(const AliCFParticleGenCuts& c) : 
+  AliCFCutBase(c),
+  fMCInfo(c.fMCInfo),
+  fRequireIsCharged(c.fRequireIsCharged),
+  fRequireIsPrimary(c.fRequireIsPrimary),
+  fRequireIsSecondary(c.fRequireIsSecondary),
+  fRequirePdgCode(c.fRequirePdgCode),
+  fPdgCode(c.fPdgCode),
+  fProdVtxXMin (c.fProdVtxXMin),
+  fProdVtxYMin (c.fProdVtxYMin),
+  fProdVtxZMin (c.fProdVtxZMin),
+  fProdVtxXMax (c.fProdVtxXMax),
+  fProdVtxYMax (c.fProdVtxYMax),
+  fProdVtxZMax (c.fProdVtxZMax),
+  fDecayVtxXMin(c.fDecayVtxXMin),
+  fDecayVtxYMin(c.fDecayVtxYMin),
+  fDecayVtxZMin(c.fDecayVtxZMin),
+  fDecayVtxXMax(c.fDecayVtxXMax),
+  fDecayVtxYMax(c.fDecayVtxYMax),
+  fDecayVtxZMax(c.fDecayVtxZMax),
+  fDecayLengthMin(c.fDecayLengthMin),
+  fDecayLengthMax(c.fDecayLengthMin),
+  fDecayRxyMin(c.fDecayLengthMin),
+  fDecayRxyMax(c.fDecayLengthMin)
+{
+  //
+  //copy ctor
+  //
+}
+
+//______________________________
+AliCFParticleGenCuts& AliCFParticleGenCuts::operator=(const AliCFParticleGenCuts& c)
+{
+  //
+  // Assignment operator
+  //
+  if (this != &c) {
+    AliCFCutBase::operator=(c) ;
+    fMCInfo=c.fMCInfo;
+    fRequireIsCharged=c.fRequireIsCharged;
+    fRequireIsPrimary=c.fRequireIsPrimary;
+    fRequireIsSecondary=c.fRequireIsSecondary;
+    fRequirePdgCode=c.fRequirePdgCode;
+    fPdgCode=c.fPdgCode;
+    fProdVtxXMin=c.fProdVtxXMin;
+    fProdVtxYMin=c.fProdVtxYMin;
+    fProdVtxZMin=c.fProdVtxZMin;
+    fProdVtxXMax=c.fProdVtxXMax;
+    fProdVtxYMax=c.fProdVtxYMax;
+    fProdVtxZMax=c.fProdVtxZMax;
+    fDecayVtxXMin=c.fDecayVtxXMin;
+    fDecayVtxYMin=c.fDecayVtxYMin;
+    fDecayVtxZMin=c.fDecayVtxZMin;
+    fDecayVtxXMax=c.fDecayVtxXMax;
+    fDecayVtxYMax=c.fDecayVtxYMax;
+    fDecayVtxZMax=c.fDecayVtxZMax;      
+    fDecayLengthMin=c.fDecayVtxZMax;
+    fDecayLengthMax=c.fDecayLengthMax;
+    fDecayRxyMin=c.fDecayRxyMin;
+    fDecayRxyMax=c.fDecayRxyMax;
+  }
+  return *this ;
+}
+
+//______________________________
+Bool_t AliCFParticleGenCuts::IsSelected(TObject* obj) {
+  //
+  // check if selections on 'obj' are passed
+  // 'obj' must be an AliMCParticle
+  //
+  
+  if (!obj) return kFALSE ;
+  TString className(obj->ClassName());
+  if (className.CompareTo("AliMCParticle") != 0) {
+    AliError("argument must point to an AliMCParticle !");
+    return kFALSE ;
+  }
+
+  AliMCParticle* mcPart = (AliMCParticle*) obj ;
+  TParticle* part = mcPart->Particle();
+  AliStack *stack=fMCInfo->MCEvent()->Stack();
+
+  // is this particle charged?
+  if ( fRequireIsCharged ) {
+    if(!IsCharged(mcPart))return kFALSE;
+  } 
+  
+  // primary cuts
+  if ( fRequireIsPrimary ) {
+     if(!IsPrimary(mcPart,stack))return kFALSE;
+  } 
+
+  //secondary cut
+  if ( fRequireIsSecondary && part->IsPrimary() ) return kFALSE ;
+  
+  //PDG code cut
+  if ( fRequirePdgCode){
+    if(!IsA(mcPart,fPdgCode))  return kFALSE ;
+  }
+  // production vertex cuts
+  Double32_t partVx=(Double32_t)part->Vx();
+  Double32_t partVy=(Double32_t)part->Vy();
+  Double32_t partVz=(Double32_t)part->Vz();
+  if ( partVx < fProdVtxXMin || partVx > fProdVtxXMax ) return kFALSE ;
+  if ( partVy < fProdVtxYMin || partVy > fProdVtxYMax ) return kFALSE ;
+  if ( partVz < fProdVtxZMin || partVz > fProdVtxZMax ) return kFALSE ;
+
+  //decay vertex cuts
+  if ( part->GetNDaughters() > 0 ) {
+    TParticle* daughter = fMCInfo->MCEvent()->Stack()->Particle(part->GetFirstDaughter()) ;
+    Double32_t decayVx=(Double32_t)daughter->Vx();
+    Double32_t decayVy=(Double32_t)daughter->Vy();
+    Double32_t decayVz=(Double32_t)daughter->Vz();
+    if ( decayVx < fDecayVtxXMin || decayVx > fDecayVtxXMax ) return kFALSE ;
+    if ( decayVy < fDecayVtxYMin || decayVy > fDecayVtxYMax ) return kFALSE ;
+    if ( decayVz < fDecayVtxZMin || decayVz > fDecayVtxZMax ) return kFALSE ;
+
+    //decay length cut
+    Double32_t decayL = TMath::Sqrt(TMath::Power(partVx-decayVx,2) + 
+                                   TMath::Power(partVy-decayVy,2) + 
+                                   TMath::Power(partVz-decayVz,2) ) ;
+    if (decayL < fDecayLengthMin || decayL > fDecayLengthMax) return kFALSE ;
+
+    Double32_t decayRxy = TMath::Sqrt(TMath::Power(decayVx,2) + 
+                                     TMath::Power(decayVy,2) ) ;
+    if (decayRxy < fDecayRxyMin || decayRxy > fDecayRxyMax) return kFALSE ;
+  }
+
+
+  return kTRUE ;
+}
+//______________________________
+Bool_t AliCFParticleGenCuts::IsCharged(AliMCParticle *mcPart) {
+  //
+  //check if particle is charged.
+  //
+  TParticle* part = mcPart->Particle();
+  TParticlePDG* pdgPart = part->GetPDG();
+  if(!pdgPart)return kFALSE;
+  if (pdgPart->Charge() == 0) return kFALSE;
+  return kTRUE;
+}
+//______________________________
+Bool_t AliCFParticleGenCuts::IsPrimary(AliMCParticle *mcPart, AliStack *stack) {
+  //
+  //check if particle is primary (standard definition)
+  //
+  if (!stack->IsPhysicalPrimary(mcPart->Label())) return kFALSE ;
+  return kTRUE;
+}
+//______________________________
+Bool_t AliCFParticleGenCuts::IsPrimaryCharged(AliMCParticle *mcPart, AliStack *stack) {
+  //
+  //check if a charged particle is primary (standard definition)
+  //
+  if (!stack->IsPhysicalPrimary(mcPart->Label()) || !IsCharged(mcPart)) return kFALSE ;
+  return kTRUE;
+}
+//______________________________
+Bool_t AliCFParticleGenCuts::IsA(AliMCParticle *mcPart, Int_t pdg, Bool_t abs) {
+  //
+  //Check on the pdg code of the MC particle. if abs=kTRUE then check on the 
+  //absolute value. By default is set to kFALSE.
+  //
+  TParticle* part = mcPart->Particle();
+  Int_t pdgCode = part->GetPdgCode();
+  if(abs)pdgCode=TMath::Abs(pdgCode);
+  if(pdgCode != pdg )return kFALSE;
+  return kTRUE;
+}
+//______________________________
+void AliCFParticleGenCuts::SetEvtInfo(TObject* mcInfo) {
+  //
+  // Sets pointer to MC event information (AliMCEventHandler)
+  //
+
+  if (!mcInfo) {
+    AliError("Pointer to MC Event Handler is null !");
+    return;
+  }
+  
+  TString className(mcInfo->ClassName());
+  if (className.CompareTo("AliMCEventHandler") != 0) {
+    AliError("argument must point to an AliMCEventHandler !");
+    return ;
+  }
+  
+  fMCInfo = (AliMCEventHandler*) mcInfo ;
+}
diff --git a/CORRFW/AliCFParticleGenCuts.h b/CORRFW/AliCFParticleGenCuts.h
new file mode 100644 (file)
index 0000000..5bb9730
--- /dev/null
@@ -0,0 +1,91 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+//////////////////////////////////////////////////////////////////////
+// AliCFParticleGenCut implementation
+// This class is designed to handle 
+// particle selection at generated level.
+//
+// author : R. Vernet (renaud.vernet@cern.ch)
+//////////////////////////////////////////////////////////////////////
+
+
+#ifndef ALICFPARTICLEGENCUTS_H
+#define ALICFPARTICLEGENCUTS_H
+
+#include "AliCFCutBase.h"
+
+class AliMCEventHandler;
+class TObject;
+class AliMCParticle;
+class AliStack;
+
+class AliCFParticleGenCuts : public AliCFCutBase
+{
+ public :
+  AliCFParticleGenCuts() ;
+  AliCFParticleGenCuts           (const Char_t* name, const Char_t* title) ;
+  AliCFParticleGenCuts           (const AliCFParticleGenCuts& c) ;
+  AliCFParticleGenCuts& operator=(const AliCFParticleGenCuts& c) ;
+  virtual ~AliCFParticleGenCuts() { };
+  virtual Bool_t IsSelected(TObject* obj) ;
+  virtual void   SetEvtInfo(TObject* mcInfo) ;
+  //static checkers
+  static Bool_t IsPrimaryCharged(AliMCParticle *mcPart,AliStack*stack);
+  static Bool_t IsPrimary(AliMCParticle *mcPart,AliStack*stack);
+  static Bool_t IsCharged(AliMCParticle *mcPart);
+  static Bool_t IsA(AliMCParticle *mcPart, Int_t pdg, Bool_t abs=kFALSE);
+
+  void SetRequireIsCharged   (Bool_t b=kTRUE)       {fRequireIsCharged=b;}
+  void SetRequireIsPrimary   (Bool_t b=kTRUE)       {fRequireIsPrimary=b;}
+  void SetRequireIsSecondary (Bool_t b=kTRUE)       {fRequireIsSecondary=b;}
+  void SetRequirePdgCode     (Int_t pdg)            {fRequirePdgCode=kTRUE; fPdgCode=pdg;}
+  void SetProdVtxRangeX    (Double32_t xmin, Double32_t xmax) {fProdVtxXMin   =xmin; fProdVtxXMax   =xmax;}
+  void SetProdVtxRangeY    (Double32_t ymin, Double32_t ymax) {fProdVtxYMin   =ymin; fProdVtxYMax   =ymax;}
+  void SetProdVtxRangeZ    (Double32_t zmin, Double32_t zmax) {fProdVtxZMin   =zmin; fProdVtxZMax   =zmax;}
+  void SetDecayVtxRangeX   (Double32_t xmin, Double32_t xmax) {fDecayVtxXMin  =xmin; fDecayVtxXMax  =xmax;}
+  void SetDecayVtxRangeY   (Double32_t ymin, Double32_t ymax) {fDecayVtxYMin  =ymin; fDecayVtxYMax  =ymax;}
+  void SetDecayVtxRangeZ   (Double32_t zmin, Double32_t zmax) {fDecayVtxZMin  =zmin; fDecayVtxZMax  =zmax;}
+  void SetDecayLengthRange (Double32_t rmin, Double32_t rmax) {fDecayLengthMin=rmin; fDecayLengthMax=rmax;}
+  void SetDecayRxyRange    (Double32_t rmin, Double32_t rmax) {fDecayRxyMin   =rmin; fDecayRxyMax   =rmax;}
+
+ protected:
+  AliMCEventHandler* fMCInfo ;    // pointer to the MC event information
+  Bool_t     fRequireIsCharged;   // require charged particle
+  Bool_t     fRequireIsPrimary;   // require primary particle
+  Bool_t     fRequireIsSecondary; // require secondary particle
+  Bool_t     fRequirePdgCode;     // require check of the PDG code
+  Int_t      fPdgCode ;           // particle PDG code
+  Double32_t fProdVtxXMin;        // min X of particle production vertex
+  Double32_t fProdVtxYMin;        // min Y of particle production vertex
+  Double32_t fProdVtxZMin;        // min Z of particle production vertex
+  Double32_t fProdVtxXMax;        // max X of particle production vertex
+  Double32_t fProdVtxYMax;        // max Y of particle production vertex
+  Double32_t fProdVtxZMax;        // max Z of particle production vertex
+  Double32_t fDecayVtxXMin;       // min X of particle decay vertex
+  Double32_t fDecayVtxYMin;       // min Y of particle decay vertex
+  Double32_t fDecayVtxZMin;       // min Z of particle decay vertex
+  Double32_t fDecayVtxXMax;       // max X of particle decay vertex
+  Double32_t fDecayVtxYMax;       // max Y of particle decay vertex
+  Double32_t fDecayVtxZMax;       // max Z of particle decay vertex
+  Double32_t fDecayLengthMin;     // min decay length (absolute)
+  Double32_t fDecayLengthMax;     // max decay length (absolute)
+  Double32_t fDecayRxyMin;        // min decay length in transverse plane wrt (0,0,0)
+  Double32_t fDecayRxyMax;        // max decay length in transverse plane wrt (0,0,0)
+
+  ClassDef(AliCFParticleGenCuts,1);
+};
+
+#endif
diff --git a/CORRFW/AliCFSingleTrackTask.C b/CORRFW/AliCFSingleTrackTask.C
new file mode 100644 (file)
index 0000000..d2263b9
--- /dev/null
@@ -0,0 +1,223 @@
+//DEFINITION OF A FEW CONSTANTS
+const Double_t ymin  = -1.0 ;
+const Double_t ymax  =  1.0 ;
+const Double_t ptmin =  0.0 ;
+const Double_t ptmax =  8.0 ;
+const Int_t    mintrackrefsTPC = 2 ;
+const Int_t    mintrackrefsITS = 3 ;
+const Int_t    charge  = 1 ;
+const Int_t    PDG = 211; 
+const Int_t    minclustersTPC = 50 ;
+//----------------------------------------------------
+
+Bool_t AliCFSingleTrackTask(
+                           const Bool_t useGrid = 1,
+                           const char * kTagXMLFile="wn.xml", // XML file containing tags
+                           Long64_t     nentries=TChain::kBigNumber
+                           )
+{
+  
+  TBenchmark benchmark;
+  benchmark.Start("AliSingleTrackTask");
+
+  AliLog::SetGlobalDebugLevel(0);
+
+  Load() ; //load the required libraries
+
+  TChain * analysisChain ;
+
+  if (useGrid) { //data located on AliEn
+    TGrid::Connect("alien://") ;    //  Create an AliRunTagCuts and an AliEventTagCuts Object and impose some selection criteria
+    AliRunTagCuts      *runCuts   = new AliRunTagCuts(); 
+    AliEventTagCuts    *eventCuts = new AliEventTagCuts(); 
+    AliLHCTagCuts      *lhcCuts   = new AliLHCTagCuts(); 
+    AliDetectorTagCuts *detCuts   = new AliDetectorTagCuts(); 
+    eventCuts->SetMultiplicityRange(0,20000);
+    //  Create an AliTagAnalysis Object and chain the tags
+    AliTagAnalysis   *tagAna = new AliTagAnalysis(); 
+    tagAna->SetType("ESD");  //for aliroot > v4-05
+    TAlienCollection *coll   = TAlienCollection::Open(kTagXMLFile); 
+    TGridResult      *tagResult = coll->GetGridResult("",0,0);
+    tagResult->Print();
+    tagAna->ChainGridTags(tagResult);
+    //  Create a new esd chain and assign the chain that is returned by querying the tags
+    analysisChain = tagAna->QueryTags(runCuts,lhcCuts,detCuts,eventCuts); 
+  }
+  else {// local data
+    analysisChain = new TChain("esdTree");
+    //here put your input data path
+    analysisChain->Add("AliESDs.root");
+  }
+  
+  
+  Info("AliCFSingleTrackTask",Form("CHAIN HAS %d ENTRIES",(Int_t)analysisChain->GetEntries()));
+
+  //CONTAINER DEFINITION
+  Info("AliCFSingleTrackTask","SETUP CONTAINER");
+  //the sensitive variables, their indices
+  Int_t ipt = 0;
+  Int_t iy  = 1;
+  //Setting up the container grid... 
+  Int_t nstep = 4 ; //number of selection steps MC 
+  const Int_t nvar   = 2 ; //number of variables on the grid:pt,y,phi,vtx
+  const Int_t nbin1  = 8 ; //bins in pt
+  const Int_t nbin2  = 8 ; //bins in y 
+  //arrays for the number of bins in each dimension
+  const Int_t iBin[nvar] ={nbin1,nbin2};
+  //arrays for lower bounds :
+  Float_t binLim1[nbin1+1];
+  Float_t binLim2[nbin2+1];
+  //values for bin lower bounds
+  for(Int_t i=0; i<=nbin1; i++) binLim1[i]=(Float_t)ptmin + (ptmax-ptmin)/nbin1*(Float_t)i ; 
+  for(Int_t i=0; i<=nbin2; i++) binLim2[i]=(Float_t)ymin  + (ymax-ymin)  /nbin2*(Float_t)i ;
+  //one "container" for MC
+  AliCFContainer* container = new AliCFContainer("container","container for tracks",nstep,nvar,iBin);
+  //setting the bin limits
+  container -> SetBinLimits(ipt,binLim1);
+  container -> SetBinLimits(iy,binLim2);
+
+
+  //CREATE THE  CUTS -----------------------------------------------
+  
+  // Gen-Level kinematic cuts
+  AliCFTrackKineCuts *mcKineCuts = new AliCFTrackKineCuts("mcKineCuts","MC-level kinematic cuts");
+  mcKineCuts->SetPtRange(ptmin,ptmax);
+  mcKineCuts->SetRapidityRange(ymin,ymax);
+  mcKineCuts->SetChargeMC(charge);
+
+  AliCFParticleGenCuts* mcGenCuts = new AliCFParticleGenCuts("mcGenCuts","MC particle generation cuts");
+  mcGenCuts->SetRequireIsPrimary();
+  mcGenCuts->SetRequirePdgCode(PDG);
+
+  //Acceptance Cuts
+  AliCFAcceptanceCuts *mcAccCuts = new AliCFAcceptanceCuts("mcAccCuts","MC acceptance cuts");
+  mcAccCuts->SetMinNHitITS(mintrackrefsITS);
+  mcAccCuts->SetMinNHitTPC(mintrackrefsTPC);
+
+  // Rec-Level kinematic cuts
+  AliCFTrackKineCuts *recKineCuts = new AliCFTrackKineCuts("recKineCuts","rec-level kine cuts");
+  recKineCuts->SetPtRange(ptmin,ptmax);
+  recKineCuts->SetRapidityRange(ymin,ymax);
+  recKineCuts->SetChargeRec(charge);
+  // QA histograms for rec-level kinematic cuts
+  recKineCuts->SetQAOn(kTRUE);
+
+  AliCFTrackQualityCuts *recQualityCuts = new AliCFTrackQualityCuts("recQualityCuts","rec-level quality cuts");
+  recQualityCuts->SetMinNClusterTPC(minclustersTPC);
+  recQualityCuts->SetRequireITSRefit(kTRUE);
+  // QA histograms for rec-level quality cuts
+  recQualityCuts->SetQAOn(kTRUE);
+
+  AliCFTrackIsPrimaryCuts *recIsPrimaryCuts = new AliCFTrackIsPrimaryCuts("recIsPrimaryCuts","rec-level isPrimary cuts");
+  recIsPrimaryCuts->SetMaxNSigmaToVertex(3);
+  // QA histograms for rec-level primary-check cuts
+  recIsPrimaryCuts->SetQAOn(kTRUE);
+
+  AliCFTrackCutPid* cutPID = new AliCFTrackCutPid("cutPID","ESD_PID") ;
+  Double_t prior[AliPID::kSPECIES] = {0.0244519,
+                                     0.0143988,
+                                     0.805747 ,
+                                     0.0928785,
+                                     0.0625243 };
+  cutPID->SetPriors(prior);
+  cutPID->SetDetectors("TPC TOF");
+  cutPID->SetProbabilityCut(0.0);
+  switch(TMath::Abs(PDG)) {
+  case 11   : cutPID->SetParticleType(AliPID::kElectron, kTRUE); break;
+  case 13   : cutPID->SetParticleType(AliPID::kMuon    , kTRUE); break;
+  case 211  : cutPID->SetParticleType(AliPID::kPion    , kTRUE); break;
+  case 321  : cutPID->SetParticleType(AliPID::kKaon    , kTRUE); break;
+  case 2212 : cutPID->SetParticleType(AliPID::kProton  , kTRUE); break;
+  default   : printf("UNDEFINED PID\n"); break;
+  }
+  cutPID->SetQAOn(kTRUE);
+
+  printf("CREATE MC KINE CUTS\n");
+  TObjArray* mcList = new TObjArray(0) ;
+  mcList->AddLast(mcKineCuts);
+  mcList->AddLast(mcGenCuts);
+
+  printf("CREATE ACCEPTANCE CUTS\n");
+  TObjArray* accList = new TObjArray(0) ;
+  accList->AddLast(mcAccCuts);
+
+  printf("CREATE RECONSTRUCTION CUTS\n");
+  TObjArray* recList = new TObjArray(0) ;
+  recList->AddLast(recKineCuts);
+  recList->AddLast(recQualityCuts);
+
+  printf("CREATE PID CUTS\n");
+  TObjArray* fPIDCutList = new TObjArray(0) ;
+  fPIDCutList->AddLast(cutPID);
+
+
+  //CREATE THE INTERFACE TO CORRECTION FRAMEWORK USED IN THE TASK
+  printf("CREATE INTERFACE AND CUTS\n");
+  AliCFManager* man = new AliCFManager() ;
+  man->SetParticleContainer     (container);
+  man->SetParticleCutsList(AliCFManager::kPartGenCuts,mcList);
+  man->SetParticleCutsList(AliCFManager::kPartAccCuts,accList);
+  man->SetParticleCutsList(AliCFManager::kPartRecCuts,recList);
+  man->SetParticleCutsList(AliCFManager::kPartSelCuts,fPIDCutList);
+
+
+  //CREATE THE TASK
+  printf("CREATE TASK\n");
+  // create the task
+  AliCFSingleTrackTask *task = new AliCFSingleTrackTask("AliSingleTrackTask");
+  task->SetCFManager(man); //here is set the CF manager
+
+
+  //SETUP THE ANALYSIS MANAGER TO READ INPUT CHAIN AND WRITE DESIRED OUTPUTS
+  printf("CREATE ANALYSIS MANAGER\n");
+  // Make the analysis manager
+  AliAnalysisManager *mgr = new AliAnalysisManager("TestManager");
+
+  // Create and connect containers for input/output
+
+  //input data
+  AliAnalysisDataContainer *cinput0  = mgr->CreateContainer("cchain0",TChain::Class(),AliAnalysisManager::kInputContainer);
+  // output histo (number of events processed)
+  AliAnalysisDataContainer *coutput0 = mgr->CreateContainer("chist0", TH1I::Class(),AliAnalysisManager::kOutputContainer,"output.root");
+  // output Correction Framework Container (for acceptance & efficiency calculations)
+  AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("ccontainer0", AliCFContainer::Class(),AliAnalysisManager::kOutputContainer,"output.root");
+  // output QA histograms 
+  AliAnalysisDataContainer *coutput2 = mgr->CreateContainer("clist0", TList::Class(),AliAnalysisManager::kOutputContainer,"output.root");
+
+  mgr->AddTask(task);
+  mgr->ConnectInput(task,0,cinput0);
+  mgr->ConnectOutput(task,0,coutput0);
+  mgr->ConnectOutput(task,1,coutput1);
+  mgr->ConnectOutput(task,2,coutput2);
+  cinput0->SetData(analysisChain);
+  //NEW INTERFACE TO MC INFORMATION
+  AliMCEventHandler* mcHandler = new AliMCEventHandler();
+  mgr->SetMCtruthEventHandler(mcHandler);
+
+  printf("READY TO RUN\n");
+  //RUN !!!
+  if (mgr->InitAnalysis()) {
+    mgr->PrintStatus();
+    mgr->StartAnalysis("local",analysisChain);
+  }
+
+  benchmark.Stop("AliSingleTrackTask");
+  benchmark.Show("AliSingleTrackTask");
+  
+  return kTRUE ;
+}
+
+void Load() {
+  //remove this file which can cause problems
+  gSystem->Exec("rm $ALICE_ROOT/ANALYSIS/AliAnalysisSelector_cxx.so");
+
+  //load the required aliroot libraries
+  gSystem->Load("libANALYSIS") ;
+  gSystem->Load("libANALYSISRL") ;
+  gSystem->Load("$ALICE_ROOT/CORRFW/libCORRFW.so") ;
+
+  //compile online the task class
+  gSystem->SetIncludePath("-I. -I$ALICE_ROOT/include -I$ROOTSYS/include");
+  gROOT->LoadMacro("./AliCFSingleTrackTask.cxx+");
+}
diff --git a/CORRFW/AliCFSingleTrackTask.cxx b/CORRFW/AliCFSingleTrackTask.cxx
new file mode 100644 (file)
index 0000000..d42c080
--- /dev/null
@@ -0,0 +1,298 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+//-----------------------------------------------------------------------
+// Example of task running on AliEn (CAF?)
+// which provides standard way of calculating acceptance and efficiency
+// between different steps of the procedure.
+// The ouptut of the task is a AliCFContainer from which the efficiencies
+// can be calculated
+//-----------------------------------------------------------------------
+// Author : R. Vernet, Consorzio Cometa - Catania (it)
+//-----------------------------------------------------------------------
+
+
+#ifndef ALICFSINGLETRACKTASK_CXX
+#define ALICFSINGLETRACKTASK_CXX
+#include <TROOT.h>
+#include <TInterpreter.h>
+
+#include "AliCFSingleTrackTask.h"
+#include "TCanvas.h"
+#include "AliStack.h"
+#include "TParticle.h"
+#include "TH1I.h"
+#include "TChain.h"
+#include "AliMCEventHandler.h"
+#include "AliMCEvent.h"
+#include "AliAnalysisManager.h"
+#include "AliESDEvent.h"
+#include "AliCFManager.h"
+#include "AliCFCutBase.h"
+#include "AliCFContainer.h"
+#include "TChain.h"
+#include "AliESDtrack.h"
+#include "AliLog.h"
+ClassImp(AliCFSingleTrackTask)
+//__________________________________________________________________________
+AliCFSingleTrackTask::AliCFSingleTrackTask() :
+  fChain(0x0),
+  fESD(0x0),
+  fCFManager(0x0),
+  fQAHistList(0x0),
+  fHistEventsProcessed(0x0)
+{
+//Defual ctor
+}
+//___________________________________________________________________________
+AliCFSingleTrackTask::AliCFSingleTrackTask(const Char_t* name) :
+  AliAnalysisTask(name,"AliCFSingleTrackTask"),
+  fChain(0x0),
+  fESD(0x0),
+  fCFManager(0x0),
+  fQAHistList(0x0),
+  fHistEventsProcessed(0x0)
+{
+  //
+  // Constructor. Initialization of Inputs and Outputs
+  //
+  Info("AliCFSingleTrackTask","Calling Constructor");
+  DefineInput (0,TChain::Class());
+  DefineOutput(0,TH1I::Class());
+  DefineOutput(1,AliCFContainer::Class());
+  DefineOutput(2,TList::Class());
+}
+
+//___________________________________________________________________________
+AliCFSingleTrackTask& AliCFSingleTrackTask::operator=(const AliCFSingleTrackTask& c) 
+{
+  //
+  // Assignment operator
+  //
+  if (this!=&c) {
+    AliAnalysisTask::operator=(c) ;
+    fChain      = c.fChain;
+    fESD        = c.fESD;
+    fCFManager  = c.fCFManager;
+    fQAHistList = c.fQAHistList ;
+    fHistEventsProcessed = c.fHistEventsProcessed;
+  }
+  return *this;
+}
+
+//___________________________________________________________________________
+AliCFSingleTrackTask::AliCFSingleTrackTask(const AliCFSingleTrackTask& c) :
+  AliAnalysisTask(c),
+  fChain(c.fChain),
+  fESD(c.fESD),
+  fCFManager(c.fCFManager),
+  fQAHistList(c.fQAHistList),
+  fHistEventsProcessed(c.fHistEventsProcessed)
+{
+  //
+  // Copy Constructor
+  //
+}
+
+//___________________________________________________________________________
+AliCFSingleTrackTask::~AliCFSingleTrackTask() {
+  //
+  //destructor
+  //
+  Info("~AliCFSingleTrackTask","Calling Destructor");
+  if (fChain)               delete fChain ;
+  if (fESD)                 delete fESD ;
+  if (fCFManager)           delete fCFManager ;
+  if (fHistEventsProcessed) delete fHistEventsProcessed ;
+  if (fQAHistList) {fQAHistList->Clear(); delete fQAHistList;}
+}
+
+//___________________________________________________________________________
+
+void AliCFSingleTrackTask::Init()
+{
+
+}
+//_________________________________________________
+void AliCFSingleTrackTask::Exec(Option_t *)
+{
+  //
+  // Main loop function
+  //
+  Info("Exec","") ;
+  // Get the mc truth
+  AliMCEventHandler* mcTruth = (AliMCEventHandler*)((AliAnalysisManager::GetAnalysisManager())->GetMCtruthEventHandler());
+
+  if (!mcTruth) Error("Exec","NO MC INFO FOUND... EXITING\n");
+
+  // transform possible old AliESD into AliESDEvent
+
+  if (fESD->GetAliESDOld()) fESD->CopyFromOldESD(); //transition to new ESD format
+
+  //pass the MC evt handler to the cuts that need it 
+
+  fCFManager->SetEventInfo(mcTruth);
+
+  // Get the MC event 
+  AliMCEvent* mcEvent = mcTruth->MCEvent();
+
+  // MC-event selection
+  Float_t containerInput[2] ;
+        
+  //loop on the MC event
+  for (Int_t ipart=0; ipart<mcEvent->GetNumberOfTracks(); ipart++) { 
+    AliMCParticle *mcPart  = mcEvent->GetTrack(ipart);
+
+    //check the MC-level cuts
+    if (!fCFManager->CheckParticleCuts(AliCFManager::kPartGenCuts,mcPart)) continue;
+
+    containerInput[0] = (Float_t)mcPart->Pt();
+    containerInput[1] = mcPart->Eta() ;
+    //fill the container for Gen-level selection
+    fCFManager->GetParticleContainer()->Fill(containerInput,kStepGenerated);
+    
+    //check the Acceptance-level cuts
+    if (!fCFManager->CheckParticleCuts(AliCFManager::kPartAccCuts,mcPart)) continue;
+    //fill the container for Acceptance-level selection
+    fCFManager->GetParticleContainer()->Fill(containerInput,kStepReconstructible);
+  }    
+
+  //Now go to rec level
+  for (Int_t iTrack = 0; iTrack<fESD->GetNumberOfTracks(); iTrack++) {
+
+    AliESDtrack* track = fESD->GetTrack(iTrack);
+    
+    fCFManager->FillQABeforeParticleCuts(AliCFManager::kPartRecCuts,track);  
+    if (!fCFManager->CheckParticleCuts(AliCFManager::kPartRecCuts,track)) continue;
+    fCFManager->FillQAAfterParticleCuts(AliCFManager::kPartRecCuts,track);
+
+    // is track associated to particle ?
+    if (track->GetLabel()<0) continue;
+    AliMCParticle *mcPart  = mcEvent->GetTrack(track->GetLabel());
+    
+    // check if this track was part of the signal
+    if (!fCFManager->CheckParticleCuts(AliCFManager::kPartGenCuts,mcPart)) continue; 
+    
+    //fill the container
+    Double_t mom[3];
+    track->GetPxPyPz(mom);
+    Double_t pt=TMath::Sqrt(mom[0]*mom[0]+mom[1]*mom[1]);
+    containerInput[0] = pt ;
+    containerInput[1] = track->Eta();
+    fCFManager->GetParticleContainer()->Fill(containerInput,kStepReconstructed) ;   
+    if (!fCFManager->CheckParticleCuts(AliCFManager::kPartSelCuts,track)) continue ;
+    fCFManager->GetParticleContainer()->Fill(containerInput,kStepSelected);
+  }
+  
+  fHistEventsProcessed->Fill(0);
+  PostData(0,fHistEventsProcessed) ;
+  PostData(1,fCFManager->GetParticleContainer()) ;
+  PostData(2,fQAHistList) ;
+}
+
+
+//___________________________________________________________________________
+void AliCFSingleTrackTask::Terminate(Option_t*)
+{
+  // The Terminate() function is the last function to be called during
+  // a query. It always runs on the client, it can be used to present
+  // the results graphically or save the results to file.
+
+  Info("Terminate","");
+  AliAnalysisTask::Terminate();
+
+
+  Double_t max1 = fCFManager->GetParticleContainer()->ShowProjection(0,0)->GetMaximum();
+  Double_t max2 = fCFManager->GetParticleContainer()->ShowProjection(1,0)->GetMaximum();
+
+  fCFManager->GetParticleContainer()->ShowProjection(0,0)->GetYaxis()->SetRangeUser(0,max1*1.2);
+  fCFManager->GetParticleContainer()->ShowProjection(0,1)->GetYaxis()->SetRangeUser(0,max1*1.2);
+  fCFManager->GetParticleContainer()->ShowProjection(0,2)->GetYaxis()->SetRangeUser(0,max1*1.2);
+  fCFManager->GetParticleContainer()->ShowProjection(0,3)->GetYaxis()->SetRangeUser(0,max1*1.2);
+
+  fCFManager->GetParticleContainer()->ShowProjection(1,0)->GetYaxis()->SetRangeUser(0,max2*1.2);
+  fCFManager->GetParticleContainer()->ShowProjection(1,1)->GetYaxis()->SetRangeUser(0,max2*1.2);
+  fCFManager->GetParticleContainer()->ShowProjection(1,2)->GetYaxis()->SetRangeUser(0,max2*1.2);
+  fCFManager->GetParticleContainer()->ShowProjection(1,3)->GetYaxis()->SetRangeUser(0,max2*1.2);
+
+  fCFManager->GetParticleContainer()->ShowProjection(0,0)->SetMarkerStyle(23) ;
+  fCFManager->GetParticleContainer()->ShowProjection(0,1)->SetMarkerStyle(24) ;
+  fCFManager->GetParticleContainer()->ShowProjection(0,2)->SetMarkerStyle(25) ;
+  fCFManager->GetParticleContainer()->ShowProjection(0,3)->SetMarkerStyle(26) ;
+
+  fCFManager->GetParticleContainer()->ShowProjection(1,0)->SetMarkerStyle(23) ;
+  fCFManager->GetParticleContainer()->ShowProjection(1,1)->SetMarkerStyle(24) ;
+  fCFManager->GetParticleContainer()->ShowProjection(1,2)->SetMarkerStyle(25) ;
+  fCFManager->GetParticleContainer()->ShowProjection(1,3)->SetMarkerStyle(26) ;
+
+  TCanvas * c =new TCanvas("c","",1400,800);
+  c->Divide(4,2);
+
+//   TCanvas * c1 =new TCanvas("c1","",600,400);
+  c->cd(1);
+  fCFManager->GetParticleContainer()->ShowProjection(0,0)->Draw("p");
+  c->cd(2);
+  fCFManager->GetParticleContainer()->ShowProjection(0,1)->Draw("p");
+  c->cd(3);
+  fCFManager->GetParticleContainer()->ShowProjection(0,2)->Draw("p");
+  c->cd(4);
+  fCFManager->GetParticleContainer()->ShowProjection(0,3)->Draw("p");
+
+//   TCanvas * c2 =new TCanvas("c2","",600,400);
+  c->cd(5);
+  fCFManager->GetParticleContainer()->ShowProjection(1,0)->Draw("p");
+  c->cd(6);
+  fCFManager->GetParticleContainer()->ShowProjection(1,1)->Draw("p");
+  c->cd(7);
+  fCFManager->GetParticleContainer()->ShowProjection(1,2)->Draw("p");
+  c->cd(8);
+  fCFManager->GetParticleContainer()->ShowProjection(1,3)->Draw("p");
+
+  c->SaveAs("plots.eps");
+
+  delete fHistEventsProcessed ;
+}
+
+//___________________________________________________________________________
+void AliCFSingleTrackTask::ConnectInputData(Option_t *) {
+  //
+  // Initialize branches.
+  //
+  Info("ConnectInputData","ConnectInputData of task %s\n",GetName());
+
+  fChain = (TChain*)GetInputData(0);
+  fChain->SetBranchStatus("*FMD*",0);
+  fChain->SetBranchStatus("*CaloClusters*",0);
+  fESD = new AliESDEvent();
+  fESD->ReadFromTree(fChain);
+}
+
+//___________________________________________________________________________
+void AliCFSingleTrackTask::CreateOutputObjects() {
+  //HERE ONE CAN CREATE OUTPUT OBJECTS, IN PARTICULAR IF THE OBJECT PARAMETERS DON'T NEED
+  //TO BE SET BEFORE THE EXECUTION OF THE TASK
+  //
+  Info("CreateOutputObjects","CreateOutputObjects of task %s\n", GetName());
+
+  //slot #0
+  fHistEventsProcessed = new TH1I("fHistEventsProcessed","",1,0,1) ;
+
+  //slot #2
+  fQAHistList = new TList();
+  fCFManager->InitQAHistos();
+  fCFManager->AddQAHistosToList(fQAHistList);
+}
+
+#endif
diff --git a/CORRFW/AliCFSingleTrackTask.h b/CORRFW/AliCFSingleTrackTask.h
new file mode 100644 (file)
index 0000000..e666161
--- /dev/null
@@ -0,0 +1,76 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+//-----------------------------------------------------------------------
+// Author : R. Vernet, Consorzio Cometa - Catania (it)
+//-----------------------------------------------------------------------
+
+#ifndef ALICFSINGLETRACKTASK_H
+#define ALICFSINGLETRACKTASK_H
+
+#include "AliAnalysisTask.h"
+
+class TH1I;
+class TParticle ;
+class TFile ;
+class AliMCEventHandler;
+class AliESDEvent;
+class AliStack ;
+class AliCFManager;
+class TChain;
+class AliESDtrack;
+
+class AliCFSingleTrackTask : public AliAnalysisTask {
+  public:
+
+  enum {
+    kStepGenerated       = 0,
+    kStepReconstructible = 1,
+    kStepReconstructed   = 2,
+    kStepSelected        = 3
+  };
+
+  AliCFSingleTrackTask();
+  AliCFSingleTrackTask(const Char_t* name);
+  AliCFSingleTrackTask& operator= (const AliCFSingleTrackTask& c);
+  AliCFSingleTrackTask(const AliCFSingleTrackTask& c);
+  virtual ~AliCFSingleTrackTask();
+
+  // ANALYSIS FRAMEWORK STUFF to loop on data and fill output objects
+  void     ConnectInputData(Option_t *option="");
+  void     CreateOutputObjects();
+  void     Exec(Option_t *option);
+  void     Init(); //loads the CF manager
+  void     LocalInit() {Init();} //needed for the slaves 
+  void     Terminate(Option_t *);
+  
+  // CORRECTION FRAMEWORK RELATED FUNCTIONS
+  void           SetCFManager(AliCFManager* io) {fCFManager = io;}   // global correction manager
+  AliCFManager * GetCFManager()                 {return fCFManager;} // get corr manager
+ protected:
+
+  TChain         *fChain      ;  //! chained files
+  AliESDEvent    *fESD        ;  //! pointer to the ESD event read
+  AliCFManager   *fCFManager  ;  // pointer to the CF manager
+  TList          *fQAHistList ;  // list of QA histograms
+
+  // Histograms
+  //Number of events
+  TH1I *fHistEventsProcessed; //! simple histo for monitoring the number of events processed
+  
+  ClassDef(AliCFSingleTrackTask,1);
+};
+
+#endif
diff --git a/CORRFW/AliCFTrackCutPid.cxx b/CORRFW/AliCFTrackCutPid.cxx
new file mode 100644 (file)
index 0000000..d47e51c
--- /dev/null
@@ -0,0 +1,683 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+//This class is intended to provide a selection on
+//the PID for single charged particles as electrons, muons
+//pions, kaons and protons. The user is supposed to set only one particle 
+//to look at. The class at the moment uses one single ESD track.
+//The identification is done in Identify(), whereas the GetID() checks 
+//the track status or if the combined PID should be applied.
+//The Correction Framework follows the Annalysis framework. 
+//The main method of this class is the IsSelected function which returns 
+//true (false) if the ESD track is (not) identified as the previously 
+//setted particle.
+//
+//
+//usage:
+//
+// -----ID by one detector------
+//AliCFTrackCutPid *pCut = new AliCFTrackCutPid("pion_sel","pion_sel");
+//Double_t priors[5]={...};
+//pCut->SetPartycleType(AliPID::kPion,kFALSE)  
+//pCut->SetDetectors("DET");          ^^^^^^
+//pCut->SetPriors(priors);
+//
+// -----ID combining more detectors----
+//AliCFTrackCutPid *pCut = new AliCFTrackCutPid("pion_sel","pion_sel");
+//Double_t priors[5]={...};
+//pCut->SetPartycleType(AliPID::kPion,kTRUE)
+//pCut->SetDetectors("DET1 DET2 .."); ^^^^^
+//pCut->SetPriors(priors)
+//
+//Comments: 
+//The user can choose not to identify a track if one residual beteween 
+//the identified particle probability and one among all the other 
+//probabilties is smaller than a predefined value. 
+//The same can be done for the detector responses. 
+//This happens by setting:
+// 
+//pCut->SetMinDiffProb(0.005,kTRUE) //for probabilities
+//
+//pCut->SetMinDiffResp(0.005,kTRUE) //for det responses
+//
+//Annalisa.Mastroserio@ba.infn.it
+//
+
+
+#include "AliCFTrackCutPid.h"
+#include "AliLog.h"
+#include <TMath.h>
+#include <TList.h>
+
+ClassImp(AliCFTrackCutPid) 
+
+//__________________________________________________________________________________
+// CUT ON TRACK PID
+//__________________________________________________________________________________
+AliCFTrackCutPid::AliCFTrackCutPid() :
+  AliCFCutBase(),
+  fCut(0.2),
+  fMinDiffResponse(0.0001),
+  fMinDiffProbability(0.001),
+  fgParticleType(10),
+  fgIsComb(kTRUE),
+  fCheckResponse(kFALSE),
+  fCheckSelection(kTRUE),
+  fIsPpriors(kFALSE),
+  fIsDetAND(kFALSE),
+  fXmin(-0.005),
+  fXmax(1.005),
+  fNbins(101),
+  fDetRestr(-1),
+  fiPartRestr(-1),
+  fDetProbRestr(1)
+{ 
+  //
+  //Default constructor 
+  //
+  for(Int_t j=0; j< AliPID::kSPECIES; j++) {
+    fPriors[j]=0.2;
+    fPriorsFunc[j]=0x0;
+  }
+  
+  for(Int_t jDet=0; jDet< kNdets; jDet++)  {
+    fDets[jDet]=kFALSE;
+    fDetsInAnd[jDet]=kFALSE;
+  }
+  
+  InitialiseHisto();
+}
+//______________________________
+AliCFTrackCutPid::AliCFTrackCutPid(const Char_t* name, const Char_t* title) :
+  AliCFCutBase(name,title),
+  fCut(0.2),
+  fMinDiffResponse(0.0001),
+  fMinDiffProbability(0.001),
+  fgParticleType(10),
+  fgIsComb(kTRUE),
+  fCheckResponse(kFALSE),
+  fCheckSelection(kTRUE),
+  fIsPpriors(kFALSE),
+  fIsDetAND(kFALSE),
+  fXmin(-0.005),
+  fXmax(1.005),
+  fNbins(101),
+  fDetRestr(-1),
+  fiPartRestr(-1),
+  fDetProbRestr(1)
+{
+  //
+  //Constructor
+  // 
+  for(Int_t j=0; j< AliPID::kSPECIES; j++) {
+    fPriors[j]=0.2;
+    fPriorsFunc[j]=0x0;
+  }
+  
+  for(Int_t jDet=0; jDet< kNdets; jDet++)  {
+    fDets[jDet]=kFALSE;
+    fDetsInAnd[jDet]=kFALSE;
+  }
+  
+  InitialiseHisto();
+}
+//______________________________
+AliCFTrackCutPid::AliCFTrackCutPid(const AliCFTrackCutPid& c) :
+  AliCFCutBase(c),
+  fCut(c.fCut),
+  fMinDiffResponse(c.fMinDiffResponse),
+  fMinDiffProbability(c.fMinDiffProbability),
+  fgParticleType(c.fgParticleType),
+  fgIsComb(c.fgIsComb),
+  fCheckResponse(c.fCheckResponse),
+  fCheckSelection(c.fCheckSelection),
+  fIsPpriors(c.fIsPpriors),
+  fIsDetAND(c.fIsDetAND),
+  fXmin(c.fXmin),
+  fXmax(c.fXmax),
+  fNbins(c.fNbins),
+  fDetRestr(c.fDetRestr),
+  fiPartRestr(c.fiPartRestr),
+  fDetProbRestr(c.fDetProbRestr)
+{
+  //
+  //Copy constructor
+  //
+  for(Int_t i=0; i< kNdets ; i++ ) { 
+    fDets[i]=c.fDets[i]; 
+    fDetsInAnd[i]=c.fDetsInAnd[i];
+    for(Int_t iP =0; iP<AliPID::kSPECIES; iP++){
+      fhResp[i][iP]=c.fhResp[i][iP];
+      fhProb[i][iP]=c.fhProb[i][iP];
+    }
+  }
+  for(Int_t j=0; j< AliPID::kSPECIES; j++){
+    fPriors[j]=c.fPriors[j];
+    fPriorsFunc[j]=c.fPriorsFunc[j];
+    fhCombResp[j]=c.fhCombResp[j];
+    fhCombProb[j]=c.fhCombProb[j];
+  }
+}
+//______________________________
+AliCFTrackCutPid& AliCFTrackCutPid::operator=(const AliCFTrackCutPid& c)
+{  
+  //
+  // Assignment operator
+  //
+  if (this != &c) {
+    AliCFCutBase::operator=(c) ;
+    this->fCut=c.fCut;
+    this->fMinDiffResponse=c.fMinDiffResponse;
+   this->fMinDiffProbability=c.fMinDiffProbability;
+    this->fgParticleType=c.fgParticleType;  
+    this->fgIsComb=c.fgIsComb;
+    this->fCheckResponse=c.fCheckResponse;
+    this->fCheckSelection=c.fCheckSelection;
+    this->fIsPpriors=c.fIsPpriors;
+    this->fIsDetAND=c.fIsDetAND;
+    this->fXmin=c.fXmin;
+    this->fXmax=c.fXmax;
+    this->fNbins=c.fNbins;
+    this->fDetRestr=c.fDetRestr;
+    this->fiPartRestr=c.fiPartRestr;
+    this->fDetProbRestr=c.fDetProbRestr;
+  
+    for(Int_t i=0; i< kNdets ; i++ )   {
+      this->fDets[i]=c.fDets[i];
+      for(Int_t iP =0; iP<AliPID::kSPECIES; iP++){
+       this->fhResp[i][iP]=c.fhResp[i][iP];
+       this->fhProb[i][iP]=c.fhProb[i][iP];
+      }  
+    }
+
+    for(Int_t j=0; j< AliPID::kSPECIES; j++){
+      this->fPriors[j]=c.fPriors[j];
+      this->fhCombResp[j]=c.fhCombResp[j];
+      this->fhCombProb[j]=c.fhCombProb[j];
+      this-> fPriorsFunc[j]=c.fPriorsFunc[j];
+
+    }
+  }
+  return *this ;
+}
+//__________________________________________________________________________________
+AliCFTrackCutPid::~AliCFTrackCutPid() {
+  //
+  //dtor
+  //
+  for(Int_t i=0; i< kNdets ; i++ )   {
+    for(Int_t iP =0; iP<AliPID::kSPECIES; iP++){
+      if(fhResp[i][iP])delete fhResp[i][iP];
+      if(fhProb[i][iP])delete fhProb[i][iP];
+    }  
+  }
+  
+  for(Int_t j=0; j< AliPID::kSPECIES; j++){
+    if(fhCombResp[j])delete fhCombResp[j];
+    if(fhCombProb[j])delete fhCombProb[j];
+    
+  }
+  
+}
+//__________________________________
+void AliCFTrackCutPid::SetDetectors(TString dets)
+{
+  //
+  // The string of detectors is translated into 
+  // the respective booelan data members
+
+  if(dets.Contains("ITS")) {fDets[kITS]=kTRUE;}
+  if(dets.Contains("TPC")) {fDets[kTPC]=kTRUE;}
+  if(dets.Contains("TRD")) {fDets[kTRD]=kTRUE;}
+  if(dets.Contains("TOF")) {fDets[kTOF]=kTRUE;}
+  if(dets.Contains("HMPID")) {fDets[kHMPID]=kTRUE;}
+}
+//__________________________________
+void AliCFTrackCutPid::SetPriors(Double_t r[AliPID::kSPECIES])
+{
+  //
+  // Sets the a priori concentrations
+  // 
+  for(Int_t i=0; i<AliPID::kSPECIES; i++) fPriors[i]=r[i];
+}
+//__________________________________
+void AliCFTrackCutPid::SetPriorFunctions(TF1 *func[AliPID::kSPECIES])
+{
+  //
+  // Sets the momentu dependent a priori concentrations
+  //
+  
+  for(Int_t i=0; i<AliPID::kSPECIES; i++) fPriorsFunc[i]=func[i];
+  fIsPpriors = kTRUE;
+}
+//____________________________________________
+void AliCFTrackCutPid::SetANDstatus(TString dets)
+{
+  //
+  //Sets the detectors to be in AND for the combined PID
+  //
+  if(dets.Contains("ITS") && fDets[kITS])     {fDetsInAnd[kITS]=kTRUE;}
+  if(dets.Contains("TPC") && fDets[kTPC])     {fDetsInAnd[kTPC]=kTRUE;}
+  if(dets.Contains("TRD") && fDets[kTRD])     {fDetsInAnd[kTRD]=kTRUE;}
+  if(dets.Contains("TOF") && fDets[kTOF])     {fDetsInAnd[kTOF]=kTRUE;}
+  if(dets.Contains("HMPID") && fDets[kHMPID]) {fDetsInAnd[kHMPID]=kTRUE;}
+  
+  fIsDetAND = kTRUE;
+}
+//
+void AliCFTrackCutPid::SetDetectorProbabilityRestriction(TString det, Int_t iPart, Double_t upperprob)
+{
+  //
+  // Sets the detector, the particle and the probability
+  // limit.
+  //
+  
+  if(det.Contains("ITS")) fDetRestr = kITS;
+  if(det.Contains("TPC")) fDetRestr = kTPC;
+  if(det.Contains("TRD")) fDetRestr = kTRD;
+  if(det.Contains("TOF")) fDetRestr = kTOF;
+  if(det.Contains("HMPID")) fDetRestr = kHMPID;
+  fiPartRestr = iPart; 
+  fDetProbRestr = upperprob;
+}
+//__________________________________
+void AliCFTrackCutPid::TrackInfo(const AliESDtrack *pTrk, ULong_t status[kNdets+1],Double_t pid[kNdets+1][AliPID::kSPECIES]) const
+{
+  //
+  // Loads the responses of the XXX chosen detectors for the pTrk
+  // and the corresponding trk status. The final trk status is also loaded.
+  // 
+  if(fDets[kITS]) {
+    pTrk->GetITSpid(pid[kITS]);
+    status[kITS]=AliESDtrack::kITSpid;
+  }
+  if(fDets[kTPC]) {
+    pTrk->GetTPCpid(pid[kTPC]);
+    status[kTPC]=AliESDtrack::kTPCpid;
+  }
+  if(fDets[kTRD]) {
+    pTrk->GetTRDpid(pid[kTRD]);
+    status[kTRD]=AliESDtrack::kTRDpid;
+  }
+  if(fDets[kTOF]) {
+    pTrk->GetTOFpid(pid[kTOF]);
+    status[kTOF]=AliESDtrack::kTOFpid;
+  }
+  if(fDets[kHMPID]) {
+    pTrk->GetHMPIDpid(pid[kHMPID]);
+    status[kHMPID]=AliESDtrack::kHMPIDpid;
+  }
+  if(fDetRestr>=0){
+    if(fDetRestr == kITS) pTrk->GetITSpid(pid[kITS]);
+    if(fDetRestr == kTPC) pTrk->GetITSpid(pid[kTPC]);
+    if(fDetRestr == kTRD) pTrk->GetITSpid(pid[kTRD]);
+    if(fDetRestr == kTOF) pTrk->GetITSpid(pid[kTOF]);
+    if(fDetRestr == kHMPID) pTrk->GetITSpid(pid[kHMPID]);
+  }
+  
+  status[kNdets]=pTrk->GetStatus();
+  pTrk->GetESDpid(pid[kNdets]);
+}
+//__________________________________
+void AliCFTrackCutPid::SetPPriors(AliESDtrack *pTrk)
+{
+  //
+  //sets the mommentum dependent a priori concentrations
+  //
+  
+  for(Int_t i=0; i< AliPID::kSPECIES; i++) {
+    if(pTrk->P()>fPriorsFunc[i]->GetXmin() && pTrk->P() < fPriorsFunc[i]->GetXmax()) fPriors[i]=fPriorsFunc[i]->Eval(pTrk->P());
+    else {AliInfo("the track momentum is not in the function range. Priors are equal") fPriors[i] = 0.2;}   
+  }
+}   
+//______________________________________
+ULong_t AliCFTrackCutPid::StatusForAND(ULong_t status[kNdets+1]) const
+{
+  //
+  //In case of AND of more detectors the AND-detector status combination. 
+  //is calculated and also returned
+  //
+
+  ULong_t andstatus=0;
+  for(Int_t i=0; i< kNdets; i++) {
+    if(!fDetsInAnd[i]) continue;
+    andstatus = andstatus | status[i];
+    AliDebug(1,Form("trk status %lu  %i AND-status  combination: %lu",status[i],i,andstatus));
+  }
+  return andstatus;
+}
+//_______________________________________
+Int_t AliCFTrackCutPid::GetID(ULong_t status[kNdets+1],Double_t pid[kNdets+1][AliPID::kSPECIES]) const
+{
+  // Identifies the track if its probability is higher than the cut
+  // value. The default value is fCut=0.2, therefore the most probable
+  // one is identified by default. Here all the checks on how to identify
+  // the track are performed (single detector or combined PID,..., detector
+  // restriction probability
+  // Returns:   integer corresponding to the identified particle
+  
+  Int_t iPart=-1;
+  
+  if(!fgIsComb){  
+    Bool_t isDet=kFALSE;
+    for(Int_t i=0; i<kNdets; i++){
+      if(!fDets[i]) continue;
+      isDet=kTRUE;
+      AliDebug(1,Form("trk status %lu  %i-det-pid status %lu   -> combination: %lu",status[kNdets],i,status[i],status[kNdets]&status[i]));
+      if(!(status[kNdets]&status[i])){
+       iPart=-10;
+       AliDebug(1,Form("detector %i -> pid trk status not ok",i));
+      }
+      else {
+        AliDebug(1,Form("resp   : %f  %f  %f  %f  %f",pid[i][0],pid[i][1],pid[i][2],pid[i][3],pid[i][4]));
+       if(fIsQAOn) iPart = IdentifyQA(pid[i],i);
+       else iPart = Identify(pid[i]);
+      } 
+    }  
+    if(!isDet){
+      AliDebug(1,Form("  !!!        No detector selected, the ESD-pid response is considered"));
+      iPart = Identify(pid[kNdets]);
+    }
+  }else{
+    Double_t calcprob[5];
+    CombPID(status,pid,calcprob);
+    iPart = Identify(calcprob);
+  }
+  
+  
+  AliDebug(1,Form("selected particle: %i",iPart));
+  
+  if(iPart >=0 && fiPartRestr>=0) {
+    AliPID restr(pid[fDetRestr]);
+    restr.SetPriors(fPriors);
+    AliDebug(1,Form("setted upper limit: %f  det %i : probability %f ",fDetProbRestr,fDetRestr,restr.GetProbability((AliPID::EParticleType)fiPartRestr)));
+    if(restr.GetProbability((AliPID::EParticleType)fiPartRestr) > fDetProbRestr) {
+      iPart = kDetRestr;
+      AliDebug(1,"\n\n the detector restrictions refused the ID \n\n");
+    }
+  }//cross checks with one detector probability
+  
+  AliDebug(1,Form("after the check the selected particle is %i",iPart));
+  
+  return iPart;
+}
+//__________________________________
+Bool_t AliCFTrackCutPid::Check(const Double_t *p, Int_t iPsel, Double_t minDiff) const
+{
+  // Checks if there are no equal values and if the valus
+  // difference between the selected particle and the others i
+  // is higher than  a lower limit.
+  // Returns:  kTRUE= is acceptable
+  
+  AliDebug(1,Form("input particle: %i",iPsel));
+  Bool_t ck=kTRUE;
+  
+  if(iPsel<0) ck=kFALSE;
+  
+  else {
+    for(Int_t j=0; j< AliPID::kSPECIES; j++) {
+      if(j!=iPsel && TMath::Abs(p[j]-p[iPsel])<minDiff) ck=kFALSE;
+    }
+    if(!ck) AliDebug(1,"the values are too close ");
+  }
+  return ck;
+}
+//___________________________________________
+Int_t AliCFTrackCutPid::Identify(Double_t pid[AliPID::kSPECIES]) const
+{
+  //
+  // The identification is actually performed here with possible
+  // checks on the det responses and/or probabilities
+  //
+  Int_t iPart = -1;
+  
+  AliPID getpid(pid,kTRUE);
+  
+  if(fgIsComb) {
+    Double_t priors[5]={0.2,0.2,0.2,0.2,0.2};
+    getpid.SetPriors(priors);
+  }
+  else getpid.SetPriors(fPriors);
+  
+  
+  AliPID::EParticleType sel = getpid.GetMostProbable();
+  Double_t probability[AliPID::kSPECIES];
+  for(Int_t iP=0; iP<AliPID::kSPECIES; iP++) probability[iP] = getpid.GetProbability((AliPID::EParticleType)iP);
+  
+  
+  if(getpid.GetProbability(sel,fPriors)>fCut) iPart= (Int_t)sel;
+  AliDebug(1,Form("resp   : %f  %f  %f  %f  %f",pid[0],pid[1],pid[2],pid[3],pid[4]));
+  AliDebug(1,Form("probab : %f  %f  %f  %f  %f",probability[0],probability[1],probability[2],probability[3],probability[4]));
+  if(fCheckResponse && !Check(pid,iPart, fMinDiffResponse)) iPart=kCheckResp;
+  if(fCheckSelection && !Check(probability,iPart,fMinDiffProbability)) iPart=kCheckProb;
+  return iPart;
+}
+//___________________________________________
+Int_t AliCFTrackCutPid::IdentifyQA(const Double_t pid[AliPID::kSPECIES], Int_t idets) const
+{
+  //
+  // The same as Identify, but with the QA histo filling 
+  //
+  //
+  
+  Int_t iPart = -1;
+  AliDebug(1,Form("resp   : %f  %f  %f  %f  %f",pid[0],pid[1],pid[2],pid[3],pid[4]));
+  
+  AliPID getpid(pid,kTRUE);
+  
+  if(fgIsComb) {
+    Double_t priors[5]={0.2,0.2,0.2,0.2,0.2};
+    getpid.SetPriors(priors);
+  }
+  else getpid.SetPriors(fPriors);
+  
+  AliPID::EParticleType sel = getpid.GetMostProbable();
+  Double_t probability[AliPID::kSPECIES];
+  for(Int_t iP=0; iP<AliPID::kSPECIES; iP++) {
+    probability[iP] = getpid.GetProbability((AliPID::EParticleType)iP);
+    fhProb[idets][iP]->Fill(probability[iP]);
+  }
+  
+  AliPID toresp(pid,kTRUE); Double_t qapriors[5]={0.2,0.2,0.2,0.2,0.2};
+  toresp.SetPriors(qapriors);
+  for(Int_t iPr=0; iPr<AliPID::kSPECIES; iPr++) fhResp[idets][iPr]->Fill(toresp.GetProbability((AliPID::EParticleType)iPr));
+  
+  if(getpid.GetProbability(sel,fPriors)>fCut) iPart= (Int_t)sel;
+  AliDebug(1,Form("resp   : %f  %f  %f  %f  %f",pid[0],pid[1],pid[2],pid[3],pid[4]));
+  AliDebug(1,Form("probab : %f  %f  %f  %f  %f",probability[0],probability[1],probability[2],probability[3],probability[4]));
+  if(fCheckResponse && !Check(pid,iPart, fMinDiffResponse)) iPart=kCheckResp;
+  if(fCheckSelection && !Check(probability,iPart,fMinDiffProbability)) iPart=kCheckProb;
+  return iPart;
+}
+//___________________________________________
+Bool_t AliCFTrackCutPid::IsSelected(TObject *track){
+  //
+  //  method for the pid-cut selction
+  //
+  
+  if (!track) return kFALSE ;
+  TString className(track->ClassName());
+  if (className.CompareTo("AliESDtrack") != 0) {
+    AliError("obj must point to a AliESDtrack ");
+    return kFALSE ;
+  }
+  
+  AliESDtrack *esdTrack = (AliESDtrack *)track;
+  ULong_t status[kNdets+1]={0,0,0,0,0,0};
+  Double_t pid[kNdets+1][AliPID::kSPECIES];
+  TrackInfo(esdTrack,status,pid);
+  if(fIsPpriors) SetPPriors(esdTrack);
+  if(GetID(status,pid)==fgParticleType) return kTRUE;
+  else return kFALSE;
+}
+//__________________________________
+void  AliCFTrackCutPid::CombPID(ULong_t status[kNdets+1],Double_t pid[kNdets+1][AliPID::kSPECIES],Double_t *combpid) const
+{
+  //
+  // Calculates the combined PID according to the chosen detectors.
+  // and provides the array of probabilities
+  //
+  
+  Bool_t isdet=kFALSE;
+  Double_t sum=0.;
+  Double_t prod[AliPID::kSPECIES]={1.,1.,1.,1.,1.};
+  Double_t comb[AliPID::kSPECIES]={0.,0.,0.,0.,0.};
+  Double_t priors[AliPID::kSPECIES]={0.2,0.2,0.2,0.2,0.2};
+  ULong_t andstatus =0;
+  if(fIsDetAND) {
+    andstatus = StatusForAND(status);
+    AliDebug(1,Form("AND combination %lu",andstatus));
+  } 
+  for(Int_t j=0; j<AliPID::kSPECIES; j++){
+    for(Int_t i=0; i< kNdets; i++){
+      if(!fDets[i]) continue;
+      if(status[kNdets]&status[i]) {
+        if(fIsDetAND) {
+         ULong_t checkstatus = status[kNdets]&andstatus;
+         if(checkstatus != andstatus) continue; 
+         else {
+           prod[j]*=pid[i][j];
+           isdet = kTRUE;
+           AliDebug(1,Form("-----> trk status %lu   and status %lu -> trk-ANDdetector status combination %lu",status[kNdets],andstatus,status[kNdets]&andstatus));
+           AliDebug(1,Form("In det loop %i ->  particle %i response is %f",i,j,pid[i][j]));
+         }
+        }
+        else {
+         prod[j]*=pid[i][j];
+         isdet=kTRUE;
+         AliDebug(1,Form("In det loop %i ->  particle %i response is %f",i,j,pid[i][j]));
+       }
+      }//combined mode
+    }//loop on dets
+  }//loop on species
+  
+  if(fIsQAOn) {
+    for(Int_t iqa =0; iqa < kNdets; iqa++){   
+      if(!fDets[iqa]) continue;              
+      AliPID normresp(pid[iqa]);
+      normresp.SetPriors(priors);
+      for(Int_t ip =0; ip< AliPID::kSPECIES; ip++){
+       if(!fhResp[iqa][ip]) {AliDebug(1,Form("no pointer to the histo fhResp%i%i, check if pidcut->Init() was called",iqa,ip));}
+       else fhResp[iqa][ip]->Fill(normresp.GetProbability((AliPID::EParticleType)ip));
+      }//loop on part
+    }//loop on dets
+  }//if qa 
+  
+  if(!isdet) {
+    AliDebug(1,"No proper status for the combined pid -> probabilities are set to zero");
+    for(Int_t nn=0; nn<AliPID::kSPECIES; nn++) {combpid[nn]=0;}
+  }
+  
+  else{
+    for(Int_t k=0; k<AliPID::kSPECIES; k++){
+      if(fIsQAOn) {
+       if(!fhCombResp[k]) AliDebug(1,Form("no fhCombResp[%i], check if pidcut->Init() was called",k));
+       else fhCombResp[k]->Fill(prod[k]);
+      }
+      AliDebug(1,Form("species %i priors %f and prod %f",k,fPriors[k],prod[k]));
+      comb[k]=fPriors[k]*prod[k];
+      AliDebug(1,Form("comb %i  %f",k,comb[k]));
+      sum+=comb[k];
+    }
+    
+    if(sum == 0) {
+      AliDebug(1,"Check the detector responses or the priors, their combined products are zero");
+      return;
+    }
+    for(Int_t n=0; n<AliPID::kSPECIES; n++) { 
+      combpid[n]=fPriors[n]*prod[n]/sum;
+      if(fIsQAOn) {
+       if(!fhCombProb[n]) Printf("no fhCombResp[%i], check if pidcut->Init() was called",n);
+       fhCombProb[n]->Fill(combpid[n]);
+      }
+    }
+  } 
+}
+//__________________________________________
+//
+//QA part
+//_________________________________________
+void AliCFTrackCutPid::InitialiseHisto()
+{
+  //
+  //QA histo initialization
+  //
+  for(Int_t iP=0; iP<AliPID::kSPECIES; iP++){
+    fhCombResp[iP]=0x0;
+    fhCombProb[iP]=0x0;
+    for(Int_t iDet =0; iDet<kNdets; iDet++){
+      fhResp[iDet][iP]=0x0;
+      fhProb[iDet][iP]=0x0;
+    }
+  } 
+}
+//______________________________________________
+void AliCFTrackCutPid::Init() 
+{
+  //
+  // initialises QA histograms
+  //
+  
+  if(fIsQAOn) DefineHistograms();
+}
+//_________________________________________________
+void AliCFTrackCutPid::DefineHistograms()
+{
+  //
+  //QA histo booking
+  //
+  char *detect[5]={"ITS","TPC","TRD","TOF","HMPID"};
+  char *partic[5]={"electron","muon","pion","kaon","proton"};
+  
+  for(Int_t iDet =0; iDet< kNdets; iDet++)
+    {
+      if(!fDets[iDet]) continue;
+      for(Int_t iP =0; iP < AliPID::kSPECIES; iP++){
+       fhResp[iDet][iP] = new TH1F(Form("rDet%iPart%i",iDet,iP),Form("%s %s response    ",detect[iDet],partic[iP]),fNbins,fXmin,fXmax);
+       fhProb[iDet][iP] = new TH1F(Form("pDet%iPart%i",iDet,iP),Form("%s %s probability ",detect[iDet],partic[iP]),fNbins,fXmin,fXmax);
+      }
+    }
+  
+  if(fgIsComb){
+    for(Int_t iPart =0; iPart < AliPID::kSPECIES; iPart++)
+      {
+       fhCombResp[iPart] = new TH1F(Form("rCombPart%i",iPart),Form(" %s combined response    ",partic[iPart]),fNbins,fXmin,fXmax);
+       fhCombProb[iPart] = new TH1F(Form("pCombPart%i",iPart),Form("%s combined probability ",partic[iPart]),fNbins,fXmin,fXmax);
+      }
+  }
+}
+//___________________________________________________
+
+void AliCFTrackCutPid::AddQAHistograms(TList *qalist) const 
+{
+  //
+  // adds QA histograms in a TList
+  //
+  if(!fIsQAOn) return;
+  
+  if(fgIsComb){
+    for(Int_t iPart =0; iPart<AliPID::kSPECIES; iPart++){
+      qalist->Add(fhCombResp[iPart]);
+      qalist->Add(fhCombProb[iPart]);
+    }
+  }
+  
+  for(Int_t iDet=0; iDet<kNdets; iDet++){
+    for(Int_t iP =0; iP<AliPID::kSPECIES; iP++){
+      if(!fgIsComb)qalist->Add(fhResp[iDet][iP]);
+      if(!fgIsComb)qalist->Add(fhProb[iDet][iP]);
+    }
+  }  
+}
diff --git a/CORRFW/AliCFTrackCutPid.h b/CORRFW/AliCFTrackCutPid.h
new file mode 100644 (file)
index 0000000..90615f4
--- /dev/null
@@ -0,0 +1,120 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+//
+// author : A. Mastroserio
+//
+
+#ifndef ALICFTRACKCUTPID_H
+#define ALICFTRACKCUTPID_H
+
+#include "AliCFCutBase.h"
+#include "AliPID.h"
+#include "AliESDtrack.h"
+#include <TString.h>
+#include <TObject.h>
+#include <TH1F.h>
+#include <TF1.h>
+//__________________________________________________________________________________
+// CUT ON TRACK PID
+//__________________________________________________________________________________
+class AliESDtrack;
+
+class AliCFTrackCutPid : public AliCFCutBase
+{
+  public :
+    AliCFTrackCutPid() ;
+  AliCFTrackCutPid(const Char_t* name, const Char_t* title) ;
+  AliCFTrackCutPid(const AliCFTrackCutPid& c) ;
+  AliCFTrackCutPid& operator=(const AliCFTrackCutPid& c) ;
+  
+  virtual ~AliCFTrackCutPid();
+  
+  enum EDetType {kITS = 0, kTPC, kTRD,  kTOF, kHMPID=4, kNoDet=-11};
+  enum EDetNum {kNdets=5};
+  enum ENoId {kCheckProb = -10, kCheckResp = -11, kDetRestr = -12};
+  
+  // Setters 
+  
+  void SetDetectors(TString dets);                            
+  void SetPriors(Double_t r[AliPID::kSPECIES]);                    
+  void SetProbabilityCut(Double_t cut) {fCut=cut;}                  
+  void SetParticleType(Int_t iType, Bool_t tocombine) {fgParticleType=iType; fgIsComb=tocombine;} 
+  void SetMinDiffResp(Bool_t check, Double_t mindiff) {fCheckResponse=check; fMinDiffResponse=mindiff;}  
+  void SetMinDiffProb(Bool_t check, Double_t mindiff) {fCheckSelection=check; fMinDiffProbability=mindiff;} 
+  void SetPriorFunctions(TF1 *func[AliPID::kSPECIES]);
+  void SetANDstatus(TString dets);
+  void SetDetectorProbabilityRestriction(TString det, Int_t iPart, Double_t upperprob); 
+  void SetHistogramAxis(Int_t nbins, Double_t xmin, Double_t xmax) {fNbins=nbins; fXmin = xmin; fXmax = xmax;}
+  
+  //loads the track detector responses and the track status
+  void TrackInfo(const AliESDtrack *pTrk,ULong_t status[kNdets+1], Double_t pid[kNdets+1][AliPID::kSPECIES]) const;  
+  
+  //identifies the track
+  Int_t Identify(Double_t pid[AliPID::kSPECIES]) const;
+  
+  //identifies the track filling the QA histograms                                                          
+  Int_t IdentifyQA(const Double_t pid[AliPID::kSPECIES],Int_t idets) const;
+  
+  //returns the track identification number  
+  Int_t GetID(ULong_t status[kNdets+1], Double_t pid[kNdets+1][AliPID::kSPECIES]) const;  
+  
+  //main 
+  virtual Bool_t IsSelected(TObject *track); 
+  
+  //histo booking                                                    
+  void Init();
+  
+  //histos are added to a list
+  void AddQAHistograms(TList *qalist) const;
+  
+  
+ private:
+  void SetPPriors(AliESDtrack *pTrk);                          
+  ULong_t StatusForAND(ULong_t status[kNdets+1]) const; //
+  void InitialiseHisto();
+  void DefineHistograms();    
+  Bool_t Check(const Double_t *p, Int_t iPsel, Double_t minDiff) const;
+  void CombPID(ULong_t status[kNdets+1],Double_t pid[kNdets+1][AliPID::kSPECIES],Double_t *combpid) const;
+  
+  Double_t fCut;                                            //probability cut
+  Double_t fMinDiffResponse;                                // minimum difference between detector resposes
+  Double_t fMinDiffProbability;                             // minimum difference between probability values
+  Int_t fgParticleType;                                     // requested particle type
+  Bool_t fgIsComb;                                          // flag for the combined pid
+  Bool_t fCheckResponse;                                    // flag to check the minimum difference of det responsess
+  Bool_t fCheckSelection;                                   // flag to check the minimum difference of probabilities
+  Bool_t fIsPpriors;                                        //flag for momentum dependent priors
+  Bool_t fIsDetAND;                                         //flag for AND with multiple detectors
+  Double_t fXmin;                                           //x min QA histo
+  Double_t fXmax;                                           //x max QA histo
+  Int_t fNbins;                                             //n bins QA histo 
+  Int_t fDetRestr;                                          //id of the detector for the restriction
+  Int_t fiPartRestr;                                        //id of the particle for the restriction
+  Double_t fDetProbRestr;                                   //probability restriction value
+
+  Double_t fPriors[AliPID::kSPECIES];                       //a priori concentrations
+  TF1 *fPriorsFunc[AliPID::kSPECIES];                       //momentum dependent priors
+  Bool_t fDets[kNdets];                                     //boolean(s) corresponding to the chosen detector(s) 
+  Bool_t fDetsInAnd[kNdets];                                //detector to be in AND for the combined PID
+  TH1F *fhResp[kNdets][AliPID::kSPECIES];                   //QA histo
+  TH1F *fhProb[kNdets][AliPID::kSPECIES];                   //QA histo
+  TH1F *fhCombResp[AliPID::kSPECIES];                       //QA histo
+  TH1F *fhCombProb[AliPID::kSPECIES];                       //QA histo
+  
+  ClassDef(AliCFTrackCutPid,1);
+};
+#endif
+    
diff --git a/CORRFW/AliCFTrackIsPrimaryCuts.cxx b/CORRFW/AliCFTrackIsPrimaryCuts.cxx
new file mode 100644 (file)
index 0000000..2bd2f57
--- /dev/null
@@ -0,0 +1,808 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+// The class AliCFTrackIsPrimaryCut is designed to select reconstructed tracks
+// with a small impact parameter and tracks which are (not) daughters of kink
+// decays and to provide corresponding QA histograms.
+// This class inherits from the Analysis' Framework abstract base class
+// AliAnalysisCuts and is a part of the Correction Framework.
+// This class acts on single, reconstructed tracks, it is applicable on
+// ESD and AOD data.
+// It mainly consists of a IsSelected function that returns a boolean.
+// This function checks whether the considered track passes a set of cuts:
+// - distance to main vertex in units of sigma (resolution)
+// - require that the dca calculation doesn't fail
+// - accept or not accept daughter tracks of kink decays
+//
+// The cut values for these cuts are set with the corresponding set functions.
+// All cut classes provided by the correction framework are supposed to be
+// added in the Analysis Framwork's class AliAnalysisFilter and applied by
+// the filter via a loop.
+//
+// author: I. Kraus (Ingrid.Kraus@cern.ch)
+// idea taken form
+// AliESDtrackCuts writte by Jan Fiete Grosse-Oetringhaus and
+// AliRsnDaughterCut class written by A. Pulvirenti.
+
+#include <TCanvas.h>
+#include <TDirectory.h>
+#include <TBits.h>
+#include <TH2.h>
+#include <AliESDtrack.h>
+#include <AliLog.h>
+#include "AliCFTrackIsPrimaryCuts.h"
+
+ClassImp(AliCFTrackIsPrimaryCuts)
+
+//__________________________________________________________________________________
+AliCFTrackIsPrimaryCuts::AliCFTrackIsPrimaryCuts() :
+  AliCFCutBase(),
+  fNSigmaToVertexMax(0),
+  fRequireSigmaToVertex(0),
+  fAcceptKinkDaughters(0),
+  fhCutStatistics(0),
+  fhCutCorrelation(0),
+  fBitmap(0x0),
+  fhNBinsNSigma(0),
+  fhNBinsRequireSigma(0),
+  fhNBinsAcceptKink(0),
+  fhNBinsDcaXY(0),
+  fhNBinsDcaZ(0),
+  fhNBinsDcaXYnorm(0),
+  fhNBinsDcaZnorm(0),
+  fhBinLimNSigma(0x0),
+  fhBinLimRequireSigma(0x0),
+  fhBinLimAcceptKink(0x0),
+  fhBinLimDcaXY(0x0),
+  fhBinLimDcaZ(0x0),
+  fhBinLimDcaXYnorm(0x0),
+  fhBinLimDcaZnorm(0x0)
+{
+  //
+  // Default constructor
+  //
+  fBitmap=new TBits(0);
+  Initialise();
+}
+//__________________________________________________________________________________
+AliCFTrackIsPrimaryCuts::AliCFTrackIsPrimaryCuts(Char_t* name, Char_t* title) :
+  AliCFCutBase(name,title),
+  fNSigmaToVertexMax(0),
+  fRequireSigmaToVertex(0),
+  fAcceptKinkDaughters(0),
+  fhCutStatistics(0),
+  fhCutCorrelation(0),
+  fBitmap(0x0),
+  fhNBinsNSigma(0),
+  fhNBinsRequireSigma(0),
+  fhNBinsAcceptKink(0),
+  fhNBinsDcaXY(0),
+  fhNBinsDcaZ(0),
+  fhNBinsDcaXYnorm(0),
+  fhNBinsDcaZnorm(0),
+  fhBinLimNSigma(0x0),
+  fhBinLimRequireSigma(0x0),
+  fhBinLimAcceptKink(0x0),
+  fhBinLimDcaXY(0x0),
+  fhBinLimDcaZ(0x0),
+  fhBinLimDcaXYnorm(0x0),
+  fhBinLimDcaZnorm(0x0)
+{
+  //
+  // Constructor
+  //
+  fBitmap=new TBits(0);
+  Initialise();
+}
+//__________________________________________________________________________________
+AliCFTrackIsPrimaryCuts::AliCFTrackIsPrimaryCuts(const AliCFTrackIsPrimaryCuts& c) :
+  AliCFCutBase(c),
+  fNSigmaToVertexMax(c.fNSigmaToVertexMax),
+  fRequireSigmaToVertex(c.fRequireSigmaToVertex),
+  fAcceptKinkDaughters(c.fAcceptKinkDaughters),
+  fhCutStatistics(c.fhCutStatistics),
+  fhCutCorrelation(c.fhCutCorrelation),
+  fBitmap(c.fBitmap),
+  fhNBinsNSigma(c.fhNBinsNSigma),
+  fhNBinsRequireSigma(c.fhNBinsRequireSigma),
+  fhNBinsAcceptKink(c.fhNBinsAcceptKink),
+  fhNBinsDcaXY(c.fhNBinsDcaXY),
+  fhNBinsDcaZ(c.fhNBinsDcaZ),
+  fhNBinsDcaXYnorm(c.fhNBinsDcaXYnorm),
+  fhNBinsDcaZnorm(c.fhNBinsDcaZnorm),
+  fhBinLimNSigma(c.fhBinLimNSigma),
+  fhBinLimRequireSigma(c.fhBinLimRequireSigma),
+  fhBinLimAcceptKink(c.fhBinLimAcceptKink),
+  fhBinLimDcaXY(c.fhBinLimDcaXY),
+  fhBinLimDcaZ(c.fhBinLimDcaZ),
+  fhBinLimDcaXYnorm(c.fhBinLimDcaXYnorm),
+  fhBinLimDcaZnorm(c.fhBinLimDcaZnorm)
+{
+  //
+  // copy constructor
+  //
+  ((AliCFTrackIsPrimaryCuts &) c).Copy(*this);
+}
+//__________________________________________________________________________________
+AliCFTrackIsPrimaryCuts& AliCFTrackIsPrimaryCuts::operator=(const AliCFTrackIsPrimaryCuts& c)
+{
+  //
+  // Assignment operator
+  //
+  if (this != &c) {
+    AliCFCutBase::operator=(c) ;
+    fNSigmaToVertexMax = c.fNSigmaToVertexMax ;
+    fRequireSigmaToVertex = c.fRequireSigmaToVertex ;
+    fAcceptKinkDaughters = c.fAcceptKinkDaughters ;
+    fhCutStatistics = c.fhCutStatistics ;
+    fhCutCorrelation = c.fhCutCorrelation ;
+    fBitmap =  c.fBitmap;
+    fhNBinsNSigma = c.fhNBinsNSigma;
+    fhNBinsRequireSigma = c.fhNBinsRequireSigma;
+    fhNBinsAcceptKink = c.fhNBinsAcceptKink;
+    fhNBinsDcaXY = c.fhNBinsDcaXY;
+    fhNBinsDcaZ = c.fhNBinsDcaZ;
+    fhNBinsDcaXYnorm = c.fhNBinsDcaXYnorm;
+    fhNBinsDcaZnorm = c.fhNBinsDcaZnorm;
+    fhBinLimNSigma = c.fhBinLimNSigma;
+    fhBinLimRequireSigma = c.fhBinLimRequireSigma;
+    fhBinLimAcceptKink = c.fhBinLimAcceptKink;
+    fhBinLimDcaXY = c.fhBinLimDcaXY;
+    fhBinLimDcaZ = c.fhBinLimDcaZ;
+    fhBinLimDcaXYnorm = c.fhBinLimDcaXYnorm;
+    fhBinLimDcaZnorm = c.fhBinLimDcaZnorm;
+    
+    for (Int_t i=0; i<c.kNHist; i++){
+      for (Int_t j=0; j<c.kNStepQA; j++){
+       if(c.fhQA[i][j]) fhQA[i][j] = (TH1F*)c.fhQA[i][j]->Clone();
+       if(c.fhDcaXYvsDcaZ[j]) fhDcaXYvsDcaZ[j] = (TH2F*)c.fhDcaXYvsDcaZ[j]->Clone();
+       if(c.fhDcaXYvsDcaZnorm[j]) fhDcaXYvsDcaZnorm[j] = (TH2F*)c.fhDcaXYvsDcaZnorm[j]->Clone();
+      }
+    }
+
+    ((AliCFTrackIsPrimaryCuts &) c).Copy(*this);
+ }
+  return *this;
+}
+//__________________________________________________________________________________
+AliCFTrackIsPrimaryCuts::~AliCFTrackIsPrimaryCuts()
+{
+  //
+  // destructor
+  //
+  if (fhCutStatistics)                 delete fhCutStatistics;
+  if (fhCutCorrelation)                        delete fhCutCorrelation;
+
+  for (Int_t j=0; j<kNStepQA; j++){
+    for (Int_t i=0; i<kNHist; i++){
+      if(fhQA[i][j]) delete fhQA[i][j];
+    }
+    if(fhDcaXYvsDcaZ[j]) delete fhDcaXYvsDcaZ[j];
+    if(fhDcaXYvsDcaZnorm[j]) delete fhDcaXYvsDcaZnorm[j];
+  }
+
+  if (fBitmap) delete fBitmap;
+  
+  if(fhBinLimNSigma) delete fhBinLimNSigma;
+  if(fhBinLimRequireSigma) delete fhBinLimRequireSigma;
+  if(fhBinLimAcceptKink) delete fhBinLimAcceptKink;
+  if(fhBinLimDcaXY) delete fhBinLimDcaXY;
+  if(fhBinLimDcaZ) delete fhBinLimDcaZ;
+  if(fhBinLimDcaXYnorm) delete fhBinLimDcaXYnorm;
+  if(fhBinLimDcaZnorm) delete fhBinLimDcaZnorm;
+}
+//__________________________________________________________________________________
+void AliCFTrackIsPrimaryCuts::Initialise()
+{
+  //
+  // sets everything to zero
+  //
+  fNSigmaToVertexMax = 0;
+  fRequireSigmaToVertex = 0;
+  fAcceptKinkDaughters = 0;
+
+  SetMaxNSigmaToVertex();
+  SetRequireSigmaToVertex();
+
+  for (Int_t j=0; j<kNStepQA; j++)  {
+    for (Int_t i=0; i<kNHist; i++){
+      fhQA[i][j] = 0x0;
+    }
+    fhDcaXYvsDcaZ[j] = 0x0;
+    fhDcaXYvsDcaZnorm[j] = 0x0;
+  }
+  fhCutStatistics = 0;
+  fhCutCorrelation = 0;
+  
+  //set default bining for QA histograms
+  SetHistogramBins(kCutNSigmaToVertex,500,0,50);
+  SetHistogramBins(kCutRequireSigmaToVertex,2,-0.5,1.5);
+  SetHistogramBins(kCutAcceptKinkDaughters,2,-0.5,1.5);
+  SetHistogramBins(kDcaXY,500,-10,10);
+  SetHistogramBins(kDcaZ,500,-10,10);
+  SetHistogramBins(kDcaXYnorm,500,-10,10);
+  SetHistogramBins(kDcaZnorm,500,-10,10);
+}
+//__________________________________________________________________________________
+void AliCFTrackIsPrimaryCuts::Copy(TObject &c) const
+{
+  //
+  // Copy function
+  //
+  AliCFTrackIsPrimaryCuts& target = (AliCFTrackIsPrimaryCuts &) c;
+
+  target.Initialise();
+
+  if (fhCutStatistics)  target.fhCutStatistics = (TH1F*) fhCutStatistics->Clone();
+  if (fhCutCorrelation) target.fhCutCorrelation = (TH2F*) fhCutCorrelation->Clone();
+
+  for (Int_t j=0; j<kNStepQA; j++){
+    for (Int_t i=0; i<kNHist; i++){
+      if(fhQA[i][j]) target.fhQA[i][j] = (TH1F*)fhQA[i][j]->Clone();
+      
+    }
+    if(fhDcaXYvsDcaZ[j]) target.fhDcaXYvsDcaZ[j] = (TH2F*)fhDcaXYvsDcaZ[j]->Clone();
+    if(fhDcaXYvsDcaZnorm[j]) target.fhDcaXYvsDcaZnorm[j] = (TH2F*)fhDcaXYvsDcaZnorm[j]->Clone();
+  }
+  
+  TNamed::Copy(c);
+}
+//____________________________________________________________________
+Float_t AliCFTrackIsPrimaryCuts::GetSigmaToVertex(AliESDtrack* esdTrack) const
+{
+  //
+  // Calculates the number of sigma to the vertex.
+  //
+  Float_t b[2];
+  Float_t bRes[2];
+  Float_t bCov[3];
+  esdTrack->GetImpactParameters(b,bCov);
+  if (bCov[0]<=0 || bCov[2]<=0) {
+    AliDebug(1, "Estimated b resolution lower or equal zero!");
+    bCov[0]=0; bCov[2]=0;
+  }
+  bRes[0] = TMath::Sqrt(bCov[0]);
+  bRes[1] = TMath::Sqrt(bCov[2]);
+
+  // -----------------------------------
+  // How to get to a n-sigma cut?
+  //
+  // The accumulated statistics from 0 to d is
+  //
+  // ->  Erf(d/Sqrt(2)) for a 1-dim gauss (d = n_sigma)
+  // ->  1 - Exp(-d**2) for a 2-dim gauss (d*d = dx*dx + dy*dy != n_sigma)
+  //
+  // It means that for a 2-dim gauss: n_sigma(d) = Sqrt(2)*ErfInv(1 - Exp((-x**2)/2)
+  // Can this be expressed in a different way?
+
+  if (bRes[0] == 0 || bRes[1] ==0)
+    return -1;
+
+  Float_t d = TMath::Sqrt(TMath::Power(b[0]/bRes[0],2) + TMath::Power(b[1]/bRes[1],2));
+
+  // stupid rounding problem screws up everything:
+  // if d is too big, TMath::Exp(...) gets 0, and TMath::ErfInverse(1) that should be infinite, gets 0 :(
+  if (TMath::Exp(-d * d / 2) < 1e-10)
+    return 1000;
+
+  d = TMath::ErfInverse(1 - TMath::Exp(-d * d / 2)) * TMath::Sqrt(2);
+  return d;
+}
+//__________________________________________________________________________________
+void AliCFTrackIsPrimaryCuts::GetBitMap(TObject* obj, TBits *bitmap)  {
+  //
+  // retrieve the pointer to the bitmap
+  //
+  bitmap = SelectionBitMap(obj);
+}
+//__________________________________________________________________________________
+TBits* AliCFTrackIsPrimaryCuts::SelectionBitMap(TObject* obj)
+{
+  //
+  // test if the track passes the single cuts
+  // and store the information in a bitmap
+  //
+
+  // bitmap stores the decision of each single cut
+  for(Int_t i=0; i<kNCuts; i++)fBitmap->SetBitNumber(i,kFALSE);
+
+  // cast TObject into ESDtrack
+  AliESDtrack* esdTrack = dynamic_cast<AliESDtrack *>(obj);
+  if ( !esdTrack ) return fBitmap ;
+
+
+  for(Int_t i=0; i<kNCuts; i++)fBitmap->SetBitNumber(i,kTRUE);
+
+  // get the track to vertex parameter
+  Float_t nSigmaToVertex = GetSigmaToVertex(esdTrack);
+
+  // fill the bitmap
+  Int_t iCutBit = 0;
+  if (nSigmaToVertex > fNSigmaToVertexMax)
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if (nSigmaToVertex<0 && fRequireSigmaToVertex)
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if (!fAcceptKinkDaughters && esdTrack->GetKinkIndex(0)>0)
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+
+  return fBitmap;
+}
+//__________________________________________________________________________________
+Bool_t AliCFTrackIsPrimaryCuts::IsSelected(TObject* obj) {
+  //
+  // loops over decisions of single cuts and returns if the track is accepted
+  //
+  TBits* bitmap = SelectionBitMap(obj);
+
+  Bool_t isSelected = kTRUE;
+
+  for (UInt_t icut=0; icut<bitmap->GetNbits();icut++)
+       if(!bitmap->TestBitNumber(icut)) isSelected = kFALSE;
+
+  return isSelected;
+}
+//__________________________________________________________________________________
+void AliCFTrackIsPrimaryCuts::Init() {
+  //
+  // initialises all histograms and the TList which holds the histograms
+  //
+  if(fIsQAOn)
+    DefineHistograms();
+}
+//__________________________________________________________________________________
+void AliCFTrackIsPrimaryCuts::SetHistogramBins(Int_t index, Int_t nbins, Double_t *bins)
+{
+  //
+  // variable bin size
+  //
+  if(!fIsQAOn) return;
+
+  switch(index){
+  case kCutNSigmaToVertex:
+    fhNBinsNSigma=nbins;
+    fhBinLimNSigma=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimNSigma[i]=bins[i];
+    break;
+
+  case kCutRequireSigmaToVertex:
+    fhNBinsRequireSigma=nbins;
+    fhBinLimRequireSigma=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimRequireSigma[i]=bins[i];
+    break;
+
+  case kCutAcceptKinkDaughters:
+    fhNBinsAcceptKink=nbins;
+    fhBinLimAcceptKink=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimAcceptKink[i]=bins[i];
+    break;
+
+  case kDcaXY:
+    fhNBinsDcaXY=nbins;
+    fhBinLimDcaXY=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimDcaXY[i]=bins[i];
+    break;
+    
+  case kDcaZ:
+    fhNBinsDcaZ=nbins;
+    fhBinLimDcaZ=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimDcaZ[i]=bins[i];
+    break;
+    
+  case kDcaXYnorm:
+    fhNBinsDcaXYnorm=nbins;
+    fhBinLimDcaXYnorm=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimDcaXYnorm[i]=bins[i];
+    break;
+    
+  case kDcaZnorm:
+    fhNBinsDcaZnorm=nbins;
+    fhBinLimDcaZnorm=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimDcaZnorm[i]=bins[i];
+    break;
+  }
+}
+//__________________________________________________________________________________
+void AliCFTrackIsPrimaryCuts::SetHistogramBins(Int_t index, Int_t nbins, Double_t xmin, Double_t xmax)
+{
+  //
+  // fixed bin size
+  //
+  if(!fIsQAOn) return;
+
+  switch(index){
+  case kCutNSigmaToVertex:
+    fhNBinsNSigma=nbins;
+    fhBinLimNSigma=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimNSigma[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+
+  case kCutRequireSigmaToVertex:
+    fhNBinsRequireSigma=nbins;
+    fhBinLimRequireSigma=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimRequireSigma[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+
+  case kCutAcceptKinkDaughters:
+    fhNBinsAcceptKink=nbins;
+    fhBinLimAcceptKink=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimAcceptKink[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+
+  case kDcaXY:
+    fhNBinsDcaXY=nbins;
+    fhBinLimDcaXY=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimDcaXY[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kDcaZ:
+    fhNBinsDcaZ=nbins;
+    fhBinLimDcaZ=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimDcaZ[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kDcaXYnorm:
+    fhNBinsDcaXYnorm=nbins;
+    fhBinLimDcaXYnorm=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimDcaXYnorm[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kDcaZnorm:
+    fhNBinsDcaZnorm=nbins;
+    fhBinLimDcaZnorm=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimDcaZnorm[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+  }
+}
+//__________________________________________________________________________________
+ void AliCFTrackIsPrimaryCuts::DefineHistograms() {
+  //
+  // histograms for cut variables, cut statistics and cut correlations
+  //
+
+  Int_t color = 2;
+
+  // book cut statistics and cut correlation histograms
+  fhCutStatistics = new TH1F(Form("%s_cut_statistics",GetName()), Form("%s cut statistics",GetName()), kNCuts,0.5,kNCuts+0.5);
+  fhCutStatistics->SetLineWidth(2);
+  fhCutStatistics->GetXaxis()->SetBinLabel(1,"n dca");
+  fhCutStatistics->GetXaxis()->SetBinLabel(2,"require dca");
+  fhCutStatistics->GetXaxis()->SetBinLabel(3,"kink daughter");
+
+  fhCutCorrelation = new TH2F(Form("%s_cut_correlation",GetName()), Form("%s cut  correlation",GetName()), kNCuts,0.5,kNCuts+0.5,kNCuts,0.5,kNCuts+0.5);
+  fhCutCorrelation->SetLineWidth(2);
+  fhCutCorrelation->GetXaxis()->SetBinLabel(1,"n dca");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(2,"require dca");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(3,"kink daughter");
+
+  fhCutCorrelation->GetYaxis()->SetBinLabel(1,"n dca");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(2,"require dca");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(3,"kink daughter");
+
+  // book QA histograms
+  Char_t str[256];
+  for (Int_t i=0; i<kNStepQA; i++) {
+    if (i==0) sprintf(str," ");
+    else sprintf(str,"_cut");
+  
+    fhDcaXYvsDcaZ[i]            = new  TH2F(Form("%s_dcaXYvsDcaZ%s",GetName(),str),"",200,-10,10,200,-10,10);
+    fhDcaXYvsDcaZnorm[i]        = new  TH2F(Form("%s_dcaXYvsDcaZnorm%s",GetName(),str),"",200,-10,10,200,-10,10);
+
+    fhQA[kCutNSigmaToVertex][i]        = new TH1F(Form("%s_nSigmaToVertex%s",GetName(),str),"",fhNBinsNSigma,fhBinLimNSigma);
+    fhQA[kCutRequireSigmaToVertex][i] = new TH1F(Form("%s_requireSigmaToVertex%s",GetName(),str),"",fhNBinsRequireSigma,fhBinLimRequireSigma);
+    fhQA[kCutAcceptKinkDaughters][i] = new TH1F(Form("%s_acceptKinkDaughters%s",GetName(),str),"",fhNBinsAcceptKink,fhBinLimAcceptKink);
+    fhQA[kDcaXY][i]            = new TH1F(Form("%s_dcaXY%s",GetName(),str),"",fhNBinsDcaXY,fhBinLimDcaXY);
+    fhQA[kDcaZ][i]             = new TH1F(Form("%s_dcaZ%s",GetName(),str),"",fhNBinsDcaZ,fhBinLimDcaZ);
+    fhQA[kDcaXYnorm][i]                = new TH1F(Form("%s_dcaXYnorm%s",GetName(),str),"",fhNBinsDcaXYnorm,fhBinLimDcaXYnorm);
+    fhQA[kDcaZnorm][i]         = new TH1F(Form("%s_dcaZnorm%s",GetName(),str),"",fhNBinsDcaZnorm,fhBinLimDcaZnorm);
+
+    fhDcaXYvsDcaZ[i]->SetXTitle("impact par. d_{z}");
+    fhDcaXYvsDcaZ[i]->SetYTitle("impact par. d_{xy}");
+    fhDcaXYvsDcaZnorm[i]->SetXTitle("norm. impact par. d_{z} / #sigma_{z}");
+    fhDcaXYvsDcaZnorm[i]->SetYTitle("norm. impact par. d_{xy} / #sigma_{xy}");
+
+    fhQA[kCutNSigmaToVertex][i]->SetXTitle("n #sigma to vertex");
+    fhQA[kCutRequireSigmaToVertex][i]->SetXTitle("require #sigma to vertex");
+    fhQA[kCutAcceptKinkDaughters][i]->SetXTitle("accept kink daughters");
+    fhQA[kDcaXY][i]->SetXTitle("impact par. d_{xy}");
+    fhQA[kDcaZ][i]->SetXTitle("impact par. d_{z}");
+    fhQA[kDcaXYnorm][i]->SetXTitle("norm. impact par. d_{xy} / #sigma_{xy}");
+    fhQA[kDcaZnorm][i]->SetXTitle("norm. impact par. d_{z} / #sigma_{z}");
+  }
+
+  for(Int_t i=0; i<kNHist; i++) fhQA[i][1]->SetLineColor(color);
+
+}
+//__________________________________________________________________________________
+void AliCFTrackIsPrimaryCuts::FillHistograms(TObject* obj, Bool_t f)
+{
+  //
+  // fill the QA histograms
+  //
+  if(!fIsQAOn) return;
+
+  // cast TObject into ESDtrack
+  AliESDtrack* esdTrack = dynamic_cast<AliESDtrack *>(obj);
+  if ( !esdTrack ) return;
+
+  // index = 0: fill histograms before cuts
+  // index = 1: fill histograms after cuts
+  Int_t index = -1;
+  index = ((f) ? 1 : 0);
+
+       Float_t b[2];
+       Float_t bRes[2];
+       Float_t bCov[3];
+       esdTrack->GetImpactParameters(b,bCov);
+       if (bCov[0]<=0 || bCov[2]<=0) {
+          AliDebug(1, "Estimated b resolution lower or equal zero!");
+          bCov[0]=0; bCov[2]=0;
+       }
+       bRes[0] = TMath::Sqrt(bCov[0]);
+       bRes[1] = TMath::Sqrt(bCov[2]);
+
+       fhQA[kDcaZ][index]->Fill(b[1]);
+       fhQA[kDcaXY][index]->Fill(b[0]);
+       fhDcaXYvsDcaZ[index]->Fill(b[1],b[0]);
+
+       if (bRes[0]!=0 && bRes[1]!=0) {
+          fhQA[kDcaZnorm][index]->Fill(b[1]/bRes[1]);
+          fhQA[kDcaXYnorm][index]->Fill(b[0]/bRes[0]);
+          fhDcaXYvsDcaZnorm[index]->Fill(b[1]/bRes[1], b[0]/bRes[0]);
+       }
+
+  // getting the track to vertex parameters
+  Float_t nSigmaToVertex = GetSigmaToVertex(esdTrack);
+
+  fhQA[kCutNSigmaToVertex][index]->Fill(nSigmaToVertex);
+  if (nSigmaToVertex<0 && fRequireSigmaToVertex) fhQA[kCutRequireSigmaToVertex][index]->Fill(0.);
+  if (!(nSigmaToVertex<0 && fRequireSigmaToVertex)) fhQA[kCutRequireSigmaToVertex][index]->Fill(1.);
+
+
+  if (!fAcceptKinkDaughters && esdTrack->GetKinkIndex(0)>0) fhQA[kCutAcceptKinkDaughters][index]->Fill(0.);
+  if (!(!fAcceptKinkDaughters && esdTrack->GetKinkIndex(0)>0)) fhQA[kCutAcceptKinkDaughters][index]->Fill(0.);
+
+  // fill cut statistics and cut correlation histograms with information from the bitmap
+  if (f) return;
+
+  // Get the bitmap of the single cuts
+  if ( !obj ) return;
+  TBits* bitmap = SelectionBitMap(obj);
+
+  // Number of single cuts in this class
+  UInt_t ncuts = bitmap->GetNbits();
+  for(UInt_t bit=0; bit<ncuts;bit++) {
+    if (!bitmap->TestBitNumber(bit)) {
+       fhCutStatistics->Fill(bit+1);
+       for (UInt_t bit2=bit; bit2<ncuts;bit2++) {
+         if (!bitmap->TestBitNumber(bit2)) 
+           fhCutCorrelation->Fill(bit+1,bit2+1);
+       }
+    }
+  }
+}
+//__________________________________________________________________________________
+void AliCFTrackIsPrimaryCuts::SaveHistograms(const Char_t* dir) {
+  //
+  // saves the histograms in a directory (dir)
+  //
+  if(!fIsQAOn) return;
+
+  if (!dir)
+    dir = GetName();
+
+  gDirectory->mkdir(dir);
+  gDirectory->cd(dir);
+
+  gDirectory->mkdir("before_cuts");
+  gDirectory->mkdir("after_cuts");
+
+  fhCutStatistics->Write();
+  fhCutCorrelation->Write();
+
+  for (Int_t j=0; j<kNStepQA; j++) {
+    if (j==0)
+      gDirectory->cd("before_cuts");
+    else
+      gDirectory->cd("after_cuts");
+
+    fhDcaXYvsDcaZ[j]    ->Write();
+    fhDcaXYvsDcaZnorm[j]->Write();
+
+    for(Int_t i=0; i<kNHist; i++) fhQA[i][j]->Write();
+
+    gDirectory->cd("../");
+  }
+  gDirectory->cd("../");
+}
+//__________________________________________________________________________________
+void AliCFTrackIsPrimaryCuts::DrawHistograms()
+{
+  //
+  // draws some histograms
+  //
+  if(!fIsQAOn) return;
+
+  // pad margins
+  Float_t right = 0.03;
+  Float_t left = 0.175;
+  Float_t top = 0.03;
+  Float_t bottom = 0.175;
+
+  TCanvas* canvas1 = new TCanvas("Track_QA_Primary_1", "Track QA Primary 1", 800, 500);
+  canvas1->Divide(2, 1);
+
+  canvas1->cd(1);
+  fhCutStatistics->SetStats(kFALSE);
+  fhCutStatistics->LabelsOption("v");
+  gPad->SetLeftMargin(left);
+  gPad->SetBottomMargin(0.25);
+  gPad->SetRightMargin(right);
+  gPad->SetTopMargin(0.1);
+  fhCutStatistics->Draw();
+
+  canvas1->cd(2);
+  fhCutCorrelation->SetStats(kFALSE);
+  fhCutCorrelation->LabelsOption("v");
+  gPad->SetLeftMargin(0.30);
+  gPad->SetRightMargin(bottom);
+  gPad->SetTopMargin(0.1);
+  gPad->SetBottomMargin(0.25);
+  fhCutCorrelation->Draw("COLZ");
+
+  canvas1->SaveAs(Form("%s.eps", canvas1->GetName()));
+  canvas1->SaveAs(Form("%s.ps", canvas1->GetName()));
+
+  // -----
+
+  TCanvas* canvas2 = new TCanvas("Track_QA_Primary_2", "Track QA Primary 2", 800, 800);
+  canvas2->Divide(2, 2);
+
+  canvas2->cd(1);
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kDcaXY][0]->SetStats(kFALSE);
+  fhQA[kDcaXY][0]->Draw();
+  fhQA[kDcaXY][1]->Draw("same");
+
+  canvas2->cd(2);
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kDcaZ][0]->SetStats(kFALSE);
+  fhQA[kDcaZ][0]->Draw();
+  fhQA[kDcaZ][1]->Draw("same");
+
+  canvas2->cd(3);
+//   fhDXYvsDZ[0]->SetStats(kFALSE);
+  gPad->SetLogz();
+  gPad->SetLeftMargin(bottom);
+  gPad->SetTopMargin(0.1);
+  gPad->SetBottomMargin(bottom);
+  gPad->SetRightMargin(0.2);
+  fhDcaXYvsDcaZ[0]->Draw("COLZ");
+
+  canvas2->cd(4);
+//   fhDXYvsDZ[1]->SetStats(kFALSE);
+  gPad->SetLogz();
+  gPad->SetLeftMargin(bottom);
+  gPad->SetTopMargin(0.1);
+  gPad->SetBottomMargin(bottom);
+  gPad->SetRightMargin(0.2);
+  fhDcaXYvsDcaZ[1]->Draw("COLZ");
+
+  canvas2->SaveAs(Form("%s.eps", canvas2->GetName()));
+  canvas2->SaveAs(Form("%s.ps", canvas2->GetName()));
+
+  // -----
+
+  TCanvas* canvas3 = new TCanvas("Track_QA_Primary_3", "Track QA Primary 3", 800, 800);
+  canvas3->Divide(2, 2);
+
+  canvas3->cd(1);
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kDcaXYnorm][0]->SetStats(kFALSE);
+  fhQA[kDcaXYnorm][0]->Draw();
+  fhQA[kDcaXYnorm][1]->Draw("same");
+
+  canvas3->cd(2);
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kDcaZnorm][0]->SetStats(kFALSE);
+  fhQA[kDcaZnorm][0]->Draw();
+  fhQA[kDcaZnorm][1]->Draw("same");
+
+  canvas3->cd(3);
+//   fhDXYvsDZ[0]->SetStats(kFALSE);
+  gPad->SetLogz();
+  gPad->SetLeftMargin(bottom);
+  gPad->SetTopMargin(0.1);
+  gPad->SetBottomMargin(bottom);
+  gPad->SetRightMargin(0.2);
+  fhDcaXYvsDcaZnorm[0]->Draw("COLZ");
+
+  canvas3->cd(4);
+//   fhDXYvsDZ[1]->SetStats(kFALSE);
+  gPad->SetLogz();
+  gPad->SetLeftMargin(bottom);
+  gPad->SetTopMargin(0.1);
+  gPad->SetBottomMargin(bottom);
+  gPad->SetRightMargin(0.2);
+  fhDcaXYvsDcaZnorm[1]->Draw("COLZ");
+
+  canvas3->SaveAs(Form("%s.eps", canvas3->GetName()));
+  canvas3->SaveAs(Form("%s.ps", canvas3->GetName()));
+
+  // -----
+
+  TCanvas* canvas4 = new TCanvas("Track_QA_Primary_4", "Track QA Primary 4", 1200, 500);
+  canvas4->Divide(3, 1);
+
+  canvas4->cd(1);
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutNSigmaToVertex][0]->SetStats(kFALSE);
+  fhQA[kCutNSigmaToVertex][0]->Draw();
+  fhQA[kCutNSigmaToVertex][1]->Draw("same");
+
+  canvas4->cd(2);
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutRequireSigmaToVertex][0]->SetStats(kFALSE);
+  fhQA[kCutRequireSigmaToVertex][0]->Draw();
+  fhQA[kCutRequireSigmaToVertex][1]->Draw("same");
+
+  canvas4->cd(3);
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutAcceptKinkDaughters][0]->SetStats(kFALSE);
+  fhQA[kCutAcceptKinkDaughters][0]->Draw();
+  fhQA[kCutAcceptKinkDaughters][1]->Draw("same");
+
+  canvas4->SaveAs(Form("%s.eps", canvas4->GetName()));
+  canvas4->SaveAs(Form("%s.ps", canvas4->GetName()));
+}
+//__________________________________________________________________________________
+void AliCFTrackIsPrimaryCuts::AddQAHistograms(TList *qaList) const {
+  //
+  // saves the histograms in a TList
+  //
+  if(!fIsQAOn) return;
+
+  qaList->Add(fhCutStatistics);
+  qaList->Add(fhCutCorrelation);
+
+  for (Int_t j=0; j<kNStepQA; j++) {
+    qaList->Add(fhDcaXYvsDcaZ[j]);
+    qaList->Add(fhDcaXYvsDcaZnorm[j]);    
+    for(Int_t i=0; i<kNHist; i++)
+      qaList->Add(fhQA[i][j]);
+  }
+}
diff --git a/CORRFW/AliCFTrackIsPrimaryCuts.h b/CORRFW/AliCFTrackIsPrimaryCuts.h
new file mode 100644 (file)
index 0000000..6eaafdf
--- /dev/null
@@ -0,0 +1,132 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+// The class AliCFTrackIsPrimaryCut is designed to select reconstructed tracks
+// with a small impact parameter and tracks which are (not) daughters of kink
+// decays and to provide corresponding QA histograms.
+// This class inherits from the Analysis' Framework abstract base class
+// AliAnalysisCuts and is a part of the Correction Framework.
+// This class acts on single, reconstructed tracks, it is applicable on
+// ESD and AOD data.
+// It mainly consists of a IsSelected function that returns a boolean.
+// This function checks whether the considered track passes a set of cuts:
+// - distance to main vertex in units of sigma (resolution)
+// - require that the dca calculation doesn't fail
+// - accept or not accept daughter tracks of kink decays
+//
+// The cut values for these cuts are set with the corresponding set functions.
+// All cut classes provided by the correction framework are supposed to be
+// added in the Analysis Framwork's class AliAnalysisFilter and applied by
+// the filter via a loop.
+//
+// author: I. Kraus (Ingrid.Kraus@cern.ch)
+// idea taken form
+// AliESDtrackCuts writte by Jan Fiete Grosse-Oetringhaus and
+// AliRsnDaughterCut class written by A. Pulvirenti.
+
+#ifndef ALICFTRACKISPRIMARYCUTS_H
+#define ALICFTRACKISPRIMARYCUTS_H
+
+#include "AliCFCutBase.h"
+
+class TBits;
+class TH2;
+class AliESDtrack ;
+
+class AliCFTrackIsPrimaryCuts : public AliCFCutBase
+{
+ public :
+  AliCFTrackIsPrimaryCuts() ;
+  AliCFTrackIsPrimaryCuts(Char_t* name, Char_t* title) ;
+  AliCFTrackIsPrimaryCuts(const AliCFTrackIsPrimaryCuts& c) ;
+  AliCFTrackIsPrimaryCuts& operator=(const AliCFTrackIsPrimaryCuts& c) ;
+  ~AliCFTrackIsPrimaryCuts();
+  void Copy(TObject &c) const;
+
+  void GetBitMap(TObject* obj, TBits *bitmap);
+  Bool_t IsSelected(TObject* obj);
+  void Init();
+  Float_t GetSigmaToVertex(AliESDtrack* esdTrack) const;
+
+  // cut value setter
+  void SetMaxNSigmaToVertex(Double_t sigma=3)  {fNSigmaToVertexMax = sigma;}
+  void SetRequireSigmaToVertex(Bool_t b=kTRUE) {fRequireSigmaToVertex=b;}
+  void SetAcceptKinkDaughters(Bool_t b=kTRUE)  {fAcceptKinkDaughters=b;}
+
+  // QA histograms
+  void FillHistogramsBeforeCuts(TObject* obj) {return FillHistograms(obj,kFALSE);}
+  void FillHistogramsAfterCuts(TObject* obj)  {return FillHistograms(obj,kTRUE);}
+  void DrawHistograms();
+  void SaveHistograms(const Char_t* dir = 0);
+  void AddQAHistograms(TList *qaList) const;
+  // QA histogram setter
+  // please use indices from the enumeration below
+  void SetHistogramBins(Int_t index, Int_t nbins, Double_t *bins);
+  void SetHistogramBins(Int_t index, Int_t nbins, Double_t xmin, Double_t xmax);
+
+  // indeces/counters for single selections
+  enum { 
+    kCutNSigmaToVertex=0,      // tracks's distance to main vertex in units of sigma
+    kCutRequireSigmaToVertex,  // calculation is successful
+    kCutAcceptKinkDaughters,   // do (not) accept secondaries
+    kDcaXY,                    // controll histogram: dca in xy plane
+    kDcaZ,                     // controll histogram: dca along z axis
+    kDcaXYnorm,                        // controll histogram: normalised dca in xy plane
+    kDcaZnorm,                 // controll histogram: normalised dca along z axis
+    kNCuts=3,                  // number of single selections
+    kNStepQA=2,                        // number of QA steps (before/after the cuts)
+    kNHist=7                   // number of QA histograms
+  };
+
+ private:
+  TBits* SelectionBitMap(TObject* obj);
+  void DefineHistograms();             // books histograms and TList
+  void Initialise();                   // sets everything to 0
+  void FillHistograms(TObject* obj, Bool_t b);
+                                       // Fills histograms before and after cuts
+  Double_t fNSigmaToVertexMax;         // max distance to main vertex in units of sigma
+  Bool_t  fRequireSigmaToVertex;       // require calculable distance to main vertex
+
+  TH2F* fhDcaXYvsDcaZ[2];              // Histogram: dca xy vs. z
+  TH2F* fhDcaXYvsDcaZnorm[2];          // Histogram: (dca xy / sigma xy) vs. (dca z / simga z)
+  Bool_t  fAcceptKinkDaughters;                // accepting kink daughters
+
+  TH1F* fhCutStatistics;              // Histogram: statistics of what cuts the tracks did not survive
+  TH2F* fhCutCorrelation;             // Histogram: 2d statistics plot
+
+  TH1F* fhQA[kNHist][kNStepQA];                // QA Histograms
+  TBits *fBitmap ;                             // stores single selection decisions
+
+  // QA histogram setters
+  Int_t fhNBinsNSigma;                 // number of bins: dca in units of sigma
+  Int_t fhNBinsRequireSigma;   // number of bins: require successful calcuation
+  Int_t fhNBinsAcceptKink;             // number of bins: acceptkink daughters
+  Int_t fhNBinsDcaXY;                  // number of bins: dca in transverse plane
+  Int_t fhNBinsDcaZ;                   // number of bins: dca along beam axis
+  Int_t fhNBinsDcaXYnorm;              // number of bins: normalised dca in transverse plane
+  Int_t fhNBinsDcaZnorm;               // number of bins: normalised dca along beam axis
+  
+  Double_t *fhBinLimNSigma;            // bin limits: dca in units of sigma
+  Double_t *fhBinLimRequireSigma;      // bin limits: require successful calcuation
+  Double_t *fhBinLimAcceptKink;                // bin limits: acceptkink daughters
+  Double_t *fhBinLimDcaXY;             // bin limits: dca in transverse plane
+  Double_t *fhBinLimDcaZ;                      // bin limits: dca along beam axis
+  Double_t *fhBinLimDcaXYnorm; // bin limits: normalised dca in transverse plane
+  Double_t *fhBinLimDcaZnorm;          // bin limits: normalised dca along beam axis
+  
+  ClassDef(AliCFTrackIsPrimaryCuts,1);
+};
+
+#endif
diff --git a/CORRFW/AliCFTrackKineCuts.cxx b/CORRFW/AliCFTrackKineCuts.cxx
new file mode 100644 (file)
index 0000000..1250365
--- /dev/null
@@ -0,0 +1,887 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+// The class AliCFTrackKineCuts is designed to select both generated 
+// and reconstructed tracks of a given range in momentum space,
+// electric charge and azimuthal emission angle phi
+// and to provide corresponding QA histograms.
+// This class inherits from the Analysis' Framework abstract base class
+// AliAnalysisCuts and is a part of the Correction Framework.
+// This class acts on single, generated and reconstructed tracks, it is 
+// applicable on ESD and AOD data.
+// It mainly consists of a IsSelected function that returns a boolean.
+// This function checks whether the considered track passes a set of cuts:
+// - total momentum
+// - pt
+// - px
+// - py
+// - pz
+// - eta
+// - rapidity
+// - phi
+// - charge
+// - is charged
+//
+// The cut values for these cuts are set with the corresponding set functions.
+// All cut classes provided by the correction framework are supposed to be
+// added in the Analysis Framwork's class AliAnalysisFilter and applied by
+// the filter via a loop.
+//
+// author: I. Kraus (Ingrid.Kraus@cern.ch)
+// idea taken form
+// AliESDtrackCuts writte by Jan Fiete Grosse-Oetringhaus and
+// AliRsnDaughterCut class written by A. Pulvirenti.
+
+#include <TCanvas.h>
+#include <TDirectory.h>
+#include <TBits.h>
+#include <TH2.h>
+
+#include <AliVParticle.h>
+#include <AliLog.h>
+#include "AliCFTrackKineCuts.h"
+
+ClassImp(AliCFTrackKineCuts)
+
+//__________________________________________________________________________________
+AliCFTrackKineCuts::AliCFTrackKineCuts() :
+  AliCFCutBase(),
+  fMomentumMin(0),
+  fMomentumMax(0),
+  fPtMin(0),
+  fPtMax(0),
+  fPxMin(0),
+  fPxMax(0),
+  fPyMin(0),
+  fPyMax(0),
+  fPzMin(0),
+  fPzMax(0),
+  fEtaMin(0),
+  fEtaMax(0),
+  fRapidityMin(0),
+  fRapidityMax(0),
+  fPhiMin(0),
+  fPhiMax(0),
+  fCharge(0),
+  fRequireIsCharged(0),
+  fhCutStatistics(0),
+  fhCutCorrelation(0),
+  fBitmap(0x0),
+  fhNBinsMomentum(0),
+  fhNBinsPt(0),
+  fhNBinsPx(0),
+  fhNBinsPy(0),
+  fhNBinsPz(0),
+  fhNBinsEta(0),
+  fhNBinsRapidity(0),
+  fhNBinsPhi(0),
+  fhNBinsCharge(0),
+  fhBinLimMomentum(0x0),
+  fhBinLimPt(0x0),
+  fhBinLimPx(0x0),
+  fhBinLimPy(0x0),
+  fhBinLimPz(0x0),
+  fhBinLimEta(0x0),
+  fhBinLimRapidity(0x0),
+  fhBinLimPhi(0x0),
+  fhBinLimCharge(0x0)
+
+{
+  //
+  // Default constructor
+  //
+  fBitmap=new TBits(0);
+  Initialise();
+}
+//__________________________________________________________________________________
+AliCFTrackKineCuts::AliCFTrackKineCuts(Char_t* name, Char_t* title) :
+  AliCFCutBase(name,title),
+  fMomentumMin(0),
+  fMomentumMax(0),
+  fPtMin(0),
+  fPtMax(0),
+  fPxMin(0),
+  fPxMax(0),
+  fPyMin(0),
+  fPyMax(0),
+  fPzMin(0),
+  fPzMax(0),
+  fEtaMin(0),
+  fEtaMax(0),
+  fRapidityMin(0),
+  fRapidityMax(0),
+  fPhiMin(0),
+  fPhiMax(0),
+  fCharge(0),
+  fRequireIsCharged(0),
+  fhCutStatistics(0),
+  fhCutCorrelation(0),
+  fBitmap(0x0),
+  fhNBinsMomentum(0),
+  fhNBinsPt(0),
+  fhNBinsPx(0),
+  fhNBinsPy(0),
+  fhNBinsPz(0),
+  fhNBinsEta(0),
+  fhNBinsRapidity(0),
+  fhNBinsPhi(0),
+  fhNBinsCharge(0),
+  fhBinLimMomentum(0x0),
+  fhBinLimPt(0x0),
+  fhBinLimPx(0x0),
+  fhBinLimPy(0x0),
+  fhBinLimPz(0x0),
+  fhBinLimEta(0x0),
+  fhBinLimRapidity(0x0),
+  fhBinLimPhi(0x0),
+  fhBinLimCharge(0x0)
+
+{
+  //
+  // Constructor
+  //
+  fBitmap=new TBits(0);
+  Initialise();
+}
+//__________________________________________________________________________________
+AliCFTrackKineCuts::AliCFTrackKineCuts(const AliCFTrackKineCuts& c) :
+  AliCFCutBase(c),
+  fMomentumMin(c.fMomentumMin),
+  fMomentumMax(c.fMomentumMax),
+  fPtMin(c.fPtMin),
+  fPtMax(c.fPtMax),
+  fPxMin(c.fPxMin),
+  fPxMax(c.fPxMax),
+  fPyMin(c.fPyMin),
+  fPyMax(c.fPyMax),
+  fPzMin(c.fPzMin),
+  fPzMax(c.fPzMax),
+  fEtaMin(c.fEtaMin),
+  fEtaMax(c.fEtaMax),
+  fRapidityMin(c.fRapidityMin),
+  fRapidityMax(c.fRapidityMax),
+  fPhiMin(c.fPhiMin),
+  fPhiMax(c.fPhiMax),
+  fCharge(c.fCharge),
+  fRequireIsCharged(c.fRequireIsCharged),
+  fhCutStatistics(c.fhCutStatistics),
+  fhCutCorrelation(c.fhCutCorrelation),
+  fBitmap(c.fBitmap),
+  fhNBinsMomentum(c.fhNBinsMomentum),
+  fhNBinsPt(c.fhNBinsPt),
+  fhNBinsPx(c.fhNBinsPx),
+  fhNBinsPy(c.fhNBinsPy),
+  fhNBinsPz(c.fhNBinsPz),
+  fhNBinsEta(c.fhNBinsEta),
+  fhNBinsRapidity(c.fhNBinsRapidity),
+  fhNBinsPhi(c.fhNBinsPhi),
+  fhNBinsCharge(c.fhNBinsCharge),
+  fhBinLimMomentum(c.fhBinLimMomentum),
+  fhBinLimPt(c.fhBinLimPt),
+  fhBinLimPx(c.fhBinLimPx),
+  fhBinLimPy(c.fhBinLimPy),
+  fhBinLimPz(c.fhBinLimPz),
+  fhBinLimEta(c.fhBinLimEta),
+  fhBinLimRapidity(c.fhBinLimRapidity),
+  fhBinLimPhi(c.fhBinLimPhi),
+  fhBinLimCharge(c.fhBinLimCharge)
+
+{
+  //
+  // copy constructor
+  //
+  ((AliCFTrackKineCuts &) c).Copy(*this);
+}
+//__________________________________________________________________________________
+AliCFTrackKineCuts& AliCFTrackKineCuts::operator=(const AliCFTrackKineCuts& c)
+{
+  //
+  // Assignment operator
+  //
+  if (this != &c) {
+    AliCFCutBase::operator=(c) ;
+    fMomentumMin = c.fMomentumMin ;
+    fMomentumMax = c.fMomentumMax ;
+    fPtMin = c.fPtMin ;
+    fPtMax = c.fPtMax ;
+    fPxMin = c.fPxMin ;
+    fPxMax = c.fPxMax ;
+    fPyMin = c.fPyMin ;
+    fPyMax = c.fPyMax ;
+    fPzMin = c.fPzMin ;
+    fPzMax = c.fPzMax ;
+    fEtaMin = c.fEtaMin ;
+    fEtaMax = c.fEtaMax ;
+    fRapidityMin = c.fRapidityMin ;
+    fRapidityMax = c.fRapidityMax ;
+    fPhiMin = c.fPhiMin ;
+    fPhiMax = c.fPhiMax ;
+    fCharge = c.fCharge ;
+    fRequireIsCharged = c.fRequireIsCharged ;
+    fhCutStatistics = c.fhCutStatistics ;
+    fhCutCorrelation = c.fhCutCorrelation ;
+    fBitmap = c.fBitmap;
+    fhNBinsMomentum = c.fhNBinsMomentum;
+    fhNBinsPt = c.fhNBinsPt;
+    fhNBinsPx = c.fhNBinsPx;
+    fhNBinsPy = c.fhNBinsPy;
+    fhNBinsPz = c.fhNBinsPz;
+    fhNBinsEta = c.fhNBinsEta;
+    fhNBinsRapidity = c.fhNBinsRapidity;
+    fhNBinsPhi = c.fhNBinsPhi;
+    fhNBinsCharge = c.fhNBinsCharge;
+    fhBinLimMomentum = c.fhBinLimMomentum;
+    fhBinLimPt = c.fhBinLimPt;
+    fhBinLimPx = c.fhBinLimPx;
+    fhBinLimPy = c.fhBinLimPy;
+    fhBinLimPz = c.fhBinLimPz;
+    fhBinLimEta = c.fhBinLimEta;
+    fhBinLimRapidity = c.fhBinLimRapidity;
+    fhBinLimPhi = c.fhBinLimPhi;
+    fhBinLimCharge = c.fhBinLimCharge;
+    
+    for (Int_t i=0; i<c.kNHist; i++){
+      for (Int_t j=0; j<c.kNStepQA; j++){
+       if(c.fhQA[i][j]) fhQA[i][j] = (TH1F*)c.fhQA[i][j]->Clone();
+      }
+    }
+
+    ((AliCFTrackKineCuts &) c).Copy(*this);
+  }
+  return *this ;
+}
+//__________________________________________________________________________________
+AliCFTrackKineCuts::~AliCFTrackKineCuts()
+{
+  //
+  // destructor
+  //
+  if (fhCutStatistics)                 delete fhCutStatistics;
+  if (fhCutCorrelation)                        delete fhCutCorrelation;
+
+  for (Int_t i=0; i<kNHist; i++){
+    for (Int_t j=0; j<kNStepQA; j++){
+      if(fhQA[i][j]) delete fhQA[i][j];
+    }
+  }
+
+  if(fBitmap)  delete   fBitmap;
+
+  if(fhBinLimMomentum) delete fhBinLimMomentum;
+  if(fhBinLimPt) delete fhBinLimPt;
+  if(fhBinLimPx) delete fhBinLimPx;
+  if(fhBinLimPy) delete fhBinLimPy;
+  if(fhBinLimPz) delete fhBinLimPz;
+  if(fhBinLimEta) delete fhBinLimEta;
+  if(fhBinLimRapidity) delete fhBinLimRapidity;
+  if(fhBinLimPhi) delete fhBinLimPhi;
+  if(fhBinLimCharge) delete fhBinLimCharge;
+}
+//__________________________________________________________________________________
+void AliCFTrackKineCuts::Initialise()
+{
+  //
+  // sets everything to zero
+  //
+  fMomentumMin = 0;
+  fMomentumMax = 0;
+  fPtMin = 0;
+  fPtMax = 0;
+  fPxMin = 0;
+  fPxMax = 0;
+  fPyMin = 0;
+  fPyMax = 0;
+  fPzMin = 0;
+  fPzMax = 0;
+  fEtaMin = 0;
+  fEtaMax = 0;
+  fRapidityMin = 0;
+  fRapidityMax = 0;
+  fPhiMin = 0;
+  fPhiMax = 0;
+  fCharge = 0;
+  fRequireIsCharged = 0;
+
+  SetMomentumRange();
+  SetPtRange();
+  SetPxRange();
+  SetPyRange();
+  SetPzRange();
+  SetEtaRange();
+  SetRapidityRange();
+  SetPhiRange();
+  SetChargeRec();
+  SetChargeMC();
+  SetRequireIsCharged();
+
+  for (Int_t i=0; i<kNHist; i++){
+    for (Int_t j=0; j<kNStepQA; j++)  {
+      fhQA[i][j] = 0x0;
+    }
+  }
+
+  fhCutStatistics = 0;
+  fhCutCorrelation = 0;
+    
+    //set default bining for QA histograms
+  SetHistogramBins(kCutP,200,0.,20.);
+  SetHistogramBins(kCutPt,200,0.,20.);
+  SetHistogramBins(kCutPx,400,-20.,20.);
+  SetHistogramBins(kCutPy,400,-20.,20.);
+  SetHistogramBins(kCutPz,400,-20.,20.);
+  SetHistogramBins(kCutRapidity,200,-10.,10.);
+  SetHistogramBins(kCutEta,200,-10.,10.);
+  SetHistogramBins(kCutPhi,38,-0.6,7.);
+  SetHistogramBins(kCutCharge,21,-10.5,10.5);
+
+}
+//__________________________________________________________________________________
+void AliCFTrackKineCuts::Copy(TObject &c) const
+{
+  //
+  // Copy function
+  //
+  AliCFTrackKineCuts& target = (AliCFTrackKineCuts &) c;
+
+  target.Initialise();
+
+  if (fhCutStatistics)  target.fhCutStatistics = (TH1F*) fhCutStatistics->Clone();
+  if (fhCutCorrelation) target.fhCutCorrelation = (TH2F*) fhCutCorrelation->Clone();
+
+  for (Int_t i=0; i<kNHist; i++){
+    for (Int_t j=0; j<kNStepQA; j++){
+      if(fhQA[i][j]) target.fhQA[i][j] = (TH1F*)fhQA[i][j]->Clone();
+    }
+  }
+
+  TNamed::Copy(c);
+}
+//__________________________________________________________________________________
+void AliCFTrackKineCuts::GetBitMap(TObject* obj, TBits *bitmap)  {
+  //
+  // retrieve the pointer to the bitmap
+  //
+  bitmap = SelectionBitMap(obj);
+}
+//__________________________________________________________________________________
+TBits* AliCFTrackKineCuts::SelectionBitMap(TObject* obj) {
+  //
+  // test if the track passes the single cuts
+  // and store the information in a bitmap
+  //
+
+  // bitmap stores the decision of each single cut
+  for(Int_t i=0; i<kNCuts; i++)fBitmap->SetBitNumber(i,kFALSE);
+  // cast TObject into VParticle
+  AliVParticle* particle = dynamic_cast<AliVParticle *>(obj);
+  if ( !particle ) return fBitmap ;
+
+
+  for(Int_t i=0; i<kNCuts; i++)fBitmap->SetBitNumber(i,kTRUE);
+
+  Int_t iCutBit = 0;
+  if((particle->P() < fMomentumMin) || (particle->P() > fMomentumMax))
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if ((particle->Pt() < fPtMin) || (particle->Pt() > fPtMax))
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if ((particle->Px() < fPxMin) || (particle->Px() > fPxMax))
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if ((particle->Py() < fPyMin) || (particle->Py() > fPyMax))
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if ((particle->Pz() < fPzMin) || (particle->Pz() > fPzMax))
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if ((particle->Eta() < fEtaMin) || (particle->Eta() > fEtaMax))
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if ((particle->Y() < fRapidityMin) || (particle->Y() > fRapidityMax))
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if ((particle->Phi() < fPhiMin) || (particle->Phi() > fPhiMax))
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if (fCharge < 10 && particle->Charge() != fCharge)
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if (fRequireIsCharged && particle->Charge()==0)
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+
+  return fBitmap;
+}
+//__________________________________________________________________________________
+Bool_t AliCFTrackKineCuts::IsSelected(TObject* obj) {
+  //
+  // loops over decisions of single cuts and returns if the track is accepted
+  //
+  TBits* bitmap = SelectionBitMap(obj);
+
+  Bool_t isSelected = kTRUE;
+
+  for (UInt_t icut=0; icut<bitmap->GetNbits();icut++)
+       if(!bitmap->TestBitNumber(icut)) isSelected = kFALSE;
+
+  return isSelected;
+}
+//__________________________________________________________________________________
+void AliCFTrackKineCuts::Init() {
+  //
+  // initialises all histograms and the TList which holds the histograms
+  //
+  if(fIsQAOn)
+    DefineHistograms();
+}
+//__________________________________________________________________________________
+void AliCFTrackKineCuts::SetHistogramBins(Int_t index, Int_t nbins, Double_t *bins)
+{
+  //
+  // variable bin size
+  //
+  if(!fIsQAOn) return;
+
+  switch(index){
+  case kCutP:
+    fhNBinsMomentum=nbins;
+    fhBinLimMomentum=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimMomentum[i]=bins[i];
+    break;
+    
+  case kCutPt:
+    fhNBinsPt=nbins;
+    fhBinLimPt=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimPt[i]=bins[i];
+    break;
+    
+  case kCutPx:
+    fhNBinsPx=nbins;
+    fhBinLimPx=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimPx[i]=bins[i];
+    break;
+
+  case kCutPy:
+    fhNBinsPy=nbins;
+    fhBinLimPy=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimPy[i]=bins[i];
+    break;
+        
+  case kCutPz:
+    fhNBinsPz=nbins;
+    fhBinLimPz=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimPz[i]=bins[i];
+    break;
+    
+  case kCutRapidity:
+    fhNBinsRapidity=nbins;
+    fhBinLimRapidity=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimRapidity[i]=bins[i];
+    break;
+    
+  case kCutEta:
+    fhNBinsEta=nbins;
+    fhBinLimEta=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimEta[i]=bins[i];
+    break;
+    
+  case kCutPhi:
+    fhNBinsPhi=nbins;
+    fhBinLimPhi=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimPhi[i]=bins[i];
+    break;
+    
+  case kCutCharge:
+    fhNBinsCharge=nbins;
+    fhBinLimCharge=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimCharge[i]=bins[i];
+    break;
+  }
+}
+//__________________________________________________________________________________
+void AliCFTrackKineCuts::SetHistogramBins(Int_t index, Int_t nbins, Double_t xmin, Double_t xmax)
+{
+  //
+  // fixed bin size
+  //
+  if(!fIsQAOn) return;
+
+  switch(index){
+  case kCutP:
+    fhNBinsMomentum=nbins;
+    fhBinLimMomentum=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimMomentum[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kCutPt:
+    fhNBinsPt=nbins;
+    fhBinLimPt=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimPt[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kCutPx:
+    fhNBinsPx=nbins;
+    fhBinLimPx=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimPx[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+
+  case kCutPy:
+    fhNBinsPy=nbins;
+    fhBinLimPy=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimPy[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+        
+  case kCutPz:
+    fhNBinsPz=nbins;
+    fhBinLimPz=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimPz[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kCutRapidity:
+    fhNBinsRapidity=nbins;
+    fhBinLimRapidity=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimRapidity[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kCutEta:
+    fhNBinsEta=nbins;
+    fhBinLimEta=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimEta[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kCutPhi:
+    fhNBinsPhi=nbins;
+    fhBinLimPhi=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimPhi[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kCutCharge:
+    fhNBinsCharge=nbins;
+    fhBinLimCharge=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimCharge[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+  }
+}
+//__________________________________________________________________________________
+ void AliCFTrackKineCuts::DefineHistograms() {
+  //
+  // histograms for cut variables, cut statistics and cut correlations
+  //
+
+  Int_t color = 2;
+
+  // book cut statistics and cut correlation histograms
+  fhCutStatistics = new TH1F(Form("%s_cut_statistics",GetName()), Form("%s cut statistics",GetName()), kNCuts,0.5,kNCuts+0.5);
+  fhCutStatistics->SetLineWidth(2);
+  fhCutStatistics->GetXaxis()->SetBinLabel(1,"p");
+  fhCutStatistics->GetXaxis()->SetBinLabel(2,"pt");
+  fhCutStatistics->GetXaxis()->SetBinLabel(3,"px");
+  fhCutStatistics->GetXaxis()->SetBinLabel(4,"py");
+  fhCutStatistics->GetXaxis()->SetBinLabel(5,"pz");
+  fhCutStatistics->GetXaxis()->SetBinLabel(6,"eta");
+  fhCutStatistics->GetXaxis()->SetBinLabel(7,"y");
+  fhCutStatistics->GetXaxis()->SetBinLabel(8,"phi");
+  fhCutStatistics->GetXaxis()->SetBinLabel(9,"charge");
+  fhCutStatistics->GetXaxis()->SetBinLabel(10,"is charged");
+
+  fhCutCorrelation = new TH2F(Form("%s_cut_correlation",GetName()), Form("%s cut  correlation",GetName()), kNCuts,0.5,kNCuts+0.5,kNCuts,0.5,kNCuts+0.5);
+  fhCutCorrelation->SetLineWidth(2);
+  fhCutCorrelation->GetXaxis()->SetBinLabel(1,"p");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(2,"pt");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(3,"px");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(4,"py");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(5,"pz");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(6,"eta");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(7,"y");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(8,"phi");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(9,"charge");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(10,"is charged");
+
+  fhCutCorrelation->GetYaxis()->SetBinLabel(1,"p");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(2,"pt");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(3,"px");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(4,"py");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(5,"pz");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(6,"eta");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(7,"y");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(8,"phi");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(9,"charge");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(10,"is charged");
+
+
+  // book QA histograms
+  Char_t str[256];
+  for (Int_t i=0; i<kNStepQA; i++) {
+    if (i==0) sprintf(str," ");
+    else sprintf(str,"_cut");
+  
+    fhQA[kCutP][i]     = new  TH1F(Form("%s_momentum%s",GetName(),str),        "",fhNBinsMomentum,fhBinLimMomentum);
+    fhQA[kCutPt][i]    = new  TH1F(Form("%s_transverse_momentum%s",GetName(),str),"",fhNBinsPt,fhBinLimPt);
+    fhQA[kCutPx][i]    = new  TH1F(Form("%s_px%s",GetName(),str),              "",fhNBinsPx,fhBinLimPx);
+    fhQA[kCutPy][i]    = new  TH1F(Form("%s_py%s",GetName(),str),              "",fhNBinsPy,fhBinLimPy);
+    fhQA[kCutPz][i]    = new  TH1F(Form("%s_pz%s",GetName(),str),              "",fhNBinsPz,fhBinLimPz);
+    fhQA[kCutRapidity][i]=new  TH1F(Form("%s_rapidity%s",GetName(),str),       "",fhNBinsRapidity,fhBinLimRapidity);
+    fhQA[kCutEta][i]   = new  TH1F(Form("%s_eta%s",GetName(),str),             "",fhNBinsEta,fhBinLimEta);
+    fhQA[kCutPhi][i]   = new  TH1F(Form("%s_phi%s",GetName(),str),             "",fhNBinsPhi,fhBinLimPhi);
+    fhQA[kCutCharge][i]        = new  TH1F(Form("%s_charge%s",GetName(),str),          "",fhNBinsCharge,fhBinLimCharge);
+
+    fhQA[kCutP][i]     ->SetXTitle("momentum p (GeV/c)");
+    fhQA[kCutPt][i]    ->SetXTitle("p_{T} (GeV/c)");
+    fhQA[kCutPx][i]    ->SetXTitle("p_{x} (GeV/c)");
+    fhQA[kCutPy][i]    ->SetXTitle("p_{y} (GeV/c)");
+    fhQA[kCutPz][i]    ->SetXTitle("p_{z} (GeV/c)");
+    fhQA[kCutRapidity][i]->SetXTitle("rapidity y");
+    fhQA[kCutEta][i]   ->SetXTitle("pseudo rapidity #eta");
+    fhQA[kCutPhi][i]   ->SetXTitle("azimuth #phi (rad)");
+    fhQA[kCutCharge][i]        ->SetXTitle("charge");
+  }
+
+  for(Int_t i=0; i<kNHist; i++) fhQA[i][1]->SetLineColor(color);
+
+}
+//__________________________________________________________________________________
+void AliCFTrackKineCuts::FillHistograms(TObject* obj, Bool_t b)
+{
+  //
+  // fill the QA histograms
+  //
+  if(!fIsQAOn) return;
+
+  // cast TObject into VParticle
+  AliVParticle* particle = dynamic_cast<AliVParticle *>(obj);
+  if ( !particle ) return;
+
+  // index = 0: fill histograms before cuts
+  // index = 1: fill histograms after cuts
+  Int_t index = -1;
+  index = ((b) ? 1 : 0);
+
+  fhQA[kCutP][index]->Fill(particle->P());
+  fhQA[kCutPt][index]->Fill(particle->Pt());
+  fhQA[kCutPx][index]->Fill(particle->Px());
+  fhQA[kCutPy][index]->Fill(particle->Py());
+  fhQA[kCutPz][index]->Fill(particle->Pz());
+  fhQA[kCutRapidity][index]->Fill(particle->Y());
+  fhQA[kCutEta][index]->Fill(particle->Eta());
+  fhQA[kCutPhi][index]->Fill(particle->Phi());
+  fhQA[kCutCharge][index]->Fill((float)particle->Charge());
+
+  // fill cut statistics and cut correlation histograms with information from the bitmap
+  if (b) return;
+
+  if (!obj) return;
+  TBits* bitmap = SelectionBitMap(obj);
+
+  // Number of single cuts in this class
+  UInt_t ncuts = bitmap->GetNbits();
+  for(UInt_t bit=0; bit<ncuts;bit++) {
+    if (!bitmap->TestBitNumber(bit)) {
+       fhCutStatistics->Fill(bit+1);
+       for (UInt_t bit2=bit; bit2<ncuts;bit2++) {
+         if (!bitmap->TestBitNumber(bit2)) 
+           fhCutCorrelation->Fill(bit+1,bit2+1);
+       }
+    }
+  }
+}
+//__________________________________________________________________________________
+void AliCFTrackKineCuts::SaveHistograms(const Char_t* dir) {
+  //
+  // saves the histograms in a directory (dir)
+  //
+  if(!fIsQAOn) return;
+
+  if (!dir)
+    dir = GetName();
+
+  gDirectory->mkdir(dir);
+  gDirectory->cd(dir);
+
+  gDirectory->mkdir("before_cuts");
+  gDirectory->mkdir("after_cuts");
+
+  fhCutStatistics->Write();
+  fhCutCorrelation->Write();
+
+  for (Int_t j=0; j<kNStepQA; j++) {
+    if (j==0)
+      gDirectory->cd("before_cuts");
+    else
+      gDirectory->cd("after_cuts");
+
+    for(Int_t i=0; i<kNHist; i++) fhQA[i][j]->Write();
+
+    gDirectory->cd("../");
+  }
+
+  gDirectory->cd("../");
+}
+//__________________________________________________________________________________
+void AliCFTrackKineCuts::DrawHistograms(Bool_t drawLogScale)
+{
+  //
+  // draws some histograms
+  //
+  if(!fIsQAOn) return;
+
+  // pad margins
+  Float_t right = 0.03;
+  Float_t left = 0.175;
+  Float_t top = 0.03;
+  Float_t bottom = 0.175;
+
+  TCanvas* canvas1 = new TCanvas("Track_QA_Kinematics_1", "Track QA Kinematics 1", 800, 500);
+  canvas1->Divide(2, 1);
+
+  canvas1->cd(1);
+  fhCutStatistics->SetStats(kFALSE);
+  fhCutStatistics->LabelsOption("v");
+  gPad->SetLeftMargin(left);
+  gPad->SetBottomMargin(0.25);
+  gPad->SetRightMargin(right);
+  gPad->SetTopMargin(0.1);
+  fhCutStatistics->Draw();
+
+  canvas1->cd(2);
+  fhCutCorrelation->SetStats(kFALSE);
+  fhCutCorrelation->LabelsOption("v");
+  gPad->SetLeftMargin(0.30);
+  gPad->SetRightMargin(bottom);
+  gPad->SetTopMargin(0.1);
+  gPad->SetBottomMargin(0.25);
+  fhCutCorrelation->Draw("COLZ");
+
+  canvas1->SaveAs(Form("%s.eps", canvas1->GetName()));
+  canvas1->SaveAs(Form("%s.ps", canvas1->GetName()));
+
+  // -----
+
+  TCanvas* canvas2 = new TCanvas("Track_QA_Kinematics_2", "Track QA Kinematics 2", 1600, 800);
+  canvas2->Divide(4, 2);
+
+  canvas2->cd(1);
+  fhQA[kCutP][0]->SetStats(kFALSE);
+  if(drawLogScale) gPad->SetLogy();
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutP][0]->Draw();
+  fhQA[kCutP][1]->Draw("same");
+
+  canvas2->cd(2);
+  fhQA[kCutPt][0]->SetStats(kFALSE);
+  if(drawLogScale) gPad->SetLogy();
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutPt][0]->Draw();
+  fhQA[kCutPt][1]->Draw("same");
+
+  canvas2->cd(3);
+  fhQA[kCutRapidity][0]->SetStats(kFALSE);
+  if(drawLogScale) gPad->SetLogy();
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutRapidity][0]->Draw();
+  fhQA[kCutRapidity][1]->Draw("same");
+
+  canvas2->cd(4);
+  fhQA[kCutEta][0]->SetStats(kFALSE);
+  if(drawLogScale) gPad->SetLogy();
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutEta][0]->Draw();
+  fhQA[kCutEta][1]->Draw("same");
+
+  canvas2->cd(5);
+  fhQA[kCutPx][0]->SetStats(kFALSE);
+  if(drawLogScale) gPad->SetLogy();
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutPx][0]->Draw();
+  fhQA[kCutPx][1]->Draw("same");
+
+  canvas2->cd(6);
+  fhQA[kCutPy][0]->SetStats(kFALSE);
+  if(drawLogScale) gPad->SetLogy();
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutPy][0]->Draw();
+  fhQA[kCutPy][1]->Draw("same");
+
+  canvas2->cd(7);
+  fhQA[kCutPz][0]->SetStats(kFALSE);
+  if(drawLogScale) gPad->SetLogy();
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutPz][0]->Draw();
+  fhQA[kCutPz][1]->Draw("same");
+
+  canvas2->SaveAs(Form("%s.eps", canvas2->GetName()));
+  canvas2->SaveAs(Form("%s.ps", canvas2->GetName()));
+
+  // -----
+
+  TCanvas* canvas3 = new TCanvas("Track_QA_Kinematics_3", "Track QA Kinematics 3", 800, 400);
+  canvas3->Divide(2, 1);
+
+  canvas3->cd(1);
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutPhi][0]->SetStats(kFALSE);
+  fhQA[kCutPhi][0]->Draw();
+  fhQA[kCutPhi][1]->Draw("same");
+
+  canvas3->cd(2);
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutCharge][0]->SetStats(kFALSE);
+  fhQA[kCutCharge][0]->Draw();
+  fhQA[kCutCharge][1]->Draw("same");
+
+  canvas3->SaveAs(Form("%s.eps", canvas3->GetName()));
+  canvas3->SaveAs(Form("%s.ps", canvas3->GetName()));
+}
+//__________________________________________________________________________________
+void AliCFTrackKineCuts::AddQAHistograms(TList *qaList) const {
+  //
+  // saves the histograms in a TList
+  //
+  if(!fIsQAOn) return;
+
+  qaList->Add(fhCutStatistics);
+  qaList->Add(fhCutCorrelation);
+
+  for (Int_t j=0; j<kNStepQA; j++) {
+    for(Int_t i=0; i<kNHist; i++)
+       qaList->Add(fhQA[i][j]);
+  }
+}
diff --git a/CORRFW/AliCFTrackKineCuts.h b/CORRFW/AliCFTrackKineCuts.h
new file mode 100644 (file)
index 0000000..ae44180
--- /dev/null
@@ -0,0 +1,166 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+// The class AliCFTrackKineCuts is designed to select both generated 
+// and reconstructed tracks of a given range in momentum space,
+// electric charge and azimuthal emission angle phi 
+// and to provide corresponding QA histograms.
+// This class inherits from the Analysis' Framework abstract base class
+// AliAnalysisCuts and is a part of the Correction Framework.
+// This class acts on single, generated and reconstructed tracks, it is 
+// applicable on ESD and AOD data.
+// It mainly consists of a IsSelected function that returns a boolean.
+// This function checks whether the considered track passes a set of cuts:
+// - total momentum
+// - pt
+// - px
+// - py
+// - pz
+// - eta
+// - rapidity
+// - phi
+// - charge
+// - is charged
+//
+// The cut values for these cuts are set with the corresponding set functions.
+// All cut classes provided by the correction framework are supposed to be
+// added in the Analysis Framwork's class AliAnalysisFilter and applied by
+// the filter via a loop.
+//
+// author: I. Kraus (Ingrid.Kraus@cern.ch)
+// idea taken form
+// AliESDtrackCuts writte by Jan Fiete Grosse-Oetringhaus and
+// AliRsnDaughterCut class written by A. Pulvirenti.
+
+#ifndef ALICFTRACKKINECUTS_H
+#define ALICFTRACKKINECUTS_H
+
+#include "AliCFCutBase.h"
+
+class TH2;
+class TBits;
+class AliVParticle;
+
+class AliCFTrackKineCuts : public AliCFCutBase
+{
+ public :
+  AliCFTrackKineCuts() ;
+  AliCFTrackKineCuts(Char_t* name, Char_t* title) ;
+  AliCFTrackKineCuts(const AliCFTrackKineCuts& c) ;
+  AliCFTrackKineCuts& operator=(const AliCFTrackKineCuts& c) ;
+  ~AliCFTrackKineCuts();
+  void Copy(TObject &c) const;
+
+  void GetBitMap(TObject* obj, TBits *bitmap);
+  Bool_t IsSelected(TObject* obj);
+  void Init();
+
+  // cut value setter
+  void SetMomentumRange(Double_t momentumMin=0., Double_t momentumMax=1e99) {fMomentumMin=momentumMin; fMomentumMax=momentumMax;}
+  void SetPtRange(Double_t ptMin=0., Double_t ptMax=1e99) {fPtMin=ptMin; fPtMax=ptMax;}
+  void SetPxRange(Double_t pxMin=-1e99, Double_t pxMax=1e99) {fPxMin=pxMin; fPxMax=pxMax;}
+  void SetPyRange(Double_t pyMin=-1e99, Double_t pyMax=1e99) {fPyMin=pyMin; fPyMax=pyMax;}
+  void SetPzRange(Double_t pzMin=-1e99, Double_t pzMax=1e99) {fPzMin=pzMin; fPzMax=pzMax;}
+  void SetEtaRange(Double_t etaMin=-1e99, Double_t etaMax=1e99) {fEtaMin=etaMin; fEtaMax=etaMax;}
+  void SetRapidityRange(Double_t rapMin=-1e99, Double_t rapMax=1e99) {fRapidityMin=rapMin; fRapidityMax=rapMax;} 
+  void SetPhiRange(Double_t phiMin=-10., Double_t phiMax=10.) {fPhiMin=phiMin; fPhiMax=phiMax;}
+  void SetChargeRec(Double_t charge=10.) {fCharge=charge;}
+  void SetChargeMC(Double_t charge=10.) {fCharge=charge*3.;}
+  void SetRequireIsCharged(Bool_t b=kFALSE) {fRequireIsCharged=b;}
+
+  // QA histograms
+  void FillHistogramsBeforeCuts(TObject* obj) {return FillHistograms(obj,kFALSE);}
+  void FillHistogramsAfterCuts(TObject* obj)  {return FillHistograms(obj,kTRUE);}
+  void DrawHistograms(Bool_t drawLogScale=kTRUE);
+  void SaveHistograms(const Char_t* dir = 0);
+  void AddQAHistograms(TList *qaList) const;
+  // QA histogram setter
+  // please use indices from the enumeration below
+  void SetHistogramBins(Int_t index, Int_t nbins, Double_t *bins);
+  void SetHistogramBins(Int_t index, Int_t nbins, Double_t xmin, Double_t xmax);
+
+  // indeces/counters for single selections
+  enum { 
+    kCutP=0,   // momentum
+    kCutPt,    // pt
+    kCutPx,    // px
+    kCutPy,    // py
+    kCutPz,    // pz
+    kCutRapidity,// raptidity
+    kCutEta,   // eta
+    kCutPhi,   // phi
+    kCutCharge,        // charge
+    kNCuts=10, // number of single selections
+    kNStepQA=2,        // number of QA steps (before/after the cuts)
+    kNHist=9   // number of QA histograms
+  };
+
+
+ private:
+  TBits* SelectionBitMap(TObject* obj);
+  void DefineHistograms();             // books histograms and TList
+  void Initialise();                   // sets everything to 0
+  void FillHistograms(TObject* obj, Bool_t b);
+                                       // Fills histograms before and after cuts
+  Double_t fMomentumMin ;              // lower limit of accepted total momentum range
+  Double_t fMomentumMax ;              // upper limit of accepted total momentum range
+  Double_t fPtMin ;                    // lower limit of accepted transverse momentum range
+  Double_t fPtMax ;                    // upper limit of accepted transverse momentum range
+  Double_t fPxMin ;                    // lower limit of accepted px range
+  Double_t fPxMax ;                    // upper limit of accepted px range
+  Double_t fPyMin ;                    // lower limit of accepted py range
+  Double_t fPyMax ;                    // upper limit of accepted py range
+  Double_t fPzMin ;                    // lower limit of accepted pz range
+  Double_t fPzMax ;                    // upper limit of accepted pz range
+  Double_t fEtaMin ;                   // lower limit of accepted pseudo-rapidity range
+  Double_t fEtaMax ;                   // upper limit of accepted pseudo-rapidity range
+  Double_t fRapidityMin ;              // lower limit of accepted rapidity range
+  Double_t fRapidityMax ;              // upper limit of accepted rapidity range
+  Double_t fPhiMin ;                   // lower limit of accepted phi range
+  Double_t fPhiMax ;                   // upper limit of accepted phi range
+  Double_t fCharge ;                   // electric charge
+  Bool_t  fRequireIsCharged;           // accept charged particles only
+
+  TH1F* fhCutStatistics;              // Histogram: statistics of what cuts the tracks did not survive
+  TH2F* fhCutCorrelation;             // Histogram: 2d statistics plot
+
+  TH1F* fhQA[kNHist][kNStepQA];                // QA Histograms
+  TBits *fBitmap ;                             // stores single selection decisions
+
+  // QA histogram setters
+  Int_t fhNBinsMomentum;               // number of bins: momentum
+  Int_t fhNBinsPt;                             // number of bins: pt
+  Int_t fhNBinsPx;                             // number of bins: px
+  Int_t fhNBinsPy;                             // number of bins: py
+  Int_t fhNBinsPz;                             // number of bins: pz
+  Int_t fhNBinsEta;                            // number of bins: eta
+  Int_t fhNBinsRapidity;                       // number of bins: rapidity
+  Int_t fhNBinsPhi;                            // number of bins: phi
+  Int_t fhNBinsCharge;                 // number of bins: charge
+  
+  Double_t *fhBinLimMomentum;  // bin limits: momentum
+  Double_t *fhBinLimPt;                        // bin limits: pt
+  Double_t *fhBinLimPx;                // bin limits: px
+  Double_t *fhBinLimPy;                // bin limits: py
+  Double_t *fhBinLimPz;                // bin limits: pz
+  Double_t *fhBinLimEta;               // bin limits: eta
+  Double_t *fhBinLimRapidity;  // bin limits: rapidity
+  Double_t *fhBinLimPhi;               // bin limits: phi
+  Double_t *fhBinLimCharge;    // bin limits: charge
+
+  ClassDef(AliCFTrackKineCuts,1);
+};
+
+#endif
diff --git a/CORRFW/AliCFTrackQualityCuts.cxx b/CORRFW/AliCFTrackQualityCuts.cxx
new file mode 100644 (file)
index 0000000..2fe43b6
--- /dev/null
@@ -0,0 +1,962 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+// The class AliCFTrackQualityCuts is designed to select reconstructed tracks
+// of high quality and to provide corresponding QA histograms.
+// This class inherits from the Analysis' Framework abstract base class
+// AliAnalysisCuts and is a part of the Correction Framework.
+// This class acts on single, reconstructed tracks, it is applicable on
+// ESD and AOD data.
+// It mainly consists of a IsSelected function that returns a boolean.
+// This function checks whether the considered track passes a set of cuts:
+// - number of clusters in the TPC
+// - number of clusters in the ITS
+// - chi2 / cluster in the TPC
+// - chi2 / cluster in the ITS
+// - successful TPC refit
+// - successful ITS refit
+// - covariance matrix diagonal elements
+//
+// The cut values for these cuts are set with the corresponding set functions.
+// All cut classes provided by the correction framework are supposed to be
+// added in the Analysis Framwork's class AliAnalysisFilter and applied by
+// the filter via a loop.
+//
+// author: I. Kraus (Ingrid.Kraus@cern.ch)
+// idea taken form
+// AliESDtrackCuts writte by Jan Fiete Grosse-Oetringhaus and
+// AliRsnDaughterCut class written by A. Pulvirenti.
+
+
+#include <TCanvas.h>
+#include <TDirectory.h>
+#include <TBits.h>
+#include <TH2.h>
+
+#include <AliESDtrack.h>
+#include <AliLog.h>
+#include "AliCFTrackQualityCuts.h"
+
+ClassImp(AliCFTrackQualityCuts)
+
+//__________________________________________________________________________________
+AliCFTrackQualityCuts::AliCFTrackQualityCuts() :
+  AliCFCutBase(),
+  fMinNClusterTPC(0),
+  fMinNClusterITS(0),
+  fMaxChi2PerClusterTPC(0),
+  fMaxChi2PerClusterITS(0),
+  fRequireTPCRefit(0),
+  fRequireITSRefit(0),
+  fCovariance11Max(0),
+  fCovariance22Max(0),
+  fCovariance33Max(0),
+  fCovariance44Max(0),
+  fCovariance55Max(0),
+  fhCutStatistics(0),
+  fhCutCorrelation(0),
+  fBitmap(0x0),
+  fhNBinsClusterTPC(0),
+  fhNBinsClusterITS(0),
+  fhNBinsChi2TPC(0),
+  fhNBinsChi2ITS(0),
+  fhNBinsRefitTPC(0),
+  fhNBinsRefitITS(0),
+  fhNBinsCovariance11(0),
+  fhNBinsCovariance22(0),
+  fhNBinsCovariance33(0),
+  fhNBinsCovariance44(0),
+  fhNBinsCovariance55(0),
+  fhBinLimClusterTPC(0x0),
+  fhBinLimClusterITS(0x0),
+  fhBinLimChi2TPC(0x0),
+  fhBinLimChi2ITS(0x0),
+  fhBinLimRefitTPC(0x0),
+  fhBinLimRefitITS(0x0),
+  fhBinLimCovariance11(0x0),
+  fhBinLimCovariance22(0x0),
+  fhBinLimCovariance33(0x0),
+  fhBinLimCovariance44(0x0),
+  fhBinLimCovariance55(0x0)
+  {
+  //
+  // Default constructor
+  //
+  fBitmap=new TBits(0);
+  Initialise();
+}
+//__________________________________________________________________________________
+AliCFTrackQualityCuts::AliCFTrackQualityCuts(Char_t* name, Char_t* title) :
+  AliCFCutBase(name,title),
+  fMinNClusterTPC(0),
+  fMinNClusterITS(0),
+  fMaxChi2PerClusterTPC(0),
+  fMaxChi2PerClusterITS(0),
+  fRequireTPCRefit(0),
+  fRequireITSRefit(0),
+  fCovariance11Max(0),
+  fCovariance22Max(0),
+  fCovariance33Max(0),
+  fCovariance44Max(0),
+  fCovariance55Max(0),
+  fhCutStatistics(0),
+  fhCutCorrelation(0),
+  fBitmap(0x0),
+  fhNBinsClusterTPC(0),
+  fhNBinsClusterITS(0),
+  fhNBinsChi2TPC(0),
+  fhNBinsChi2ITS(0),
+  fhNBinsRefitTPC(0),
+  fhNBinsRefitITS(0),
+  fhNBinsCovariance11(0),
+  fhNBinsCovariance22(0),
+  fhNBinsCovariance33(0),
+  fhNBinsCovariance44(0),
+  fhNBinsCovariance55(0),
+  fhBinLimClusterTPC(0x0),
+  fhBinLimClusterITS(0x0),
+  fhBinLimChi2TPC(0x0),
+  fhBinLimChi2ITS(0x0),
+  fhBinLimRefitTPC(0x0),
+  fhBinLimRefitITS(0x0),
+  fhBinLimCovariance11(0x0),
+  fhBinLimCovariance22(0x0),
+  fhBinLimCovariance33(0x0),
+  fhBinLimCovariance44(0x0),
+  fhBinLimCovariance55(0x0)
+
+{
+  //
+  // Constructor
+  //
+  fBitmap=new TBits(0);
+  Initialise();
+}
+//__________________________________________________________________________________
+AliCFTrackQualityCuts::AliCFTrackQualityCuts(const AliCFTrackQualityCuts& c) :
+  AliCFCutBase(c),
+  fMinNClusterTPC(c.fMinNClusterTPC),
+  fMinNClusterITS(c.fMinNClusterITS),
+  fMaxChi2PerClusterTPC(c.fMaxChi2PerClusterTPC),
+  fMaxChi2PerClusterITS(c.fMaxChi2PerClusterITS),
+  fRequireTPCRefit(c.fRequireTPCRefit),
+  fRequireITSRefit(c.fRequireITSRefit),
+  fCovariance11Max(c.fCovariance11Max),
+  fCovariance22Max(c.fCovariance22Max),
+  fCovariance33Max(c.fCovariance33Max),
+  fCovariance44Max(c.fCovariance44Max),
+  fCovariance55Max(c.fCovariance55Max),
+  fhCutStatistics(c.fhCutStatistics),
+  fhCutCorrelation(c.fhCutCorrelation),
+  fBitmap(c.fBitmap),
+  fhNBinsClusterTPC(c.fhNBinsClusterTPC),
+  fhNBinsClusterITS(c.fhNBinsClusterITS),
+  fhNBinsChi2TPC(c.fhNBinsChi2TPC),
+  fhNBinsChi2ITS(c.fhNBinsChi2ITS),
+  fhNBinsRefitTPC(c.fhNBinsRefitTPC),
+  fhNBinsRefitITS(c.fhNBinsRefitITS),
+  fhNBinsCovariance11(c.fhNBinsCovariance11),
+  fhNBinsCovariance22(c.fhNBinsCovariance22),
+  fhNBinsCovariance33(c.fhNBinsCovariance33),
+  fhNBinsCovariance44(c.fhNBinsCovariance44),
+  fhNBinsCovariance55(c.fhNBinsCovariance55),
+  fhBinLimClusterTPC(c.fhBinLimClusterTPC),
+  fhBinLimClusterITS(c.fhBinLimClusterITS),
+  fhBinLimChi2TPC(c.fhBinLimChi2TPC),
+  fhBinLimChi2ITS(c.fhBinLimChi2ITS),
+  fhBinLimRefitTPC(c.fhBinLimRefitTPC),
+  fhBinLimRefitITS(c.fhBinLimRefitITS),
+  fhBinLimCovariance11(c.fhBinLimCovariance11),
+  fhBinLimCovariance22(c.fhBinLimCovariance22),
+  fhBinLimCovariance33(c.fhBinLimCovariance33),
+  fhBinLimCovariance44(c.fhBinLimCovariance44),
+  fhBinLimCovariance55(c.fhBinLimCovariance55)
+{
+  //
+  // copy constructor
+  //
+  ((AliCFTrackQualityCuts &) c).Copy(*this);
+}
+//__________________________________________________________________________________
+AliCFTrackQualityCuts& AliCFTrackQualityCuts::operator=(const AliCFTrackQualityCuts& c)
+{
+  //
+  // Assignment operator
+  //
+  if (this != &c) {
+    AliCFCutBase::operator=(c) ;
+    fMinNClusterTPC = c.fMinNClusterTPC ;
+    fMinNClusterITS = c.fMinNClusterITS ;
+    fMaxChi2PerClusterTPC = c.fMaxChi2PerClusterTPC ;
+    fMaxChi2PerClusterITS = c.fMaxChi2PerClusterITS ;
+    fRequireTPCRefit = c.fRequireTPCRefit ;
+    fRequireITSRefit = c.fRequireITSRefit ;
+    fCovariance11Max = c.fCovariance11Max ;
+    fCovariance22Max = c.fCovariance22Max ;
+    fCovariance33Max = c.fCovariance33Max ;
+    fCovariance44Max = c.fCovariance44Max ;
+    fCovariance55Max = c.fCovariance55Max ;
+    fhCutStatistics = c.fhCutStatistics ;
+    fhCutCorrelation = c.fhCutCorrelation ;
+    fBitmap =  c.fBitmap ;
+    
+    fhNBinsClusterTPC = c.fhNBinsClusterTPC ;
+    fhNBinsClusterITS = c.fhNBinsClusterITS ;
+    fhNBinsChi2TPC = c.fhNBinsChi2TPC ;
+    fhNBinsChi2ITS = c.fhNBinsChi2ITS ;
+    fhNBinsRefitTPC = c.fhNBinsRefitTPC ;
+    fhNBinsRefitITS = c.fhNBinsRefitITS ;
+    fhNBinsCovariance11 = c.fhNBinsCovariance11 ;
+    fhNBinsCovariance22 = c.fhNBinsCovariance22 ;
+    fhNBinsCovariance33 = c.fhNBinsCovariance33 ;
+    fhNBinsCovariance44 = c.fhNBinsCovariance44 ;
+    fhNBinsCovariance55 = c.fhNBinsCovariance55 ;
+    fhBinLimClusterTPC = c.fhBinLimClusterTPC ;
+    fhBinLimClusterITS = c.fhBinLimClusterITS ;
+    fhBinLimChi2TPC = c.fhBinLimChi2TPC ;
+    fhBinLimChi2ITS = c.fhBinLimChi2ITS ;
+    fhBinLimRefitTPC = c.fhBinLimRefitTPC ;
+    fhBinLimRefitITS = c.fhBinLimRefitITS ;
+    fhBinLimCovariance11 = c.fhBinLimCovariance11 ;
+    fhBinLimCovariance22 = c.fhBinLimCovariance22 ;
+    fhBinLimCovariance33 = c.fhBinLimCovariance33 ;
+    fhBinLimCovariance44 = c.fhBinLimCovariance44 ;
+    fhBinLimCovariance55 = c.fhBinLimCovariance55 ;
+    
+    for (Int_t i=0; i<c.kNHist; i++){
+      for (Int_t j=0; j<c.kNStepQA; j++){
+       if(c.fhQA[i][j]) fhQA[i][j] = (TH1F*)c.fhQA[i][j]->Clone();
+      }
+    }
+
+    ((AliCFTrackQualityCuts &) c).Copy(*this);
+ }
+  return *this;
+}
+//__________________________________________________________________________________
+AliCFTrackQualityCuts::~AliCFTrackQualityCuts()
+{
+  //
+  // destructor
+  //
+  if (fhCutStatistics)                 delete fhCutStatistics;
+  if (fhCutCorrelation)                        delete fhCutCorrelation;
+
+  for (Int_t i=0; i<kNHist; i++){
+    for (Int_t j=0; j<kNStepQA; j++){
+      if(fhQA[i][j]) delete fhQA[i][j];
+    }
+  }
+
+  if(fBitmap)  delete   fBitmap;
+
+  if(fhBinLimClusterTPC) delete fhBinLimClusterTPC;
+  if(fhBinLimClusterITS) delete fhBinLimClusterITS;
+  if(fhBinLimChi2TPC) delete fhBinLimChi2TPC;
+  if(fhBinLimChi2ITS) delete fhBinLimChi2ITS;
+  if(fhBinLimRefitTPC) delete fhBinLimRefitTPC;
+  if(fhBinLimRefitITS) delete fhBinLimRefitITS;
+  if(fhBinLimCovariance11) delete fhBinLimCovariance11;
+  if(fhBinLimCovariance22) delete fhBinLimCovariance22;
+  if(fhBinLimCovariance33) delete fhBinLimCovariance33;
+  if(fhBinLimCovariance44) delete fhBinLimCovariance44;
+  if(fhBinLimCovariance55) delete fhBinLimCovariance55;
+  
+  
+  
+}
+//__________________________________________________________________________________
+void AliCFTrackQualityCuts::Initialise()
+{
+  //
+  // sets everything to zero
+  //
+  fMinNClusterTPC = 0;
+  fMinNClusterITS = 0;
+  fMaxChi2PerClusterTPC = 0;
+  fMaxChi2PerClusterITS = 0;
+  fRequireTPCRefit = 0;
+  fRequireITSRefit = 0;
+  fCovariance11Max = 0;
+  fCovariance22Max = 0;
+  fCovariance33Max = 0;
+  fCovariance44Max = 0;
+  fCovariance55Max = 0;
+
+  SetMinNClusterTPC();
+  SetMinNClusterITS();
+  SetMaxChi2PerClusterTPC();
+  SetMaxChi2PerClusterITS();
+  SetRequireTPCRefit();
+  SetRequireITSRefit();
+  SetMaxCovDiagonalElements();
+
+  for (Int_t i=0; i<kNHist; i++){
+    for (Int_t j=0; j<kNStepQA; j++)  {
+      fhQA[i][j] = 0x0;
+    }
+  }
+  fhCutStatistics = 0;
+  fhCutCorrelation = 0;
+
+  
+    //set default bining for QA histograms
+  SetHistogramBins(kCutClusterTPC,165,-0.5,164.5);
+  SetHistogramBins(kCutClusterITS,8,-0.5,7.5);
+  SetHistogramBins(kCutChi2TPC,500,0,10);
+  SetHistogramBins(kCutChi2ITS,500,0,10);
+  SetHistogramBins(kCutRefitTPC,2,-0.5,1.5);
+  SetHistogramBins(kCutRefitITS,2,-0.5,1.5);
+  SetHistogramBins(kCutCovElement11,200,0,20);
+  SetHistogramBins(kCutCovElement22,200,0,20);
+  SetHistogramBins(kCutCovElement33,100,0,1);
+  SetHistogramBins(kCutCovElement44,100,0,5);
+  SetHistogramBins(kCutCovElement55,100,0,5);
+  
+}
+//__________________________________________________________________________________
+void AliCFTrackQualityCuts::Copy(TObject &c) const
+{
+  //
+  // Copy function
+  //
+  AliCFTrackQualityCuts& target = (AliCFTrackQualityCuts &) c;
+
+  target.Initialise();
+
+  if (fhCutStatistics)  target.fhCutStatistics = (TH1F*) fhCutStatistics->Clone();
+  if (fhCutCorrelation) target.fhCutCorrelation = (TH2F*) fhCutCorrelation->Clone();
+
+  for (Int_t i=0; i<kNHist; i++){
+    for (Int_t j=0; j<kNStepQA; j++){
+      if(fhQA[i][j]) target.fhQA[i][j] = (TH1F*)fhQA[i][j]->Clone();
+    }
+  }
+
+  TNamed::Copy(c);
+}
+//__________________________________________________________________________________
+void AliCFTrackQualityCuts::GetBitMap(TObject* obj, TBits *bitmap) {
+  //
+  // retrieve the pointer to the bitmap
+  //
+  bitmap = SelectionBitMap(obj);
+}
+//__________________________________________________________________________________
+TBits* AliCFTrackQualityCuts::SelectionBitMap(TObject* obj)
+{
+  //
+  // test if the track passes the single cuts
+  // and store the information in a bitmap
+  //
+
+  // bitmap stores the decision of each single cut
+  for(Int_t i=0; i<kNCuts; i++)fBitmap->SetBitNumber(i,kFALSE);
+
+  // cast TObject into ESDtrack
+  AliESDtrack* esdTrack = dynamic_cast<AliESDtrack *>(obj);
+  if ( !esdTrack ) return fBitmap ;
+
+  for(Int_t i=0; i<kNCuts; i++)fBitmap->SetBitNumber(i,kTRUE);
+
+  // get cut quantities
+  Int_t  fIdxInt[200];
+  Int_t nClustersTPC = esdTrack->GetTPCclusters(fIdxInt);
+  Int_t nClustersITS = esdTrack->GetITSclusters(fIdxInt);
+
+  Float_t chi2PerClusterTPC = -1;
+  Float_t chi2PerClusterITS = -1;
+
+  if (nClustersTPC != 0)
+    chi2PerClusterTPC = esdTrack->GetTPCchi2() / Float_t(nClustersTPC);
+  if (nClustersITS!=0)
+    chi2PerClusterITS = esdTrack->GetITSchi2() / Float_t(nClustersITS);
+
+  Double_t extCov[15];
+  esdTrack->GetExternalCovariance(extCov);
+
+
+  // fill the bitmap
+  Int_t iCutBit = 0;
+
+  if (nClustersTPC < fMinNClusterTPC)
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if (nClustersITS < fMinNClusterITS)
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if (chi2PerClusterTPC > fMaxChi2PerClusterTPC)
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if (chi2PerClusterITS > fMaxChi2PerClusterITS)
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if (fRequireTPCRefit && (esdTrack->GetStatus()&AliESDtrack::kTPCrefit)==0)
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if (fRequireITSRefit && (esdTrack->GetStatus()&AliESDtrack::kITSrefit)==0)
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if (extCov[0]  > fCovariance11Max)
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if (extCov[2]  > fCovariance22Max)
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if (extCov[5]  > fCovariance33Max)
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if (extCov[9]  > fCovariance44Max)
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+  iCutBit++;
+  if (extCov[14] > fCovariance55Max)
+       fBitmap->SetBitNumber(iCutBit,kFALSE);
+
+  return fBitmap;
+}
+//__________________________________________________________________________________
+Bool_t AliCFTrackQualityCuts::IsSelected(TObject* obj) {
+  //
+  // loops over decisions of single cuts and returns if the track is accepted
+  //
+  TBits* bitmap = SelectionBitMap(obj);
+
+  Bool_t isSelected = kTRUE;
+
+  for (UInt_t icut=0; icut<bitmap->GetNbits();icut++)
+       if(!bitmap->TestBitNumber(icut)) isSelected = kFALSE;
+
+  return isSelected;
+}
+//__________________________________________________________________________________
+void AliCFTrackQualityCuts::Init() {
+  //
+  // initialises all histograms and the TList which holds the histograms
+  //
+  if(fIsQAOn)
+    DefineHistograms();
+}
+//__________________________________________________________________________________
+void AliCFTrackQualityCuts::SetHistogramBins(Int_t index, Int_t nbins, Double_t *bins)
+{
+  //
+  // variable bin size
+  //
+  if(!fIsQAOn) return;
+
+  switch(index){
+  case kCutClusterTPC:
+    fhNBinsClusterTPC=nbins;
+    fhBinLimClusterTPC=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimClusterTPC[i]=bins[i];
+    break;
+    
+  case kCutClusterITS:
+    fhNBinsClusterITS=nbins;
+    fhBinLimClusterITS=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimClusterITS[i]=bins[i];
+    break;
+    
+  case kCutChi2TPC:
+    fhNBinsChi2TPC=nbins;
+    fhBinLimChi2TPC=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimChi2TPC[i]=bins[i];
+    break;
+    
+  case kCutChi2ITS:
+    fhNBinsChi2ITS=nbins;
+    fhBinLimChi2ITS=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimChi2ITS[i]=bins[i];
+    break;
+    
+  case kCutRefitTPC:
+    fhNBinsRefitTPC=nbins;
+    fhBinLimRefitTPC=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimRefitTPC[i]=bins[i];
+    break;
+    
+  case kCutRefitITS:
+    fhNBinsRefitITS=nbins;
+    fhBinLimRefitITS=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimRefitITS[i]=bins[i];
+    break;
+    
+  case kCutCovElement11:
+    fhNBinsCovariance11=nbins;
+    fhBinLimCovariance11=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimCovariance11[i]=bins[i];
+    break;
+    
+  case kCutCovElement22:
+    fhNBinsCovariance22=nbins;
+    fhBinLimCovariance22=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimCovariance22[i]=bins[i];
+    break;
+    
+  case kCutCovElement33:
+    fhNBinsCovariance33=nbins;
+    fhBinLimCovariance33=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimCovariance33[i]=bins[i];
+    break;
+    
+  case kCutCovElement44:
+    fhNBinsCovariance44=nbins;
+    fhBinLimCovariance44=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimCovariance44[i]=bins[i];
+    break;
+  
+  case kCutCovElement55:
+    fhNBinsCovariance55=nbins;
+    fhBinLimCovariance55=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimCovariance55[i]=bins[i];
+    break;
+ }
+}
+//__________________________________________________________________________________
+void AliCFTrackQualityCuts::SetHistogramBins(Int_t index, Int_t nbins, Double_t xmin, Double_t xmax)
+{
+  //
+  // fixed bin size
+  //
+  if(!fIsQAOn) return;
+
+  switch(index){
+  case kCutClusterTPC:
+    fhNBinsClusterTPC=nbins;
+    fhBinLimClusterTPC=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimClusterTPC[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kCutClusterITS:
+    fhNBinsClusterITS=nbins;
+    fhBinLimClusterITS=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimClusterITS[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kCutChi2TPC:
+    fhNBinsChi2TPC=nbins;
+    fhBinLimChi2TPC=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimChi2TPC[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kCutChi2ITS:
+    fhNBinsChi2ITS=nbins;
+    fhBinLimChi2ITS=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimChi2ITS[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kCutRefitTPC:
+    fhNBinsRefitTPC=nbins;
+    fhBinLimRefitTPC=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimRefitTPC[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kCutRefitITS:
+    fhNBinsRefitITS=nbins;
+    fhBinLimRefitITS=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimRefitITS[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kCutCovElement11:
+    fhNBinsCovariance11=nbins;
+    fhBinLimCovariance11=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimCovariance11[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kCutCovElement22:
+    fhNBinsCovariance22=nbins;
+    fhBinLimCovariance22=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimCovariance22[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kCutCovElement33:
+    fhNBinsCovariance33=nbins;
+    fhBinLimCovariance33=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimCovariance33[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+    
+  case kCutCovElement44:
+    fhNBinsCovariance44=nbins;
+    fhBinLimCovariance44=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimCovariance44[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+  
+  case kCutCovElement55:
+    fhNBinsCovariance55=nbins;
+    fhBinLimCovariance55=new Double_t[nbins+1];
+    for(Int_t i=0;i<nbins+1;i++)fhBinLimCovariance55[i]=xmin+i*(xmax-xmin)/Double_t(nbins);
+    break;
+ }
+}
+//__________________________________________________________________________________
+ void AliCFTrackQualityCuts::DefineHistograms() {
+  //
+  // histograms for cut variables, cut statistics and cut correlations
+  //
+
+  Int_t color = 2;
+
+  // book cut statistics and cut correlation histograms
+  fhCutStatistics = new TH1F(Form("%s_cut_statistics",GetName()), Form("%s cut statistics",GetName()), kNCuts,0.5,kNCuts+0.5);
+  fhCutStatistics->SetLineWidth(2);
+  fhCutStatistics->GetXaxis()->SetBinLabel(1,"nClustersTPC");
+  fhCutStatistics->GetXaxis()->SetBinLabel(2,"nClustersITS");
+  fhCutStatistics->GetXaxis()->SetBinLabel(3,"chi2PerClusterTPC");
+  fhCutStatistics->GetXaxis()->SetBinLabel(4,"chi2PerClusterITS");
+  fhCutStatistics->GetXaxis()->SetBinLabel(5,"refitTPC");
+  fhCutStatistics->GetXaxis()->SetBinLabel(6,"refitITS");
+  fhCutStatistics->GetXaxis()->SetBinLabel(7,"covElement11");
+  fhCutStatistics->GetXaxis()->SetBinLabel(8,"covElement22");
+  fhCutStatistics->GetXaxis()->SetBinLabel(9,"covElement33");
+  fhCutStatistics->GetXaxis()->SetBinLabel(10,"covElement44");
+  fhCutStatistics->GetXaxis()->SetBinLabel(11,"covElement55");
+
+  fhCutCorrelation = new TH2F(Form("%s_cut_correlation",GetName()), Form("%s cut  correlation",GetName()), kNCuts,0.5,kNCuts+0.5,kNCuts,0.5,kNCuts+0.5);
+  fhCutCorrelation->SetLineWidth(2);
+  fhCutCorrelation->GetXaxis()->SetBinLabel(1,"nClustersTPC");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(2,"nClustersITS");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(3,"chi2PerClusterTPC");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(4,"chi2PerClusterITS");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(5,"refitTPC");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(6,"refitITS");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(7,"covElement11");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(8,"covElement22");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(9,"covElement33");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(10,"covElement44");
+  fhCutCorrelation->GetXaxis()->SetBinLabel(11,"covElement55");
+
+  fhCutCorrelation->GetYaxis()->SetBinLabel(1,"nClustersTPC");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(2,"nClustersITS");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(3,"chi2PerClusterTPC");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(4,"chi2PerClusterITS");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(5,"refitTPC");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(6,"refitITS");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(7,"covElement11");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(8,"covElement22");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(9,"covElement33");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(10,"covElement44");
+  fhCutCorrelation->GetYaxis()->SetBinLabel(11,"covElement55");
+
+
+  // book QA histograms
+  Char_t str[256];
+  for (Int_t i=0; i<kNStepQA; i++) {
+    if (i==0) sprintf(str," ");
+    else sprintf(str,"_cut");
+        
+    fhQA[kCutClusterTPC][i]    = new TH1F(Form("%s_nClustersTPC%s",GetName(),str)     ,"",fhNBinsClusterTPC,fhBinLimClusterTPC);
+    fhQA[kCutClusterITS][i]    = new TH1F(Form("%s_nClustersITS%s",GetName(),str)     ,"",fhNBinsClusterITS,fhBinLimClusterITS);
+    fhQA[kCutChi2TPC][i]       = new TH1F(Form("%s_chi2PerClusterTPC%s",GetName(),str),"",fhNBinsChi2TPC,fhBinLimChi2TPC);
+    fhQA[kCutChi2ITS][i]       = new TH1F(Form("%s_chi2PerClusterITS%s",GetName(),str),"",fhNBinsChi2ITS,fhBinLimChi2ITS);
+    fhQA[kCutRefitTPC][i]      = new TH1F(Form("%s_refitTPC%s",GetName(),str)     ,"",fhNBinsRefitTPC,fhBinLimRefitTPC);
+    fhQA[kCutRefitITS][i]      = new TH1F(Form("%s_refitITS%s",GetName(),str)     ,"",fhNBinsRefitITS,fhBinLimRefitITS);
+    fhQA[kCutCovElement11][i]  = new TH1F(Form("%s_covMatrixDiagonal11%s",GetName(),str),"",fhNBinsCovariance11,fhBinLimCovariance11);
+    fhQA[kCutCovElement22][i]  = new TH1F(Form("%s_covMatrixDiagonal22%s",GetName(),str),"",fhNBinsCovariance22,fhBinLimCovariance22);
+    fhQA[kCutCovElement33][i]  = new TH1F(Form("%s_covMatrixDiagonal33%s",GetName(),str),"",fhNBinsCovariance33,fhBinLimCovariance33);
+    fhQA[kCutCovElement44][i]  = new TH1F(Form("%s_covMatrixDiagonal44%s",GetName(),str),"",fhNBinsCovariance44,fhBinLimCovariance44);
+    fhQA[kCutCovElement55][i]  = new TH1F(Form("%s_covMatrixDiagonal55%s",GetName(),str),"",fhNBinsCovariance55,fhBinLimCovariance55);
+
+    fhQA[kCutClusterTPC][i]    ->SetXTitle("n TPC clusters");
+    fhQA[kCutClusterITS][i]    ->SetXTitle("n ITS clusters");
+    fhQA[kCutChi2TPC][i]       ->SetXTitle("#chi^{2} per TPC cluster");
+    fhQA[kCutChi2ITS][i]       ->SetXTitle("#chi^{2} per ITS cluster");
+    fhQA[kCutRefitTPC][i]      ->SetXTitle("refit TPC");
+    fhQA[kCutRefitITS][i]      ->SetXTitle("refit ITS");
+    fhQA[kCutCovElement11][i]  ->SetXTitle("cov 11 : #sigma_{y}^{2} (cm^{2})");
+    fhQA[kCutCovElement22][i]  ->SetXTitle("cov 22 : #sigma_{z}^{2} (cm^{2})");
+    fhQA[kCutCovElement33][i]  ->SetXTitle("cov 33 : #sigma_{sin(#phi)}^{2}");
+    fhQA[kCutCovElement44][i]  ->SetXTitle("cov 44 : #sigma_{tan(#theta_{dip})}^{2}");
+    fhQA[kCutCovElement55][i]  ->SetXTitle("cov 55 : #sigma_{1/p_{T}}^{2} ((c/GeV)^2)");
+  }
+
+  for(Int_t i=0; i<kNHist; i++) fhQA[i][1]->SetLineColor(color);
+
+}
+//__________________________________________________________________________________
+void AliCFTrackQualityCuts::FillHistograms(TObject* obj, Bool_t b)
+{
+  //
+  // fill the QA histograms
+  //
+  if(!fIsQAOn) return;
+
+  // cast TObject into ESDtrack
+  AliESDtrack* esdTrack = dynamic_cast<AliESDtrack *>(obj);
+  if ( !esdTrack ) return;
+
+  // index = 0: fill histograms before cuts
+  // index = 1: fill histograms after cuts
+  Int_t index = -1;
+  index = ((b) ? 1 : 0);
+
+  Int_t  fIdxInt[200];
+  Int_t nClustersTPC = esdTrack->GetTPCclusters(fIdxInt);
+  fhQA[kCutClusterTPC][index]->Fill((float)nClustersTPC);
+  Float_t chi2PerClusterTPC = -1.;
+  if (nClustersTPC!=0)
+    chi2PerClusterTPC = esdTrack->GetTPCchi2()/((float)nClustersTPC);
+  fhQA[kCutChi2TPC][index]->Fill(chi2PerClusterTPC);
+  
+  Int_t nClustersITS = esdTrack->GetITSclusters(fIdxInt);
+  fhQA[kCutClusterITS][index]->Fill((float)nClustersITS);
+  Float_t chi2PerClusterITS = -1.;
+  if (nClustersITS!=0)
+    chi2PerClusterITS = esdTrack->GetITSchi2()/((float)nClustersITS);
+  fhQA[kCutChi2ITS][index]->Fill(chi2PerClusterITS);
+  
+  
+  if ((esdTrack->GetStatus()&AliESDtrack::kTPCrefit)==0)
+    fhQA[kCutRefitTPC][index]->Fill(0.);
+  if (!((esdTrack->GetStatus()&AliESDtrack::kTPCrefit)==0))
+    fhQA[kCutRefitTPC][index]->Fill(1.);
+  
+  if ((esdTrack->GetStatus()&AliESDtrack::kITSrefit)==0)
+    fhQA[kCutRefitITS][index]->Fill(0.);
+  if (!((esdTrack->GetStatus()&AliESDtrack::kITSrefit)==0))
+    fhQA[kCutRefitITS][index]->Fill(1.);
+  
+  
+  Double_t extCov[15];
+  esdTrack->GetExternalCovariance(extCov);
+  
+  fhQA[kCutCovElement11][index]->Fill(extCov[0]);
+  fhQA[kCutCovElement22][index]->Fill(extCov[2]);
+  fhQA[kCutCovElement33][index]->Fill(extCov[5]);
+  fhQA[kCutCovElement44][index]->Fill(extCov[9]);
+  fhQA[kCutCovElement55][index]->Fill(extCov[14]);
+  
+  // fill cut statistics and cut correlation histograms with information from the bitmap
+  if (b) return;
+
+  // Get the bitmap of the single cuts
+  if ( !obj ) return;
+  TBits* bitmap = SelectionBitMap(obj);
+
+  // Number of single cuts in this class
+  UInt_t ncuts = bitmap->GetNbits();
+  for(UInt_t bit=0; bit<ncuts;bit++) {
+    if (!bitmap->TestBitNumber(bit)) {
+       fhCutStatistics->Fill(bit+1);
+       for (UInt_t bit2=bit; bit2<ncuts;bit2++) {
+         if (!bitmap->TestBitNumber(bit2)) 
+           fhCutCorrelation->Fill(bit+1,bit2+1);
+       }
+    }
+  }
+}
+//__________________________________________________________________________________
+void AliCFTrackQualityCuts::SaveHistograms(const Char_t* dir) {
+  //
+  // saves the histograms in a directory (dir)
+  //
+  if(!fIsQAOn) return;
+
+  if (!dir)
+    dir = GetName();
+
+  gDirectory->mkdir(dir);
+  gDirectory->cd(dir);
+
+  gDirectory->mkdir("before_cuts");
+  gDirectory->mkdir("after_cuts");
+
+  fhCutStatistics->Write();
+  fhCutCorrelation->Write();
+
+  for (Int_t j=0; j<kNStepQA; j++) {
+    if (j==0)
+      gDirectory->cd("before_cuts");
+    else
+      gDirectory->cd("after_cuts");
+
+    for(Int_t i=0; i<kNHist; i++) fhQA[i][j]->Write();
+
+    gDirectory->cd("../");
+  }
+  gDirectory->cd("../");
+}
+//__________________________________________________________________________________
+void AliCFTrackQualityCuts::DrawHistograms(Bool_t drawLogScale)
+{
+  //
+  // draws some histograms
+  //
+  if(!fIsQAOn) return;
+
+  // pad margins
+  Float_t right = 0.03;
+  Float_t left = 0.175;
+  Float_t top = 0.03;
+  Float_t bottom = 0.175;
+
+  TCanvas* canvas1 = new TCanvas("Track_QA_Quality_1", "Track QA Quality 1", 800, 500);
+  canvas1->Divide(2, 1);
+
+  canvas1->cd(1);
+  fhCutStatistics->SetStats(kFALSE);
+  fhCutStatistics->LabelsOption("v");
+  gPad->SetLeftMargin(left);
+  gPad->SetBottomMargin(0.25);
+  gPad->SetRightMargin(right);
+  gPad->SetTopMargin(0.1);
+  fhCutStatistics->Draw();
+
+  canvas1->cd(2);
+  fhCutCorrelation->SetStats(kFALSE);
+  fhCutCorrelation->LabelsOption("v");
+  gPad->SetLeftMargin(0.30);
+  gPad->SetRightMargin(bottom);
+  gPad->SetTopMargin(0.1);
+  gPad->SetBottomMargin(0.25);
+  fhCutCorrelation->Draw("COLZ");
+
+  canvas1->SaveAs(Form("%s.eps", canvas1->GetName()));
+  canvas1->SaveAs(Form("%s.ps", canvas1->GetName()));
+
+  // -----
+
+  TCanvas* canvas2 = new TCanvas("Track_QA_Quality_2", "Track QA Quality 2", 1200, 800);
+  canvas2->Divide(3, 2);
+
+  canvas2->cd(1);
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutClusterTPC][0]->SetStats(kFALSE);
+  fhQA[kCutClusterTPC][0]->Draw();
+  fhQA[kCutClusterTPC][1]->Draw("same");
+
+  canvas2->cd(2);
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutChi2TPC][0]->SetStats(kFALSE);
+  fhQA[kCutChi2TPC][0]->Draw();
+  fhQA[kCutChi2TPC][1]->Draw("same");
+
+  canvas2->cd(3);
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+//   fhQA[kCutRefitTPC][0]->SetStats(kFALSE);
+  fhQA[kCutRefitTPC][0]->Draw();
+  fhQA[kCutRefitTPC][1]->Draw("same");
+
+  canvas2->cd(4);
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutClusterITS][0]->SetStats(kFALSE);
+  fhQA[kCutClusterITS][0]->Draw();
+  fhQA[kCutClusterITS][1]->Draw("same");
+
+  canvas2->cd(5);
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutChi2ITS][0]->SetStats(kFALSE);
+  fhQA[kCutChi2ITS][0]->Draw();
+  fhQA[kCutChi2ITS][1]->Draw("same");
+
+  canvas2->cd(6);
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+//   fhQA[kCutRefitITS][0]->SetStats(kFALSE);
+  fhQA[kCutRefitITS][0]->Draw();
+  fhQA[kCutRefitITS][1]->Draw("same");
+
+  canvas2->SaveAs(Form("%s.eps", canvas2->GetName()));
+  canvas2->SaveAs(Form("%s.ps", canvas2->GetName()));
+
+  // -----
+
+  TCanvas* canvas3 = new TCanvas("Track_QA_Quality_3", "Track QA Quality 3", 1200, 800);
+  canvas3->Divide(3, 2);
+
+  canvas3->cd(1);
+  if(drawLogScale) gPad->SetLogy();
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutCovElement11][0]->SetStats(kFALSE);
+  fhQA[kCutCovElement11][0]->Draw();
+  fhQA[kCutCovElement11][1]->Draw("same");
+
+  canvas3->cd(2);
+  if(drawLogScale) gPad->SetLogy();
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutCovElement22][0]->SetStats(kFALSE);
+  fhQA[kCutCovElement22][0]->Draw();
+  fhQA[kCutCovElement22][1]->Draw("same");
+
+  canvas3->cd(3);
+  if(drawLogScale) gPad->SetLogy();
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutCovElement33][0]->SetStats(kFALSE);
+  fhQA[kCutCovElement33][0]->Draw();
+  fhQA[kCutCovElement33][1]->Draw("same");
+
+  canvas3->cd(4);
+  if(drawLogScale) gPad->SetLogy();
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutCovElement44][0]->SetStats(kFALSE);
+  fhQA[kCutCovElement44][0]->Draw();
+  fhQA[kCutCovElement44][1]->Draw("same");
+
+  canvas3->cd(5);
+  if(drawLogScale) gPad->SetLogy();
+  gPad->SetRightMargin(right);
+  gPad->SetLeftMargin(left);
+  gPad->SetTopMargin(top);
+  gPad->SetBottomMargin(bottom);
+  fhQA[kCutCovElement55][0]->SetStats(kFALSE);
+  fhQA[kCutCovElement55][0]->Draw();
+  fhQA[kCutCovElement55][1]->Draw("same");
+
+  canvas3->SaveAs(Form("%s.eps", canvas3->GetName()));
+  canvas3->SaveAs(Form("%s.ps", canvas3->GetName()));
+}
+//__________________________________________________________________________________
+void AliCFTrackQualityCuts::AddQAHistograms(TList *qaList)  const {
+  //
+  // saves the histograms in a TList
+  //
+  if(!fIsQAOn) return;
+
+  qaList->Add(fhCutStatistics);
+  qaList->Add(fhCutCorrelation);
+
+  for (Int_t j=0; j<kNStepQA; j++) {
+    for(Int_t i=0; i<kNHist; i++)
+       qaList->Add(fhQA[i][j]);
+  }
+}
diff --git a/CORRFW/AliCFTrackQualityCuts.h b/CORRFW/AliCFTrackQualityCuts.h
new file mode 100644 (file)
index 0000000..99f364b
--- /dev/null
@@ -0,0 +1,157 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+// The class AliCFTrackQualityCuts is designed to select reconstructed tracks
+// of high quality and to provide corresponding QA histograms.
+// This class inherits from the Analysis' Framework abstract base class
+// AliAnalysisCuts and is a part of the Correction Framework.
+// This class acts on single, reconstructed tracks, it is applicable on
+// ESD and AOD data.
+// It mainly consists of a IsSelected function that returns a boolean.
+// This function checks whether the considered track passes a set of cuts:
+// - number of clusters in the TPC
+// - number of clusters in the ITS
+// - chi2 / cluster in the TPC
+// - chi2 / cluster in the ITS
+// - successful TPC refit
+// - successful ITS refit
+// - covariance matrix diagonal elements
+//
+// The cut values for these cuts are set with the corresponding set functions.
+// All cut classes provided by the correction framework are supposed to be
+// added in the Analysis Framwork's class AliAnalysisFilter and applied by
+// the filter via a loop.
+//
+// author: I. Kraus (Ingrid.Kraus@cern.ch)
+// idea taken form
+// AliESDtrackCuts writte by Jan Fiete Grosse-Oetringhaus and
+// AliRsnDaughterCut class written by A. Pulvirenti.
+
+#ifndef ALICFTRACKQUALITYCUTS_H
+#define ALICFTRACKQUALITYCUTS_H
+
+#include "AliCFCutBase.h"
+
+class TH2;
+class TBits;
+class AliESDtrack ;
+
+class AliCFTrackQualityCuts : public AliCFCutBase
+{
+ public :
+  AliCFTrackQualityCuts() ;
+  AliCFTrackQualityCuts(Char_t* name, Char_t* title) ;
+  AliCFTrackQualityCuts(const AliCFTrackQualityCuts& c) ;
+  AliCFTrackQualityCuts& operator=(const AliCFTrackQualityCuts& c) ;
+  ~AliCFTrackQualityCuts();
+  void Copy(TObject &c) const;
+
+  void GetBitMap(TObject* obj, TBits *bitmap) ;
+  Bool_t IsSelected(TObject* obj);
+  void Init();
+
+  // cut value setter
+  void SetMinNClusterTPC(Int_t cluster=-1)             {fMinNClusterTPC = cluster;}
+  void SetMinNClusterITS(Int_t cluster=-1)             {fMinNClusterITS = cluster;}
+  void SetMaxChi2PerClusterTPC(Double_t chi=1e99)      {fMaxChi2PerClusterTPC = chi;}
+  void SetMaxChi2PerClusterITS(Double_t chi=1e99)      {fMaxChi2PerClusterITS = chi;}
+  void SetRequireTPCRefit(Bool_t b=kFALSE)             {fRequireTPCRefit = b;}
+  void SetRequireITSRefit(Bool_t b=kFALSE)             {fRequireITSRefit = b;}
+  void SetMaxCovDiagonalElements(Float_t c1=1e99, Float_t c2=1e99, Float_t c3=1e99, Float_t c4=1e99, Float_t c5=1e99) 
+{fCovariance11Max=c1;fCovariance22Max=c2;fCovariance33Max=c3;fCovariance44Max=c4;fCovariance55Max=c5;}
+
+  // QA histograms
+  void FillHistogramsBeforeCuts(TObject* obj) {return FillHistograms(obj,kFALSE);}
+  void FillHistogramsAfterCuts(TObject* obj)  {return FillHistograms(obj,kTRUE);}
+  void DrawHistograms(Bool_t drawLogScale=kTRUE);
+  void SaveHistograms(const Char_t* dir = 0);
+  void AddQAHistograms(TList *qaList) const;
+  // QA histogram setter
+  // please use indices from the enumeration below
+  void SetHistogramBins(Int_t index, Int_t nbins, Double_t *bins);
+  void SetHistogramBins(Int_t index, Int_t nbins, Double_t xmin, Double_t xmax);
+
+  // indeces/counters for single selections
+  enum { 
+    kCutClusterTPC=0,  // number of clusters in TPC
+    kCutClusterITS,    // number of clusters in ITS
+    kCutChi2TPC,       // chi2 per cluster in TPC
+    kCutChi2ITS,       // chi2 per cluster in ITS
+    kCutRefitTPC,      // require TPC refit
+    kCutRefitITS,      // require ITS refit
+    kCutCovElement11,  // diagonal element 11 of covariance matrix
+    kCutCovElement22,  // diagonal element 22 of covariance matrix
+    kCutCovElement33,  // diagonal element 33 of covariance matrix
+    kCutCovElement44,  // diagonal element 44 of covariance matrix
+    kCutCovElement55,  // diagonal element 55 of covariance matrix
+    kNCuts=11,         // number of single selections
+    kNStepQA=2,                // number of QA steps (before/after the cuts)
+    kNHist=11          // number of QA histograms
+  };
+
+ private:
+  TBits* SelectionBitMap(TObject* obj);
+  void DefineHistograms();             // books histograms and TList
+  void Initialise();                   // sets everything to 0
+  void FillHistograms(TObject* obj, Bool_t b);
+                                       // Fills histograms before and after cuts
+  Double_t fMinNClusterTPC;            // min number of clusters in TPC
+  Double_t fMinNClusterITS;            // min number of clusters in ITS
+  Double_t fMaxChi2PerClusterTPC;      // max chi2 per clusters in TPC
+  Double_t fMaxChi2PerClusterITS;      // max chi2 per clusters in ITS
+  Bool_t fRequireTPCRefit;             // require TPC refit
+  Bool_t fRequireITSRefit;             // require ITS refit
+
+  Double_t fCovariance11Max ;          // max covariance matrix element 11
+  Double_t fCovariance22Max ;          // max covariance matrix element 22
+  Double_t fCovariance33Max ;          // max covariance matrix element 33
+  Double_t fCovariance44Max ;          // max covariance matrix element 44
+  Double_t fCovariance55Max ;          // max covariance matrix element 55
+
+  TH1F* fhCutStatistics;              // Histogram: statistics of what cuts the tracks did not survive
+  TH2F* fhCutCorrelation;             // Histogram: 2d statistics plot
+
+  TH1F* fhQA[kNHist][kNStepQA];                // QA Histograms
+  TBits *fBitmap ;                             // stores single selection decisions
+
+  // QA histogram setters
+  Int_t fhNBinsClusterTPC;             // number of bins: cluster TPC
+  Int_t fhNBinsClusterITS;             // number of bins: cluster ITS
+  Int_t fhNBinsChi2TPC;                        // number of bins: chi2 per cluster TPC
+  Int_t fhNBinsChi2ITS;                        // number of bins: chi2 per cluster ITS
+  Int_t fhNBinsRefitTPC;                       // number of bins: require refit TPC
+  Int_t fhNBinsRefitITS;                       // number of bins: require refit ITS  
+  Int_t fhNBinsCovariance11;           // number of bins: covariance matrix element 11
+  Int_t fhNBinsCovariance22;           // number of bins: covariance matrix element 22
+  Int_t fhNBinsCovariance33;           // number of bins: covariance matrix element 33
+  Int_t fhNBinsCovariance44;           // number of bins: covariance matrix element 44
+  Int_t fhNBinsCovariance55;           // number of bins: covariance matrix element 55
+  
+  Double_t *fhBinLimClusterTPC;        // bin limits: cluster TPC
+  Double_t *fhBinLimClusterITS;        // bin limits: cluster ITS
+  Double_t *fhBinLimChi2TPC;   // bin limits: chi2 per cluster TPC
+  Double_t *fhBinLimChi2ITS;   // bin limits: chi2 per cluster ITS
+  Double_t *fhBinLimRefitTPC;  // bin limits: require refit TPC
+  Double_t *fhBinLimRefitITS;  // bin limits: require refit ITS
+  Double_t *fhBinLimCovariance11;      // bin limits: covariance matrix element 11
+  Double_t *fhBinLimCovariance22;      // bin limits: covariance matrix element 22
+  Double_t *fhBinLimCovariance33;      // bin limits: covariance matrix element 33
+  Double_t *fhBinLimCovariance44;      // bin limits: covariance matrix element 44
+  Double_t *fhBinLimCovariance55;      // bin limits: covariance matrix element 55
+  
+  ClassDef(AliCFTrackQualityCuts,1);
+};
+
+#endif
diff --git a/CORRFW/CORRFWLinkDef.h b/CORRFW/CORRFWLinkDef.h
new file mode 100644 (file)
index 0000000..67f1cff
--- /dev/null
@@ -0,0 +1,25 @@
+#ifdef __CINT__
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+
+#pragma link C++ class  AliCFFrame+;
+#pragma link C++ class  AliCFGrid+;
+#pragma link C++ class  AliCFEffGrid+;
+#pragma link C++ class  AliCFDataGrid+;
+#pragma link C++ class  AliCFContainer+;
+#pragma link C++ class  AliCFManager+;
+#pragma link C++ class  AliCFCutBase+;
+#pragma link C++ class  AliCFEventClassCuts+;
+#pragma link C++ class  AliCFEventClassCuts+;
+#pragma link C++ class  AliCFEventGenCuts+;
+#pragma link C++ class  AliCFEventRecCuts+;
+#pragma link C++ class  AliCFParticleGenCuts+;
+#pragma link C++ class  AliCFAcceptanceCuts+;
+#pragma link C++ class  AliCFTrackKineCuts+;
+#pragma link C++ class  AliCFTrackQualityCuts+;
+#pragma link C++ class  AliCFTrackIsPrimaryCuts+;
+#pragma link C++ class  AliCFTrackCutPid+;
+
+#endif
diff --git a/CORRFW/Makefile b/CORRFW/Makefile
new file mode 100644 (file)
index 0000000..9fb4fc0
--- /dev/null
@@ -0,0 +1,100 @@
+
+include Makefile.arch
+
+default-target: libCORRFW.so
+
+ALICEINC      = -I.
+
+# add include paths from other par files
+ifneq ($(STEERBase_INCLUDE),)
+   ALICEINC += -I../$(STEERBase_INCLUDE)
+endif
+
+ifneq ($(ESD_INCLUDE),)
+   ALICEINC += -I../$(ESD_INCLUDE)
+endif
+
+ifneq ($(AOD_INCLUDE),)
+   ALICEINC += -I../$(AOD_INCLUDE)
+endif
+
+ifneq ($(ANALYSIS_INCLUDE),)
+   ALICEINC += -I../$(ANALYSIS_INCLUDE)
+endif
+
+
+# only if no par file was loaded before
+ifeq ($(ALICEINC),-I.)
+  ifneq ($(ALICE_ROOT),)
+    ALICEINC += -I$(ALICE_ROOT)/include
+  endif
+endif
+
+CXXFLAGS     += $(ALICEINC) -g
+
+PACKAGE = CORRFW
+include lib$(PACKAGE).pkg
+
+DHDR_CORRFW := $(DHDR)
+HDRS_CORRFW := $(HDRS)
+SRCS_CORRFW := $(SRCS) G__$(PACKAGE).cxx
+OBJS_CORRFW := $(SRCS_CORRFW:.cxx=.o)
+
+PARFILE       = $(PACKAGE).par
+
+
+lib$(PACKAGE).so: $(OBJS_CORRFW)
+       @echo "Linking" $@ ...
+       @/bin/rm -f $@
+ifeq ($(PLATFORM),macosx)
+       @$(LD) -bundle -undefined $(UNDEFOPT) $(LDFLAGS) $^ -o $@
+else
+       @$(LD) $(SOFLAGS) $(LDFLAGS) $^ -o $@
+endif
+       @chmod a+x $@
+       @echo "done"
+
+%.o:    %.cxx %.h
+       $(CXX) $(CXXFLAGS) $(PACKCXXFLAGS) -c $< -o $@
+
+clean:
+       @rm -f $(OBJS_CORRFW) *.so G__$(PACKAGE).* $(PARFILE)
+
+G__$(PACKAGE).cxx G__$(PACKAGE).h: $(HDRS) $(DHDR)
+       @echo "Generating dictionary ..."
+       rootcint -f $@ -c $(CINTFLAGS) $(ALICEINC) $^
+
+### CREATE PAR FILE
+
+$(PARFILE): $(patsubst %,$(PACKAGE)/%,$(filter-out G__%, $(HDRS_CORRFW) $(SRCS_CORRFW) $(DHDR_CORRFW) Makefile Makefile.arch lib$(PACKAGE).pkg PROOF-INF))
+       @echo "Creating archive" $@ ...
+       @tar cfzh $@ $(PACKAGE)
+       @rm -rf $(PACKAGE)
+       @echo "done"
+
+$(PACKAGE)/Makefile: Makefile #.$(PACKAGE)
+       @echo Copying $< to $@ with transformations
+       @[ -d $(dir $@) ] || mkdir -p $(dir $@)
+       @sed 's/include \$$(ROOTSYS)\/test\/Makefile.arch/include Makefile.arch/' < $^ > $@
+
+$(PACKAGE)/Makefile.arch: $(ROOTSYS)/test/Makefile.arch
+       @echo Copying $< to $@
+       @[ -d $(dir $@) ] || mkdir -p $(dir $@)
+       @cp -a $^ $@
+
+$(PACKAGE)/PROOF-INF: PROOF-INF.$(PACKAGE)
+       @echo Copying $< to $@
+       @[ -d $(dir $@) ] || mkdir -p $(dir $@)
+       @cp -a -r $^ $@
+
+$(PACKAGE)/%: %
+       @echo Copying $< to $@
+       @[ -d $(dir $@) ] || mkdir -p $(dir $@)
+       @cp -a $< $@
+
+test-%.par: %.par
+       @echo "INFO: The file $< is now tested, in case of an error check in par-tmp."
+       @mkdir -p par-tmp
+       @cd par-tmp; tar xfz ../$<;     cd $(subst .par,,$<); PROOF-INF/BUILD.sh
+       @rm -rf par-tmp
+       @echo "INFO: Testing succeeded (already cleaned up)"
diff --git a/CORRFW/Makefile.arch b/CORRFW/Makefile.arch
new file mode 100644 (file)
index 0000000..048e324
--- /dev/null
@@ -0,0 +1,516 @@
+# -*- mode: makefile -*-
+#
+# Makefile containing platform dependencies for ROOT based projects.
+#
+# Copyright (c) 2000 Rene Brun and Fons Rademakers
+#
+# Author: Fons Rademakers, 29/2/2000
+
+ROOTCONFIG   := root-config
+
+ARCH         := $(shell $(ROOTCONFIG) --arch)
+PLATFORM     := $(shell $(ROOTCONFIG) --platform)
+
+CXX           =
+ObjSuf        = o
+SrcSuf        = cxx
+ExeSuf        =
+DllSuf        = so
+OutPutOpt     = -o # keep whitespace after "-o"
+
+ifeq (debug,$(findstring debug,$(ROOTBUILD)))
+OPT           = -g
+OPT2          = -g
+else
+ifneq ($(findstring debug, $(strip $(shell $(ROOTCONFIG) --config))),)
+OPT           = -g
+OPT2          = -g
+else
+OPT           = -O
+OPT2          = -O2
+endif
+endif
+
+ROOTCFLAGS   := $(shell $(ROOTCONFIG) --cflags)
+ROOTLDFLAGS  := $(shell $(ROOTCONFIG) --ldflags)
+ROOTLIBS     := $(shell $(ROOTCONFIG) --libs)
+ROOTGLIBS    := $(shell $(ROOTCONFIG) --glibs)
+HASTHREAD    := $(shell $(ROOTCONFIG) --has-thread)
+
+ifeq ($(ARCH),hpuxacc)
+# HP-UX 10.x with aCC
+CXX           = aCC
+CXXFLAGS      = $(OPT) +Z
+LD            = aCC
+LDFLAGS       = $(OPT) -z
+SOFLAGS       = -b
+endif
+
+ifeq ($(ARCH),hpuxia64acc)
+# HP-UX 11i 1.5 (IA-64) with aCC
+CXX           = aCC
+CXXFLAGS      = +DD64 $(OPT) +Z
+LD            = aCC
+LDFLAGS       = +DD64 $(OPT) -z
+SOFLAGS       = -b
+endif
+
+ifeq ($(ARCH),hpuxgcc)
+# HP-UX 10.x with g++
+CXXFLAGS      = $(OPT) -fPIC
+CXX           = g++
+LD            = g++
+LDFLAGS       = $(OPT)
+SOFLAGS       = -fPIC -shared
+endif
+
+ifeq ($(ARCH),hurddeb)
+# GNU/Hurd
+CXX           = g++
+CXXFLAGS      = $(OPT2) -Wall -fPIC
+LD            = g++
+LDFLAGS       = $(OPT2)
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),aix)
+# IBM AIX xlC 4.x
+CXX           = xlC
+CXXFLAGS      = $(OPT)
+LD            = xlC
+LDFLAGS       = $(OPT)
+SOFLAGS       =
+DllSuf        = a
+endif
+
+ifeq ($(ARCH),aix5)
+# IBM AIX xlC 5.x
+CXX           = xlC
+CXXFLAGS      = $(OPT)
+LD            = xlC
+LDFLAGS       = $(OPT)
+SOFLAGS       =
+DllSuf        = a
+endif
+
+ifeq ($(ARCH),aixgcc)
+# IBM AIX with GCC
+CXX           = g++
+CXXFLAGS      = $(OPT)
+LD            = g++
+LDFLAGS       = $(OPT)
+SOFLAGS       = -shared
+DllSuf        = a
+EXPLLINKLIBS  = $(ROOTLIBS) $(ROOTGLIBS)
+endif
+
+ifeq ($(ARCH),solaris)
+# Solaris CC
+CXX           = /opt/SUNWspro/bin/CC
+CXXFLAGS      = $(OPT) -KPIC
+LD            = /opt/SUNWspro/bin/CC
+LDFLAGS       = $(OPT)
+SOFLAGS       = -G
+endif
+
+ifeq ($(ARCH),solarisCC5)
+# Solaris CC 5.0
+CXX           = CC
+CXXFLAGS      = $(OPT) -KPIC
+LD            = CC
+LDFLAGS       = $(OPT)
+SOFLAGS       = -G
+endif
+
+ifeq ($(ARCH),solarisgcc)
+# Solaris gcc
+CXX           = g++
+CXXFLAGS      = $(OPT) -fPIC
+LD            = g++
+LDFLAGS       = $(OPT)
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),solariskcc)
+# Solaris kcc
+CXX           = KCC --one_instantiation_per_object
+CXXFLAGS      = -O4 -KPIC
+LD            = KCC
+LDFLAGS       = -O4
+SOFLAGS       =
+endif
+
+ifeq ($(ARCH),solarisx86)
+# Solaris CC on Intel
+CXX           = CC
+CXXFLAGS      = $(OPT) -KPIC
+LD            = CC
+LDFLAGS       = $(OPT)
+SOFLAGS       = -G
+endif
+
+ifeq ($(ARCH),sgicc)
+# SGI
+CXX           = CC -n32  -I/usr/include/CC.sgi
+CXXFLAGS      = $(OPT)
+LD            = CC -n32 -LANG:std  -I/usr/include/CC.sgi
+LDFLAGS       = $(OPT)
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),sgicc64)
+# SGI
+CXX           = CC -64  -I/usr/include/CC.sgi
+CXXFLAGS      = $(OPT)
+LD            = CC -64 -LANG:std -I/usr/include/CC.sgi
+LDFLAGS       = $(OPT)
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),sgigcc)
+# SGI 6.x with gcc
+CXX           = g++
+CXXFLAGS      = $(OPT) -Wall -fPIC
+LD            = g++
+LDFLAGS       = $(OPT) -Wl,-u,__builtin_new -Wl,-u,__builtin_delete -Wl,-u,__nw__FUiPv
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),sgin32gcc)
+# SGI 6.x with gcc for n32 ABI
+CXX           = g++
+CXXFLAGS      = $(OPT) -Wall -fPIC
+LD            = g++
+LDFLAGS       = $(OPT) -L/usr/lib32 -Wl,-woff,134 -lgen
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),sgikcc)
+# SGI with KCC
+CXX           = KCC -n32 --one_instantiation_per_object
+CXXFLAGS      = $(OPT)
+LD            = KCC -n32
+LDFLAGS       = $(OPT)
+SOFLAGS       =
+endif
+
+ifeq ($(ARCH),alphagcc)
+# Alpha/OSF with gcc
+CXX           = g++
+CXXFLAGS      = $(OPT2) -Wall -fPIC
+LD            = g++
+LDFLAGS       = $(OPT2)
+SOFLAGS       = -Wl,-expect_unresolved,* -shared
+endif
+
+ifeq ($(ARCH),alphakcc)
+# Alpha/OSF with kai compiler (not yet valid)
+CXX           = KCC --one_instantiation_per_object
+CXXFLAGS      = $(OPT) -fPIC
+LD            = KCC
+LDFLAGS       = $(OPT)
+SOFLAGS       = -Wl,-expect_unresolved,* -shared
+endif
+
+ifeq ($(ARCH),alphacxx6)
+# Alpha/OSF with cxx6
+CXX           = cxx
+CXXFLAGS      = $(OPT)
+LD            = cxx
+LDFLAGS       = $(OPT)
+SOFLAGS       = -shared -nocxxstd -Wl,-expect_unresolved,*,-msym
+endif
+
+ifeq ($(ARCH),linuxdeb2ppc)
+# Debian/Linux on the PowerPC
+CXX           = g++
+CXXFLAGS      = $(OPT2) -Wall -fPIC
+LD            = g++
+LDFLAGS       = $(OPT2)
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),linux)
+# Linux with egcs, gcc 2.9x, gcc 3.x
+CXX           = g++
+CXXFLAGS      = $(OPT2) -Wall -fPIC
+LD            = g++
+LDFLAGS       = $(OPT2)
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),linuxkcc)
+# Linux with the KAI compiler
+CXX           = KCC --one_instantiation_per_object
+CXXFLAGS      = $(OPT) -fPIC +K0
+LD            = KCC
+LDFLAGS       = $(OPT) $(shell $(ROOTCONFIG) --cflags)
+SOFLAGS       =
+endif
+
+ifeq ($(ARCH),linuxicc)
+# Linux with Intel icc compiler
+ICC_MAJOR    := $(shell icc -v 2>&1 | awk '{ if (NR==1) print $$2 }' | \
+                cut -d'.' -f1)
+ICC_MINOR    := $(shell icc -v 2>&1 | awk '{ if (NR==1) print $$2 }' | \
+                cut -d'.' -f2)
+CXX           = icc
+CXXFLAGS      = $(OPT) -fPIC -wd1476
+LD            = icpc
+LDFLAGS       = $(OPT)
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),linuxppcgcc)
+# PPC Linux with gcc and glibc
+CXX           = g++
+CXXFLAGS      = $(OPT2) -Wall -fPIC
+LD            = g++
+LDFLAGS       = $(OPT2)
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),linuxia64gcc)
+# Itanium Linux with gcc 2.9x
+CXX           = g++
+CXXFLAGS      = $(OPT2) -Wall -fPIC
+LD            = g++
+LDFLAGS       = $(OPT2)
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),linuxia64sgi)
+# Itanium Linux with sgiCC
+CXX           = sgiCC
+CXXFLAGS      = $(OPT) -Wall -fPIC
+LD            = gsgiCC
+LDFLAGS       = $(OPT)
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),linuxia64ecc)
+# Itanium Linux with Intel icc (was ecc)
+ICC_MAJOR    := $(shell icc -v 2>&1 | awk '{ if (NR==1) print $$2 }' | \
+                cut -d'.' -f1)
+ICC_MINOR    := $(shell icc -v 2>&1 | awk '{ if (NR==1) print $$2 }' | \
+                cut -d'.' -f2)
+CXX           = icc
+CXXFLAGS      = $(OPT) -fPIC -wd1476
+LD            = icpc
+LDFLAGS       = $(OPT)
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),linuxx8664gcc)
+# AMD Opteron and Intel EM64T (64 bit mode) Linux with gcc 3.x
+CXX           = g++
+CXXFLAGS      = $(OPT2) -Wall -fPIC
+LD            = g++
+LDFLAGS       = $(OPT2)
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),linuxppc64gcc)
+# PPC64 Linux with gcc 3.x
+CXX           = g++
+CXXFLAGS      = $(OPT) -Wall -fPIC
+LD            = g++
+LDFLAGS       = $(OPT)
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),linuxx8664icc)
+# AMD Opteron and Intel EM64T (64 bit mode) Linux with Intel icc compiler
+CXX           = icc
+CXXFLAGS      = $(OPT) -fPIC -wd1476 -wd1572
+LD            = icpc
+LDFLAGS       = $(OPT)
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),linuxalphagcc)
+# Alpha Linux with gcc
+CXX           = g++
+CXXFLAGS      = $(OPT2) -Wall -fPIC
+LD            = g++
+LDFLAGS       = $(OPT2)
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),linuxarm)
+# ARM Linux with egcs
+CXX           = g++
+CXXFLAGS      = $(OPT) -Wall -fPIC
+LD            = g++
+LDFLAGS       = $(OPT)
+SOFLAGS       = -shared
+endif
+
+ifeq ($(ARCH),freebsd4)
+# FreeBSD with glibc
+CXX           = g++
+CXXFLAGS      = $(OPT) -W -Wall -fPIC
+LD            = $(CXX)
+LDFLAGS       = $(OPT)
+SOFLAGS       = -shared -Wl,-x
+endif
+
+ifeq ($(ARCH),freebsd5)
+# FreeBSD with glibc
+CXX           = g++
+CXXFLAGS      = $(OPT) -W -Wall -fPIC
+LD            = $(CXX)
+LDFLAGS       = $(OPT)
+SOFLAGS       = -shared -Wl,-x
+endif
+
+ifeq ($(ARCH),openbsd)
+# OpenBSD with libc
+CXX           = g++
+CXXFLAGS      = $(OPT) -pipe -W -Wall -fPIC
+LD            = g++
+LDFLAGS       = $(OPT)
+SOFLAGS       = -shared -Wl,-x
+endif
+
+ifeq ($(ARCH),macosx)
+# MacOS X with cc (GNU cc 2.95.2 and gcc 3.3)
+MACOSX_MINOR := $(shell sw_vers | sed -n 's/ProductVersion://p' | cut -d . -f 2)
+MACOSXTARGET := MACOSX_DEPLOYMENT_TARGET=10.$(MACOSX_MINOR)
+ifeq ($(MACOSX_MINOR),5)
+MACOSX_MINOR  = 4
+endif
+CXX           = c++
+CXXFLAGS      = $(OPT2) -pipe -Wall -W -Woverloaded-virtual
+LD            = $(MACOSXTARGET) c++
+LDFLAGS       = $(OPT2) -bind_at_load
+# The SOFLAGS will be used to create the .dylib,
+# the .so will be created separately
+DllSuf        = dylib
+UNDEFOPT      = dynamic_lookup
+ifneq ($(MACOSX_MINOR),4)
+ifneq ($(MACOSX_MINOR),3)
+UNDEFOPT      = suppress
+LD            = c++
+endif
+endif
+SOFLAGS       = -dynamiclib -single_module -undefined $(UNDEFOPT)
+endif
+
+ifeq ($(ARCH),macosxicc)
+# MacOS X with Intel icc compiler
+MACOSX_MINOR := $(shell sw_vers | sed -n 's/ProductVersion://p' | cut -d . -f 2)
+MACOSXTARGET := MACOSX_DEPLOYMENT_TARGET=10.$(MACOSX_MINOR)
+ifeq ($(MACOSX_MINOR),5)
+MACOSX_MINOR  = 4
+endif
+CXX           = icc
+CXXFLAGS      = $(OPT) -fPIC -wd1476
+LD            = $(MACOSXTARGET) icpc
+LDFLAGS       = $(OPT)
+# The SOFLAGS will be used to create the .dylib,
+# the .so will be created separately
+DllSuf        = dylib
+SOFLAGS       = -dynamiclib -single_module -undefined dynamic_lookup
+endif
+
+ifeq ($(ARCH),macosx64)
+# MacOS X >= 10.4 with gcc 64 bit mode (GNU gcc 4.*)
+# Only specific option (-m64) comes from root-config
+MACOSX_MINOR := $(shell sw_vers | sed -n 's/ProductVersion://p' | cut -d . -f 2)
+MACOSXTARGET := MACOSX_DEPLOYMENT_TARGET=10.$(MACOSX_MINOR)
+ifeq ($(MACOSX_MINOR),5)
+MACOSX_MINOR  = 4
+endif
+CXX           = c++
+CXXFLAGS      = $(OPT2) -pipe -Wall -W -Woverloaded-virtual
+LD            = $(MACOSXTARGET) c++ -m64
+LDFLAGS       = $(OPT2) -bind_at_load
+# The SOFLAGS will be used to create the .dylib,
+# the .so will be created separately
+DllSuf        = dylib
+SOFLAGS       = -m64 -dynamiclib -single_module -undefined dynamic_lookup
+endif
+
+ifeq ($(ARCH),macosxxlc)
+# MacOS X with IBM xlC compiler
+MACOSX_MINOR := $(shell sw_vers | sed -n 's/ProductVersion://p' | cut -d . -f 2)
+MACOSXTARGET := MACOSX_DEPLOYMENT_TARGET=10.$(MACOSX_MINOR)
+ifeq ($(MACOSX_MINOR),5)
+MACOSX_MINOR  = 4
+endif
+CXX           = xlC
+CXXFLAGS      = $(OPT)
+LD            = $(MACOSXTARGET) xlC
+LDFLAGS       = $(OPT) -Wl,-bind_at_load
+# The SOFLAGS will be used to create the .dylib,
+# the .so will be created separately
+DllSuf        = dylib
+UNDEFOPT      = dynamic_lookup
+ifneq ($(MACOSX_MINOR),4)
+ifneq ($(MACOSX_MINOR),3)
+UNDEFOPT      = suppress
+LD            = xlC
+endif
+endif
+SOFLAGS       = -qmkshrobj -single_module -undefined $(UNDEFOPT)
+endif
+
+ifeq ($(ARCH),win32)
+# Windows with the VC++ compiler
+VC_MAJOR     := $(shell unset VS_UNICODE_OUTPUT; cl.exe 2>&1 | awk '{ if (NR==1) print $$8 }' | \
+                cut -d'.' -f1)
+ObjSuf        = obj
+SrcSuf        = cxx
+ExeSuf        = .exe
+DllSuf        = dll
+OutPutOpt     = -out:
+CXX           = cl
+ifeq (debug,$(findstring debug,$(ROOTBUILD)))
+CXXOPT        = -Z7
+LDOPT         = -debug
+else
+ifneq ($(findstring debug, $(strip $(shell $(ROOTCONFIG) --config))),)
+CXXOPT        = -Z7
+LDOPT         = -debug
+else
+CXXOPT        = -O2
+LDOPT         = -opt:ref
+endif
+endif
+CXXFLAGS      = $(CXXOPT) -nologo -I$(shell $(ROOTCONFIG) --incdir) -FIw32pragma.h
+LD            = link
+LDFLAGS       = $(LDOPT) -nologo
+SOFLAGS       = -DLL
+
+EXPLLINKLIBS  = $(ROOTLIBS) $(ROOTGLIBS)
+ifeq ($(VC_MAJOR),14)
+MT_EXE        = mt -nologo -manifest $@.manifest -outputresource:$@\;1; rm -f $@.manifest
+MT_DLL        = mt -nologo -manifest $@.manifest -outputresource:$@\;2; rm -f $@.manifest
+else
+MT_EXE        =
+MT_DLL        =
+endif
+endif
+
+ifeq ($(ARCH),win32gcc)
+# Windows with gcc
+DllSuf        = dll
+ExeSuf        = .exe
+CXX           = g++
+CXXFLAGS      = $(OPT) -pipe -Wall -Woverloaded-virtual -I/usr/X11R6/include
+LD            = g++
+LDFLAGS       = $(OPT) -Wl,--enable-auto-import -Wl,--enable-runtime-pseudo-reloc \
+               -L/usr/X11R6/lib
+SOFLAGS       = -shared -D_DLL -Wl,--export-all-symbols
+EXPLLINKLIBS  = $(ROOTLIBS) $(ROOTGLIBS)
+endif
+
+ifeq ($(CXX),)
+$(error $(ARCH) invalid architecture)
+endif
+
+CXXFLAGS     += $(ROOTCFLAGS)
+LDFLAGS      += $(ROOTLDFLAGS)
+LIBS          = $(ROOTLIBS) $(SYSLIBS)
+GLIBS         = $(ROOTGLIBS) $(SYSLIBS)
diff --git a/CORRFW/PROOF-INF.CORRFW/BUILD.sh b/CORRFW/PROOF-INF.CORRFW/BUILD.sh
new file mode 100755 (executable)
index 0000000..fc9490a
--- /dev/null
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+make 
diff --git a/CORRFW/PROOF-INF.CORRFW/SETUP.C b/CORRFW/PROOF-INF.CORRFW/SETUP.C
new file mode 100644 (file)
index 0000000..c2138c0
--- /dev/null
@@ -0,0 +1,11 @@
+void SETUP()
+{
+  // Load the CF library
+   gSystem->Load("libCORRFW");
+
+   // Set the include paths
+   gROOT->ProcessLine(".include CORRFW");
+
+   // Set our location, so that other packages can find us
+   gSystem->Setenv("CORRFW_INCLUDE", "CORRFW");
+}
diff --git a/CORRFW/libCORRFW.pkg b/CORRFW/libCORRFW.pkg
new file mode 100644 (file)
index 0000000..6776485
--- /dev/null
@@ -0,0 +1,36 @@
+SRCS = AliCFFrame.cxx \
+       AliCFGrid.cxx \
+       AliCFEffGrid.cxx \
+       AliCFDataGrid.cxx \
+       AliCFContainer.cxx \
+       AliCFManager.cxx \
+       AliCFCutBase.cxx \
+       AliCFEventClassCuts.cxx \
+       AliCFEventGenCuts.cxx \
+       AliCFEventRecCuts.cxx \
+       AliCFParticleGenCuts.cxx \
+       AliCFAcceptanceCuts.cxx \
+       AliCFTrackKineCuts.cxx \
+       AliCFTrackQualityCuts.cxx \
+       AliCFTrackIsPrimaryCuts.cxx \
+       AliCFTrackCutPid.cxx \
+
+CHECKALIEN = $(shell root-config --has-alien)
+ifeq (yes,$(CHECKALIEN))
+PACKCXXFLAGS := $(CXXFLAGS) -DWITHALIEN
+endif
+
+CHECKXML = $(shell root-config --has-xml)
+ifeq (yes,$(CHECKXML))
+PACKCXXFLAGS += $(CXXFLAGS) -DWITHXML
+CINTFLAGS += -DWITHXML
+endif
+
+HDRS:= $(SRCS:.cxx=.h) 
+
+DHDR= CORRFWLinkDef.h
+
+EXPORT:=$(SRCS:.cxx=.h)
+
+
+
diff --git a/CORRFW/test/AliCFSingleTrackTask.C b/CORRFW/test/AliCFSingleTrackTask.C
new file mode 100644 (file)
index 0000000..66d7156
--- /dev/null
@@ -0,0 +1,225 @@
+//DEFINITION OF A FEW CONSTANTS
+const Double_t ymin  = -1.0 ;
+const Double_t ymax  =  1.0 ;
+const Double_t ptmin =  0.0 ;
+const Double_t ptmax =  8.0 ;
+const Int_t    mintrackrefsTPC = 2 ;
+const Int_t    mintrackrefsITS = 3 ;
+const Int_t    charge  = 1 ;
+const Int_t    PDG = 2212; 
+const Int_t    minclustersTPC = 50 ;
+//----------------------------------------------------
+
+Bool_t AliCFSingleTrackTask(
+                           const Bool_t useGrid = 1,
+                           const char * kTagXMLFile="wn.xml", // XML file containing tags
+                           Long64_t     nentries=TChain::kBigNumber
+                           )
+{
+  
+  TBenchmark benchmark;
+  benchmark.Start("AliSingleTrackTask");
+
+  AliLog::SetGlobalDebugLevel(0);
+
+  Load() ; //load the required libraries
+
+  TChain * analysisChain ;
+
+  if (useGrid) { //data located on AliEn
+    TGrid::Connect("alien://") ;    //  Create an AliRunTagCuts and an AliEventTagCuts Object and impose some selection criteria
+    AliRunTagCuts      *runCuts   = new AliRunTagCuts(); 
+    AliEventTagCuts    *eventCuts = new AliEventTagCuts(); 
+    AliLHCTagCuts      *lhcCuts   = new AliLHCTagCuts(); 
+    AliDetectorTagCuts *detCuts   = new AliDetectorTagCuts(); 
+    eventCuts->SetMultiplicityRange(0,20000);
+    //  Create an AliTagAnalysis Object and chain the tags
+    AliTagAnalysis   *tagAna = new AliTagAnalysis(); 
+    tagAna->SetType("ESD");  //for aliroot > v4-05
+    TAlienCollection *coll   = TAlienCollection::Open(kTagXMLFile); 
+    TGridResult      *tagResult = coll->GetGridResult("",0,0);
+    tagResult->Print();
+    tagAna->ChainGridTags(tagResult);
+    //  Create a new esd chain and assign the chain that is returned by querying the tags
+    analysisChain = tagAna->QueryTags(runCuts,lhcCuts,detCuts,eventCuts); 
+  }
+  else {// local data
+    analysisChain = new TChain("esdTree");
+    //here put your input data path
+    analysisChain->Add("AliESDs.root");
+  }
+  
+  
+  Info("AliCFSingleTrackTask",Form("CHAIN HAS %d ENTRIES",(Int_t)analysisChain->GetEntries()));
+
+  //CONTAINER DEFINITION
+  Info("AliCFSingleTrackTask","SETUP CONTAINER");
+  //the sensitive variables, their indices
+  Int_t ipt = 0;
+  Int_t iy  = 1;
+  //Setting up the container grid... 
+  Int_t nstep = 4 ; //number of selection steps MC 
+  const Int_t nvar   = 2 ; //number of variables on the grid:pt,y,phi,vtx
+  const Int_t nbin1  = 8 ; //bins in pt
+  const Int_t nbin2  = 8 ; //bins in y 
+  //arrays for the number of bins in each dimension
+  const Int_t iBin[nvar] ={nbin1,nbin2};
+  //arrays for lower bounds :
+  Float_t binLim1[nbin1+1];
+  Float_t binLim2[nbin2+1];
+  //values for bin lower bounds
+  for(Int_t i=0; i<=nbin1; i++) binLim1[i]=(Float_t)ptmin + (ptmax-ptmin)/nbin1*(Float_t)i ; 
+  for(Int_t i=0; i<=nbin2; i++) binLim2[i]=(Float_t)ymin  + (ymax-ymin)  /nbin2*(Float_t)i ;
+  //one "container" for MC
+  AliCFContainer* container = new AliCFContainer("container","container for tracks",nstep,nvar,iBin);
+  //setting the bin limits
+  container -> SetBinLimits(ipt,binLim1);
+  container -> SetBinLimits(iy,binLim2);
+
+
+  //CREATE THE  CUTS -----------------------------------------------
+  //Particle-Level cuts:  
+
+  // Gen-Level kinematic cuts
+  AliCFTrackKineCuts *mcKineCuts = new AliCFTrackKineCuts("mcKineCuts","MC-level kinematic cuts");
+  mcKineCuts->SetPtRange(ptmin,ptmax);
+  mcKineCuts->SetRapidityRange(ymin,ymax);
+  mcKineCuts->SetChargeMC(charge);
+
+  AliCFParticleGenCuts* mcGenCuts = new AliCFParticleGenCuts("mcGenCuts","MC particle generation cuts");
+  mcGenCuts->SetRequireIsPrimary();
+  mcGenCuts->SetRequirePdgCode(PDG);
+
+  //Acceptance Cuts
+  AliCFAcceptanceCuts *mcAccCuts = new AliCFAcceptanceCuts("mcAccCuts","MC acceptance cuts");
+  mcAccCuts->SetMinNHitITS(mintrackrefsITS);
+  mcAccCuts->SetMinNHitTPC(mintrackrefsTPC);
+
+  // Rec-Level kinematic cuts
+  AliCFTrackKineCuts *recKineCuts = new AliCFTrackKineCuts("recKineCuts","rec-level kine cuts");
+  recKineCuts->SetPtRange(ptmin,ptmax);
+  recKineCuts->SetRapidityRange(ymin,ymax);
+  recKineCuts->SetChargeRec(charge);
+  // QA histograms for rec-level kinematic cuts
+  recKineCuts->SetQAOn(kTRUE);
+
+  AliCFTrackQualityCuts *recQualityCuts = new AliCFTrackQualityCuts("recQualityCuts","rec-level quality cuts");
+  recQualityCuts->SetMinNClusterTPC(minclustersTPC);
+  recQualityCuts->SetRequireITSRefit(kTRUE);
+  // QA histograms for rec-level quality cuts
+  recQualityCuts->SetQAOn(kTRUE);
+
+  AliCFTrackIsPrimaryCuts *recIsPrimaryCuts = new AliCFTrackIsPrimaryCuts("recIsPrimaryCuts","rec-level isPrimary cuts");
+  recIsPrimaryCuts->SetMaxNSigmaToVertex(3);
+  // QA histograms for rec-level primary-check cuts
+  recIsPrimaryCuts->SetQAOn(kTRUE);
+
+  AliCFTrackCutPid* cutPID = new AliCFTrackCutPid("cutPID","ESD_PID") ;
+  Double_t prior[AliPID::kSPECIES] = {0.0244519,
+                                     0.0143988,
+                                     0.805747 ,
+                                     0.0928785,
+                                     0.0625243 };
+  cutPID->SetPriors(prior);
+  cutPID->SetProbabilityCut(0.0);
+  cutPID->SetDetectors("