]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWGDQ/dielectron/AliAnalysisTaskReducedTree.cxx
update from pr task : sjena
[u/mrichter/AliRoot.git] / PWGDQ / dielectron / AliAnalysisTaskReducedTree.cxx
index a26f07187ce953958a5996e4724eb8910f61c085..685ee9b061d86a633e6b9f9879c1bc5b012af0e5 100644 (file)
 #include <AliVEvent.h>
 #include <AliESDEvent.h>
 #include <AliAODEvent.h>
+#include <AliESDHeader.h>
+#include <AliAODHeader.h>
 #include <AliAODTrack.h>
+//#include <AliAODForwardMult.h>
+//#include <AliForwardUtil.h>
 #include <AliTriggerAnalysis.h>
 #include <AliESDtrackCuts.h>
 #include <AliVZDC.h>
 #include <AliESDv0.h>
 #include <AliESDv0Cuts.h>
+#include <AliESDv0KineCuts.h>
+#include <AliESDFMD.h>
 #include <AliVCluster.h>
+#include <AliAODTracklets.h>
+#include <AliMultiplicity.h>
+#include <AliPIDResponse.h>
 #include "AliDielectron.h"
 #include "AliDielectronHistos.h"
 #include "AliDielectronMC.h"
 #include "AliReducedEvent.h"
 #include "AliAnalysisTaskReducedTree.h"
 
+#include <iostream>
+using std::cout;
+using std::endl;
+
 ClassImp(AliAnalysisTaskReducedTree)
 
 
@@ -63,18 +76,30 @@ AliAnalysisTaskReducedTree::AliAnalysisTaskReducedTree() :
   fFillTrackInfo(kTRUE),
   fFillDielectronInfo(kTRUE),
   fFillV0Info(kTRUE),
+  fFillGammaConversions(kTRUE),
+  fFillK0s(kTRUE),
+  fFillLambda(kTRUE),
+  fFillALambda(kTRUE),
   fFillCaloClusterInfo(kTRUE),
+  fFillFMDSectorInfo(kFALSE),
+  fFillFMDChannelInfo(kFALSE),
+  //fFillCorrectedFMDInfo(kTRUE),
   fFillFriendInfo(kTRUE),
   fEventFilter(0x0),
   fTrackFilter(0x0),
   fFlowTrackFilter(0x0),
   fK0sCuts(0x0),
   fLambdaCuts(0x0),
+  fGammaConvCuts(0x0),
   fK0sPionCuts(0x0),
   fLambdaProtonCuts(0x0),
   fLambdaPionCuts(0x0),
+  fGammaElectronCuts(0x0),
+  fV0OpenCuts(0x0),
+  fV0StrongCuts(0x0),
   fK0sMassRange(),
   fLambdaMassRange(),
+  fGammaMassRange(),
   fV0Histos(0x0),
   fTreeFile(0x0),
   fTree(0x0),
@@ -99,18 +124,30 @@ AliAnalysisTaskReducedTree::AliAnalysisTaskReducedTree(const char *name) :
   fFillTrackInfo(kTRUE),
   fFillDielectronInfo(kTRUE),
   fFillV0Info(kTRUE),
+  fFillGammaConversions(kTRUE),
+  fFillK0s(kTRUE),
+  fFillLambda(kTRUE),
+  fFillALambda(kTRUE),
   fFillCaloClusterInfo(kTRUE),
+  fFillFMDSectorInfo(kFALSE),
+  fFillFMDChannelInfo(kFALSE),
+  //fFillCorrectedFMDInfo(kTRUE),
   fFillFriendInfo(kTRUE),
   fEventFilter(0x0),
   fTrackFilter(0x0),
   fFlowTrackFilter(0x0),
   fK0sCuts(0x0),
   fLambdaCuts(0x0),
+  fGammaConvCuts(0x0),
   fK0sPionCuts(0x0),
   fLambdaProtonCuts(0x0),
   fLambdaPionCuts(0x0),
+  fGammaElectronCuts(0x0),
+  fV0OpenCuts(0x0),
+  fV0StrongCuts(0x0),
   fK0sMassRange(),
   fLambdaMassRange(),
+  fGammaMassRange(),
   fV0Histos(0x0),
   fTreeFile(0x0),
   fTree(0x0),
@@ -124,13 +161,15 @@ AliAnalysisTaskReducedTree::AliAnalysisTaskReducedTree(const char *name) :
   //
   fK0sMassRange[0] = 0.4; fK0sMassRange[1] = 0.6;
   fLambdaMassRange[0] = 1.08; fLambdaMassRange[1] = 1.15;
+  fGammaMassRange[0] = 0.0; fGammaMassRange[1] = 0.1;
   
   DefineInput(0,TChain::Class());
+  //DefineInput(2,AliAODForwardMult::Class());
   DefineOutput(1, TList::Class());   // QA histograms
-  //DefineOutput(2, TTree::Class());   // reduced information tree
+  DefineOutput(2, TTree::Class());   // reduced information tree
   //if(fFillFriendInfo) DefineOutput(3, TTree::Class());   // reduced information tree with friends
   //DefineOutput(2, TTree::Class());   // reduced information tree with friends
-  DefineOutput(2, TTree::Class());   // reduced information tree  
+  //DefineOutput(2, TTree::Class());   // reduced information tree  
 
   fListHistos.SetName("QAhistograms");
   fListDielectron.SetOwner();
@@ -162,6 +201,7 @@ void AliAnalysisTaskReducedTree::UserCreateOutputObjects()
   }
   
   //fTreeFile = new TFile("dstTree.root", "RECREATE");
+  OpenFile(2);
   fTree = new TTree("DstTree","Reduced ESD information");
   fReducedEvent = new AliReducedEvent("DstEvent");
   fTree->Branch("Event",&fReducedEvent,16000,99);
@@ -174,12 +214,11 @@ void AliAnalysisTaskReducedTree::UserCreateOutputObjects()
 }
 
 //_________________________________________________________________________________
-void AliAnalysisTaskReducedTree::UserExec(Option_t *option)
+void AliAnalysisTaskReducedTree::UserExec(Option_t *)
 {
   //
   // Main loop. Called for every event
-  //  
-  option = option;
+  //
   AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
   Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
   Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
@@ -192,7 +231,7 @@ void AliAnalysisTaskReducedTree::UserExec(Option_t *option)
   } else {
     AliFatal("This task needs the PID response attached to the input event handler!");
   }
-  
+
   // Was event selected ?
   UInt_t isSelected = AliVEvent::kAny;
   if(fSelectPhysics && inputHandler){
@@ -205,7 +244,47 @@ void AliAnalysisTaskReducedTree::UserExec(Option_t *option)
   if(isSelected==0) {
     return;
   }
+/*
+  cout<<"get AOD"<<endl;
+  
+  AliAODEvent* aodEvent = AliForwardUtil::GetAODEvent(this);
+  if (!aodEvent) return;
+  cout<<"got AOD"<<endl;
+
+  TObject* obj = aodEvent->FindListObject("Forward");  
+  if (!obj) return;
+  cout<<"got AOD forward"<<endl;
+
+  AliAODForwardMult* aodForward = static_cast<AliAODForwardMult*>(obj);
+
+   //if (!aodForward->CheckEvent(mask,ipZmin,ipZmax,cMin,cMax)) return 0;
 
+  Double_t ret = 0;
+  const TH2D& d2Ndetadphi = aodForward->GetHistogram();
+
+
+  cout<<d2Ndetadphi.GetXaxis()->GetNbins()<<endl;
+*/
+
+  // FMD corrections
+//  AliAODEvent* aodEvent;
+//  TObject* obj;
+//  AliAODForwardMult* aodForward=NULL;
+//
+//  if(fFillCorrectedFMDInfo){
+//  aodEvent = AliForwardUtil::GetAODEvent(this);
+//  if (!aodEvent) return;
+//
+//  obj = aodEvent->FindListObject("Forward");  
+//  if (!obj) return;}
+//
+//  aodForward = static_cast<AliAODForwardMult*>(obj);
+//
+//   //if (!aodForward->CheckE vent(fTriggerMask,ipZmin,ipZmax,cMin,cMax)) return 0;
+//
+//  const TH2D& d2Ndetadphi = aodForward->GetHistogram();
+  
+  
   // fill event histograms before event filter
   Double_t values[AliDielectronVarManager::kNMaxValues]={0};
   AliDielectronVarManager::Fill(InputEvent(),values);
@@ -239,6 +318,7 @@ void AliAnalysisTaskReducedTree::UserExec(Option_t *option)
   fReducedEvent->ClearEvent();
   if(fFillFriendInfo) fReducedEventFriend->ClearEvent();
   FillEventInfo();
+  //if(fFillCorrectedFMDInfo) FillCorrectedFMDInfo(d2Ndetadphi);   //Fill corrected FMD info
   if(fFillV0Info) FillV0PairInfo();
   
   Short_t idie=0;
@@ -259,10 +339,10 @@ void AliAnalysisTaskReducedTree::UserExec(Option_t *option)
       
   // if there are candidate pairs, add the information to the reduced tree
   PostData(1, &fListHistos);
-  //PostData(2, fTree);
+  PostData(2, fTree);
   //if(fFillFriendInfo) PostData(3, fFriendTree);
   //PostData(2, fFriendTree);
-  PostData(2, fTree);
+  //PostData(2, fTree);
 }
 
 
@@ -278,6 +358,11 @@ void AliAnalysisTaskReducedTree::FillEventInfo()
   Bool_t isESD = (event->IsA()==AliESDEvent::Class());
   Bool_t isAOD = (event->IsA()==AliAODEvent::Class());
   
+  AliESDEvent* esdEvent = 0x0;
+  if(isESD) esdEvent = static_cast<AliESDEvent*>(event);
+  AliAODEvent* aodEvent = 0x0;
+  if(isAOD) aodEvent = static_cast<AliAODEvent*>(event);
+  
   AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
   UInt_t isSelected = AliVEvent::kAny;
   if(inputHandler){
@@ -286,17 +371,19 @@ void AliAnalysisTaskReducedTree::FillEventInfo()
       isSelected&=fTriggerMask;
     }
   }
-
   Double_t values[AliDielectronVarManager::kNMaxValues];
   AliDielectronVarManager::Fill(event, values);
   
   fReducedEvent->fRunNo       = event->GetRunNumber();
   fReducedEvent->fBC          = event->GetBunchCrossNumber();
+  fReducedEvent->fEventType   = event->GetEventType();
   fReducedEvent->fTriggerMask = event->GetTriggerMask();
   fReducedEvent->fIsPhysicsSelection = (isSelected!=0 ? kTRUE : kFALSE);
+  fReducedEvent->fIsSPDPileup = event->IsPileupFromSPD(3,0.8,3.,2.,5.);
+  fReducedEvent->fIsSPDPileupMultBins = event->IsPileupFromSPDInMultBins();
   AliVVertex* eventVtx = 0x0;
-  if(isESD) eventVtx = const_cast<AliESDVertex*>((static_cast<AliESDEvent*>(event))->GetPrimaryVertexTracks());
-  if(isAOD) eventVtx = const_cast<AliAODVertex*>((static_cast<AliAODEvent*>(event))->GetPrimaryVertex());
+  if(isESD) eventVtx = const_cast<AliESDVertex*>(esdEvent->GetPrimaryVertexTracks());
+  if(isAOD) eventVtx = const_cast<AliAODVertex*>(aodEvent->GetPrimaryVertex());
   if(eventVtx) {
     fReducedEvent->fVtx[0] = (isESD ? ((AliESDVertex*)eventVtx)->GetXv() : ((AliAODVertex*)eventVtx)->GetX());
     fReducedEvent->fVtx[1] = (isESD ? ((AliESDVertex*)eventVtx)->GetYv() : ((AliAODVertex*)eventVtx)->GetY());
@@ -304,15 +391,92 @@ void AliAnalysisTaskReducedTree::FillEventInfo()
     fReducedEvent->fNVtxContributors = eventVtx->GetNContributors();
   }
   if(isESD) {
-    eventVtx = const_cast<AliESDVertex*>((static_cast<AliESDEvent*>(event))->GetPrimaryVertexTPC());
+    eventVtx = const_cast<AliESDVertex*>(esdEvent->GetPrimaryVertexTPC());
+    fReducedEvent->fEventNumberInFile = esdEvent->GetEventNumberInFile();
+    fReducedEvent->fL0TriggerInputs = esdEvent->GetHeader()->GetL0TriggerInputs();
+    fReducedEvent->fL1TriggerInputs = esdEvent->GetHeader()->GetL1TriggerInputs();
+    fReducedEvent->fL2TriggerInputs = esdEvent->GetHeader()->GetL2TriggerInputs();
+    fReducedEvent->fIRIntClosestIntMap[0] = esdEvent->GetHeader()->GetIRInt1ClosestInteractionMap();
+    fReducedEvent->fIRIntClosestIntMap[1] = esdEvent->GetHeader()->GetIRInt2ClosestInteractionMap();
     if(eventVtx) {
       fReducedEvent->fVtxTPC[0] = ((AliESDVertex*)eventVtx)->GetXv();
       fReducedEvent->fVtxTPC[1] = ((AliESDVertex*)eventVtx)->GetYv();
       fReducedEvent->fVtxTPC[2] = ((AliESDVertex*)eventVtx)->GetZv();
       fReducedEvent->fNVtxTPCContributors = eventVtx->GetNContributors();
     }
+    fReducedEvent->fTimeStamp     = esdEvent->GetTimeStamp();
+    fReducedEvent->fNpileupSPD    = esdEvent->GetNumberOfPileupVerticesSPD();
+    fReducedEvent->fNpileupTracks = esdEvent->GetNumberOfPileupVerticesTracks();
+    fReducedEvent->fNPMDtracks    = esdEvent->GetNumberOfPmdTracks();
+    fReducedEvent->fNTRDtracks    = esdEvent->GetNumberOfTrdTracks();
+    fReducedEvent->fNTRDtracklets = esdEvent->GetNumberOfTrdTracklets();
+    
+    AliESDZDC* zdc = esdEvent->GetESDZDC();
+    if(zdc) {
+      for(Int_t i=0; i<5; ++i)  fReducedEvent->fZDCnEnergy[i]   = zdc->GetZN1TowerEnergy()[i];
+      for(Int_t i=5; i<10; ++i)  fReducedEvent->fZDCnEnergy[i]   = zdc->GetZN2TowerEnergy()[i-5];
+      for(Int_t i=0; i<5; ++i)  fReducedEvent->fZDCpEnergy[i]   = zdc->GetZP1TowerEnergy()[i];
+      for(Int_t i=5; i<10; ++i)  fReducedEvent->fZDCpEnergy[i]   = zdc->GetZP2TowerEnergy()[i-5];
+    }
+  }
+  if(isAOD) {
+    fReducedEvent->fIRIntClosestIntMap[0] = aodEvent->GetHeader()->GetIRInt1ClosestInteractionMap();
+    fReducedEvent->fIRIntClosestIntMap[1] = aodEvent->GetHeader()->GetIRInt2ClosestInteractionMap();
+    fReducedEvent->fEventNumberInFile = aodEvent->GetHeader()->GetEventNumberESDFile();
+    fReducedEvent->fL0TriggerInputs = aodEvent->GetHeader()->GetL0TriggerInputs();
+    fReducedEvent->fL1TriggerInputs = aodEvent->GetHeader()->GetL1TriggerInputs();
+    fReducedEvent->fL2TriggerInputs = aodEvent->GetHeader()->GetL2TriggerInputs();
+    fReducedEvent->fTimeStamp     = 0;
+    fReducedEvent->fNpileupSPD    = aodEvent->GetNumberOfPileupVerticesSPD();
+    fReducedEvent->fNpileupTracks = aodEvent->GetNumberOfPileupVerticesTracks();
+    fReducedEvent->fNPMDtracks    = aodEvent->GetNPmdClusters();
+    fReducedEvent->fNTRDtracks    = 0;
+    fReducedEvent->fNTRDtracklets = 0;
+    
+    AliAODZDC* zdc = aodEvent->GetZDCData();
+    if(zdc) {
+      for(Int_t i=0; i<5; ++i)  fReducedEvent->fZDCnEnergy[i]   = zdc->GetZNATowerEnergy()[i];
+      for(Int_t i=5; i<10; ++i)  fReducedEvent->fZDCnEnergy[i]   = zdc->GetZNCTowerEnergy()[i-5];
+      for(Int_t i=0; i<5; ++i)  fReducedEvent->fZDCpEnergy[i]   = zdc->GetZPATowerEnergy()[i];
+      for(Int_t i=5; i<10; ++i)  fReducedEvent->fZDCpEnergy[i]   = zdc->GetZPCTowerEnergy()[i-5];
+    }
+  }
+  
+  // Fill TZERO information
+  if(isESD) {
+    const AliESDTZERO* tzero = esdEvent->GetESDTZERO();
+    if(tzero) {
+      fReducedEvent->fT0start = tzero->GetT0();
+      fReducedEvent->fT0zVertex = tzero->GetT0zVertex();
+      for(Int_t i = 0;i<24;i++)
+        fReducedEvent->fT0amplitude[i] = tzero->GetT0amplitude()[i];
+      for(Int_t i = 0;i<3;i++)
+        fReducedEvent->fT0TOF[i] = tzero->GetT0TOF()[i];
+      for(Int_t i = 0;i<3;i++)
+        fReducedEvent->fT0TOFbest[i] = tzero->GetT0TOFbest()[i];
+      fReducedEvent->fT0pileup = tzero->GetPileupFlag();
+      fReducedEvent->fT0sattelite = tzero->GetSatellite();
+    }
+  }
+  if(isAOD) {
+    AliAODTZERO* tzero = aodEvent->GetTZEROData();
+    if(tzero) {
+      fReducedEvent->fT0start = -999.;   // not available
+      fReducedEvent->fT0zVertex = tzero->GetT0zVertex();
+      for(Int_t i = 0;i<26;i++)
+        fReducedEvent->fT0amplitude[i] = tzero->GetAmp(i);
+      for(Int_t i = 0;i<3;i++)
+        fReducedEvent->fT0TOF[i] = tzero->GetT0TOF()[i];
+      for(Int_t i = 0;i<3;i++)
+        fReducedEvent->fT0TOFbest[i] = tzero->GetT0TOFbest()[i];
+      fReducedEvent->fT0pileup = tzero->GetPileupFlag();
+      fReducedEvent->fT0sattelite = tzero->GetSatellite();
+    }
   }
   
+  if(fFillFMDChannelInfo&&isESD) fReducedEvent->fIsFMDReduced = kFALSE;
+  if((fFillFMDSectorInfo||fFillFMDChannelInfo)&&isESD) FillFMDInfo();
+  
   AliCentrality *centrality = event->GetCentrality();
   if(centrality) {
     fReducedEvent->fCentrality[0] = centrality->GetCentralityPercentile("V0M");
@@ -322,18 +486,16 @@ void AliAnalysisTaskReducedTree::FillEventInfo()
     fReducedEvent->fCentQuality   = centrality->GetQuality();
   }
   
+  //cout << "event vtxZ/cent: " << fReducedEvent->fVtx[2] << "/" << fReducedEvent->fCentrality[0] << endl;
+  
   fReducedEvent->fNtracks[0] = event->GetNumberOfTracks();
-  fReducedEvent->fSPDntracklets = (UChar_t)values[AliDielectronVarManager::kNaccTrckltsEsd10Corr];
-
+  fReducedEvent->fSPDntracklets = GetSPDTrackletMultiplicity(event, -1.0, 1.0);
+  for(Int_t ieta=0; ieta<32; ++ieta)
+    fReducedEvent->fSPDntrackletsEta[ieta] = GetSPDTrackletMultiplicity(event, -1.6+0.1*ieta, -1.6+0.1*(ieta+1));
+  
   AliVVZERO* vzero = event->GetVZEROData();
   for(Int_t i=0;i<64;++i) 
     fReducedEvent->fVZEROMult[i] = vzero->GetMultiplicity(i);  
-
-  AliESDZDC* zdc = (isESD ? (static_cast<AliESDEvent*>(event))->GetESDZDC() : 0x0);
-  if(zdc) {
-    for(Int_t i=0; i<4; ++i)  fReducedEvent->fZDCnEnergy[i]   = zdc->GetZN1TowerEnergy()[i];
-    for(Int_t i=4; i<8; ++i)  fReducedEvent->fZDCnEnergy[i]   = zdc->GetZN2TowerEnergy()[i-4];
-  }
   
   // EMCAL/PHOS clusters
   if(fFillCaloClusterInfo) FillCaloClusters();
@@ -362,6 +524,9 @@ void AliAnalysisTaskReducedTree::FillCaloClusters() {
     reducedCluster->fEnergy  = cluster->E();
     reducedCluster->fTrackDx = cluster->GetTrackDx();
     reducedCluster->fTrackDz = cluster->GetTrackDz();
+    reducedCluster->fM20     = cluster->GetM20();
+    reducedCluster->fM02     = cluster->GetM02();
+    reducedCluster->fDispersion = cluster->GetDispersion();
     fReducedEvent->fNCaloClusters += 1;
   }  // end loop over clusters
 }
@@ -381,6 +546,129 @@ void AliAnalysisTaskReducedTree::FillFriendEventInfo() {
 }
 
 
+//_________________________________________________________________________________
+void AliAnalysisTaskReducedTree::FillFMDInfo()
+{
+  //
+  // fill reduced FMD information
+  //
+  AliVEvent* event = InputEvent();
+  Bool_t isESD = (event->IsA()==AliESDEvent::Class());
+
+  if(!isESD) return;
+
+  AliESDEvent* esdEvent = 0x0;
+  if(isESD) esdEvent = static_cast<AliESDEvent*>(event);
+
+  AliESDFMD* esdFmd = esdEvent->GetFMDData();
+  //const AliFMDFloatMap multMap = esdFmd->MultiplicityMap();
+  //const AliFMDFloatMap etaMap  = esdFmd->EtaMap();
+
+  //esdFmd->Print();
+  Int_t nFMD=0;
+  Int_t id=-1;
+  Int_t maxDet=3;
+  Int_t maxRing=2;
+  Int_t maxSector;
+  Int_t maxStrip;
+  Float_t m=0.0;
+  Double_t phi;
+  Char_t ring;
+  Float_t fmdMult;
+  Float_t msum=0;
+  UShort_t fmdDet=0;
+  Int_t phiBin=0;
+    
+  for(UShort_t det = 1; det <= maxDet; ++det) {
+    (det == 1 ? maxRing=1 : maxRing=2);
+    for(UShort_t ir = 0; ir < maxRing; ++ir) {
+      ring = (ir == 0 ? 'I' : 'O');
+      (ir == 0 ? maxSector=20 : maxSector=40);
+      (ir == 0 ? maxStrip=512 : maxStrip=256);
+      nFMD=-1;
+      for(UShort_t sec = 0; sec < maxSector; ++sec) {
+        phi  =  esdFmd->Phi(det, ring, sec, 0)/180.*TMath::Pi();
+        phiBin = Int_t (phi/2/TMath::Pi()*maxSector);
+       fmdMult = 0;
+        for(UShort_t str = 0; str < maxStrip; ++str) {
+          ++id;
+          m  =  esdFmd->Multiplicity(det, ring, sec, str);
+         //cout << "det/ir/sec/str/m :: " << det << "/" << ir << "/" << sec << "/" << str << "/" << m << endl;
+          if(fFillFMDChannelInfo) 
+           if(m<1.e-6) continue;
+          if(m ==  AliESDFMD::kInvalidMult) m=0;
+          fmdMult += m;
+          msum+=m;
+          ++nFMD;
+            
+         if(fFillFMDChannelInfo){
+            if(m>15.) m=15.;
+            m = UShort_t(m*4369+0.5);
+            TClonesArray& fmd = *(fReducedEvent->GetFMD(fmdDet));
+            AliReducedFMD   *reducedFMD=new(fmd[nFMD]) AliReducedFMD();
+           fReducedEvent->fNFMDchannels[fmdDet] += 1;
+            reducedFMD->fMultiplicity     =  m;    
+            //reducedFMD->fEta              =  esdFmd->Eta(det, ring, 0, str);
+            reducedFMD->fId               =  id;
+          }  
+        }  // end loop over strips
+        
+        if(fFillFMDSectorInfo) {
+          TClonesArray& fmd = *(fReducedEvent->GetFMD(fmdDet));
+          AliReducedFMD   *reducedFMD=new(fmd[phiBin]) AliReducedFMD();
+          reducedFMD->fMultiplicity     = fmdMult;
+         fReducedEvent->fNFMDchannels[fmdDet] += 1;
+          //cout<<sec<<"  "<<fmdMult<<endl;
+          fmdMult=0.0;
+        }
+      }  // end loop over sectors      
+      
+      fReducedEvent->fFMDtotalMult[fmdDet] = msum;
+      msum=0.0;
+      ++fmdDet;
+      id=-1;
+    }  // end loop over rings
+  } // end loop over detectors
+}
+
+////_________________________________________________________________________________
+//void AliAnalysisTaskReducedTree::FillCorrectedFMDInfo(const TH2D& fmdhist) 
+//{
+//
+//
+//Int_t nEta = fmdhist.GetXaxis()->GetNbins();
+//Int_t nPhi = fmdhist.GetYaxis()->GetNbins();
+////Int_t nBins= fmdhist.GetNbins();
+//Float_t eta=0.0;
+//Float_t phi=0.0;
+//Float_t mult=0.0;
+//
+//
+//Int_t nFMD=0;
+////fReducedEvent->fNCorFmdChannels = 0;
+//for (Int_t e = 1; e <= nEta; e++) {
+//    eta = fmdhist.GetXaxis()->GetBinCenter(e);
+//    for (Int_t p = 1; p <= nPhi; p++) {
+//         phi = fmdhist.GetYaxis()->GetBinCenter(p);
+//         mult = fmdhist.GetBinContent(e, p);
+//      //TClonesArray& Corfmd = *(fReducedEvent->fCorFMD);
+//      //AliReducedFMD *reducedCorFMD=new(Corfmd[nFMD]) AliReducedCorFMD();
+//    std::cout<<mult<<"  "<<eta<<"  "<<phi<<std::endl;
+//     }
+//
+//     //fReducedEvent->fNCorFmdChannels += 1;
+//     nFMD += 1;
+////reducedFMD->fCorMultiplicity = mult;
+////reducedFMD->fCorEta          = eta;
+////reducedFMD->fCorPhi          = phi;
+//
+//
+//}
+//
+//
+//}
+
+
 //_________________________________________________________________________________
 void AliAnalysisTaskReducedTree::FillTrackInfo() 
 {
@@ -391,70 +679,236 @@ void AliAnalysisTaskReducedTree::FillTrackInfo()
   Bool_t isESD = (event->IsA()==AliESDEvent::Class());
   Bool_t isAOD = (event->IsA()==AliAODEvent::Class());
 
+  AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
+  AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
+  AliPIDResponse* pidResponse = inputHandler->GetPIDResponse();
+  
+  // find all the tracks which belong to a V0 stored in the reduced event
+  UShort_t trackIdsV0[4][20000]={{0}};
+  UShort_t trackIdsPureV0[4][20000]={{0}};
+  Int_t nV0LegsTagged[4] = {0}; Int_t nPureV0LegsTagged[4] = {0};
+  Bool_t leg1Found[4]; Bool_t leg2Found[4];
+  for(Int_t iv0=0;iv0<fReducedEvent->fNV0candidates[1];++iv0) {
+    AliReducedPair* pair = fReducedEvent->GetV0Pair(iv0);
+    if(!pair) continue;
+    Int_t pairId = 0; Bool_t isPureV0 = kFALSE;
+    if(pair->fCandidateId==AliReducedPair::kGammaConv) {
+      pairId=0;
+      if(pair->IsPureV0Gamma()) isPureV0 = kTRUE;
+    }
+    if(pair->fCandidateId==AliReducedPair::kK0sToPiPi) {
+      pairId=1;
+      if(pair->IsPureV0K0s()) isPureV0 = kTRUE;
+    }
+    if(pair->fCandidateId==AliReducedPair::kLambda0ToPPi) {
+      pairId=2;
+      if(pair->IsPureV0Lambda()) isPureV0 = kTRUE;
+    }
+    if(pair->fCandidateId==AliReducedPair::kALambda0ToPPi) {
+      pairId=3;
+      if(pair->IsPureV0ALambda()) isPureV0 = kTRUE;
+    }
+    
+    leg1Found[pairId] = kFALSE; leg2Found[pairId] = kFALSE;
+    for(Int_t it=0;it<nV0LegsTagged[pairId];++it) {
+      if(trackIdsV0[pairId][it]==pair->fLegIds[0]) leg1Found[pairId]=kTRUE;
+      if(trackIdsV0[pairId][it]==pair->fLegIds[1]) leg2Found[pairId]=kTRUE;
+    }
+    // if the legs of this V0 were not already stored then add them now to the list
+    if(!leg1Found[pairId]) {trackIdsV0[pairId][nV0LegsTagged[pairId]] = pair->fLegIds[0]; ++nV0LegsTagged[pairId];}
+    if(!leg2Found[pairId]) {trackIdsV0[pairId][nV0LegsTagged[pairId]] = pair->fLegIds[1]; ++nV0LegsTagged[pairId];}
+    
+    if(isPureV0) {
+      leg1Found[pairId] = kFALSE; leg2Found[pairId] = kFALSE;
+      for(Int_t it=0;it<nPureV0LegsTagged[pairId];++it) {
+        if(trackIdsPureV0[pairId][it]==pair->fLegIds[0]) leg1Found[pairId]=kTRUE;
+        if(trackIdsPureV0[pairId][it]==pair->fLegIds[1]) leg2Found[pairId]=kTRUE;
+      }
+      // if the legs of this pure V0 were not already stored then add them now to the list
+      if(!leg1Found[pairId]) {trackIdsPureV0[pairId][nPureV0LegsTagged[pairId]] = pair->fLegIds[0]; ++nPureV0LegsTagged[pairId];}
+      if(!leg2Found[pairId]) {trackIdsPureV0[pairId][nPureV0LegsTagged[pairId]] = pair->fLegIds[1]; ++nPureV0LegsTagged[pairId];}
+    }
+  }
+  
+  // find all the tracks which belong to a stored dielectron pair
+  UShort_t trackIdsDiele[20000]={0};
+  Int_t nDieleLegsTagged = 0;
+  for(Int_t idie=0;idie<fReducedEvent->NDielectrons();++idie) {
+    AliReducedPair* pair = fReducedEvent->GetDielectronPair(idie);
+    leg1Found[0]=kFALSE; leg2Found[0]=kFALSE;
+    for(Int_t it=0; it<nDieleLegsTagged; ++it) {
+      if(trackIdsDiele[it]==pair->fLegIds[0]) leg1Found[0]=kTRUE;
+      if(trackIdsDiele[it]==pair->fLegIds[1]) leg2Found[0]=kTRUE;
+    }
+    // if the legs of this dielectron were not already stored then add them now to the list
+    if(!leg1Found[0]) {trackIdsDiele[nDieleLegsTagged] = pair->fLegIds[0]; ++nDieleLegsTagged;}
+    if(!leg2Found[0]) {trackIdsDiele[nDieleLegsTagged] = pair->fLegIds[1]; ++nDieleLegsTagged;}
+  }
+    
+  AliESDtrack* esdTrack=0;
+  AliAODTrack* aodTrack=0;
   Int_t ntracks=event->GetNumberOfTracks();
+  Int_t trackId = 0; 
+  Bool_t usedForV0[4] = {kFALSE}; 
+  Bool_t usedForPureV0[4] = {kFALSE};
+  Bool_t usedForV0Or = kFALSE;
+  Bool_t usedForDielectron = kFALSE;
   for(Int_t itrack=0; itrack<ntracks; ++itrack){
     AliVParticle *particle=event->GetTrack(itrack);
+    if(isESD) {
+      esdTrack=static_cast<AliESDtrack*>(particle);
+      trackId = esdTrack->GetID();
+    }
+    if(isAOD) {
+      aodTrack=static_cast<AliAODTrack*>(particle);
+      trackId = aodTrack->GetID();
+    }
+    // check whether this track belongs to a V0 stored in the reduced event
+    usedForV0Or = kFALSE;
+    for(Int_t i=0; i<4; ++i) {
+      usedForV0[i] = kFALSE;
+      for(Int_t ii=0; ii<nV0LegsTagged[i]; ++ii) {
+        if(UShort_t(trackId)==trackIdsV0[i][ii]) {
+          usedForV0[i] = kTRUE;
+          //cout << "track " << trackId << " used for V0 type " << i << endl;
+          break;
+        }
+      }
+      usedForV0Or = usedForV0Or || usedForV0[i];
+      usedForPureV0[i] = kFALSE;
+      for(Int_t ii=0; ii<nPureV0LegsTagged[i]; ++ii) {
+        if(UShort_t(trackId)==trackIdsPureV0[i][ii]) {
+          usedForPureV0[i] = kTRUE;
+          //cout << "track " << trackId << " used for pure V0 type " << i << endl;
+          break;
+        }
+      }
+    }
+    // check whether this track belongs to a dielectron stored in the reduced event
+    usedForDielectron = kFALSE;
+    for(Int_t ii=0; ii<nDieleLegsTagged; ++ii) {
+      if(UShort_t(trackId)==trackIdsDiele[ii]) {
+        usedForDielectron = kTRUE;
+        break;
+      }
+    }
+    
+    ULong_t status = (isESD ? esdTrack->GetStatus() : aodTrack->GetStatus());
+    //cout << "TRACK" << endl;
+    for(Int_t ibit=0; ibit<32; ++ibit) {
+      if(status & (ULong_t(1)<<ibit)) {
+        //cout << "bit " << ibit << endl;
+        fReducedEvent->fNtracksPerTrackingFlag[ibit] += 1;
+      }
+    }
+    
     //apply track cuts
-    if(fTrackFilter && !fTrackFilter->IsSelected(particle)) continue;
+    if(!usedForV0Or && !usedForDielectron && fTrackFilter && !fTrackFilter->IsSelected(particle)) continue;
+    //cout << "storing track " << trackId << endl;
     
     TClonesArray& tracks = *(fReducedEvent->fTracks);
     AliReducedTrack *reducedParticle=new(tracks[fReducedEvent->fNtracks[1]]) AliReducedTrack();
         
     Double_t values[AliDielectronVarManager::kNMaxValues];
     AliDielectronVarManager::Fill(particle, values);
-    reducedParticle->fStatus        = (ULong_t)values[AliDielectronVarManager::kTrackStatus];
+    reducedParticle->fStatus        = status;//(ULong_t)values[AliDielectronVarManager::kTrackStatus];
     reducedParticle->fGlobalPhi     = values[AliDielectronVarManager::kPhi];
     reducedParticle->fGlobalPt      = values[AliDielectronVarManager::kPt]*values[AliDielectronVarManager::kCharge];
     reducedParticle->fGlobalEta     = values[AliDielectronVarManager::kEta];    
     reducedParticle->fMomentumInner = values[AliDielectronVarManager::kPIn];
     reducedParticle->fDCA[0]        = values[AliDielectronVarManager::kImpactParXY];
     reducedParticle->fDCA[1]        = values[AliDielectronVarManager::kImpactParZ];
+    reducedParticle->fTrackLength   = values[AliDielectronVarManager::kTrackLength];
     
-    reducedParticle->fITSclusterMap = values[AliDielectronVarManager::kITSclusterMap];
+    reducedParticle->fITSclusterMap = (UChar_t)values[AliDielectronVarManager::kITSclusterMap];
     reducedParticle->fITSsignal     = values[AliDielectronVarManager::kITSsignal];
+    reducedParticle->fITSnSig[0]    = values[AliDielectronVarManager::kITSnSigmaEle];
+    reducedParticle->fITSnSig[1]    = values[AliDielectronVarManager::kITSnSigmaPio];
+    reducedParticle->fITSnSig[2]    = values[AliDielectronVarManager::kITSnSigmaKao];
+    reducedParticle->fITSnSig[3]    = values[AliDielectronVarManager::kITSnSigmaPro];
+    reducedParticle->fITSchi2       = values[AliDielectronVarManager::kITSchi2Cl];
     
     reducedParticle->fTPCNcls      = (UChar_t)values[AliDielectronVarManager::kNclsTPC];
     reducedParticle->fTPCNclsF     = (UChar_t)values[AliDielectronVarManager::kNFclsTPC];
     reducedParticle->fTPCNclsIter1 = (UChar_t)values[AliDielectronVarManager::kNclsTPCiter1];
     reducedParticle->fTPCsignal    = values[AliDielectronVarManager::kTPCsignal];
+    reducedParticle->fTPCsignalN   = values[AliDielectronVarManager::kTPCsignalN];
     reducedParticle->fTPCnSig[0]   = values[AliDielectronVarManager::kTPCnSigmaEle];
     reducedParticle->fTPCnSig[1]   = values[AliDielectronVarManager::kTPCnSigmaPio];
     reducedParticle->fTPCnSig[2]   = values[AliDielectronVarManager::kTPCnSigmaKao];
     reducedParticle->fTPCnSig[3]   = values[AliDielectronVarManager::kTPCnSigmaPro];
+    reducedParticle->fTPCClusterMap = EncodeTPCClusterMap(particle, isAOD);
+    reducedParticle->fTPCchi2       = values[AliDielectronVarManager::kTPCchi2Cl];
     
     reducedParticle->fTOFbeta      = values[AliDielectronVarManager::kTOFbeta];
     reducedParticle->fTOFnSig[0]   = values[AliDielectronVarManager::kTOFnSigmaEle];
     reducedParticle->fTOFnSig[1]   = values[AliDielectronVarManager::kTOFnSigmaPio];
     reducedParticle->fTOFnSig[2]   = values[AliDielectronVarManager::kTOFnSigmaKao];
     reducedParticle->fTOFnSig[3]   = values[AliDielectronVarManager::kTOFnSigmaPro];
-
-    reducedParticle->fTRDpid[0]    = values[AliDielectronVarManager::kTRDprobEle];
-    reducedParticle->fTRDpid[1]    = values[AliDielectronVarManager::kTRDprobPio];
     
+    Double_t trdProbab[AliPID::kSPECIES]={0.0};
+        
     if(fFlowTrackFilter) {
       // switch on the first bit if this particle should be used for the event plane
-      if(fFlowTrackFilter->IsSelected(particle)) reducedParticle->fFlags |= (1<<0);
+      if(fFlowTrackFilter->IsSelected(particle)) reducedParticle->fFlags |= (UShort_t(1)<<0);
+    }
+    for(Int_t iV0type=0;iV0type<4;++iV0type) {
+      if(usedForV0[iV0type]) reducedParticle->fFlags |= (UShort_t(1)<<(iV0type+1));
+      if(usedForPureV0[iV0type]) reducedParticle->fFlags |= (UShort_t(1)<<(iV0type+8));
     }
     
     if(isESD){
-      AliESDtrack *track=static_cast<AliESDtrack*>(particle);
-      reducedParticle->fTrackId          = (UShort_t)track->GetID();
-      reducedParticle->fTPCCrossedRows   = (UChar_t)track->GetTPCCrossedRows();
-      reducedParticle->fTPCClusterMap    = EncodeTPCClusterMap(track);
-      const AliExternalTrackParam* tpcInner = track->GetTPCInnerParam();
+      //AliESDtrack *track=static_cast<AliESDtrack*>(particle);
+      reducedParticle->fTrackId          = (UShort_t)esdTrack->GetID();
+      reducedParticle->fTPCCrossedRows   = (UChar_t)esdTrack->GetTPCCrossedRows();
+      //reducedParticle->fTPCClusterMap    = EncodeTPCClusterMap(esdTrack);
+      const AliExternalTrackParam* tpcInner = esdTrack->GetInnerParam();
       reducedParticle->fTPCPhi        = (tpcInner ? tpcInner->Phi() : 0.0);
       reducedParticle->fTPCPt         = (tpcInner ? tpcInner->Pt() : 0.0);
       reducedParticle->fTPCEta        = (tpcInner ? tpcInner->Eta() : 0.0);
-      reducedParticle->fTRDntracklets[0] = track->GetTRDntracklets();
-      reducedParticle->fTRDntracklets[1] = track->GetTRDntrackletsPID();
-      if(track->IsEMCAL()) reducedParticle->fCaloClusterId = track->GetEMCALcluster();
-      if(track->IsPHOS()) reducedParticle->fCaloClusterId = track->GetPHOScluster();
+      
+      reducedParticle->fTOFdeltaBC    = esdTrack->GetTOFDeltaBC();
+      
+      reducedParticle->fTRDntracklets[0] = esdTrack->GetTRDntracklets();
+      reducedParticle->fTRDntracklets[1] = esdTrack->GetTRDntrackletsPID();
+      pidResponse->ComputeTRDProbability(esdTrack,AliPID::kSPECIES,trdProbab,AliTRDPIDResponse::kLQ1D);
+      reducedParticle->fTRDpid[0]    = trdProbab[AliPID::kElectron];
+      reducedParticle->fTRDpid[1]    = trdProbab[AliPID::kPion];
+      pidResponse->ComputeTRDProbability(esdTrack,AliPID::kSPECIES,trdProbab,AliTRDPIDResponse::kLQ2D);
+      reducedParticle->fTRDpidLQ2D[0]    = trdProbab[AliPID::kElectron];
+      reducedParticle->fTRDpidLQ2D[1]    = trdProbab[AliPID::kPion];
+            
+      for(Int_t idx=0; idx<3; ++idx) if(esdTrack->GetKinkIndex(idx)>0) reducedParticle->fFlags |= (1<<(5+idx));
+      if(esdTrack->IsEMCAL()) reducedParticle->fCaloClusterId = esdTrack->GetEMCALcluster();
+      if(esdTrack->IsPHOS()) reducedParticle->fCaloClusterId = esdTrack->GetPHOScluster();
     }
     if(isAOD) {
-      AliAODTrack *track=static_cast<AliAODTrack*>(particle);
-      reducedParticle->fTrackId = track->GetID(); 
-      if(track->IsEMCAL()) reducedParticle->fCaloClusterId = track->GetEMCALcluster();
-      if(track->IsPHOS()) reducedParticle->fCaloClusterId = track->GetPHOScluster();
+      //AliAODTrack *track=static_cast<AliAODTrack*>(particle);
+      const AliExternalTrackParam* tpcInner = aodTrack->GetInnerParam();
+      reducedParticle->fTPCPhi        = (tpcInner ? tpcInner->Phi() : 0.0);
+      reducedParticle->fTPCPt         = (tpcInner ? tpcInner->Pt() : 0.0);
+      reducedParticle->fTPCEta        = (tpcInner ? tpcInner->Eta() : 0.0);
+      
+      reducedParticle->fTrackId = aodTrack->GetID(); 
+      reducedParticle->fITSsignal = aodTrack->GetITSsignal();
+      if(pidResponse) {
+        reducedParticle->fITSnSig[0]    = pidResponse->NumberOfSigmasITS(aodTrack,AliPID::kElectron);
+        reducedParticle->fITSnSig[1]    = pidResponse->NumberOfSigmasITS(aodTrack,AliPID::kPion);
+        reducedParticle->fITSnSig[2]    = pidResponse->NumberOfSigmasITS(aodTrack,AliPID::kKaon);
+        reducedParticle->fITSnSig[3]    = pidResponse->NumberOfSigmasITS(aodTrack,AliPID::kProton);
+      }
+      reducedParticle->fTRDntracklets[0] = aodTrack->GetTRDntrackletsPID();
+      reducedParticle->fTRDntracklets[1] = aodTrack->GetTRDntrackletsPID();
+      pidResponse->ComputeTRDProbability(aodTrack,AliPID::kSPECIES,trdProbab,AliTRDPIDResponse::kLQ1D);
+      reducedParticle->fTRDpid[0]    = trdProbab[AliPID::kElectron];
+      reducedParticle->fTRDpid[1]    = trdProbab[AliPID::kPion];
+      pidResponse->ComputeTRDProbability(aodTrack,AliPID::kSPECIES,trdProbab,AliTRDPIDResponse::kLQ2D);
+      reducedParticle->fTRDpidLQ2D[0]    = trdProbab[AliPID::kElectron];
+      reducedParticle->fTRDpidLQ2D[1]    = trdProbab[AliPID::kPion];
+      
+      if(aodTrack->IsEMCAL()) reducedParticle->fCaloClusterId = aodTrack->GetEMCALcluster();
+      if(aodTrack->IsPHOS()) reducedParticle->fCaloClusterId = aodTrack->GetPHOScluster();
+      if(values[AliDielectronVarManager::kKinkIndex0]>0.0) reducedParticle->fFlags |= (1<<5);
     }
 
     fReducedEvent->fNtracks[1] += 1;
@@ -486,19 +940,20 @@ void AliAnalysisTaskReducedTree::FillDielectronPairInfo(AliDielectron* die, Shor
       // !!! hardcoded flag for dielectron id 
       reducedParticle->fCandidateId  = (iDie==0 ? AliReducedPair::kJpsiToEE : AliReducedPair::kPhiToKK);
       reducedParticle->fPairType     = (Char_t)values[AliDielectronVarManager::kPairType];
-      reducedParticle->fLegIds[0]    = (UShort_t)(static_cast<AliVTrack*>(pair->GetFirstDaughter()))->GetID();
-      reducedParticle->fLegIds[1]    = (UShort_t)(static_cast<AliVTrack*>(pair->GetSecondDaughter()))->GetID();
+      reducedParticle->fLegIds[0]    = (UShort_t)(static_cast<AliVTrack*>(pair->GetFirstDaughterP()))->GetID();
+      reducedParticle->fLegIds[1]    = (UShort_t)(static_cast<AliVTrack*>(pair->GetSecondDaughterP()))->GetID();
       reducedParticle->fMass[0]      = values[AliDielectronVarManager::kM];
       reducedParticle->fMass[1]      = -999.;
       reducedParticle->fMass[2]      = -999.;
+      reducedParticle->fMass[3]      = -999.;
       reducedParticle->fPhi          = values[AliDielectronVarManager::kPhi];  // in the [-pi,pi] interval
       if(reducedParticle->fPhi<0.0) reducedParticle->fPhi = 2.0*TMath::Pi() + reducedParticle->fPhi;  // converted to [0,2pi]
       reducedParticle->fPt           = values[AliDielectronVarManager::kPt];
       reducedParticle->fEta          = values[AliDielectronVarManager::kEta];
       reducedParticle->fLxy          = values[AliDielectronVarManager::kPseudoProperTime];
       reducedParticle->fLxyErr       = values[AliDielectronVarManager::kPseudoProperTimeErr];
-      reducedParticle->fOpeningAngle = values[AliDielectronVarManager::kOpeningAngle];     
-     
+      reducedParticle->fPointingAngle = values[AliDielectronVarManager::kCosPointingAngle];
+      
       reducedParticle->fMCid         = 0;
       if(hasMC) {
        AliDielectronMC::Instance()->ConnectMCEvent();
@@ -529,9 +984,21 @@ void AliAnalysisTaskReducedTree::FillV0PairInfo()
   
   fReducedEvent->fNV0candidates[0] = InputEvent()->GetNumberOfV0s();
   
+  if(!(fFillK0s || fFillLambda || fFillALambda || fFillGammaConversions)) return;
+    
   Double_t valuesPos[AliDielectronVarManager::kNMaxValues];
   Double_t valuesNeg[AliDielectronVarManager::kNMaxValues];
-   
+  
+  if(fV0OpenCuts) {
+    fV0OpenCuts->SetEvent(esd);
+    fV0OpenCuts->SetPrimaryVertex(&primaryVertexKF);
+  }
+  if(fV0StrongCuts) {
+    fV0StrongCuts->SetEvent(esd);
+    fV0StrongCuts->SetPrimaryVertex(&primaryVertexKF);
+  }
+  
+  Int_t pdgV0=0; Int_t pdgP=0; Int_t pdgN=0;
   for(Int_t iV0=0; iV0<InputEvent()->GetNumberOfV0s(); ++iV0) {   // loop over V0s
     AliESDv0 *v0 = esd->GetV0(iV0);
        
@@ -546,68 +1013,107 @@ void AliAnalysisTaskReducedTree::FillV0PairInfo()
     legPos = (!v0ChargesAreCorrect ? esd->GetTrack(v0->GetNindex()) : legPos);
     legNeg = (!v0ChargesAreCorrect ? esd->GetTrack(v0->GetPindex()) : legNeg); 
     
-    // apply the K0s filter
-    Bool_t goodK0s = kTRUE;
-    if(fK0sPionCuts && (!fK0sPionCuts->IsSelected(legPos) || !fK0sPionCuts->IsSelected(legNeg))) goodK0s = kFALSE;
-    if(fK0sCuts) {
-      TList k0sList;
-      k0sList.Add(v0);
-      k0sList.Add(legPos); k0sList.Add(legNeg);
-      k0sList.Add(const_cast<AliESDVertex*>(primaryVertex));
-      if(!fK0sCuts->IsSelected(&k0sList)) goodK0s = kFALSE;
+    pdgV0=0; pdgP=0; pdgN=0;
+    Bool_t goodK0s = kTRUE; Bool_t goodLambda = kTRUE; Bool_t goodALambda = kTRUE; Bool_t goodGamma = kTRUE;
+    if(fV0OpenCuts) {
+      goodK0s = kFALSE; goodLambda = kFALSE; goodALambda = kFALSE; goodGamma = kFALSE;
+      Bool_t processV0 = fV0OpenCuts->ProcessV0(v0, pdgV0, pdgP, pdgN);
+      if(processV0 && TMath::Abs(pdgV0)==310 && TMath::Abs(pdgP)==211 && TMath::Abs(pdgN)==211) {
+        goodK0s = kTRUE;
+        if(fK0sPionCuts && (!fK0sPionCuts->IsSelected(legPos) || !fK0sPionCuts->IsSelected(legNeg))) goodK0s = kFALSE;
+      }
+      if(processV0 && pdgV0==3122 && (TMath::Abs(pdgP)==211 || TMath::Abs(pdgP)==2212) && (TMath::Abs(pdgN)==211 || TMath::Abs(pdgN)==2212)) {
+        goodLambda = kTRUE;
+        if(fLambdaProtonCuts && !fLambdaProtonCuts->IsSelected(legPos)) goodLambda = kFALSE;
+        if(fLambdaPionCuts && !fLambdaPionCuts->IsSelected(legNeg)) goodLambda = kFALSE;
+      }
+      if(processV0 && pdgV0==-3122 && (TMath::Abs(pdgP)==211 || TMath::Abs(pdgP)==2212) && (TMath::Abs(pdgN)==211 || TMath::Abs(pdgN)==2212)) {
+        goodALambda = kTRUE;
+        if(fLambdaProtonCuts && !fLambdaProtonCuts->IsSelected(legNeg)) goodALambda = kFALSE;
+        if(fLambdaPionCuts && !fLambdaPionCuts->IsSelected(legPos)) goodALambda = kFALSE;
+      }
+      if(processV0 && TMath::Abs(pdgV0)==22 && TMath::Abs(pdgP)==11 && TMath::Abs(pdgN)==11) {
+        goodGamma = kTRUE;
+        if(fGammaElectronCuts && (!fGammaElectronCuts->IsSelected(legPos) || !fGammaElectronCuts->IsSelected(legNeg))) goodGamma = kFALSE;
+      }
+      //cout << "open cuts  pdgV0/pdgP/pdgN/processV0 : " << pdgV0 << "/" << pdgP << "/" << pdgN << "/" << processV0 << endl;     
+      //cout << "good K0s/Lambda/ALambda/Gamma : " << goodK0s << "/" << goodLambda << "/" << goodALambda << "/" << goodGamma << endl;
     }
     
-    // apply the lambda filter
-    Bool_t goodLambda = kTRUE;
-    if(fLambdaProtonCuts && !fLambdaProtonCuts->IsSelected(legPos)) goodLambda = kFALSE;
-    if(fLambdaPionCuts && !fLambdaPionCuts->IsSelected(legNeg)) goodLambda = kFALSE;
-    Bool_t goodALambda = kTRUE;
-    if(fLambdaProtonCuts && !fLambdaProtonCuts->IsSelected(legNeg)) goodALambda = kFALSE;
-    if(fLambdaPionCuts && !fLambdaPionCuts->IsSelected(legPos)) goodALambda = kFALSE;
-    if(fLambdaCuts) {
-      TList lambdaList;
-      lambdaList.Add(v0);
-      lambdaList.Add(legPos); lambdaList.Add(legNeg);
-      lambdaList.Add(const_cast<AliESDVertex*>(primaryVertex));
-      if(!fLambdaCuts->IsSelected(&lambdaList)) {goodLambda = kFALSE; goodALambda = kFALSE;}
+    Bool_t veryGoodK0s = kFALSE; Bool_t veryGoodLambda = kFALSE; Bool_t veryGoodALambda = kFALSE; Bool_t veryGoodGamma = kFALSE;
+    if(fV0StrongCuts && (goodK0s || goodLambda || goodALambda || goodGamma)) {
+      pdgV0=0; pdgP=0; pdgN=0;
+      Bool_t processV0 = fV0StrongCuts->ProcessV0(v0, pdgV0, pdgP, pdgN);
+      if(processV0 && goodK0s && TMath::Abs(pdgV0)==310 && TMath::Abs(pdgP)==211 && TMath::Abs(pdgN)==211)
+        veryGoodK0s = kTRUE;
+      if(processV0 && goodLambda && pdgV0==3122 && (TMath::Abs(pdgP)==211 || TMath::Abs(pdgP)==2212) && (TMath::Abs(pdgN)==211 || TMath::Abs(pdgN)==2212))
+        veryGoodLambda = kTRUE;
+      if(processV0 && goodALambda && pdgV0==-3122 && (TMath::Abs(pdgP)==211 || TMath::Abs(pdgP)==2212) && (TMath::Abs(pdgN)==211 || TMath::Abs(pdgN)==2212))
+        veryGoodALambda = kTRUE;
+      if(processV0 && goodGamma && TMath::Abs(pdgV0)==22 && TMath::Abs(pdgP)==11 && TMath::Abs(pdgN)==11)
+        veryGoodGamma = kTRUE;
+      //cout << "strong cuts  pdgV0/pdgP/pdgN/processV0 : " << pdgV0 << "/" << pdgP << "/" << pdgN << "/" << processV0 << endl;     
+      //cout << "very good K0s/Lambda/ALambda/Gamma : " << veryGoodK0s << "/" << veryGoodLambda << "/" << veryGoodALambda << "/" << veryGoodGamma << endl;
     }
+              
+    if(!((goodK0s && fFillK0s) || 
+         (goodLambda && fFillLambda) || 
+         (goodALambda && fFillALambda) || 
+         (goodGamma && fFillGammaConversions))) continue;
     
-    if(!(goodK0s || goodLambda || goodALambda)) continue;
-    
-    // Fill the V0 information into the tree for 3 hypothesis: K0s, Lambda, Anti-Lambda
+    // Fill the V0 information into the tree for 4 hypothesis: K0s, Lambda, Anti-Lambda and gamma conversion
     AliReducedPair* k0sReducedPair     = FillV0PairInfo(v0, AliReducedPair::kK0sToPiPi,     legPos, legNeg, &primaryVertexKF, v0ChargesAreCorrect);
     AliReducedPair* lambdaReducedPair  = FillV0PairInfo(v0, AliReducedPair::kLambda0ToPPi,  legPos, legNeg, &primaryVertexKF, v0ChargesAreCorrect);
     AliReducedPair* alambdaReducedPair = FillV0PairInfo(v0, AliReducedPair::kALambda0ToPPi, legPos, legNeg, &primaryVertexKF, v0ChargesAreCorrect);
-
-    if(goodK0s && k0sReducedPair->fMass[0]>fK0sMassRange[0] && k0sReducedPair->fMass[0]<fK0sMassRange[1]) {
+    AliReducedPair* gammaReducedPair   = FillV0PairInfo(v0, AliReducedPair::kGammaConv,     legPos, legNeg, &primaryVertexKF, v0ChargesAreCorrect);
+    
+    if(fFillK0s && goodK0s && k0sReducedPair->fMass[0]>fK0sMassRange[0] && k0sReducedPair->fMass[0]<fK0sMassRange[1]) {
       TClonesArray& tracks = *(fReducedEvent->fCandidates);
       AliReducedPair *goodK0sPair = new (tracks[fReducedEvent->fNV0candidates[1]]) AliReducedPair(*k0sReducedPair);
       goodK0sPair->fMass[0] = k0sReducedPair->fMass[0];
       goodK0sPair->fMass[1] = lambdaReducedPair->fMass[0];
       goodK0sPair->fMass[2] = alambdaReducedPair->fMass[0];
+      goodK0sPair->fMass[3] = gammaReducedPair->fMass[0];
+      if(veryGoodK0s) goodK0sPair->fMCid |= (UInt_t(1)<<1);
       fReducedEvent->fNV0candidates[1] += 1;
     } else {goodK0s=kFALSE;}
-    if(goodLambda && lambdaReducedPair->fMass[0]>fLambdaMassRange[0] && lambdaReducedPair->fMass[0]<fLambdaMassRange[1]) {
+    if(fFillLambda && goodLambda && lambdaReducedPair->fMass[0]>fLambdaMassRange[0] && lambdaReducedPair->fMass[0]<fLambdaMassRange[1]) {
       TClonesArray& tracks = *(fReducedEvent->fCandidates);
       AliReducedPair *goodLambdaPair = new (tracks[fReducedEvent->fNV0candidates[1]]) AliReducedPair(*lambdaReducedPair);
-      fReducedEvent->fNV0candidates[1] += 1;
       goodLambdaPair->fMass[0] = k0sReducedPair->fMass[0];
       goodLambdaPair->fMass[1] = lambdaReducedPair->fMass[0];
       goodLambdaPair->fMass[2] = alambdaReducedPair->fMass[0];
+      goodLambdaPair->fMass[3] = gammaReducedPair->fMass[0];
+      if(veryGoodLambda) goodLambdaPair->fMCid |= (UInt_t(1)<<2);
+      fReducedEvent->fNV0candidates[1] += 1;
     } else {goodLambda=kFALSE;}
-    if(goodALambda && alambdaReducedPair->fMass[0]>fLambdaMassRange[0] && alambdaReducedPair->fMass[0]<fLambdaMassRange[1]) {
+    if(fFillALambda && goodALambda && alambdaReducedPair->fMass[0]>fLambdaMassRange[0] && alambdaReducedPair->fMass[0]<fLambdaMassRange[1]) {
       TClonesArray& tracks = *(fReducedEvent->fCandidates);
       AliReducedPair *goodALambdaPair = new (tracks[fReducedEvent->fNV0candidates[1]]) AliReducedPair(*alambdaReducedPair);
-      fReducedEvent->fNV0candidates[1] += 1;  
       goodALambdaPair->fMass[0] = k0sReducedPair->fMass[0];
       goodALambdaPair->fMass[1] = lambdaReducedPair->fMass[0];
       goodALambdaPair->fMass[2] = alambdaReducedPair->fMass[0];
+      goodALambdaPair->fMass[3] = gammaReducedPair->fMass[0];
+      if(veryGoodALambda) goodALambdaPair->fMCid |= (UInt_t(1)<<3);
+      fReducedEvent->fNV0candidates[1] += 1;
     } else {goodALambda = kFALSE;}
+    //cout << "gamma mass: " << gammaReducedPair->fMass[0] << endl;
+    if(fFillGammaConversions && goodGamma && gammaReducedPair->fMass[0]>fGammaMassRange[0] && gammaReducedPair->fMass[0]<fGammaMassRange[1]) {
+      TClonesArray& tracks = *(fReducedEvent->fCandidates);
+      AliReducedPair *goodGammaPair = new (tracks[fReducedEvent->fNV0candidates[1]]) AliReducedPair(*gammaReducedPair);
+      goodGammaPair->fMass[0] = k0sReducedPair->fMass[0];
+      goodGammaPair->fMass[1] = lambdaReducedPair->fMass[0];
+      goodGammaPair->fMass[2] = alambdaReducedPair->fMass[0];
+      goodGammaPair->fMass[3] = gammaReducedPair->fMass[0];
+      if(veryGoodGamma) goodGammaPair->fMCid |= (UInt_t(1)<<4);
+      fReducedEvent->fNV0candidates[1] += 1;
+    } else {goodGamma=kFALSE;}
     delete k0sReducedPair;
     delete lambdaReducedPair;
     delete alambdaReducedPair;
-
-    if(!(goodK0s || goodLambda || goodALambda)) continue;
+    delete gammaReducedPair;
+    
+    if(!(goodK0s || goodLambda || goodALambda || goodGamma)) continue;
     
     //  Fill histograms and the CF container
     AliDielectronVarManager::Fill(legPos, valuesPos);
@@ -631,21 +1137,23 @@ AliReducedPair* AliAnalysisTaskReducedTree::FillV0PairInfo(AliESDv0* v0, Int_t i
   AliReducedPair* reducedPair=new AliReducedPair();  
   reducedPair->fCandidateId = id;
   reducedPair->fPairType    = v0->GetOnFlyStatus();    // on the fly status
-  //reducedPair->fOnTheFly    = v0->GetOnFlyStatus();
   reducedPair->fLegIds[0]   = legPos->GetID();
   reducedPair->fLegIds[1]   = legNeg->GetID();
   if(!reducedPair->fPairType) {    // offline
     UInt_t pidPos = AliPID::kPion;
     if(id==AliReducedPair::kLambda0ToPPi) pidPos = AliPID::kProton;
+    if(id==AliReducedPair::kGammaConv) pidPos = AliPID::kElectron;
     UInt_t pidNeg = AliPID::kPion;
     if(id==AliReducedPair::kALambda0ToPPi) pidNeg = AliPID::kProton;
+    if(id==AliReducedPair::kGammaConv) pidNeg = AliPID::kElectron;
     reducedPair->fMass[0]      = v0->GetEffMass(pidPos, pidNeg);
     reducedPair->fPhi          = v0->Phi();
     if(reducedPair->fPhi<0.0) reducedPair->fPhi = 2.0*TMath::Pi() + reducedPair->fPhi;  // converted to [0,2pi]
     reducedPair->fPt           = v0->Pt();
     reducedPair->fEta          = v0->Eta();
-    reducedPair->fLxy          = 0.0;           //TODO
-    reducedPair->fOpeningAngle = 0.0;
+    reducedPair->fLxy          = v0->GetRr();
+    reducedPair->fPointingAngle = v0->GetV0CosineOfPointingAngle(vtxKF->GetX(), vtxKF->GetY(), vtxKF->GetZ());
+    reducedPair->fChisquare    = v0->GetChi2V0();
   }
   else {
     const AliExternalTrackParam *negHelix=v0->GetParamN();
@@ -654,8 +1162,14 @@ AliReducedPair* AliAnalysisTaskReducedTree::FillV0PairInfo(AliESDv0* v0, Int_t i
       negHelix = v0->GetParamP();
       posHelix = v0->GetParamN();
     }
-    AliKFParticle negKF(*(negHelix),(id==AliReducedPair::kALambda0ToPPi ? -2212 : -211));
-    AliKFParticle posKF(*(posHelix),(id==AliReducedPair::kLambda0ToPPi ? +2212 : +211));
+    Int_t pdgPos = 211;
+    if(id==AliReducedPair::kLambda0ToPPi) pdgPos = 2212;
+    if(id==AliReducedPair::kGammaConv) pdgPos = -11;
+    Int_t pdgNeg = -211;
+    if(id==AliReducedPair::kALambda0ToPPi) pdgNeg = -2212;
+    if(id==AliReducedPair::kGammaConv) pdgNeg = 11;
+    AliKFParticle negKF(*(negHelix), pdgPos);
+    AliKFParticle posKF(*(posHelix), pdgNeg);
     AliKFParticle v0Refit;
     v0Refit += negKF;
     v0Refit += posKF;
@@ -667,22 +1181,35 @@ AliReducedPair* AliAnalysisTaskReducedTree::FillV0PairInfo(AliESDv0* v0, Int_t i
     reducedPair->fPt           = v0Refit.GetPt();
     reducedPair->fEta          = v0Refit.GetEta();
     reducedPair->fLxy          = v0Refit.GetPseudoProperDecayTime(*vtxKF, massFit);
-    reducedPair->fOpeningAngle = negKF.GetAngle(posKF);
+    Double_t deltaPos[3];
+    deltaPos[0] = v0Refit.GetX() - vtxKF->GetX(); deltaPos[1] = v0Refit.GetY() - vtxKF->GetY(); deltaPos[2] = v0Refit.GetZ() - vtxKF->GetZ();
+    Double_t momV02 = v0Refit.GetPx()*v0Refit.GetPx() + v0Refit.GetPy()*v0Refit.GetPy() + v0Refit.GetPz()*v0Refit.GetPz();
+    Double_t deltaPos2 = deltaPos[0]*deltaPos[0] + deltaPos[1]*deltaPos[1] + deltaPos[2]*deltaPos[2];
+    reducedPair->fPointingAngle = (deltaPos[0]*v0Refit.GetPx() + deltaPos[1]*v0Refit.GetPy() + deltaPos[2]*v0Refit.GetPz()) / 
+                                  TMath::Sqrt(momV02*deltaPos2);
+    reducedPair->fChisquare = v0Refit.GetChi2();                              
   }
   return reducedPair;
 }
 
 
 //_________________________________________________________________________________
-UChar_t AliAnalysisTaskReducedTree::EncodeTPCClusterMap(AliESDtrack* track) {
+UChar_t AliAnalysisTaskReducedTree::EncodeTPCClusterMap(AliVParticle* track, Bool_t isAOD) {
   //
   // Encode the TPC cluster map into an UChar_t
   // Divide the 159 bits from the bit map into 8 groups of adiacent clusters
   // For each group enable its corresponding bit if in that group there are more clusters compared to
   // a threshold.
   //
+  AliESDtrack* esdTrack=0x0;
+  AliAODTrack* aodTrack=0x0;
+  if(isAOD)
+    aodTrack=static_cast<AliAODTrack*>(track);
+  else
+    esdTrack=static_cast<AliESDtrack*>(track);
+  
   const UChar_t threshold=5;
-  TBits tpcClusterMap = track->GetTPCClusterMap();
+  TBits tpcClusterMap = (isAOD ? aodTrack->GetTPCClusterMap() : esdTrack->GetTPCClusterMap());
   UChar_t map=0;
   UChar_t n=0;
   UChar_t j=0;
@@ -695,12 +1222,47 @@ UChar_t AliAnalysisTaskReducedTree::EncodeTPCClusterMap(AliESDtrack* track) {
 }
 
 
+//_________________________________________________________________________________
+Int_t AliAnalysisTaskReducedTree::GetSPDTrackletMultiplicity(AliVEvent* event, Float_t lowEta, Float_t highEta) {
+  //
+  // Count the number of SPD tracklets in a given eta range
+  //
+  if (!event) return -1;
+  
+  Int_t nTracklets = 0;
+  Int_t nAcc = 0;
+  
+  if(event->IsA() == AliAODEvent::Class()) {
+    AliAODTracklets *tracklets = ((AliAODEvent*)event)->GetTracklets();
+    nTracklets = tracklets->GetNumberOfTracklets();
+    for(Int_t nn=0; nn<nTracklets; ++nn) {
+      Double_t theta = tracklets->GetTheta(nn);
+      Double_t eta = -TMath::Log(TMath::Tan(theta/2.0));
+      if(eta < lowEta) continue;
+      if(eta > highEta) continue;
+      ++nAcc;
+    }
+  } else if(event->IsA() == AliESDEvent::Class()) {
+    nTracklets = ((AliESDEvent*)event)->GetMultiplicity()->GetNumberOfTracklets();
+    for(Int_t nn=0; nn<nTracklets; ++nn) {
+      Double_t eta = ((AliESDEvent*)event)->GetMultiplicity()->GetEta(nn);
+      if(eta < lowEta) continue;
+      if(eta > highEta) continue; 
+      ++nAcc;
+    }
+  } else return -1;
+  
+  return nAcc;
+}
+
+
 //_________________________________________________________________________________
 void AliAnalysisTaskReducedTree::FinishTaskOutput()
 {
   //
   // Finish Task 
   //
+  
   //fTreeFile->Write();
   //fTreeFile->Close();
 }