New task to produce lightweight events for correlation analysis
authorekryshen <evgeny.kryshen@cern.ch>
Mon, 10 Mar 2014 16:16:56 +0000 (17:16 +0100)
committermkrzewic <mikolaj.krzewicki@cern.ch>
Tue, 11 Mar 2014 20:32:35 +0000 (21:32 +0100)
PWGCF/CMakelibPWGCFCorrelationsBase.pkg
PWGCF/Correlations/Base/AliAnalysisTaskCFTree.cxx [new file with mode: 0644]
PWGCF/Correlations/Base/AliAnalysisTaskCFTree.h [new file with mode: 0644]
PWGCF/Correlations/Base/AliCFParticle.cxx [new file with mode: 0644]
PWGCF/Correlations/Base/AliCFParticle.h [new file with mode: 0644]
PWGCF/Correlations/macros/cftree/AddTaskCFTree.C [new file with mode: 0644]
PWGCF/PWGCFCorrelationsBaseLinkDef.h

index b31b9f7..cb13778 100644 (file)
@@ -30,6 +30,8 @@ set ( SRCS
     Correlations/Base/AliUEHistograms.cxx
     Correlations/Base/AliUEHist.cxx
     Correlations/Base/AliAnalyseLeadingTrackUE.cxx
+    Correlations/Base/AliCFParticle.cxx
+    Correlations/Base/AliAnalysisTaskCFTree.cxx
     )
 
 string ( REPLACE ".cxx" ".h" HDRS "${SRCS}" )
diff --git a/PWGCF/Correlations/Base/AliAnalysisTaskCFTree.cxx b/PWGCF/Correlations/Base/AliAnalysisTaskCFTree.cxx
new file mode 100644 (file)
index 0000000..c38105e
--- /dev/null
@@ -0,0 +1,337 @@
+/**************************************************************************
+ * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ *                                                                        *
+ * Author: The ALICE Off-line Project.                                    *
+ * Contributors are mentioned in the code where appropriate.              *
+ *                                                                        *
+ * Permission to use, copy, modify and distribute this software and its   *
+ * documentation strictly for non-commercial purposes is hereby granted   *
+ * without fee, provided that the above copyright notice appears in all   *
+ * copies and that both the copyright notice and this permission notice   *
+ * appear in the supporting documentation. The authors make no claims     *
+ * about the suitability of this software for any purpose. It is          *
+ * provided "as is" without express or implied warranty.                  *
+ **************************************************************************/
+
+// Analysis task to produce trees of lightweight events
+// evgeny.kryshen@cern.ch
+
+// aliroot
+#include "AliAnalysisTaskCFTree.h"
+#include "AliCFParticle.h"
+#include "AliAnalysisManager.h"
+#include "AliInputEventHandler.h"
+#include "AliESDEvent.h"
+#include "AliAODEvent.h"
+#include "AliMCEvent.h"
+#include "AliHeader.h"
+#include "AliESDHeader.h"
+#include "AliAODHeader.h"
+#include "AliAODMCHeader.h"
+#include "AliGenEventHeader.h"
+#include "AliGenCocktailEventHeader.h"
+#include "AliAODTrack.h"
+#include "AliESDtrack.h"
+#include "AliMCParticle.h"
+#include "AliAODMCParticle.h"
+#include "AliExternalTrackParam.h"
+#include "AliCentrality.h"
+#include "AliAnalysisFilter.h"
+#include "AliPIDResponse.h"
+#include "AliTPCPIDResponse.h"
+// root
+#include "TMath.h"
+#include "TFile.h"
+#include "TList.h"
+#include "TH1I.h"
+#include "TChain.h"
+#include "TTree.h"
+#include "TClonesArray.h"
+ClassImp(AliAnalysisTaskCFTree)
+
+//-----------------------------------------------------------------------------
+AliAnalysisTaskCFTree::AliAnalysisTaskCFTree(const char* name) :
+  AliAnalysisTask(name,""),
+  fDebug(0),
+  fMode(0),
+  fInputHandler(0x0),
+  fMcHandler(0x0),
+  fTrackFilter(0x0),
+  fHybridConstrainedMask(0),
+  fTPConlyConstrainedMask(0),
+  fPIDResponse(0x0),
+  fListOfHistos(0x0),
+  fEventStatistics(0x0),
+  fTree(0x0),
+  fParticles(0x0),
+  fField(0),
+  fCentrality(0),
+  fZvtx(0),
+  fRunNumber(0),
+  fPeriod(0),
+  fOrbit(),
+  fBc(),
+  fSelectMask(0),
+  fSelectBit(AliVEvent::kMB),
+  fZVertexCut(10.),
+  fnTracksVertex(1),
+  fCentralityMethod("V0M"),
+  fTrackFilterBit(0xffffffff),
+  fTrackEtaCut(1.0),
+  fPtMin(0.15),
+  fSharedClusterCut(0.4),
+  fCrossedRowsCut(100),
+  fFoundFractionCut(0.8)
+{
+  Info("AliAnalysisTaskCFTree","Calling Constructor");
+  DefineInput(0,TChain::Class());
+  DefineOutput(0,TList::Class());
+  DefineOutput(1,TTree::Class());
+}
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+void AliAnalysisTaskCFTree::ConnectInputData(Option_t* /*option*/){
+  fInputHandler = dynamic_cast<AliInputEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+  fMcHandler    = dynamic_cast<AliInputEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
+}
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+void AliAnalysisTaskCFTree::CreateOutputObjects(){
+  fListOfHistos = new TList();
+  fListOfHistos->SetOwner();
+  fEventStatistics = new TH1I("fEventStatistics","",10,0,10);
+  fEventStatistics->SetBit(TH1::kCanRebin);
+
+  fListOfHistos->Add(fEventStatistics);
+
+  fParticles = new TClonesArray("AliCFParticle",2000);
+  // create file-resident tree
+  TDirectory *owd = gDirectory;
+  OpenFile(1);
+  fTree = new TTree("events","events");
+  owd->cd();
+  fTree->Branch("cent",&fCentrality);
+  fTree->Branch("zvtx",&fZvtx);
+  fTree->Branch("field",&fField);
+  fTree->Branch("run",&fRunNumber);
+  fTree->Branch("period",&fPeriod);
+  fTree->Branch("orbit",&fOrbit);
+  fTree->Branch("bc",&fBc);
+  fTree->Branch("mask",&fSelectMask);
+  fTree->Branch("particles",&fParticles);
+  PostData(0,fListOfHistos);
+  PostData(1,fTree);
+}
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+void AliAnalysisTaskCFTree::Exec(Option_t *){
+  fParticles->Clear();
+  
+  fEventStatistics->Fill("before cuts",1);
+  
+  AliVEvent* event = fInputHandler->GetEvent();
+  if (!event) return;
+  fEventStatistics->Fill("after event check",1);
+  
+  fPIDResponse = fInputHandler->GetPIDResponse();
+  
+  fSelectMask = fInputHandler->IsEventSelected();
+  if (!(fSelectMask & fSelectBit)) return;
+  fEventStatistics->Fill("after trigger selection",1);
+  fRunNumber  = event->GetRunNumber();
+  fPeriod     = event->GetPeriodNumber();
+  fOrbit      = event->GetOrbitNumber();
+  fBc         = event->GetBunchCrossNumber();
+  fField      = event->GetMagneticField();
+  fCentrality = event->GetCentrality()->GetCentralityPercentile(fCentralityMethod);
+  
+  if (fMode==0){ // Data analysis
+    const AliVVertex* vertex  = event->GetPrimaryVertex();
+    if (!vertex) return;
+    fZvtx  = vertex->GetZ();
+    TString name(vertex->GetName());
+    if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex")) return; // Reject TPC only vertex
+    fEventStatistics->Fill("after rejection of TPC only vertex",1);
+    if (TMath::Abs(fZvtx) >= fZVertexCut || vertex->GetNContributors()<fnTracksVertex)  return;
+    fEventStatistics->Fill("after vertex selection",1);
+    
+    for (Int_t ipart=0;ipart<event->GetNumberOfTracks();ipart++){
+      AliVTrack* track = (AliVTrack*) event->GetTrack(ipart);
+      if (!track) continue;
+      UInt_t mask = GetFilterMap(track);
+      if (!(mask & fTrackFilterBit)) continue;
+
+      if (track->InheritsFrom("AliAODTrack")) AddTrack(track,mask,0);
+      else if (track->InheritsFrom("AliESDtrack")) {
+        if (mask)                           AddTrack(track,mask,1);
+        if (mask & fHybridConstrainedMask)  AddTrack(track,mask,2);
+        if (mask & fTPConlyConstrainedMask) AddTrack(track,mask,3);
+      }
+    }
+  }
+  else { // MC analysis
+    AliMCEvent* mcEvent = 0;
+    TClonesArray* mcTracks = 0;
+    Int_t nPrimGen = 0;
+    Int_t nProduced = 0;
+
+    mcEvent = fMcHandler ? fMcHandler->MCEvent() : 0;
+    mcTracks = (TClonesArray*) event->FindListObject(AliAODMCParticle::StdBranchName());
+    
+    if (!mcEvent && !mcTracks) { printf("No mc object found\n"); return; }
+    fEventStatistics->Fill("after mc objects check",1);
+
+    if (mcEvent) {
+      AliHeader* header = (AliHeader*) mcEvent->Header();
+      AliGenCocktailEventHeader* cocktailHeader = dynamic_cast<AliGenCocktailEventHeader*> (header->GenEventHeader());
+      AliGenEventHeader* mcHeader = dynamic_cast<AliGenEventHeader*> (cocktailHeader ? cocktailHeader->GetHeaders()->First() : header->GenEventHeader());
+      nProduced = mcEvent->GetNumberOfTracks();
+      nPrimGen = mcHeader->NProduced();
+      fZvtx = mcEvent->GetPrimaryVertex()->GetZ();
+    } else if (mcTracks) {
+      AliAODMCHeader* mcHeader = (AliAODMCHeader*) event->FindListObject(AliAODMCHeader::StdBranchName());
+      nProduced = mcTracks->GetEntriesFast();
+      nPrimGen = mcHeader->GetCocktailHeaders() ? mcHeader->GetCocktailHeader(0)->NProduced() : nProduced;
+      fZvtx = mcHeader->GetVtxZ();
+    } else return;
+    fEventStatistics->Fill("after mc header check",1);
+
+    if (TMath::Abs(fZvtx)>fZVertexCut) return;
+    fEventStatistics->Fill("after MC vertex cut",1);
+
+    const AliVVertex* vertex = event->GetPrimaryVertex();
+    if (!vertex) return;
+    fEventStatistics->Fill("after check for vertex object",1);
+    TString name(vertex->GetName());
+    if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex")) fZvtx=1000; // Reject TPC only vertex
+    fEventStatistics->Fill("after rejection of TPC only vertex",1);
+    if (vertex->GetNContributors()<fnTracksVertex)  fZvtx=-1000;
+    fEventStatistics->Fill("after check for vertex contributors",1);
+    
+    UInt_t* masks = new UInt_t[nProduced];
+    for (Int_t i=0;i<nProduced;i++) masks[i]=0;
+    
+    // Loop over reconstructed tracks to set masks
+    for (Int_t ipart=0;ipart<event->GetNumberOfTracks();ipart++){
+      AliVTrack* part = (AliVTrack*) event->GetTrack(ipart);
+      if (!part) continue;
+      Int_t label = TMath::Abs(part->GetLabel());
+      if (label>=nProduced) continue;
+      masks[label] |= GetFilterMap(part);
+    }
+    
+    // Loop over mc tracks to be stored
+    for (Int_t ipart=0;ipart<nProduced;ipart++){
+      AliVParticle* part = 0;
+      Bool_t isPrimary = 0;
+      if (mcTracks) { // AOD analysis
+        AliAODMCParticle* particle = (AliAODMCParticle*) mcTracks->At(ipart);
+        if (!particle) continue;
+        // skip injected signals
+        AliAODMCParticle* mother = particle;
+        while (!mother->IsPrimary()) mother = (AliAODMCParticle*) mcTracks->At(mother->GetMother());
+        if (mother->GetLabel()>=nPrimGen) continue;
+        part = particle;
+        // check for primary
+        isPrimary = particle->IsPhysicalPrimary();
+      } else { // ESD analysis
+        AliMCParticle* particle = (AliMCParticle*) mcEvent->GetTrack(ipart);
+        if (!particle) continue;
+        // skip injected signals
+        AliMCParticle* mother = particle;
+        while (mother->GetMother()>=0) mother = (AliMCParticle*) mcEvent->GetTrack(mother->GetMother());
+        if (mother->GetLabel()>=nPrimGen) continue;
+        part = particle;
+        // check for primary
+        isPrimary = mcEvent->IsPhysicalPrimary(ipart);
+      }
+      
+      // store only primaries and all reconstructed (non-zero mask)
+      Int_t mask = masks[ipart];
+      if (isPrimary) mask |= (1 << 30);
+      if (!mask) continue; 
+      AddTrack(part,mask);
+    }
+    delete[] masks;
+  }
+  fTree->Fill();
+  PostData(0,fListOfHistos);
+  PostData(1,fTree);
+}
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+UInt_t AliAnalysisTaskCFTree::GetFilterMap(AliVParticle* particle){
+  UInt_t mask = 0;
+  if (particle->InheritsFrom("AliAODTrack")) {
+    AliAODTrack* part = (AliAODTrack*) particle;
+    mask = part->GetFilterMap();
+    Double_t nCrossedRaws      = part->GetTPCNCrossedRows();
+    Double_t nFindableClusters = part->GetTPCNclsF();
+    Double_t nSharedClusters   = part->GetTPCnclsS();
+    Double_t nClusters         = part->GetTPCncls();
+    Bool_t itsRefit            = part->GetStatus() & AliVTrack::kITSrefit;
+    if (nCrossedRaws/nFindableClusters > fFoundFractionCut) mask |= (1 << 26);
+    if (nCrossedRaws>fCrossedRowsCut)                       mask |= (1 << 27);
+    if (itsRefit)                                           mask |= (1 << 28);
+    if (nSharedClusters/nClusters<=fSharedClusterCut)       mask |= (1 << 29);
+    if (part->GetLabel()<0)                                 mask |= (1 << 31);
+  } else if (particle->InheritsFrom("AliESDtrack")){
+    AliESDtrack* part = (AliESDtrack*) particle;
+    if (!fTrackFilter) AliFatal("Track filter undefined");
+    mask |= fTrackFilter->IsSelected(part);
+  }
+  
+  return mask;
+}
+//-----------------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------------
+AliCFParticle* AliAnalysisTaskCFTree::AddTrack(AliVParticle* part, UInt_t mask, UInt_t flag){
+
+  // skip neutral mc particles
+  Char_t charge = part->Charge();
+  if (charge==0) return NULL;
+  
+  // set pt,eta,phi
+  Float_t pt=0,eta=0,phi=0;
+  if (flag==0 || flag==1){ // AOD, MC or Global ESD tracks
+    pt  = part->Pt();
+    eta = part->Eta();
+    phi = part->Phi();
+    if  (flag==1) mask &= (~fHybridConstrainedMask) & (~fTPConlyConstrainedMask);
+  } 
+  else if (flag==2) { // Hybrid constrained tracks (ESD)
+    AliESDtrack* track = (AliESDtrack*) part;
+    const AliExternalTrackParam* param = track->GetConstrainedParam();
+    pt  = param->Pt();
+    eta = param->Eta();
+    phi = param->Phi();
+    mask &= fHybridConstrainedMask;
+  } 
+  else if (flag==3) { // TPC only constrained tracks (ESD)
+    AliESDtrack* track = (AliESDtrack*) part;
+    AliESDtrack tpcTrack;
+    if (!track->FillTPCOnlyTrack(tpcTrack)) return NULL;
+    AliExternalTrackParam param;
+    const AliESDVertex* vtxSPD = ((AliESDEvent*) fInputHandler->GetEvent())->GetPrimaryVertexSPD();
+    if (!tpcTrack.RelateToVertexTPC(vtxSPD,fField,1.e30,&param)) return NULL;
+    pt  = param.Pt();
+    eta = param.Eta();
+    phi = param.Phi();
+    mask &= fTPConlyConstrainedMask;
+  }
+
+  // kinematic cuts
+  if (pt < fPtMin || TMath::Abs(eta) > fTrackEtaCut) return NULL;
+
+  return new ((*fParticles)[fParticles->GetEntriesFast()]) AliCFParticle(pt,eta,phi,charge,mask);
+}
diff --git a/PWGCF/Correlations/Base/AliAnalysisTaskCFTree.h b/PWGCF/Correlations/Base/AliAnalysisTaskCFTree.h
new file mode 100644 (file)
index 0000000..93567f0
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef AliAnalysisTaskCFTree_h
+#define AliAnalysisTaskCFTree_h
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+// Analysis task to produce trees of lightweight events
+// evgeny.kryshen@cern.ch
+
+#include "AliAnalysisTask.h"
+class AliInputEventHandler;
+class TList;
+class TH1I;
+class TTree;
+class TClonesArray;
+class AliAnalysisFilter;
+class AliPIDResponse;
+class AliVParticle;
+class AliCFParticle;
+
+class AliAnalysisTaskCFTree : public AliAnalysisTask {
+ public:
+  AliAnalysisTaskCFTree(const char* name="AliAnalysisTaskCFTree");
+  virtual ~AliAnalysisTaskCFTree(){};
+  virtual void ConnectInputData(Option_t *);
+  virtual void CreateOutputObjects();
+  virtual void Exec(Option_t *option);
+
+  void SetTrackFilter(AliAnalysisFilter* filter) { fTrackFilter = filter; }
+  void SetHybridConstrainedMask(UInt_t mask)  { fHybridConstrainedMask = mask; }
+  void SetTPConlyConstrainedMask(UInt_t mask) { fTPConlyConstrainedMask = mask; }
+  void SetDebug(Int_t val)              { fDebug = val; }
+  void SetMode(Int_t val)               { fMode = val; }
+  // Event cut setters
+  void SetEventSelectionBit(UInt_t val) { fSelectBit = val; }
+  void SetZVertex(Float_t val)          { fZVertexCut = val; }
+  void SetTracksInVertex(Int_t val)     { fnTracksVertex = val; }
+  void SetCentralityMethod(char* val)   { fCentralityMethod = val; }
+  // Track cut setters
+  void SetTrackFilterBit(UInt_t val)    { fTrackFilterBit = val; }
+  void SetTrackEtaCut(Float_t val)      { fTrackEtaCut = val; }
+  void SetPtMin(Float_t val)            { fPtMin = val; } 
+  void SetSharedClusterCut(Float_t val) { fSharedClusterCut = val;  }
+  void SetCrossedRowsCut(Int_t val)     { fCrossedRowsCut = val; }
+  void SetFoundFractionCut(Float_t val) { fFoundFractionCut = val;  }
+
+ protected:
+  AliAnalysisTaskCFTree(const  AliAnalysisTaskCFTree &task);
+  AliAnalysisTaskCFTree& operator=(const  AliAnalysisTaskCFTree &task);
+
+  UInt_t GetFilterMap(AliVParticle* part);
+  AliCFParticle* AddTrack(AliVParticle* track, UInt_t mask, UInt_t flag=0);
+
+  Int_t fDebug;               // debug level
+  Int_t fMode;                // Analysis mode: 0 - data, 1 - mc
+  AliInputEventHandler* fInputHandler; // AOD or ESD input handler 
+  AliInputEventHandler* fMcHandler;    // MC input handler (ESD)
+  AliAnalysisFilter* fTrackFilter;     // track filter used in ESD analysis
+  UInt_t fHybridConstrainedMask;       // Filter mask for hybrid constrained tracks (ESD analysis)
+  UInt_t fTPConlyConstrainedMask;      // Filter mask for TPConly constrained tracks (ESD analysis)
+  AliPIDResponse* fPIDResponse;        //!
+  TList* fListOfHistos;       //! list of output histograms
+  TH1I*  fEventStatistics;    //! cut-by-cut counter of events
+  TTree* fTree;               //! output tree
+  // Tree variables
+  TClonesArray* fParticles;   //! tree var: selected AliCFParticles
+  Float_t fField;             //  tree var: magnetic field value
+  Float_t fCentrality;        //  tree var: centrality
+  Float_t fZvtx;              //  tree var: z-vertex
+  Int_t fRunNumber;           //  tree var: run number
+  UInt_t fPeriod;             //  tree var: period
+  UInt_t fOrbit;              //  tree var: orbit
+  UShort_t fBc;               //  tree var: bunch crossing
+  UInt_t fSelectMask;         //  tree var: physics selection mask
+  // Event cuts
+  UInt_t fSelectBit;          // event selection bit
+  Float_t fZVertexCut;        // Z-vertex cut
+  Int_t fnTracksVertex;       // min number of vertex contributors
+  TString  fCentralityMethod; // method to determine centrality
+  // Track cuts
+  UInt_t fTrackFilterBit;     // track filter bits to be stored
+  Float_t fTrackEtaCut;       // maximum abs(eta) cut
+  Float_t fPtMin;             // minimum pt cut
+  Float_t fSharedClusterCut;  // cut on shared clusters
+  Int_t   fCrossedRowsCut;    // cut on crossed rows
+  Float_t fFoundFractionCut;  // cut on crossed rows/findable clusters
+
+  ClassDef(AliAnalysisTaskCFTree,1);
+};
+#endif
+
diff --git a/PWGCF/Correlations/Base/AliCFParticle.cxx b/PWGCF/Correlations/Base/AliCFParticle.cxx
new file mode 100644 (file)
index 0000000..8053833
--- /dev/null
@@ -0,0 +1,21 @@
+/**************************************************************************
+ * 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.                  *
+ **************************************************************************/
+
+// Class to store basic track parameters in the tree
+// evgeny.kryshen@cern.ch
+
+
+#include "AliCFParticle.h"
+ClassImp(AliCFParticle)
diff --git a/PWGCF/Correlations/Base/AliCFParticle.h b/PWGCF/Correlations/Base/AliCFParticle.h
new file mode 100644 (file)
index 0000000..11ea1ab
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef AliCFParticle_h
+#define AliCFParticle_h
+
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice                               */
+
+// Class to store basic track parameters in the tree
+// evgeny.kryshen@cern.ch
+
+
+#include "AliVParticle.h"
+#include "AliLog.h"
+
+class AliCFParticle : public AliVParticle {
+ public:
+  AliCFParticle():AliVParticle(),fPt(0),fEta(0),fPhi(0),fCharge(0),fMask(0)
+  {
+  }
+  AliCFParticle(Float_t pt, Float_t eta, Float_t phi, Short_t charge, UInt_t mask)
+  :AliVParticle(),fPt(pt),fEta(eta),fPhi(phi),fCharge(charge),fMask(mask)
+  {
+  }
+  virtual ~AliCFParticle(){}
+  virtual Double_t Pt()    const { return fPt;      }
+  virtual Double_t Phi()   const { return fPhi;     }
+  virtual Double_t Eta()   const { return fEta;     }
+  virtual Short_t Charge() const { return fCharge;  }
+  virtual UInt_t Mask()    const { return fMask;    }
+  
+  virtual Double_t Px() const { AliFatal("Not implemented"); return 0; }
+  virtual Double_t Py() const { AliFatal("Not implemented"); return 0; }
+  virtual Double_t Pz() const { AliFatal("Not implemented"); return 0; }
+  virtual Double_t P()  const { AliFatal("Not implemented"); return 0; }
+  virtual Bool_t   PxPyPz(Double_t[3]) const { AliFatal("Not implemented"); return 0; }
+
+  virtual Double_t Xv() const { AliFatal("Not implemented"); return 0; }
+  virtual Double_t Yv() const { AliFatal("Not implemented"); return 0; }
+  virtual Double_t Zv() const { AliFatal("Not implemented"); return 0; }
+  virtual Bool_t   XvYvZv(Double_t[3]) const { AliFatal("Not implemented"); return 0; }
+
+  virtual Double_t OneOverPt()  const { AliFatal("Not implemented"); return 0; }
+  virtual Double_t Theta()      const { AliFatal("Not implemented"); return 0; }
+  virtual Double_t E()          const { AliFatal("Not implemented"); return 0; }
+  virtual Double_t M()          const { AliFatal("Not implemented"); return 0; }
+  virtual Double_t Y()          const { AliFatal("Not implemented"); return 0; }
+  virtual Int_t   GetLabel()    const { AliFatal("Not implemented"); return 0; }
+  
+  virtual Int_t   PdgCode()     const { AliFatal("Not implemented"); return 0; }
+  virtual const Double_t *PID() const { AliFatal("Not implemented"); return 0; }
+
+  virtual Bool_t IsEqual(const TObject* obj) const { return (obj->GetUniqueID() == GetUniqueID()); }
+
+  virtual void SetPhi(Double_t phi) { fPhi = phi; }
+
+ protected:
+  Float_t fPt;
+  Float_t fEta;
+  Float_t fPhi;
+  Short_t fCharge;
+  UInt_t fMask;     // Filter bit mask
+  ClassDef(AliCFParticle,1);
+};
+
+#endif
+
diff --git a/PWGCF/Correlations/macros/cftree/AddTaskCFTree.C b/PWGCF/Correlations/macros/cftree/AddTaskCFTree.C
new file mode 100644 (file)
index 0000000..c6fc773
--- /dev/null
@@ -0,0 +1,31 @@
+AliAnalysisTaskCFTree *AddTaskCFTree(
+    Int_t analysisMode = 0,
+    UInt_t selectionBit = AliVEvent::kMB,
+    Double_t zVtxMax = 10,
+    Double_t etaMax = 1,
+    Double_t ptMin = 0.15,
+    const char* outputFileName = 0,
+    const char* folderName = "CorrelationTree")
+{
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+  if (!mgr) {
+    ::Error("AddTaskPhiCorrelations", "No analysis manager to connect to.");
+    return NULL;
+  }  
+  
+  AliAnalysisTaskCFTree* ana = new AliAnalysisTaskCFTree();
+  ana->SetMode(analysisMode);
+  ana->SetEventSelectionBit(AliVEvent::kMB);
+  ana->SetZVertex(zVtxMax);
+  ana->SetTrackEtaCut(etaMax);
+  ana->SetPtMin(ptMin);
+  mgr->AddTask(ana);
+  
+  if (!outputFileName) outputFileName = AliAnalysisManager::GetCommonFileName();
+  AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("histos", TList::Class(),AliAnalysisManager::kOutputContainer,Form("%s:%s", outputFileName, folderName));
+  AliAnalysisDataContainer *coutput2 = mgr->CreateContainer("events", TTree::Class(),AliAnalysisManager::kOutputContainer,Form("%s:%s", outputFileName, folderName));
+  mgr->ConnectInput  (ana, 0, mgr->GetCommonInputContainer());
+  mgr->ConnectOutput (ana, 0, coutput1);
+  mgr->ConnectOutput (ana, 1, coutput2);
+  return ana;
+}
index 775eb11..541c227 100644 (file)
@@ -7,5 +7,7 @@
 #pragma link C++ class AliUEHist+;
 #pragma link C++ class AliUEHistograms+;
 #pragma link C++ class AliAnalyseLeadingTrackUE+;
+#pragma link C++ class AliCFParticle+;
+#pragma link C++ class AliAnalysisTaskCFTree+;
 
 #endif