which included commits to RCS files with non-trunk default branches.
--- /dev/null
+/**************************************************************************
+ * 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 ;
+}
--- /dev/null
+/**************************************************************************
+ * 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
--- /dev/null
+/* $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);
+}
--- /dev/null
+#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
+
--- /dev/null
+/**************************************************************************
+ * 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
+ //
+}
--- /dev/null
+#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
--- /dev/null
+/* $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;
+
+}
--- /dev/null
+#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
+
--- /dev/null
+/* $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;
+}
--- /dev/null
+#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
+
--- /dev/null
+/**************************************************************************
+ * 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]);
+ }
+}
--- /dev/null
+#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
--- /dev/null
+/**************************************************************************
+ * 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);
+
+}
--- /dev/null
+
+#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
--- /dev/null
+/**************************************************************************
+ * 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);
+
+}
--- /dev/null
+#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
--- /dev/null
+/* $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;
+}
--- /dev/null
+#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
+
--- /dev/null
+/* $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;
+
+}
--- /dev/null
+#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
+
--- /dev/null
+/**************************************************************************
+ * 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;
+}
+
+
--- /dev/null
+#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
--- /dev/null
+/**************************************************************************
+ * 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 ;
+}
--- /dev/null
+/**************************************************************************
+ * 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
--- /dev/null
+//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+");
+}
--- /dev/null
+/**************************************************************************
+ * 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
--- /dev/null
+/**************************************************************************
+ * 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
--- /dev/null
+/**************************************************************************
+ * 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]);
+ }
+ }
+}
--- /dev/null
+/**************************************************************************
+ * 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
+
--- /dev/null
+/**************************************************************************
+ * 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]);
+ }
+}
--- /dev/null
+/**************************************************************************
+ * 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
--- /dev/null
+/**************************************************************************
+ * 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]);
+ }
+}
--- /dev/null
+/**************************************************************************
+ * 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
--- /dev/null
+/**************************************************************************
+ * 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]);
+ }
+}
--- /dev/null
+/**************************************************************************
+ * 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
--- /dev/null
+#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
--- /dev/null
+
+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)"
--- /dev/null
+# -*- 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)
--- /dev/null
+#! /bin/sh
+
+make
--- /dev/null
+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");
+}
--- /dev/null
+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)
+
+
+
--- /dev/null
+//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("